reffy-cli
v1.9.1
Published
Planning system for AI assisted development.
Maintainers
Readme
reffy
Reffy is a planning system for AI assisted development. It keeps ideation artifacts in straightforward version-controlled markdown files and manages formal planning files under .reffy/reffyspec/.
Install
npm install -g reffy-cli@latestQuickstart (CLI-only)
Inside your project:
cd your-project
reffy initCommand summary:
reffy init: runs the canonical first-run setup flow, creates the.reffy/and.reffy/reffyspec/structure, writes managed instructions, reindexes artifacts, and on first-run text output prints a copy/paste instruction for your agent harness.reffy bootstrap: compatibility alias forreffy init.reffy doctor: diagnoses required Reffy setup and workspace health.reffy reindex: reconciles.reffy/manifest.jsonwith.reffy/artifactsby adding missing files and removing stale entries.reffy validate: validates.reffy/manifest.jsonagainst manifest v1 contract.reffy summarize: generates a read-only handoff summary from indexed artifacts.reffy plan create: generates proposal, task, design, and spec scaffolds from indexed Reffy artifacts.reffy plan validate|list|show|archive: manages the planning lifecycle under.reffy/reffyspec/.reffy spec list|show: inspects current spec state under.reffy/reffyspec/.reffy skill list|show|create|validate: lists, prints, scaffolds, and validates task-oriented skills under.reffy/skills/.reffy remote init|status|push|ls|cat|snapshot: links, publishes, and inspects a Paseo-backed remote.reffy/workspace.reffy remote workspace create|getandreffy remote project register|list: control-plane operations against the workspace manager actor.reffy diagram render: renders Mermaid diagrams as SVG or ASCII, including spec-aware generation from compatiblespec.mdfiles.
Run reffy <command> --help for the full flag list of any command. Most commands accept --repo PATH so they can be invoked from outside the project root (useful for agent harnesses).
Output modes:
--output text(default)--output json--json(shortcut for--output json)
Examples:
reffy reindex --output json
reffy validate --repo .
reffy doctor --output text
reffy doctor --output json
reffy summarize --output text
reffy summarize --output json
reffy plan create --change-id add-login-flow --artifacts login-idea.md
reffy plan list --output json
reffy plan archive add-login-flow
reffy spec show auth --output json
reffy skill list --output json
reffy skill show create-change
reffy skill create my-workflow
reffy skill validate
reffy remote init --provision
reffy remote status --output json
reffy remote push
reffy remote ls
reffy remote cat .reffy/manifest.json
reffy diagram render --stdin --format svg < diagram.mmd
reffy diagram render --input .reffy/reffyspec/specs/auth/spec.md --format ascii
reffy diagram render --input .reffy/reffyspec/specs/auth/spec.md --format svg --output .reffy/artifacts/auth-spec.svgDiagnostics and Inspection
reffy doctor
Audits the local Reffy setup: the .reffy/ workspace exists, manifest.json is valid, managed AGENTS.md blocks are in place, and optional tooling (mermaid CLI) is reachable. Useful as a first step when a command is misbehaving in an unfamiliar repo.
reffy doctor # human-readable check list
reffy doctor --output json # machine-readable for CIreffy summarize
Produces a read-only handoff summary of indexed artifacts — titles, kinds, tags, related changes, derived outputs. Use it to brief a fresh agent or to audit what context has accumulated under .reffy/artifacts/ without opening every file.
reffy summarize # text overview grouped by kind
reffy summarize --output json # full structured payloadreffy spec list|show
Inspects the current truth in .reffy/reffyspec/specs/. Each capability has its own spec file with requirements and scenarios; list enumerates capabilities, show prints one spec's requirements.
reffy spec list
reffy spec show remote-workspace-manager --output jsonSkills
Reffy gives procedures the same deterministic treatment it gives data. Skills are named, agent-readable task recipes that live as files under .reffy/skills/, one directory per skill:
.reffy/skills/
├── create-change/
│ └── SKILL.md
└── <your-skill>/
└── SKILL.mdEach SKILL.md opens with frontmatter that doubles as a discovery index, followed by a markdown body:
---
name: create-change
description: Turn one or more ideation artifacts into a ReffySpec change proposal.
triggers: ["new change", "plan create", "turn artifact into proposal"]
commands: ["reffy plan create", "reffy plan validate"]
managed: true
---
## When to use this skill
...
## Steps
1. ...name,description, andtriggersare required;triggersmust have at least one entry so the skill is discoverable.commandsdeclares the CLI commands the skill wraps, whichreffy doctorcross-checks against the installed CLI.managed: truemarks skills Reffy owns.reffy initscaffolds and refreshes managed skills in place and never touches unmanaged ones.
reffy init ships seven managed skills covering the core workflows: create-artifact, create-change, archive-change, supersede-change, inspect-specs, sync-remote, and diagnose. Author your own with reffy skill create <name>.
reffy skill list # name + description + managed flag
reffy skill list --output json # harness-native descriptors for programmatic discovery
reffy skill show create-change # print the procedure body
reffy skill create my-workflow # scaffold an unmanaged skill from a template
reffy skill validate # check the frontmatter contract for every skillreffy skill list/show --output json emit a tool/function-definition style descriptor (name, description, triggers, commands, managed, path; show adds body) so an agent harness can feed skills into its own discovery machinery without parsing markdown. Skills are discovered from the filesystem and validated by contract — they are not indexed in manifest.json. reffy validate enforces the skills contract (required fields, unique names, kebab-case directory names matching name) alongside the manifest, and reffy doctor warns when a skill's declared commands drift from the installed CLI.
Remote Sync
Reffy can publish the local .reffy/ workspace to a Paseo-backed remote workspace and inspect it later with native CLI commands.
The Paseo remote splits into two actor surfaces:
reffyWorkspaceManager.v1is the control plane. It owns workspace lifecycle (create / get) and project registration.reffyRemoteBackend.v2is the storage plane. One actor instance represents one sharedworkspace_idand accepts contributions keyed byproject_id.
Reffy stores manager identity once per linkage file and the workspace backend identity per workspace_id.
The current remote flow is:
- Reffy reads
project_idandworkspace_idsfrom.reffy/manifest.json. - You select one workspace projection to act on. Reffy infers the selection when
workspace_idshas exactly one entry; otherwise pass--workspace-id <id>. - Reffy connects to Paseo using
PASEO_ENDPOINTor--endpointand configured manager identity. reffy remote initresolves (or creates) the workspace through the manager, persists the workspace backend identity, and registers the localproject_idfor that workspace.reffy remote pushregisters the project if needed (idempotent on 409), then imports the full local.reffy/tree throughPOST /workspace/projects/{project_id}/importon the workspace backend actor withreplace_missing=true.reffy remote status|ls|cat|snapshotinspects the selected workspace projection per project on the workspace backend actor.
Bearer-token authentication
Every Paseo request from the CLI carries Authorization: Bearer ${PASEO_TOKEN}. The token is the only thing that grants access — manager / workspace-backend identifiers in .reffy/state/remote.json are inert without it.
Required env for any remote command:
PASEO_ENDPOINT="https://your-paseo-endpoint.example"
PASEO_TOKEN="<bearer token issued by manager provisioning>"Both must be present; the CLI fails fast and names the missing variable before issuing any network call. Endpoint is never persisted to remote.json. The token is never persisted anywhere by the CLI.
First-time provisioning
PASEO_ENDPOINT="https://your-paseo-endpoint.example" reffy remote init --provision--provision creates a fresh pod and reffyWorkspaceManager.v1 actor. The manager mints a bearer token and the CLI prints it once with strong "save this now" guidance. Save it to your team secret store immediately — the CLI does not keep a copy.
After provisioning, export it for subsequent commands:
export PASEO_TOKEN="<token from init output>"
reffy remote statusOptional overrides:
PASEO_MANAGER_PODandPASEO_MANAGER_ACTOR(or--manager-pod/--manager-actor) to reuse an existing manager actor instead of provisioning one.--workspace-id <id>when the manifest lists more than oneworkspace_ids.--createor--resolveto force-create or force-resolve the workspace through the manager during init. The default is "resolve when present, create when absent."
Joining an existing manager from another repo
Drop the team's shared values into the new repo's .env:
PASEO_ENDPOINT="..."
PASEO_TOKEN="..."
PASEO_MANAGER_POD="..."
PASEO_MANAGER_ACTOR="..."Then reffy remote init --workspace-id <id> resolves the workspace through the manager and registers the local project. No --provision, no new token issuance.
Saved remote linkage
After reffy remote init, Reffy stores manager and workspace-backend identifiers in:
.reffy/state/remote.json
{
"version": 4,
"provider": "paseo",
"manager": { "pod_name": "...", "actor_id": "..." },
"targets": {
"my-project": {
"workspace_backend": { "pod_name": "...", "actor_id": "..." },
"last_imported_at": "..."
},
"portfolio-alpha": {
"workspace_backend": { "pod_name": "...", "actor_id": "..." }
}
}
}Each workspace_id is its own backend actor. Manager identity is shared across workspaces in this linkage file.
The file deliberately does not contain the Paseo endpoint URL or the bearer token. Both are sourced from environment configuration on every command. Without PASEO_TOKEN, the identifiers in this file grant nothing.
If workspace_backend for a workspace is missing or stale, Reffy automatically resolves it through the manager and refreshes the linkage file before continuing.
Control-plane subcommands
reffy remote workspace create <workspace-id> [--label "Pretty name"]
reffy remote workspace get <workspace-id>
reffy remote workspace delete <workspace-id> --yes
reffy remote project register [--workspace-id <id>] [--project-id <id>]
reffy remote project list [--workspace-id <id>]workspace delete is destructive (it removes the shared workspace and all of its contributions) and requires --yes to proceed. The CLI also drops the workspace entry from the local linkage file on success, and treats a 404 from the manager as an idempotent "already gone" outcome.
These talk directly to the manager actor and let you provision or inspect state without re-running init.
Example flow
reffy init
reffy remote init --provision
reffy remote status
reffy remote push
reffy remote ls
reffy remote cat .reffy/manifest.json
reffy remote snapshotreffy remote status reports:
- the saved manager and workspace backend linkage for the selected workspace id
- the local manifest identity (source
project_idand selectedworkspace_id) - the remote workspace identity (
workspace.workspace_id,source.actor_type,source.version) - remote document counts and registered project counts when available
reffy remote push reports:
- whether the project was newly registered or already registered
- local document count
- imported / created / updated / deleted counts
- last imported timestamp
That makes the default prune/import behavior auditable without dropping to direct backend API calls.
Manifest Contract
Reffy keeps workspace metadata in .reffy/manifest.json. New managed manifests separate stable source identity (project_id) from plural workspace membership (workspace_ids):
{
"version": 1,
"created_at": "2026-04-18T00:00:00.000Z",
"updated_at": "2026-04-18T00:00:00.000Z",
"project_id": "my-project",
"workspace_ids": ["my-project"],
"artifacts": []
}A single .reffy/ tree can belong to more than one planning workspace:
{
"project_id": "my-project",
"workspace_ids": ["my-project", "portfolio-alpha", "nuveris-cross-project-planning"]
}Running reffy init populates project_id and workspace_ids with deterministic defaults derived from the repository name for any managed manifest that is missing them.
Using Reffy With ReffySpec
A practical pattern is:
- Use Reffy for ideation and context capture in
.reffy/artifacts/. - Use Reffy to scaffold and manage planning files in
.reffy/reffyspec/. - Keep a clear traceable path from exploratory artifacts to formal specs.
- Use Reffy commands for day-to-day workflow.
Planning lifecycle
The end-to-end arc for a non-trivial change:
# 1. Capture raw context as artifacts. Each artifact is a free-form
# markdown note; reindex registers it in the manifest.
echo "..." > .reffy/artifacts/login-flow-idea.md
reffy reindex
# 2. Scaffold a ReffySpec change from selected artifacts. This creates
# .reffy/reffyspec/changes/add-login-flow/ with proposal, design,
# tasks, and a placeholder spec delta — all linked back to the
# artifacts you passed in.
reffy plan create \
--change-id add-login-flow \
--artifacts login-flow-idea.md \
--title "Add login flow"
# 3. Edit the generated files:
# - proposal.md: Why / What Changes / Impact / Reffy References
# - design.md: decisions, data model, open questions
# - tasks.md: implementation + verification checklists
# - specs/<capability>/spec.md: ADDED / MODIFIED / REMOVED requirements
# with at least one Scenario each
# 4. Validate before implementing. Catches missing scenarios, malformed
# delta sections, and broken artifact references.
reffy plan validate add-login-flow
# 5. Implement, tick tasks in tasks.md as you go, re-validate.
# 6. Archive once shipped. Moves the change under
# .reffy/reffyspec/changes/archive/<date>-<change-id>/ and merges
# the delta spec(s) into the canonical specs in
# .reffy/reffyspec/specs/.
reffy plan archive add-login-flowUseful side commands during the arc:
reffy plan list— enumerate active and archived changes.reffy plan show <change-id>— inspect one change's state without opening every file.reffy spec list/reffy spec show <capability>— see the canonical specs the deltas will land into.
Representing pivots
Pivots, deprecations, and wind-downs are not a separate concept in ReffySpec — they are ordinary changes whose delta is mostly REMOVED or MODIFIED requirements instead of ADDED ones. Because every change's specs/<capability>/spec.md is already a delta against the canonical spec, a course correction reuses the same machinery as a feature addition: scaffold a change, author a delta that removes or rewrites the relevant requirements, pair it with code-removal tasks, and archive it when shipped. The history of pivots stays legible as a series of deltas under changes/archive/, rather than getting buried in code commits.
There is no pivot command and no per-requirement "deprecated" flag: signaling a change of direction just requires another change. The archive is append-only — you never edit or delete an archived change to reverse it; you land a new change on top, and canonical specs/ always reflects current truth. When a change reverses or replaces a prior one, name the prior change-id(s) in an optional ## Supersedes section of proposal.md:
## Supersedes
- add-old-directionThis is a navigational pointer that keeps the lineage explicit; the spec delta remains the authoritative record of what actually changed. reffy plan create scaffolds the ## Supersedes section (defaulting to None) so the convention is there when you need it.
Reference implementation in this repo
AGENTS.md: contains both managed instruction blocks and encodes sequencing.AGENTS.md: Reffy block routes ideation/exploration requests to@/.reffy/AGENTS.md.AGENTS.md: ReffySpec block routes planning/proposal/spec requests to@/.reffy/reffyspec/AGENTS.md..reffy/AGENTS.md: defines the artifact and ideation workflow..reffy/reffyspec/AGENTS.md: defines the ReffySpec planning/spec workflow conventions used in this repo..reffy/reffyspec/project.md: captures durable project context for agents, including purpose, stack, architecture, conventions, and constraints.
Develop
For local development of this repo:
npm install
npm run build
npm run check
npm testnpm install runs this package's prepare step, which builds dist/ automatically.
Release Security
Reffy publishes from GitHub Actions using npm trusted publishing with provenance enabled.
To verify an installed package:
- Check the package provenance details on npm.
- Run
npm audit signaturesafter install to verify registry signatures and available provenance attestations.
