@pathmode/cli
v2.7.0
Published
Find the product decisions a request leaves open before your coding agent builds: a deterministic, keyless preflight for intent.md and OpenSpec changes
Maintainers
Readme
@pathmode/cli
Find the product decisions a request leaves open, before your coding agent builds.
pathmode preflight grades an intent.md, or an OpenSpec change, against six readiness checks.
No account, no model call, and nothing leaves your machine.
Try it on a real example
Fieldnote is a small fictional billing app. Its ticket
FN-412 asks for one thing: a Cancel plan button. A coding agent running the
Pathmode plugin was given one instruction,
implement FN-412, and changed no product code. It wrote an intent.md and stopped
(what the agent did and said).
Check that file yourself:
git clone -b run-4/fn-412-keyless-proposal https://github.com/pathmodeio/fieldnote
cd fieldnote
npx -y @pathmode/cli preflightRead intent.md at intent.md
✓ goal
✓ objective
✓ outcomes
✓ constraints
✓ edgeCases
✓ verification
✓ Preflight passed. 6/6 checks.
⛔ Not ready to hand to an agent: 4 product choices still unresolved.
⛔ When a customer cancels, does access end immediately or at the end of the period they have already paid for?
⛔ Does cancelling refund any unused part of the current period?
⛔ Can a customer undo a scheduled cancellation before the period ends?
⛔ What happens when a past-due (payment failed) customer cancels?
A recommendation attached to an open choice is an assumption, not a requirement. A person answers or explicitly excludes each one before implementing.
✓ Title ✓ Objective ✓ Outcomes ✓ Constraints ✓ Edge cases ✓ VerificationThe spec itself is complete, and it is still not ready. The ticket never says whether a customer
who cancels keeps the rest of the month they paid for, and the only cancel code in the repository
was written for refunds: it ends access on the spot. Building the button on it would take paid days
away from every customer who cancels. The agent recorded that as an open choice, with its
recommendation, the alternative, and what each costs, and left the decision to a person. The exit
code is 1 while any choice is open, so the same command works as a CI gate.
What a pass means
- Validation (
pathmode validate, or the GitHub Action) checks structure: the file is well-formed IntentSpec. - Preflight checks readiness: a specific title, an objective with an actor and a concrete problem,
at least two observable outcomes, a hard constraint, an edge case with its expected behavior, a
check specific enough to run, and no open product choice. It reads your text against a fixed
vocabulary, so a
?can mean the check missed valid phrasing. It cannot tell you the decision is right. - A person decides each open choice. Until then a recommendation is an assumption, not a
requirement. Without a workspace, you answer the agent, and it records each answer in
intent.mdwith your words for that choice, marked answered locally (unverified): a faithful record of the conversation that nobody else has seen or signed. With a workspace, a reviewer answers from a review link, and the answer and their authorization of that exact revision are recorded against their name. - Verification after the build tests whether the outcomes actually happened.
Install
npm i -g @pathmode/cliThis installs the pathmode binary (pathmode --version to check). Or run any command without
installing, as above, with npx -y @pathmode/cli <command>.
preflight and validate need no account and make no network request.
Connect a workspace
The other five commands talk to the Pathmode API and need a key. Connect when the evidence behind a decision cannot be committed to the repository, or when someone who is not in the repository needs to review and authorize a spec.
pathmode login # paste your pm_live_ API key
pathmode init # write intent.md, .cursorrules, CLAUDE.mdAuthentication
- Open your Pathmode workspace, go to Workspace Settings > API Keys, and create a key. Keys start with
pm_live_. - Run
pathmode login. With no flags it prompts for the key and workspace ID, verifies them against the API, and reports the workspace it connected to.
pathmode login
# or non-interactively:
pathmode login --key pm_live_xxx --workspace <workspace-id>Credentials are written to ~/.pathmode/config.json with 0600 permissions.
Environment variables
Environment variables take precedence over the config file, so use them in CI instead of committing a config:
| Variable | Purpose | Default |
|---|---|---|
| PATHMODE_API_KEY | API key (pm_live_...) | none |
| PATHMODE_API_URL | API base URL | https://pathmode.io |
| PATHMODE_WORKSPACE_ID | Workspace ID | none |
Commands
| Command | What it does | Needs auth |
|---|---|---|
| preflight | Run the readiness gate on an intent.md or OpenSpec change | No |
| validate | Check a spec against the IntentSpec schema | No |
| login | Store and verify your API key | Sets it up |
| init | Scaffold intent files in a fresh repo | Yes |
| pull | Refresh local context files from the workspace | Yes |
| push | Send status changes and notes back | Yes |
| status | List workspace intents and their status | Yes |
preflight [path]
pathmode preflight # ./intent.md, else intent/**/intent.md, else the active OpenSpec change
pathmode preflight specs/login.md # a specific intent file
pathmode preflight intent/checkout/intent.md # one feature when intent/ holds several
pathmode preflight openspec/changes/add-auth # an OpenSpec change directorySix deterministic checks: title, objective, outcomes, constraints, edge cases, verification. Pure
functions, no model call, no network; the same spec always gets the same verdict. A ? means the
check read your text and could not confirm it, which is often the check's fixed vocabulary rather
than your writing. Reading an OpenSpec change writes nothing.
Exit codes: 0 ready, 1 the gate blocks, 2 nothing to grade. With several OpenSpec changes
present it refuses to guess and lists them.
Markdown proto-specs may use ## Problem or ## Why in place of ## Objective, and
## Proposed outcome in place of ## Outcomes; YAML frontmatter is optional for preflight.
Canonical sections win if both are present. A written outcome is preserved even if
it does not yet pass the gate. A ## What section is not read as outcomes; when outcomes
are missing, the verdict names it and says where success criteria belong. Open questions still need human resolution before
implementation.
With no path, preflight reads ./intent.md, or, when there is none, the single file
named intent.md in an intent/ folder (intent/intent.md or intent/<feature>/intent.md),
where Anthropic's AI-native SDLC playbook keeps it. The spec.md and plan.md beside it are
never graded as the intent. With several features in intent/, or a file there named something
else, it exits 2 and names the command to run. Preflight never modifies the source file.
validate [file]
Validates the YAML frontmatter of a markdown file against the IntentSpec schema. Exits 0 when valid and 1 when not, printing each failed field, so it works as a CI gate.
pathmode validate # defaults to intent.md
pathmode validate specs/login.mdRequired fields are id, status, objective, and outcomes. status must be one of draft, validated, approved, shipped, or verified. See the full standard for the optional fields.
login
| Option | Description | Default |
|---|---|---|
| --key <key> | API key, starting with pm_live_ | prompts |
| --workspace <id> | Workspace ID | prompts |
| --url <url> | Pathmode API URL | https://pathmode.io |
If the connection test fails the config is still saved, so you can fix the network and retry with pathmode pull.
init
Pulls your workspace context and writes three files into the current directory:
intent.md, the current intent spec.cursorrules, rules for CursorCLAUDE.md, workspace context for Claude Code
pathmode init
pathmode init --dry-run # preview without writing
pathmode init --intent abc-123 # use a specific intent| Option | Description |
|---|---|
| --intent <id> | Use a specific intent instead of the current approved one |
| --dry-run | Print what would be written and exit |
pull
Re-syncs the files init created. Run it whenever the spec changes upstream.
pathmode pull
pathmode pull --only claude-md,intent-md
pathmode pull --only agents-md| Option | Description |
|---|---|
| --intent <id> | Pull a specific intent |
| --only <files> | Comma-separated subset of claude-md, agents-md, cursorrules, intent-md |
AGENTS.md is opt-in. It carries the same context as CLAUDE.md, so syncing it by default would only duplicate that file. Request it with --only agents-md if you use OpenAI Codex or a recent Cursor version.
push
Reports progress back to the workspace. The intent ID comes from the id in your local intent.md frontmatter unless you pass --intent.
pathmode push --shipped
pathmode push --verified
pathmode push --note "Rate limiting added in middleware, not the route handler"| Option | Description |
|---|---|
| --shipped | Mark the intent as shipped |
| --verified | Mark the intent as verified |
| --note <text> | Log an implementation note against the intent |
| --intent <id> | Target a specific intent |
status
Lists the workspace's intents with their status, severity, and stage.
pathmode status
pathmode status --filter approved| Option | Description |
|---|---|
| --filter <status> | One of draft, validated, approved, shipped, verified |
How CLAUDE.md is updated
init and pull do not overwrite CLAUDE.md or AGENTS.md. They replace only the block between these markers, leaving your own notes and conventions intact:
<!-- PATHMODE:START - Do not edit this section manually -->
... generated content ...
<!-- PATHMODE:END -->If the markers are absent the section is appended. .cursorrules and intent.md are fully replaced on every sync.
Using it in CI
Validate every spec on a pull request:
- uses: actions/checkout@v4
- run: npx @pathmode/cli validate intent.mdKeep context files fresh on a schedule, using repository secrets for the credentials:
- run: npm i -g @pathmode/cli
- run: pathmode pull
env:
PATHMODE_API_KEY: ${{ secrets.PATHMODE_API_KEY }}
PATHMODE_WORKSPACE_ID: ${{ secrets.PATHMODE_WORKSPACE_ID }}This package also ships an action.yml, so the same bundle runs directly as a GitHub Action that validates a spec. It reads the file input, defaulting to intent.md.
- uses: pathmodeio/validate-intentspec-action@v1
with:
file: 'intent.md'IntentSpec
validate checks against IntentSpec, the open standard for describing what a change is supposed to accomplish before an agent writes the code.
- Standard: https://intentspec.org/spec
- JSON Schema: https://intentspec.org/schema.json
License
MIT
