feat(core): plugin-registered init steps for agnos init#10
Merged
Conversation
Add a top-level `initSteps` array on `DomainPlugin` so each installed
domain can contribute its own interactive setup prompts to `agnos init`.
Each step declares `{ id, type, message, default, callback }` and the
runner orchestrates them in domain-priority order. `agnos <domain> init`
synthesizes the same flow when the plugin doesn't declare `cli.init`.
- rules: prompts for `rules.source` (default reads current value)
- skills: prompts for `paths.skillsDir` and now persists the value
- docs: prompts for route / index / content / docRules / inject flags
- mcp: opts out — no init step and no synthesized init command
Adds `agnos init --only=<ids>` to scope a re-run to specific domains
(skips the agents picker + skills.sh lock migration). Extracts a
`setRulesSource` helper from `runRules` so the same write/move/dispatch
logic powers both the CLI prompt and the rules-domain callback.
Core was importing `@luxia/domain-rules/template` directly and listed `@luxia/domain-rules` in its runtime dependencies, while domain-rules already peer-depends on core. Turbo refuses to compute a task graph with a cycle, so `pnpm typecheck` failed in CI on every PR after the template-templates refactor (bc3880e) landed. Replace the direct subpath import with an optional `getStarterContent?(): string | Promise<string>` hook on `DomainPlugin`. Core's `ensureStarterRules` / `setRulesSource` now accept a content provider and fall back to a minimal inline template. The rules-domain plugin exposes `readDefaultRulesTemplate` via the new hook, and `agnos rules <path>` (core CLI) looks it up via `loadPlugins` instead of importing the plugin's package directly. `@luxia/domain-rules` is removed from core's dependencies.
`runInject` now short-circuits when either `agnos.json#rules.source` is unset (no rules domain installed / no rules managed by agnos) or when the configured rules file is missing on disk. Previously it threw when unset and silently wrote into a fresh file when the path existed in config but not on disk — both surprising when docs is enabled without rules. The docs `injectIndex` / `injectRules` init steps now skip prompting entirely when no managed rules file exists, via a new optional `when?(ctx): boolean | Promise<boolean>` predicate on `InitStep`. If rules.source is missing or the file isn't on disk, the prompts don't appear and stored values are effectively a no-op downstream.
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
initSteps?: InitStep[]field onDomainPluginso each installed domain contributes its own interactive setup prompts toagnos init. Steps declare{ id, type, message, default, callback }; the runner orchestrates them in domain-priority order (rules → mcp → skills → docs).agnos init --only=<ids>to scope a re-run to specific domains (skips the agents picker + skills.sh lock migration). Per-domainagnos <domain> initis auto-synthesized from the plugin'sinitStepswhen no explicitcli.initexists.setRulesSource(target, opts)(withnoDispatch?) so the same write/move/dispatch logic powers both the CLI prompt path and the rules-domain callback.Built-in domain steps
sourcetext step, default reads currentagnos.json#rules.source(or./AGENTS.md)skillsDirtext step — now actually persistsagnos.json#paths.skillsDir, dropping the key when set to default to keepagnos.jsoncleanroute,index,content(bool),docRules,injectIndex,injectRules— with dynamic defaults pulling from currentagnos.json#docsmcp initPublic API additions
InitStepdiscriminated union (text|boolean|select) —defaultaccepts a literal or(ctx) => valuefor dynamic defaultsrunDomainInitSteps(plugin, ctx, opts)andrunAllDomainInitSteps(registry, ctx, opts, onlyIds?)exported from@luxia/coresetRulesSource(target, opts)andSetRulesSourceOptionsexported from@luxia/coreTest plan
pnpm -r build— all 8 packages build cleanpnpm -r typecheck— passespnpm -r test— 160 tests pass (core: 115, skills: 8, docs: 37)pnpm -r lint— no new warnings introducedagnos initwalks rules → skills → docs prompts in order, then picks agentsagnos init -ywrites defaults without promptingagnos init --only=docsruns only docs prompts, skips agents pickeragnos rules init/agnos skill init/agnos docs initeach prompt their domain's stepsagnos mcp initerrors with "unknown subcommand"