Skip to content

fix(cli): explain the checkout requirement and fix the docs that led users outside one - #216

Merged
AbirAbbas merged 4 commits into
mainfrom
fix/init-outside-checkout
Sep 2, 2026
Merged

fix(cli): explain the checkout requirement and fix the docs that led users outside one#216
AbirAbbas merged 4 commits into
mainfrom
fix/init-outside-checkout

Conversation

@AbirAbbas

Copy link
Copy Markdown
Contributor

Summary

Following the README's "built for coding agents" block literally fails. af-stack init my-ai-product scaffolds a small standalone app that calls a running BackAI; the next two lines, af-stack init --name … and af-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 bare must 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 dev in it (which cannot work there), and the skill's "primary path" used af-stack init acme-coder --template coding-agent, which the positional form rejects with exit 2 (it only knows node and saas), followed by the same impossible dev.

Changes

CLI: one checkout finder with an error that explains itself. The duplicated root finders in initcmd and project move into services/cli/internal/checkout. When no clone encloses the working directory, the 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 … && cd … for a fork, or af-stack init <name> for a standalone app. This covers init --name, dev, agent|module|plugin new, and deploy. Behaviour inside a clone, including subdirectories, is unchanged.

af-stack: init: must run from inside a BackAI checkout — a clone of https://github.com/Agent-Field/backai (a directory containing apps/dashboard and apps/customer-app); /home/me/my-ai-product is not one.
  /home/me/my-ai-product is a standalone app created by `af-stack init <name>`: it calls a running BackAI and has no fork surfaces to brand or extend.
  To brand a fork or add agents, modules, or plugins:  git clone https://github.com/Agent-Field/backai my-fork && cd my-fork
  To scaffold a standalone app instead:                af-stack init <name>   (works in any directory)

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 with git clone … && cd …, state that the flag form and the scaffolds run inside that clone, and say plainly that af-stack init <name> is a different thing: a standalone app that calls a running BackAI, in any directory.

init --name on a fresh clone no longer opens with a Node stack trace. It ran pnpm run generate:brand unconditionally and echoed everything the failed command wrote, so on a clone without pnpm install — the README case — the first thing on screen was a twenty-line ERR_MODULE_NOT_FOUND trace. It now skips the generator when node_modules is 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 --brand flag that does not exist.

Verification

  • Contract tests in checkout, initcmd, and project: outside a clone the error carries the directory, the definition, the clone command, and the standalone alternative; inside a scaffolded app (both node and saas templates) 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 new from a clone subdirectory still writes to the root.
  • Replayed the user's exact sequence with the rebuilt binary: init my-ai-product, cd, init --name … --logo …, agent new researcher, dev — each now prints the explanation above and exits 1.
  • Replayed the rewritten README fork block and the rewritten skill primary path literally in a throwaway clone: init --name "Acme AI" --color "#2563EB" --logo ./logo.png updates brand.yaml and copies the logo, agent new researcher scaffolds the agent, and init --name "Acme Coder" --template coding-agent brands the clone and wires the coding agent into compose.
  • Generator behaviour pinned by tests: skipped with a one-line hint when deps are missing, run when they are present, trimmed output on a real failure.
  • Full 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

AbirAbbas and others added 4 commits September 2, 2026 11:10
`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>
@AbirAbbas
AbirAbbas merged commit 526d29d into main Sep 2, 2026
30 checks passed
@AbirAbbas
AbirAbbas deleted the fix/init-outside-checkout branch September 2, 2026 15:50
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant