fix(cli): explain the checkout requirement and fix the docs that led users outside one - #216
Merged
Conversation
`af-stack init --name …`, `agent|module|plugin new`, `dev`, and `deploy` all need a clone of this repo, and when run elsewhere they died with the bare "must run from inside an AF Stack checkout". The README shows `af-stack init my-ai-product` (a standalone app that calls a running BackAI) right next to the fork commands, so the natural next move — cd into the new app and run them — hit that message with no way forward. Move the duplicated root finders from initcmd and project into one checkout package whose error names the directory, says a checkout is a clone containing apps/dashboard and apps/customer-app, recognises an app written by `af-stack init <name>` and says it has no surfaces to brand or extend, and prints both next steps: the git clone for a fork, or `af-stack init <name>` for a standalone app. Behaviour inside a clone, including subdirectories, is unchanged and now pinned by tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com>
…hich README's "built for coding agents" block listed `af-stack init my-ai-product` and then, after an "Or", `af-stack init --name …` and `af-stack agent new …` with no clone step, so readers ran the fork commands inside the standalone app and got the checkout error. The dx hub's golden path called the positional form a fork scaffold and then ran `af-stack dev` in it, which cannot work; the skill's primary path used `af-stack init acme-coder --template coding-agent`, which the positional form rejects (it knows node and saas), followed by the same impossible `dev`. Each now starts the fork sequence with `git clone … && cd …`, states that the flag form and the scaffolds run inside that clone, and says plainly that `af-stack init <name>` is a different thing: a small standalone app that calls a running BackAI, in any directory. Both sequences were replayed literally in a throwaway clone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com>
`af-stack init --name …` on a fresh clone printed a twenty-line Node ERR_MODULE_NOT_FOUND stack trace before its own summary, because it ran `pnpm run generate:brand` unconditionally and echoed everything the failed command wrote. The README's fork sequence is exactly that case, so the trace was the first thing a new user saw. Skip the generator when node_modules is absent or pnpm is not on PATH and say in one line what to run; when the deps are present and the generator genuinely fails, report the tail of its output, where the actual error is, instead of the whole trace. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com>
This was referenced Sep 2, 2026
AbirAbbas
added a commit
that referenced
this pull request
Sep 2, 2026
Each of the 29 fixes was re-checked by a separate verifier against the final tree and the binary. Ten came back with a leftover or an overstatement in the new text; this commit takes them: - README told readers to change the seeded operator password "from the console"; the console has no such page. Say how the seed actually works instead, and fix .env.example's wrong port and same claim. - run.md quoted the pre-#216 checkout error text. - architecture.md still showed manifest.yaml/handler.go and a jobs/crons field for workload modules; EDITING.md still named the nonexistent (app)/ route group and sidebar file. - The cost-explorer phantom survived in the docs-site reference page and as dead code in scripts/capture-screenshots.mjs; rules/sdk.md pointed at example plugins as SDK usage when they use plain fetch. - product.md claimed a harness dashboard page that does not exist. - The restore runbook and restore.sh said the runtime exits non-zero on any failed migration; only core migrations are fatal, module and jobs failures are logged and disable that piece, so grep for both. - adapters.md omitted that personal mode needs no operator key; SKILL.md claimed init prompts only on a TTY (it always prompts on stdin). - scripts/test-quickstart.sh hardcoded supportdesk.echo, which breaks on a branded fork; it now reads the node id from compose. The SDK conformance scripts note the same assumption. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com>
AbirAbbas
added a commit
that referenced
this pull request
Sep 2, 2026
…it fixes) (#218) * docs(quickstart): make the README and AGENTS.md sequences runnable as written An audit ran every documented af-stack invocation against the real CLI; this commit takes the root-level findings. - README's fork-branding line passed `--logo ./logo.png`, a file no clone contains; since the logo is copied before brand.yaml is written, the whole init aborted with nothing applied. The runnable line is now `af-stack init --name "Acme AI" --color "#2563EB"` with the logo as an opt-in comment. Same in examples/starter/README.md. - README sent readers to the operator console without the seeded login it requires in the default saas mode. It now gives the credentials, how to seed different ones before first boot, and that `af-stack mode personal` turns login off. The two dashboard source comments that claimed this was already documented now are true. - AGENTS.md's proof-of-wiring curl is written against `supportdesk.echo`, but `af-stack init --name` rewrites the agent node id, so the call target vanishes on every branded fork. The prose now explains the `<node_id>.echo` shape and how to list what is registered. - AGENTS.md listed `adapter list` under "no key"; it needs a running runtime and an operator key, as does billing. Recategorised. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * docs(cli): bring the CLI reference back in line with the binary - `secrets` and `db` were listed as "planned / not yet shipped"; both ship and cli-admin.md documents them. - Scaffold and deploy blocks now state the checkout precondition, and `af-stack init --logo` no longer points at a file no clone has. - Drop the retracted `backai.dev/install.sh` one-liner and the claim that `af-stack serve` is the server mode (no such command). - `operator create` needs DATABASE_URL before it runs, not after. - The app-developer table no longer promises `--json` for `db` and notes db's checkout precondition; `adapter new` and the `agent|module validate` subcommands are documented. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * docs(dx): state preconditions and stop describing things that do not exist - run.md's quick start ran `af-stack dev` with no clone step; it and the hub now start inside a checkout. `--no-open` is described as it behaves. - theming.md claimed `init --logo` copies the logo into the app public paths and runs generate:brand; on a fresh clone it writes brand.yaml and brand/logo.* and skips generation until deps are installed. - adapters.md presented `adapter list` as offline; it needs a running runtime and an operator key. `adapter new` is documented. - sdk-strategy.md's "not in any SDK" list named CLI commands that do not exist; dashboard-plugins.md and stack.md pointed at a `cost-explorer` example plugin that was never in the repo. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * docs(modules): describe the module loader and manifest that actually ship The workload-module docs said there was no runtime loader and documented a manifest filename and schema the runtime rejects; product.md listed `af-stack harness list/install` as shipped CLI commands. Rewritten against the loader and manifest in the tree. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * docs(runbooks): remove commands the operator CLI does not have The restore runbook (and scripts/restore.sh) told operators to run `af-stack migrate up`, which does not exist as a subcommand and would boot a second runtime; KMS rotation documented `af-stack secrets rotate-kms` and `AF_STACK_KMS_KEY_NEW`, which are unimplemented; the graceful-shutdown smoke test started "the runtime" with `af-stack &`, which is the operator CLI on PATH. Each now names the real command or says plainly that the capability is not implemented yet. Stale `supportdesk.echo` literals note that a branded fork renames the node. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * docs(skill): fix the workflow step, paths, and references coding agents follow - Canonical-workflow step 4 still told agents to run `af-stack init <name> --template coding-agent`, which the positional form rejects; it now clones and brands in place like the header. - The customer-app surface was described as an `(app)/` route group with layouts and pages that do not exist; corrected to the real `src/app/` layout, including the snippet. - Cross-references pointed at four files that do not exist, a `cost-explorer` plugin that was never in the repo, and a wrong path for the checked-in OpenAPI document. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * docs(site): drop the cost-explorer plugin reference that never existed Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * fix(cli): make help and usage text match what the commands accept - `af-stack init --help` documented only the in-checkout form and advertised `--template coding-agent` for the positional form, which rejects it; both forms are now described where each applies. - The usage example `af-stack init --template coding-agent` fails non-interactively because --name is required; the example now passes it. - `agent validate`, `module validate`, and `adapter new` ship but were absent from help; `--no-open`'s flag help described the opposite of its behaviour; the generated saas app's next steps named a command that does not exist. - AGENTS.md joins the files whose `<node_id>.echo` literal `af-stack init --name` rewrites, so the proof-of-wiring curl follows the branded node id. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> * docs: corrections from independent verification of the sweep Each of the 29 fixes was re-checked by a separate verifier against the final tree and the binary. Ten came back with a leftover or an overstatement in the new text; this commit takes them: - README told readers to change the seeded operator password "from the console"; the console has no such page. Say how the seed actually works instead, and fix .env.example's wrong port and same claim. - run.md quoted the pre-#216 checkout error text. - architecture.md still showed manifest.yaml/handler.go and a jobs/crons field for workload modules; EDITING.md still named the nonexistent (app)/ route group and sidebar file. - The cost-explorer phantom survived in the docs-site reference page and as dead code in scripts/capture-screenshots.mjs; rules/sdk.md pointed at example plugins as SDK usage when they use plain fetch. - product.md claimed a harness dashboard page that does not exist. - The restore runbook and restore.sh said the runtime exits non-zero on any failed migration; only core migrations are fatal, module and jobs failures are logged and disable that piece, so grep for both. - adapters.md omitted that personal mode needs no operator key; SKILL.md claimed init prompts only on a TTY (it always prompts on stdin). - scripts/test-quickstart.sh hardcoded supportdesk.echo, which breaks on a branded fork; it now reads the node id from compose. The SDK conformance scripts note the same assumption. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> --------- Signed-off-by: Abir Abbas <abirabbas1998@gmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Following the README's "built for coding agents" block literally fails.
af-stack init my-ai-productscaffolds a small standalone app that calls a running BackAI; the next two lines,af-stack init --name …andaf-stack agent new …, only work inside a clone of this repo, and the README never says so. The natural move — cd into the new app and run them — died with the baremust run from inside an AF Stack checkout, which gives no hint what a checkout is or how to get one.The same confusion runs through the docs: the dx hub's golden path called the positional form a fork scaffold and then ran
af-stack devin it (which cannot work there), and the skill's "primary path" usedaf-stack init acme-coder --template coding-agent, which the positional form rejects with exit 2 (it only knowsnodeandsaas), followed by the same impossibledev.Changes
CLI: one checkout finder with an error that explains itself. The duplicated root finders in
initcmdandprojectmove intoservices/cli/internal/checkout. When no clone encloses the working directory, the error names the directory, says a checkout is a clone containingapps/dashboardandapps/customer-app, recognises an app written byaf-stack init <name>and says it has no surfaces to brand or extend, and prints both next steps: thegit clone … && cd …for a fork, oraf-stack init <name>for a standalone app. This coversinit --name,dev,agent|module|plugin new, anddeploy. Behaviour inside a clone, including subdirectories, is unchanged.Docs: the clone comes before the fork commands, and each init form is named. README, the dx hub,
docs/cli-distribution.md,docs/theming.md, and the skill's primary path now start the fork sequence withgit clone … && cd …, state that the flag form and the scaffolds run inside that clone, and say plainly thataf-stack init <name>is a different thing: a standalone app that calls a running BackAI, in any directory.init --nameon a fresh clone no longer opens with a Node stack trace. It ranpnpm run generate:brandunconditionally and echoed everything the failed command wrote, so on a clone withoutpnpm install— the README case — the first thing on screen was a twenty-lineERR_MODULE_NOT_FOUNDtrace. It now skips the generator whennode_modulesis absent or pnpm is not on PATH and says in one line what to run; a genuine generator failure is reported by the tail of its output, where the error is. The usage comment also advertised an--brandflag that does not exist.Verification
checkout,initcmd, andproject: outside a clone the error carries the directory, the definition, the clone command, and the standalone alternative; inside a scaffolded app (bothnodeandsaastemplates) it says so; a plain Node project is not mistaken for one; a clone that also carries the scaffold markers is still a clone;agent newfrom a clone subdirectory still writes to the root.init my-ai-product, cd,init --name … --logo …,agent new researcher,dev— each now prints the explanation above and exits 1.init --name "Acme AI" --color "#2563EB" --logo ./logo.pngupdatesbrand.yamland copies the logo,agent new researcherscaffolds the agent, andinit --name "Acme Coder" --template coding-agentbrands the clone and wires the coding agent into compose.go build,go vet,go test ./...pass; golangci-lint v2.13.1 in CI's new-issues mode reports 0 new issues; docs lint and the docs-site build pass.🤖 Generated with Claude Code