CLI
The theway command line and its fifteen subcommands.
The theway program has fifteen subcommands: install, uninstall, list, archive, change, task done, path, project, config, standards, context, workflow, authority, validate-id and next-id. Install writes it to ~/.local/bin/theway (or $THEWAY_INSTALL_DIR/theway), and the slash commands call it as plain theway, so its folder must be on your PATH. See Installation.
theway install [--home <path>] [--standards <keys>]
theway uninstall
theway list [--project <key>]
theway archive <change-id> [--force] [--project <key>]
theway change <change-id> [--project <key>]
theway task done <change-id> <n>... [--project <key>]
theway path [<change-id>] [--verbose] [--project <key>]
theway project [--project <key>]
theway config [--project <key>]
theway standards <engineering|develop|document> [--project <key>]
theway context <engineering|develop|document> [<change-id>] [--project <key>]
theway workflow [<name>] [--input <name>=<value>]... [--compact] [--project <key>]
theway authority
theway validate-id <id> [--series]
theway next-id <series-id> [--count <n>] [--project <key>]It needs Node.js 22.12 or later and exits 1 with a message on older versions.
Locations
The data home holds the config, the standards, the templates and the change folders. The CLI resolves it on every run, in this order:
THEWAY_HOME, when it is set and not empty.- The pointer file
${XDG_CONFIG_HOME:-~/.config}/theway/home, when it exists and is not empty. Install writes it whenever the resulting home is not the default: one chosen with--homeor the install question, one set byTHEWAY_HOME, or the custom home an earlier pointer names on a reinstall. ~/.theway.
theway path --verbose says which one it used.
Every subcommand that uses a project derives its key from the current directory (see project); --project <key> replaces it. A project's files live in <home>/projects/<key>/.
User standards live in <home>/standards/ (every project) and <home>/projects/<key>/standards/ (one project). Install never touches them.
Other environment variables:
CLAUDE_CONFIG_DIRreplaces~/.claude.THEWAY_INSTALL_DIRreplaces~/.local/bin, for install and uninstall.
install
npx --yes @pixelfactoryio/theway@latest installCopies the plugin to ~/.claude/skills/theway, the CLI to ~/.local/bin/theway, sets up the data home (--home, else THEWAY_HOME, else the home the pointer names, else ~/.theway), writes or removes the pointer file and adds the two permission rules to ~/.claude/settings.json, always dropping the Edit rule earlier versions added for the new and the previous home, and dropping the previous home's Read rule when the home changed. It stops and changes nothing when ~/.local/bin/theway is another program, not a theway binary. It also stops and changes nothing when the data home is your home folder or one of its parents, or a custom home containing a glob character or a line break. It prints the export PATH=… line when the install folder is not on PATH, and warns when another theway comes first on PATH. Run it through npx, which carries the plugin files; the installed theway install exits 1 and prints the npx command. See What install writes.
On a first install from a terminal (stdin and stdout), it asks where to keep the data home, only when theway was never installed, then which opt-in standards to enable, only when the data home has no config.yaml. The options answer without a question:
--home <path>: the data home, an absolute path or one starting with~/.--standards <keys>: the opt-in standards to enable in a newconfig.yaml, comma-separated (core_principles,sre,web_development,quality), ornone.
It exits 1 and changes nothing when:
--homeis not an absolute path and does not start with~/:theway: invalid --home '<value>': <reason>; nothing was changed, with<reason>must be an absolute path or start with ~/, ormust not be emptyfor a value of only spaces (an empty--home ''is refused by the argument parser);--homeand a setTHEWAY_HOMEname different paths:theway: --home <a> and THEWAY_HOME <b> differ; unset THEWAY_HOME or drop --home; nothing was changed;--standardsnames an unknown key:theway: unknown standard '<element>' in --standards; valid: core_principles, sre, web_development, quality, or none;--standardscombinesnonewith a key:theway: --standards none cannot be combined with other standards;--standardsis given and the data home already has aconfig.yaml:theway: --standards applies only to a first install; <home>/config.yaml exists, so set standards.<key>.enabled there instead; nothing was changed;- you cancel a question:
theway: install cancelled; nothing was changed.
With no terminal and no --standards, a first install leaves the opt-in standards off and prints the line that says how to enable one.
uninstall
npx --yes @pixelfactoryio/theway@latest uninstallRemoves ~/.claude/skills/theway, ~/.local/bin/theway when it is a theway binary, the pointer file and the permission rules of THEWAY_HOME, of the home the pointer names and of ~/.theway. The data home is kept.
list
theway listPrints a header line, theway changes — <key>, then the active changes of the project, then the archived change folders and a summary line. An active change is one line, <change-id> <files> files <done>/<total> tasks done, the ID padded to 20 characters: <files> counts every regular, non-hidden file directly in the change folder, and the tasks are those of its change.yaml. A change whose change.yaml is missing or invalid shows its first error in place of the count: invalid: not found, invalid: version: must be theway.change/v1beta. Used by /theway:list and /theway:archive.
A --project value must follow the rule of project, and a derived key must be at most 200 characters; otherwise it exits 1 with one line on stderr.
archive
theway archive <change-id> [--force]Moves <home>/projects/<key>/changes/<change-id> to <home>/projects/<key>/changes/archive/YYYY-MM-DD-<change-id>, with today's local date, and prints Archived: <path>.
It exits 1 and moves nothing when:
-
the key is invalid (see
project) or<change-id>does not follow the rule ofpath; -
the change folder does not exist;
-
the archive folder already exists;
-
its
change.yamlis invalid:Error: <change-id> has an invalid change.yaml — not archiving. changes/<change-id>/change.yaml: <where>: <message> Fix it, or re-run with --force. -
a task of its
change.yamlis open. It prints each one with its number and the first line of its text:Error: <change-id> has open tasks — not archiving. 2. Answer 429 with a `Retry-After` header when the bucket is empty Tick them with theway task done, or re-run with --force.
--force archives anyway and prints WARNING: archiving with an invalid change.yaml (--force), or WARNING: archiving with open tasks (--force): followed by the open tasks.
change
theway change <change-id>Validates <home>/projects/<key>/changes/<change-id>/change.yaml, the file that holds a change's description and its tasks:
version: theway.change/v1beta
description: Limit requests per API key with a token bucket
tasks:
- text: Add a token bucket per API key, kept in memory
done: true
- text: Answer 429 with a `Retry-After` header when the bucket is empty
- text: Read the limit and the burst from the settings| Where | Rule | Message |
|---|---|---|
| file | exists and is a YAML map | not found · invalid YAML: <reason> · must be a map |
| any node | no anchor (&name) and no alias (*name) | anchors and aliases are not allowed |
version | required, exactly theway.change/v1beta | must be theway.change/v1beta |
description | required, a non-empty string on one line | must be a non-empty string on one line |
tasks | required, a list with at least one item | must be a list with at least one task |
tasks[i] | a map | must be a map |
tasks[i].text | required, a non-empty string | must be a non-empty string |
tasks[i].done | optional, true or false; absent means false | must be true or false |
| any other key | at the root or in a task | unknown key |
A task's number is its position in the list, counted from 1; tasks[i] in an error is counted from 0. A missing required key is reported as <key>: is required. Every error is reported, in the file's key order, then the missing keys.
Anchors and aliases are checked first: each one gives its own line, in document order, and no other rule is checked. The line's <where> is the path of the node in the table above, never deeper: a map key takes the path of the map that holds it, and a node below a root key's value or below tasks[i].<key> the path of its nearest ancestor the table names (description: [&a x] gives description, tasks[0].text: {k: &a v} gives tasks[0].text). An anchor on the file's root map has no <where>: the line is anchors and aliases are not allowed.
When the file is valid, it prints the change as JSON on stdout and exits 0:
{
"id": "<change-id>",
"dir": "<change folder>",
"description": "…",
"tasks": [
{
"n": 1,
"text": "…",
"done": true
}
]
}When it is not, it prints each error on stderr and exits 1, with nothing on stdout:
theway: changes/<change-id>/change.yaml: not found
theway: changes/<change-id>/change.yaml: tasks[1].done: must be true or falseThe scaffold and fix-spec run it after writing a change.yaml, and fix the file until it exits 0. The key and the change ID follow the rules of archive.
task done
theway task done <change-id> <n>...Ticks the tasks numbered <n> of the change's change.yaml: it sets done: true on each and keeps the rest of the file (comments, key order, line endings and its mode). An inserted done: true line ends as the line it follows (\r\n in a CRLF file). A task already done stays done. It prints <done>/<total> tasks done and exits 0.
It exits 1 and writes nothing when the file is invalid (with the error lines of change), or with one line per bad argument, in the order given, when an argument is not a task number (digits not starting with 0) or is greater than the number of tasks:
theway: changes/<change-id>/change.yaml: task 01: not a task number
theway: changes/<change-id>/change.yaml: task 9: no such task (1 to 3)When the file or its folder cannot be written, it exits 1 with one line, the file left as it was:
theway: changes/<change-id>/change.yaml: cannot write: EACCES: permission denied, access '<path>'The implementer runs it when a task is finished. To undo a tick, edit change.yaml. theway task alone prints its help.
path
theway path
theway path <change-id>Prints one line on stdout:
theway path: the data home, such as/home/you/.theway. It derives no key; a given--projectis still validated.theway path <change-id>:<home>/projects/<key>/changes/<change-id>, whether or not the folder exists yet, such as/home/you/.theway/projects/-home-you-code-my-api/changes/add-xin/home/you/code/my-api. A single argument is always a change ID.
The slash commands run it to find the home (for the config, standards and templates) and the change folder they read and write.
--verbose adds one line on stderr naming where the home came from:
theway: home /data/tw (from pointer)The source is env, pointer or default. When THEWAY_HOME is set and differs from the pointer file, it prints the THEWAY_HOME value and one warning on stderr that names both values and their sources. Run install again with the new THEWAY_HOME to update the pointer.
A change id must be lowercase letters and digits in words separated by single hyphens (as validate-id produces), at most 200 characters. Any other value exits 1 with one reason on stderr:
theway: invalid change id '..': must be lowercase letters and digits in words separated by single hyphensThe key is checked first, as project says.
project
theway project
theway project --project <key>Prints the project key and the project folder, in /home/you/code/my-api:
key: -home-you-code-my-api
dir: /home/you/.theway/projects/-home-you-code-my-apiThe key is the project root's absolute path with every character outside [A-Za-z0-9] replaced by -, as Claude Code names its ~/.claude/projects/ folders. The project root is:
- in a git repository, any of its subfolders or a linked worktree: the main repository's root (git's common directory,
.git, without its last segment), so every worktree shares one key; - in a bare repository or one with a separate git dir: the worktree root (
git rev-parse --show-toplevel), else the current directory; - outside git, or without
gitonPATH: the current directory.
The root is resolved to its physical path (symlinks followed) before the key is built. A linked worktree of a --separate-git-dir repository and a submodule get their own worktree root, so they do not share the main repository's key. See Project key.
--project <key> replaces the derived key; no git command runs. Every subcommand that uses a project takes it: list, archive, change, task done, path, project, config, standards, context, workflow and next-id. It exits 1 with one line on stderr when:
-
the
--projectvalue is not letters, digits and-, 1 to 200 characters:theway: invalid project 'a/b': must be letters, digits and "-", at most 200 characters -
the derived key is longer than 200 characters:
theway: project key for <root> is longer than 200 characters; pass --project <key>
Every subcommand checks the key first, then its other arguments; an empty <change-id> for archive and an invalid --count for next-id are refused by the argument parser before it.
config
theway configPrints the effective configuration of the project as YAML on stdout: the defaults, then <home>/config.yaml, then <home>/projects/<key>/config.yaml when it exists, merged key by key (see Layering). It prints every key, without comments, and every value it prints is valid. /theway:engineering, with or without --light, takes its keys from the same config, through context.
The standards section lists every switchable standard of the project, each as <key>: with its effective enabled: the four opt-in keys core_principles, sre, web_development and quality first, then the keys of the user standards of <home>/standards/ and <home>/projects/<key>/standards/, sorted.
standards:
core_principles:
enabled: false
...An invalid value, an unknown key, a section that is not a map or a file whose root is not a map is ignored with a warning on stderr, the global file's first, and the exit code stays 0. <file> is the path relative to the home, config.yaml or projects/<key>/config.yaml:
theway: warning: <file>: <key> must be <rule>; ignored
theway: warning: <file>: unknown key <key>; ignored
theway: warning: <file>: <key> must be a map; ignored
theway: warning: <file>: not a map; ignored
theway: warning: <file>: standards.<key> has no standard file; ignored
theway: warning: <file>: standards.<key> cannot be switched; ignoredA workflow key, which earlier versions read for workflow.defaults, is an unknown key now: theway: warning: config.yaml: unknown key workflow; ignored. Set the value in the workflow file or in the prompt's header, and remove the key.
The standards warnings name a standards key that no standard file of the project gives, and the key of a standard that cannot be switched: one that is always read (interaction, develop, authority, tamm_framework, spec_review, spec_investigation), unless the project's <home>/projects/<key>/standards/ holds a file with that name (or, for authority, unless the global authority.md is one .shipped.json does not list, which makes it a user standard), or a convention standard (commits, git_host).
It exits 1 and prints nothing on stdout when:
-
the key is invalid, with the line of
projecton stderr; -
<home>/config.yamlis missing:theway: config.yaml not found in <home>; run npx --yes @pixelfactoryio/theway@latest install, then /reload-plugins -
either file exists but cannot be read:
theway: <file>: cannot be read -
either file is not valid YAML, duplicate keys included:
theway: <file>: invalid YAML: Map keys must be unique at line 3, column 3
standards
theway standards engineering
theway standards develop
theway standards documentPrints the absolute path of every enabled standard that applies to the phase, one per line: the regular .md files directly in <home>/standards/, then directly in <home>/projects/<key>/standards/, each group sorted by name. Subfolders and other files are ignored. In <home>/standards/, interaction.md, develop.md, tamm-framework.md, spec-review.md and spec-investigation.md are never listed, nor authority.md when .shipped.json lists standards/authority.md (one it does not list is your own standard, key authority, listed and switched like any other); commits.md and git-host.md, the convention standards, are never listed from either folder; core-principles.md, sre.md, web-development.md and quality.md are the opt-in standards; the other files that .shipped.json lists as standards/<name>, and any *.default.md copy there, belong to theway and are not listed. A project file with the same name as a global one replaces it for the phases the project file applies to; for the other phases, the global file is printed as usual.
- A standard, opt-in or yours, applies to the phases its
applies_tofrontmatter lists (engineering,developand/ordocument), or to all three without one. - A standard is printed only when its effective
standards.<key>.enabledistrue: it computes the project's config asconfigdoes, without printing its warnings. A missing<home>/config.yamlcounts as empty, so the defaults apply: opt-in standards off, user standards on.
With nothing to print, it prints nothing and exits 0.
/home/you/.theway/standards/tdd.md
/home/you/.theway/projects/-home-you-code-my-api/standards/review.mdAn enabled file whose applies_to has any other value or form is skipped for every phase, with a warning on stderr; the exit code stays 0:
theway: warning: <path>: applies_to must list engineering, develop and/or document; skippedA file that cannot be read is skipped, with a warning on stderr; the others are still listed and the exit code stays 0:
theway: warning: <path>: cannot be read; skippedIt exits 1 and prints nothing on stdout when:
-
the key is invalid, with the line of
projecton stderr; -
the phase is not
engineering,developordocument:theway: invalid phase '<value>': must be engineering, develop or document -
either
config.yamlcannot be read or is not valid YAML, with the message ofconfig.
The commands get the same list through context.
context
theway context <engineering|develop|document>
theway context <engineering|develop|document> <change-id>Prints what a command loads in its first step, as one YAML document with these keys, in this order:
home: the data home, aspathprints it;project: the project key, asprojectprints it;project_dir: the project folder,<home>/projects/<key>;change_dir: only with<change-id>, the foldertheway path <change-id>prints;standards: the pathsstandardsprints for the phase, as a list,[]when there are none;config: the effective configconfigprints.
home: /home/you/.theway
project: -home-you-code-my-api
project_dir: /home/you/.theway/projects/-home-you-code-my-api
change_dir: /home/you/.theway/projects/-home-you-code-my-api/changes/add-redis-cache
standards:
- /home/you/.theway/standards/tdd.md
config:
standards:
...It writes the warnings of config to stderr once. It exits 1 and prints nothing on stdout when the key is invalid (see project), when the phase is invalid (the message of standards), when <change-id> does not follow the rule of path, or when <home>/config.yaml is missing or a config file cannot be read or is not valid YAML (the messages of config).
/theway:document runs it with document. The shipped prompts run it too: prompts/change.md with develop and the change ID, taking change_dir as the change folder, and prompts/spec-review.md with engineering.
workflow
theway workflow
theway workflow <name>
theway workflow <name> --input <name>=<value> [--input <name>=<value>]...
theway workflow <name> --input <name>=<value> --compactReads one workflow and every prompt its steps use, checks them, and prints the resolved document as JSON on stdout. /theway:workflow runs it first to read the workflow's inputs, then with --input and --compact to get the document it runs.
Which file:
- With
<name>:<home>/projects/<key>/workflows/<name>.yamlwhen it is a file, else<home>/workflows/<name>.yaml. A<name>matches^[a-z0-9]+(-[a-z0-9]+)*$; the workflow's name is its file stem. - Without
<name>: the one workflow that setsdefault: true, among the project's workflow files and the global ones no project file of the same name hides. The shippeddevelopsets it. When none sets it, it exits 1 withtheway: no workflow sets default: true; when several do, with a line naming them, for exampletheway: workflows/agents.yaml and workflows/develop.yaml both set default: true. - Each prompt a step names,
prompts/<name>.md, is<home>/projects/<key>/prompts/<name>.mdwhen it is a file, else<home>/prompts/<name>.md. - A
*.default.yamlfile is the shipped copy install writes next to an edited file, never a workflow.
--input <name>=<value>, repeatable, gives a workflow input its value. When every required input is given, the document says "resolved": true and every ${{ inputs.… }} and ${{ matrix.… }} reference is replaced in each run's prompt. Without --input, a workflow that declares a required input keeps its input references as written and says "resolved": false; one with no required input resolves with each input's default, else the empty string. Refused, each with one line: an input the workflow does not declare, an invalid change ID for an input of type: change, a value without =, a name given twice and, once any --input is given, a required input that is not given or is given empty (theway: --input <name>: required input is not given).
theway workflow agents --input change=add-foo, with the shipped agents.yaml (shortened):
{
"name": "agents",
"version": "theway.workflow/v1beta",
"description": "Implement, review and open the PR through agents",
"file": "/home/you/.theway/workflows/agents.yaml",
"default": false,
"inputs": {
"change": { "description": "The change to implement", "required": true, "default": null, "type": "change", "value": "add-foo" }
},
"runs_on": "agents",
"resolved": true,
"steps": [
{
"index": 0,
"uses": "prompts/branch.md",
"file": "/home/you/.theway/prompts/branch.md",
"description": "Sync the default branch and create or check out the change's feature branch",
"runs_on": "session",
"model": null,
"matrix": null,
"with": { "change": "${{ inputs.change }}" },
"runs": [{ "label": "1.branch", "with": { "change": "add-foo" }, "prompt": "# Branch\n\nYou prepare the feature branch of the change `add-foo`. …" }],
"on_fail": null,
"tries": null
},
{ "index": 1, "uses": "prompts/implement.md", "...": "..." },
{
"index": 2,
"uses": "prompts/review.md",
"runs_on": "agents",
"model": "opus",
"matrix": { "key": "lens", "values": ["prompts/conformance.md", "prompts/correctness.md"] },
"runs": [
{ "label": "3.review[prompts/conformance.md]", "...": "..." },
{ "label": "3.review[prompts/correctness.md]", "...": "..." }
],
"...": "..."
},
{
"index": 3,
"uses": "prompts/triage.md",
"...": "...",
"on_fail": { "uses": "prompts/fix-review.md", "model": "opus", "label": "4.fix-review", "prompt": "# Fix the Review\n\n…", "...": "..." },
"tries": 1
},
{ "index": 4, "uses": "prompts/open-pr.md", "...": "..." },
{ "index": 5, "uses": "prompts/ci.md", "...": "...", "tries": 2 }
]
}inputsholds each declared input with itsvalue: the given one, else itsdefault, else"";nullwhile the document is not resolved.- Each step has its
index,usesand the prompt's absolutefileanddescription, its effectiveruns_on(its own, else the workflow's) andmodel(its own, else its prompt's;nullfor a step that runs in your session), itsmatrix, itswithas written, itsrunsand itson_failandtries. - A step has one run, or one per matrix value. Each run has its
label,<n>.<prompt>(<n>.<prompt>[<value>]for a matrix copy), every input of its prompt with its final value, and the prompt's body with the values substituted. - The
on_failhas its ownlabel,<n>.<prompt>,modelandprompt.
--compact prints the same document without its bulky text, for a session to pass on whole. It checks the workflow the same way and fails with the same lines.
- The top level keeps
name,file,resolved,runs_onandinputs, each with itsvalue. - Each step keeps
index,uses,file,runs_on,model,matrix,runs,on_failandtries; nodescriptionand nowithas written. - Each run keeps its
labeland itswith, the final values; theon_failitsuses,file,model,labelandwith. Neither has aprompt: an agent reads the prompt'sfileand uses thewithvalues where its text says${{ inputs.<name> }}.
{
"name": "agents",
"file": "/home/you/.theway/workflows/agents.yaml",
"resolved": true,
"runs_on": "agents",
"inputs": {
"change": { "description": "The change to implement", "required": true, "default": null, "type": "change", "value": "add-foo" }
},
"steps": [
{
"index": 0,
"uses": "prompts/branch.md",
"file": "/home/you/.theway/prompts/branch.md",
"runs_on": "session",
"model": null,
"matrix": null,
"runs": [{ "label": "1.branch", "with": { "change": "add-foo" } }],
"on_fail": null,
"tries": null
},
{ "index": 1, "uses": "prompts/implement.md", "...": "..." },
{ "index": 2, "uses": "prompts/review.md", "...": "..." },
{
"index": 3,
"uses": "prompts/triage.md",
"...": "...",
"on_fail": {
"uses": "prompts/fix-review.md",
"file": "/home/you/.theway/prompts/fix-review.md",
"model": "opus",
"label": "4.fix-review",
"with": { "change": "add-foo" }
},
"tries": 1
},
{ "index": 4, "uses": "prompts/open-pr.md", "...": "..." },
{ "index": 5, "uses": "prompts/ci.md", "...": "...", "tries": 2 }
]
}A file whose version is theway.workflow/v1 is no longer read:
theway: workflows/<name>.yaml: theway.workflow/v1 is no longer read: rewrite it as theway.workflow/v1betaMoving from v1 says what replaces each of its parts.
Every mistake of the file and of the prompts it uses is one line on stderr, theway: <file>: <place>: <message>, in file order; it then prints nothing on stdout and exits 1. <file> is the path relative to the home, or the folder that holds it:
theway: invalid workflow name '<name>'
theway: workflows/w.yaml: not found in <home>/projects/<key>/workflows or <home>/workflows
theway: workflows/w.yaml: version: must be theway.workflow/v1beta
theway: workflows/w.yaml: steps[0].uses: prompts/nope.md not found in <home>/projects/<key>/prompts or <home>/prompts
theway: workflows/w.yaml: steps[1].with: required input change is not set
theway: workflows/w.yaml: steps[2].on-fail: needs tries (an integer from 1 to 10)
theway: prompts/open-pr.md: body: ${{ inputs.nope }} names no input of this prompt
theway: --input change: required input is not givenValidation describes every rule. It also exits 1 with the line of project for an invalid key.
authority
theway authorityPrints the authority whole, without trailing blank lines. A file that is empty or holds only whitespace counts as missing.
-
When
.shipped.jsonlistsstandards/authority.md, it prints<home>/standards/authority.md, else the shipped<home>/standards/authority.default.md. When neither can be printed, it exits 1:theway: no <home>/standards/authority.md; run npx --yes @pixelfactoryio/theway@latest install, then /reload-plugins -
When
.shipped.jsondoes not list it,authority.mdis your own standard (seestandards), and it prints<home>/standards/authority.default.mdonly. When that cannot be printed, it exits 1:theway: no <home>/standards/authority.default.md; run npx --yes @pixelfactoryio/theway@latest install, then /reload-plugins
The commands that spawn agents quote its output verbatim in every agent prompt, and /theway:workflow, /theway:document and /theway:archive follow it in the session.
validate-id
theway validate-id <id>
theway validate-id <id> --seriesChecks a change ID. It exits 0 when the ID is valid. Otherwise it exits 1 and prints one line on stderr:
invalid change id '<id>': <reason>Every ID must be lowercase kebab-case ([a-z0-9] segments joined by single hyphens) and start with add-, update-, refactor-, remove- or fix-. An ID with uppercase letters is rejected with uppercase letters are not allowed; use lowercase kebab-case, one with underscores with underscores are not allowed; use kebab-case (-); any other start is rejected with:
invalid change id '<id>': must start with a verb prefix: add-, update-, refactor-, remove- or fix-- Without
--series(a standalone change): the ID must not end in a one- or two-digit number. - With
--series(a series member): the ID must end in a two-digit ordinal from01, such asadd-user-auth-01. Letter suffixes,-00and double ordinals are rejected.
/theway:engineering, with or without --light, runs it before it writes a standalone change folder; next-id validates the members of a series.
next-id
theway next-id <series-id>
theway next-id <series-id> --count <n>Prints the next <n> free member IDs of a series, one per line (--count defaults to 1):
add-user-auth-04
add-user-auth-05-
A trailing
-NNis removed from<series-id>first, soadd-user-auth-07gives the same IDs asadd-user-auth. The rest must fit thevalidate-idformat and must not end in a one- or two-digit number; when it is invalid, it exits 1 with aninvalid change id '<id>': <reason>line,<id>being the series ID without its ordinal, for example:invalid change id 'add-thing-01': ends in a number (-01); a series id cannot end in a number -
It counts the folders
<home>/projects/<key>/changes/<series-id>-NNand the archived<home>/projects/<key>/changes/archive/YYYY-MM-DD-<series-id>-NN, and continues after the highestNN, or from01when there is none. -
A
--countthat is not a positive integer is rejected witherror: option '--count <n>' argument '<value>' is invalid. must be a positive integer. When the last ID would be past-99, it exits 1:theway: series <series-id> would go past -99
/theway:engineering runs it to name the members of a new series.