Skip to content

LNK

lnk is the repository command-line interface for changing a vanityURLs instance. It edits source files in custom/, runs npm run check, then stages, commits, and pushes successful write operations.

Use it when you want the change to become part of your Git history and deploy through the normal Worker workflow. Use Local helper when you only want to open an existing redirect from the terminal.

Requirements

  • A configured vanityURLs repository available locally
  • Node.js 20 or newer
  • npm
  • Git

Run the repo-local command:

./scripts/lnk --help

If you installed the workstation tools with npm run local-install, you can usually run lnk from any directory. Set V8S_REPO when an installed command needs to point at a specific local repository.

Core commands

CommandWhat it does
./scripts/lnk LONG_URL [SLUG]Add a link to custom/v8s-links.txt
./scripts/lnk LONG_URL --random-slug-length NAdd a link with a generated slug of N characters
./scripts/lnk --splat LONG_URL_WITH_:splat SLUGAdd a splat link stored as SLUG/*
./scripts/lnk list [SLUG]List generated registry entries from build/v8s.json
./scripts/lnk tag listList tag-specific random slug defaults
./scripts/lnk tag set TAG --random-slug-length NSet a random slug length for a tag
./scripts/lnk tag unset TAGRemove a tag-specific random slug length
./scripts/lnk schedule add SLUG TARGET ...Add or replace a scheduled target rule
./scripts/lnk schedule default SLUG TARGETSet the fallback target for an existing schedule
./scripts/lnk schedule list [SLUG]List schedule rules
./scripts/lnk block add DOMAIN ...Add or update a blocked domain
./scripts/lnk block keyword KEYWORD ...Add or update a blocked keyword
./scripts/lnk block allow DOMAIN ...Add or update an allowed domain
./scripts/lnk list policySummarize the active source policy
./scripts/lnk list categoriesList policy categories and severities
./scripts/lnk list domain [block|allow]List blocked and allowed domains
./scripts/lnk list keywordList blocked keywords
./scripts/lnk versionPrint the package version

List commands accept --format table or --format json. Table is the default.

Command details

./scripts/lnk https://github.com/vanityURLs github
./scripts/lnk https://www.linkedin.com/company/example social/linkedin --title LinkedIn --tags social --owner team
./scripts/lnk --splat https://docs.example.com/:splat docs
./scripts/lnk --state ephemeral --title "Launch" https://example.com campaign/launch

If you omit the slug, lnk generates one with the effective random slug length from the merged site config. custom/v8s-site-config.json can override the value, and missing values inherit from defaults/v8s-site-config.json. npm run setup writes 3 when the value is missing. Generated slugs use the configured readable alphabet. The product default is 34789abcdefghjkmnpqrstvwxy.

Override the length for one command with:

./scripts/lnk https://github.com/houba/styleGuide --random-slug-length 5

You can also configure tag-specific defaults:

./scripts/lnk tag set social --random-slug-length 5
./scripts/lnk tag list
./scripts/lnk tag unset social

When a generated link has multiple tags with configured lengths, lnk uses the shortest matching tag length. An explicit --random-slug-length or --slug-length on the command line wins over tag and global defaults.

The product defaults include training links at 4 characters and debug links at 2 characters.

If the slug already exists, lnk shows the current entry and the proposed replacement, then asks whether to replace it. Use --replace to replace without prompting, or --no-replace to leave the existing entry unchanged.

Valid states are permanent, ephemeral, expired, disabled, maintenance, and deactivated.

Useful link options:

OptionPurpose
--state STATESet the lifecycle state
--title TEXTAdd a human-readable title
--description TEXTAdd a human-readable description
--tags TAGSAdd comma-separated tags
--owner OWNERSet the accountability label
--expires-at DATESet an ISO date or timestamp
--notes TEXTAdd internal notes
--random-slug-length NSet the generated slug length for this command
--slug-length NAlias for --random-slug-length
--replaceReplace an existing slug without prompting
--no-replaceLeave an existing slug unchanged
--splatStore the slug as SLUG/* and require :splat in the target
./scripts/lnk list
./scripts/lnk list social/linkedin
./scripts/lnk list --format json

lnk list reads the generated registry. If build/v8s.json does not exist, it runs npm run build first.

Manage schedules

./scripts/lnk schedule add hangout https://zoom.us/j/work --label work --days mon,tue,wed,thu,fri --from 09:00 --to 17:00 --timezone America/Toronto --default https://discord.gg/personal
./scripts/lnk schedule default hangout https://discord.gg/personal --timezone America/Toronto
./scripts/lnk schedule list hangout

Schedule rules from this command are written to legacy custom/v8s-schedules.json during the 3.x compatibility period. New hand-authored schedules should use inline @schedule blocks in custom/v8s-links.txt. schedule add requires --label, --days, --from, and --to. Times use HH:MM; days use mon, tue, wed, thu, fri, sat, and sun.

Use --dry-run on schedule commands to print the updated JSON without writing, checking, committing, or pushing.

Manage source policy

./scripts/lnk list policy
./scripts/lnk list categories
./scripts/lnk list domain block
./scripts/lnk list keyword --format json
./scripts/lnk block add example-bad.test --category phishing --severity high --reason "Fake login page"
./scripts/lnk block keyword wallet-drain --category phishing --severity high --reason "Credential theft lure"
./scripts/lnk block allow example.com --reason "Owner-controlled domain"

Policy commands write custom/v8s-policies.json. The build turns the source policy into build/v8s-blocklist.json. Categories and severities are validated against defaults/v8s-blocklist-categories.json.

Use --dry-run on policy commands to print the updated JSON without writing, checking, committing, or pushing.

Environment overrides

VariablePurpose
DRY_RUN=truePrint the planned change without writing, checking, committing, or pushing
V8S_REPO=PATHPoint an installed lnk command at a local vanityURLs repository
V8S_LINKS_OWNER=OWNERSet the default owner value for new links
V8S_LINKS_FILE=FILEOverride the links file
V8S_SCHEDULES_FILE=FILEOverride the legacy schedules file
V8S_POLICY_FILE=FILEOverride the policy file

On Windows PowerShell:

$env:V8S_REPO="C:\path\to\YOUR-SHORT-DOMAIN"
$env:V8S_LINKS_OWNER="team"
node ./scripts/lnk https://example.com example

Write behavior

Successful link, schedule, and policy write operations run:

npm run check
git add FILE
git commit -m OPERATION_MESSAGE
git push

Direct lnk write commands use operation-specific conventional commits, such as feat(links): add SLUG, feat(schedules): update SLUG, feat(policies): block DOMAIN, and feat(policies): allow DOMAIN.

For broader local publishing, npm run local-publish selects commit messages from local_publish.commit_messages in defaults/v8s-local-config.json, merged with custom/v8s-local-config.json. The default keys are:

KeyUsed when
linksOnly custom/v8s-links.txt is staged
policiesOnly custom/v8s-policies.json or custom/v8s-blocklist.json is staged
site_configOnly custom/v8s-site-config.json is staged
mixedMultiple files or configured publish paths are staged

Override the selected local-publish message with:

npm run local-publish -- --message "chore: update short-link configuration"

That means lnk is intentionally opinionated: it is for changes you are ready to validate and publish. Use DRY_RUN=true or command-specific --dry-run when you want to preview first.

Edit this page Last modified: