@ag-eco/agentplate-cli 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +462 -0
- package/agents/ap-co-creation.md +90 -0
- package/agents/builder.md +144 -0
- package/agents/coordinator.md +377 -0
- package/agents/lead.md +435 -0
- package/agents/merger.md +164 -0
- package/agents/monitor.md +214 -0
- package/agents/orchestrator.md +239 -0
- package/agents/reviewer.md +140 -0
- package/agents/scout.md +125 -0
- package/agents/supervisor.md +427 -0
- package/package.json +66 -0
- package/src/agents/capabilities.test.ts +85 -0
- package/src/agents/capabilities.ts +125 -0
- package/src/agents/checkpoint.test.ts +88 -0
- package/src/agents/checkpoint.ts +101 -0
- package/src/agents/copilot-hooks-deployer.test.ts +162 -0
- package/src/agents/copilot-hooks-deployer.ts +93 -0
- package/src/agents/guard-rules.test.ts +372 -0
- package/src/agents/guard-rules.ts +97 -0
- package/src/agents/headless-mail-injector.test.ts +709 -0
- package/src/agents/headless-mail-injector.ts +377 -0
- package/src/agents/headless-prompt.test.ts +102 -0
- package/src/agents/headless-prompt.ts +68 -0
- package/src/agents/hooks-deployer.test.ts +3119 -0
- package/src/agents/hooks-deployer.ts +804 -0
- package/src/agents/identity.test.ts +604 -0
- package/src/agents/identity.ts +384 -0
- package/src/agents/lifecycle.test.ts +196 -0
- package/src/agents/lifecycle.ts +183 -0
- package/src/agents/mail-poll-detect.test.ts +153 -0
- package/src/agents/mail-poll-detect.ts +73 -0
- package/src/agents/manifest.test.ts +1026 -0
- package/src/agents/manifest.ts +376 -0
- package/src/agents/overlay.test.ts +1058 -0
- package/src/agents/overlay.ts +490 -0
- package/src/agents/scope-detect.test.ts +190 -0
- package/src/agents/scope-detect.ts +146 -0
- package/src/agents/turn-lock.test.ts +181 -0
- package/src/agents/turn-lock.ts +235 -0
- package/src/agents/turn-runner-dispatch.test.ts +182 -0
- package/src/agents/turn-runner-dispatch.ts +105 -0
- package/src/agents/turn-runner.test.ts +2312 -0
- package/src/agents/turn-runner.ts +1383 -0
- package/src/beads/client.test.ts +217 -0
- package/src/beads/client.ts +230 -0
- package/src/beads/molecules.test.ts +338 -0
- package/src/beads/molecules.ts +198 -0
- package/src/commands/agents.test.ts +328 -0
- package/src/commands/agents.ts +299 -0
- package/src/commands/clean.test.ts +797 -0
- package/src/commands/clean.ts +791 -0
- package/src/commands/completions.test.ts +348 -0
- package/src/commands/completions.ts +981 -0
- package/src/commands/coordinator.test.ts +2975 -0
- package/src/commands/coordinator.ts +1841 -0
- package/src/commands/costs.test.ts +1183 -0
- package/src/commands/costs.ts +599 -0
- package/src/commands/dashboard.test.ts +954 -0
- package/src/commands/dashboard.ts +1212 -0
- package/src/commands/discover.test.ts +288 -0
- package/src/commands/discover.ts +202 -0
- package/src/commands/doctor.test.ts +303 -0
- package/src/commands/doctor.ts +311 -0
- package/src/commands/ecosystem.test.ts +226 -0
- package/src/commands/ecosystem.ts +248 -0
- package/src/commands/errors.test.ts +654 -0
- package/src/commands/errors.ts +197 -0
- package/src/commands/feed.test.ts +709 -0
- package/src/commands/feed.ts +260 -0
- package/src/commands/group.test.ts +475 -0
- package/src/commands/group.ts +546 -0
- package/src/commands/hooks.test.ts +458 -0
- package/src/commands/hooks.ts +263 -0
- package/src/commands/init.test.ts +1011 -0
- package/src/commands/init.ts +967 -0
- package/src/commands/inspect.test.ts +1239 -0
- package/src/commands/inspect.ts +648 -0
- package/src/commands/log.test.ts +1913 -0
- package/src/commands/log.ts +958 -0
- package/src/commands/logs.test.ts +801 -0
- package/src/commands/logs.ts +483 -0
- package/src/commands/mail.test.ts +1501 -0
- package/src/commands/mail.ts +848 -0
- package/src/commands/merge.test.ts +864 -0
- package/src/commands/merge.ts +381 -0
- package/src/commands/metrics.test.ts +458 -0
- package/src/commands/metrics.ts +129 -0
- package/src/commands/monitor.test.ts +191 -0
- package/src/commands/monitor.ts +409 -0
- package/src/commands/nudge.test.ts +579 -0
- package/src/commands/nudge.ts +646 -0
- package/src/commands/orchestrator.ts +42 -0
- package/src/commands/prime.test.ts +612 -0
- package/src/commands/prime.ts +359 -0
- package/src/commands/replay.test.ts +757 -0
- package/src/commands/replay.ts +231 -0
- package/src/commands/run.test.ts +469 -0
- package/src/commands/run.ts +353 -0
- package/src/commands/serve/agent-actions.test.ts +210 -0
- package/src/commands/serve/agent-actions.ts +192 -0
- package/src/commands/serve/build.test.ts +202 -0
- package/src/commands/serve/build.ts +206 -0
- package/src/commands/serve/coordinator-actions.test.ts +339 -0
- package/src/commands/serve/coordinator-actions.ts +410 -0
- package/src/commands/serve/dev.test.ts +168 -0
- package/src/commands/serve/dev.ts +117 -0
- package/src/commands/serve/mail-actions.test.ts +312 -0
- package/src/commands/serve/mail-actions.ts +167 -0
- package/src/commands/serve/rest.test.ts +1680 -0
- package/src/commands/serve/rest.ts +1130 -0
- package/src/commands/serve/static.ts +51 -0
- package/src/commands/serve/ws.test.ts +361 -0
- package/src/commands/serve/ws.ts +332 -0
- package/src/commands/serve.test.ts +459 -0
- package/src/commands/serve.ts +654 -0
- package/src/commands/sling.test.ts +1583 -0
- package/src/commands/sling.ts +1351 -0
- package/src/commands/spec.test.ts +179 -0
- package/src/commands/spec.ts +105 -0
- package/src/commands/status.test.ts +614 -0
- package/src/commands/status.ts +403 -0
- package/src/commands/stop.test.ts +964 -0
- package/src/commands/stop.ts +319 -0
- package/src/commands/supervisor.test.ts +185 -0
- package/src/commands/supervisor.ts +537 -0
- package/src/commands/trace.test.ts +762 -0
- package/src/commands/trace.ts +205 -0
- package/src/commands/update.test.ts +466 -0
- package/src/commands/update.ts +263 -0
- package/src/commands/upgrade.test.ts +48 -0
- package/src/commands/upgrade.ts +240 -0
- package/src/commands/watch.test.ts +257 -0
- package/src/commands/watch.ts +308 -0
- package/src/commands/worktree.test.ts +1297 -0
- package/src/commands/worktree.ts +451 -0
- package/src/config.test.ts +1535 -0
- package/src/config.ts +1064 -0
- package/src/doctor/agents.test.ts +523 -0
- package/src/doctor/agents.ts +399 -0
- package/src/doctor/config-check.test.ts +191 -0
- package/src/doctor/config-check.ts +183 -0
- package/src/doctor/consistency.test.ts +807 -0
- package/src/doctor/consistency.ts +347 -0
- package/src/doctor/databases.test.ts +350 -0
- package/src/doctor/databases.ts +243 -0
- package/src/doctor/dependencies.test.ts +296 -0
- package/src/doctor/dependencies.ts +272 -0
- package/src/doctor/ecosystem.test.ts +308 -0
- package/src/doctor/ecosystem.ts +156 -0
- package/src/doctor/logs.test.ts +253 -0
- package/src/doctor/logs.ts +295 -0
- package/src/doctor/merge-queue.test.ts +315 -0
- package/src/doctor/merge-queue.ts +167 -0
- package/src/doctor/providers.test.ts +409 -0
- package/src/doctor/providers.ts +250 -0
- package/src/doctor/serve.test.ts +95 -0
- package/src/doctor/serve.ts +86 -0
- package/src/doctor/structure.test.ts +423 -0
- package/src/doctor/structure.ts +285 -0
- package/src/doctor/types.ts +43 -0
- package/src/doctor/version.test.ts +241 -0
- package/src/doctor/version.ts +132 -0
- package/src/doctor/watchdog.test.ts +167 -0
- package/src/doctor/watchdog.ts +214 -0
- package/src/e2e/init-sling-lifecycle.test.ts +283 -0
- package/src/errors.test.ts +350 -0
- package/src/errors.ts +217 -0
- package/src/events/store.test.ts +660 -0
- package/src/events/store.ts +369 -0
- package/src/events/tailer.test.ts +719 -0
- package/src/events/tailer.ts +332 -0
- package/src/events/tool-filter.test.ts +330 -0
- package/src/events/tool-filter.ts +126 -0
- package/src/index.ts +533 -0
- package/src/insights/analyzer.test.ts +466 -0
- package/src/insights/analyzer.ts +203 -0
- package/src/insights/quality-gates.test.ts +141 -0
- package/src/insights/quality-gates.ts +156 -0
- package/src/json.test.ts +72 -0
- package/src/json.ts +53 -0
- package/src/loam/client.test.ts +752 -0
- package/src/loam/client.ts +664 -0
- package/src/logging/color.test.ts +252 -0
- package/src/logging/color.ts +105 -0
- package/src/logging/format.test.ts +110 -0
- package/src/logging/format.ts +255 -0
- package/src/logging/logger.test.ts +814 -0
- package/src/logging/logger.ts +266 -0
- package/src/logging/reporter.test.ts +259 -0
- package/src/logging/reporter.ts +110 -0
- package/src/logging/sanitizer.test.ts +190 -0
- package/src/logging/sanitizer.ts +57 -0
- package/src/logging/theme.ts +140 -0
- package/src/mail/broadcast.test.ts +204 -0
- package/src/mail/broadcast.ts +92 -0
- package/src/mail/client.test.ts +774 -0
- package/src/mail/client.ts +236 -0
- package/src/mail/store.test.ts +898 -0
- package/src/mail/store.ts +425 -0
- package/src/merge/lock.test.ts +149 -0
- package/src/merge/lock.ts +140 -0
- package/src/merge/predict.test.ts +387 -0
- package/src/merge/predict.ts +249 -0
- package/src/merge/queue.test.ts +426 -0
- package/src/merge/queue.ts +246 -0
- package/src/merge/resolver.test.ts +1993 -0
- package/src/merge/resolver.ts +926 -0
- package/src/metrics/pricing.test.ts +258 -0
- package/src/metrics/pricing.ts +135 -0
- package/src/metrics/store.test.ts +978 -0
- package/src/metrics/store.ts +501 -0
- package/src/metrics/summary.test.ts +398 -0
- package/src/metrics/summary.ts +178 -0
- package/src/metrics/transcript.test.ts +483 -0
- package/src/metrics/transcript.ts +114 -0
- package/src/runtimes/__fixtures__/claude-stream-fixture.ts +22 -0
- package/src/runtimes/aider.test.ts +124 -0
- package/src/runtimes/aider.ts +147 -0
- package/src/runtimes/amp.test.ts +164 -0
- package/src/runtimes/amp.ts +154 -0
- package/src/runtimes/claude.test.ts +1474 -0
- package/src/runtimes/claude.ts +579 -0
- package/src/runtimes/codex.test.ts +805 -0
- package/src/runtimes/codex.ts +273 -0
- package/src/runtimes/connections.test.ts +214 -0
- package/src/runtimes/connections.ts +103 -0
- package/src/runtimes/copilot.test.ts +707 -0
- package/src/runtimes/copilot.ts +316 -0
- package/src/runtimes/cursor.test.ts +497 -0
- package/src/runtimes/cursor.ts +205 -0
- package/src/runtimes/gemini.test.ts +537 -0
- package/src/runtimes/gemini.ts +243 -0
- package/src/runtimes/goose.test.ts +133 -0
- package/src/runtimes/goose.ts +157 -0
- package/src/runtimes/headless-connection.test.ts +264 -0
- package/src/runtimes/headless-connection.ts +158 -0
- package/src/runtimes/opencode.test.ts +325 -0
- package/src/runtimes/opencode.ts +188 -0
- package/src/runtimes/pi-guards.test.ts +486 -0
- package/src/runtimes/pi-guards.ts +367 -0
- package/src/runtimes/pi.test.ts +789 -0
- package/src/runtimes/pi.ts +305 -0
- package/src/runtimes/registry.test.ts +196 -0
- package/src/runtimes/registry.ts +99 -0
- package/src/runtimes/sapling.test.ts +1267 -0
- package/src/runtimes/sapling.ts +710 -0
- package/src/runtimes/types.ts +266 -0
- package/src/schema-consistency.test.ts +246 -0
- package/src/sessions/compat.test.ts +281 -0
- package/src/sessions/compat.ts +105 -0
- package/src/sessions/store.test.ts +1748 -0
- package/src/sessions/store.ts +858 -0
- package/src/test-helpers.test.ts +124 -0
- package/src/test-helpers.ts +145 -0
- package/src/test-setup.test.ts +31 -0
- package/src/test-setup.ts +28 -0
- package/src/tools/loam/api.ts +368 -0
- package/src/tools/loam/cli.ts +278 -0
- package/src/tools/loam/commands/add.ts +52 -0
- package/src/tools/loam/commands/archive.ts +214 -0
- package/src/tools/loam/commands/audit.ts +276 -0
- package/src/tools/loam/commands/compact.ts +1062 -0
- package/src/tools/loam/commands/completions.ts +79 -0
- package/src/tools/loam/commands/config.ts +381 -0
- package/src/tools/loam/commands/delete-domain.ts +121 -0
- package/src/tools/loam/commands/delete.ts +316 -0
- package/src/tools/loam/commands/diff.ts +200 -0
- package/src/tools/loam/commands/doctor.ts +1113 -0
- package/src/tools/loam/commands/edit.ts +226 -0
- package/src/tools/loam/commands/init.ts +31 -0
- package/src/tools/loam/commands/learn.ts +179 -0
- package/src/tools/loam/commands/move.ts +323 -0
- package/src/tools/loam/commands/onboard.ts +374 -0
- package/src/tools/loam/commands/outcome.ts +185 -0
- package/src/tools/loam/commands/prime.ts +688 -0
- package/src/tools/loam/commands/prune.ts +614 -0
- package/src/tools/loam/commands/query.ts +218 -0
- package/src/tools/loam/commands/rank.ts +180 -0
- package/src/tools/loam/commands/ready.ts +189 -0
- package/src/tools/loam/commands/record.ts +1210 -0
- package/src/tools/loam/commands/restore.ts +166 -0
- package/src/tools/loam/commands/search.ts +327 -0
- package/src/tools/loam/commands/setup.ts +887 -0
- package/src/tools/loam/commands/status.ts +103 -0
- package/src/tools/loam/commands/sync.ts +298 -0
- package/src/tools/loam/commands/update.ts +19 -0
- package/src/tools/loam/commands/upgrade.ts +93 -0
- package/src/tools/loam/commands/validate.ts +190 -0
- package/src/tools/loam/index.ts +62 -0
- package/src/tools/loam/log.ts +127 -0
- package/src/tools/loam/registry/builtins.ts +409 -0
- package/src/tools/loam/registry/custom.ts +431 -0
- package/src/tools/loam/registry/init.ts +55 -0
- package/src/tools/loam/registry/template.ts +40 -0
- package/src/tools/loam/registry/type-registry.ts +113 -0
- package/src/tools/loam/schemas/config-schema.ts +489 -0
- package/src/tools/loam/schemas/config.ts +245 -0
- package/src/tools/loam/schemas/index.ts +18 -0
- package/src/tools/loam/schemas/record-schema.ts +191 -0
- package/src/tools/loam/schemas/record.ts +115 -0
- package/src/tools/loam/utils/active-work.ts +205 -0
- package/src/tools/loam/utils/anchor-validity.ts +80 -0
- package/src/tools/loam/utils/archive.ts +146 -0
- package/src/tools/loam/utils/audit.ts +667 -0
- package/src/tools/loam/utils/bm25.ts +238 -0
- package/src/tools/loam/utils/budget.ts +142 -0
- package/src/tools/loam/utils/config.ts +344 -0
- package/src/tools/loam/utils/dir-anchors.ts +62 -0
- package/src/tools/loam/utils/domain-rules.ts +114 -0
- package/src/tools/loam/utils/expertise.ts +393 -0
- package/src/tools/loam/utils/format-helpers.ts +96 -0
- package/src/tools/loam/utils/format.ts +1234 -0
- package/src/tools/loam/utils/git-context.ts +50 -0
- package/src/tools/loam/utils/git.ts +183 -0
- package/src/tools/loam/utils/hooks.ts +299 -0
- package/src/tools/loam/utils/index.ts +52 -0
- package/src/tools/loam/utils/json-output.ts +13 -0
- package/src/tools/loam/utils/lock.ts +76 -0
- package/src/tools/loam/utils/markers.ts +48 -0
- package/src/tools/loam/utils/numeric-flags.ts +20 -0
- package/src/tools/loam/utils/palette.ts +44 -0
- package/src/tools/loam/utils/prime-ranking.ts +135 -0
- package/src/tools/loam/utils/recipe-discovery.ts +195 -0
- package/src/tools/loam/utils/runtime-flags.ts +28 -0
- package/src/tools/loam/utils/scoring.ts +94 -0
- package/src/tools/loam/utils/version.ts +116 -0
- package/src/tools/sprout/commands/block.ts +64 -0
- package/src/tools/sprout/commands/blocked.ts +86 -0
- package/src/tools/sprout/commands/close.ts +129 -0
- package/src/tools/sprout/commands/completions.ts +198 -0
- package/src/tools/sprout/commands/config.ts +238 -0
- package/src/tools/sprout/commands/create.ts +164 -0
- package/src/tools/sprout/commands/dep.ts +148 -0
- package/src/tools/sprout/commands/doctor.ts +979 -0
- package/src/tools/sprout/commands/init.ts +83 -0
- package/src/tools/sprout/commands/label.ts +178 -0
- package/src/tools/sprout/commands/list.ts +210 -0
- package/src/tools/sprout/commands/migrate.ts +133 -0
- package/src/tools/sprout/commands/onboard.ts +207 -0
- package/src/tools/sprout/commands/plan-show.ts +278 -0
- package/src/tools/sprout/commands/plan.ts +2526 -0
- package/src/tools/sprout/commands/prime.ts +399 -0
- package/src/tools/sprout/commands/ready.ts +245 -0
- package/src/tools/sprout/commands/search.ts +221 -0
- package/src/tools/sprout/commands/show.ts +277 -0
- package/src/tools/sprout/commands/stats.ts +146 -0
- package/src/tools/sprout/commands/sync.ts +134 -0
- package/src/tools/sprout/commands/tpl.ts +364 -0
- package/src/tools/sprout/commands/unblock.ts +115 -0
- package/src/tools/sprout/commands/update.ts +257 -0
- package/src/tools/sprout/commands/upgrade.ts +91 -0
- package/src/tools/sprout/config-schema.ts +152 -0
- package/src/tools/sprout/config.ts +355 -0
- package/src/tools/sprout/filter.ts +107 -0
- package/src/tools/sprout/format.ts +43 -0
- package/src/tools/sprout/id.ts +22 -0
- package/src/tools/sprout/index.ts +204 -0
- package/src/tools/sprout/log.ts +76 -0
- package/src/tools/sprout/markers.ts +22 -0
- package/src/tools/sprout/output.ts +121 -0
- package/src/tools/sprout/plan-backref.ts +93 -0
- package/src/tools/sprout/plan-context.ts +81 -0
- package/src/tools/sprout/plan-domain.ts +139 -0
- package/src/tools/sprout/plan-lifecycle.ts +65 -0
- package/src/tools/sprout/plan-loam.ts +207 -0
- package/src/tools/sprout/plan-schema.ts +209 -0
- package/src/tools/sprout/sort.ts +31 -0
- package/src/tools/sprout/store.ts +172 -0
- package/src/tools/sprout/types.ts +118 -0
- package/src/tools/sprout/validation.ts +119 -0
- package/src/tools/sprout/version.ts +1 -0
- package/src/tools/sprout/yaml.ts +387 -0
- package/src/tools/trellis/commands/archive.ts +87 -0
- package/src/tools/trellis/commands/completions.ts +610 -0
- package/src/tools/trellis/commands/config.ts +382 -0
- package/src/tools/trellis/commands/create.ts +252 -0
- package/src/tools/trellis/commands/diff.ts +150 -0
- package/src/tools/trellis/commands/doctor.ts +771 -0
- package/src/tools/trellis/commands/emit.ts +365 -0
- package/src/tools/trellis/commands/history.ts +83 -0
- package/src/tools/trellis/commands/import.ts +198 -0
- package/src/tools/trellis/commands/init.ts +81 -0
- package/src/tools/trellis/commands/list.ts +103 -0
- package/src/tools/trellis/commands/onboard.ts +156 -0
- package/src/tools/trellis/commands/pin.ts +172 -0
- package/src/tools/trellis/commands/prime.ts +193 -0
- package/src/tools/trellis/commands/render.ts +122 -0
- package/src/tools/trellis/commands/schema.ts +353 -0
- package/src/tools/trellis/commands/show.ts +115 -0
- package/src/tools/trellis/commands/stats.ts +65 -0
- package/src/tools/trellis/commands/sync.ts +112 -0
- package/src/tools/trellis/commands/tree.ts +123 -0
- package/src/tools/trellis/commands/update.ts +330 -0
- package/src/tools/trellis/commands/upgrade.ts +95 -0
- package/src/tools/trellis/commands/validate.ts +166 -0
- package/src/tools/trellis/config-schema.ts +81 -0
- package/src/tools/trellis/config.ts +108 -0
- package/src/tools/trellis/frontmatter.ts +348 -0
- package/src/tools/trellis/id.ts +24 -0
- package/src/tools/trellis/index.ts +209 -0
- package/src/tools/trellis/markers.ts +28 -0
- package/src/tools/trellis/output.ts +84 -0
- package/src/tools/trellis/render.ts +212 -0
- package/src/tools/trellis/store.ts +144 -0
- package/src/tools/trellis/types.ts +82 -0
- package/src/tools/trellis/validate.ts +199 -0
- package/src/tools/trellis/yaml.ts +309 -0
- package/src/tracker/beads.test.ts +454 -0
- package/src/tracker/beads.ts +56 -0
- package/src/tracker/factory.test.ts +90 -0
- package/src/tracker/factory.ts +65 -0
- package/src/tracker/sprout.test.ts +461 -0
- package/src/tracker/sprout.ts +182 -0
- package/src/tracker/types.ts +52 -0
- package/src/trellis/client.test.ts +107 -0
- package/src/trellis/client.ts +179 -0
- package/src/types.ts +970 -0
- package/src/utils/bin.test.ts +10 -0
- package/src/utils/bin.ts +37 -0
- package/src/utils/browser.test.ts +49 -0
- package/src/utils/browser.ts +48 -0
- package/src/utils/fs.test.ts +119 -0
- package/src/utils/fs.ts +62 -0
- package/src/utils/pid.test.ts +152 -0
- package/src/utils/pid.ts +130 -0
- package/src/utils/process-scan.test.ts +53 -0
- package/src/utils/process-scan.ts +76 -0
- package/src/utils/time.test.ts +43 -0
- package/src/utils/time.ts +37 -0
- package/src/utils/version.test.ts +33 -0
- package/src/utils/version.ts +70 -0
- package/src/version.ts +5 -0
- package/src/watchdog/daemon.test.ts +3721 -0
- package/src/watchdog/daemon.ts +1257 -0
- package/src/watchdog/health.test.ts +830 -0
- package/src/watchdog/health.ts +434 -0
- package/src/watchdog/triage.test.ts +205 -0
- package/src/watchdog/triage.ts +205 -0
- package/src/worktree/manager.test.ts +720 -0
- package/src/worktree/manager.ts +405 -0
- package/src/worktree/process.test.ts +172 -0
- package/src/worktree/process.ts +131 -0
- package/src/worktree/tmux.test.ts +1616 -0
- package/src/worktree/tmux.ts +721 -0
- package/templates/CLAUDE.md.tmpl +100 -0
- package/templates/copilot-hooks.json.tmpl +13 -0
- package/templates/hooks.json.tmpl +109 -0
- package/templates/overlay.md.tmpl +88 -0
- package/ui/dist/apple-touch-icon-bdy6teep.png +0 -0
- package/ui/dist/chunk-8s31f05k.css +1 -0
- package/ui/dist/chunk-vm5rz679.js +300 -0
- package/ui/dist/favicon-nzb39vza.svg +4 -0
- package/ui/dist/index.html +17 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import type { Command } from "commander";
|
|
4
|
+
import { findSproutDir, projectRootFromSproutDir } from "../config.ts";
|
|
5
|
+
import { hasMarkerSection, replaceMarkerSection, wrapInMarkers } from "../markers.ts";
|
|
6
|
+
import { outputJson, printError, printSuccess } from "../output.ts";
|
|
7
|
+
import { VERSION } from "../version.ts";
|
|
8
|
+
|
|
9
|
+
// Schema version drives outdated-snippet detection. Bump when the snippet body changes
|
|
10
|
+
// in a way agents should re-render. Independent of the package version so patch releases
|
|
11
|
+
// don't mark every existing snippet as outdated.
|
|
12
|
+
const ONBOARD_SCHEMA = 7;
|
|
13
|
+
const SCHEMA_MARKER = `<!-- sprout-onboard-schema:${String(ONBOARD_SCHEMA)} -->`;
|
|
14
|
+
const VERSION_MARKER = `<!-- sprout-onboard:v${VERSION} -->`;
|
|
15
|
+
const LEGACY_VERSION_MARKER_PREFIX = "<!-- sprout-onboard-v:";
|
|
16
|
+
|
|
17
|
+
const CANDIDATE_FILES = ["CLAUDE.md", ".claude/CLAUDE.md", "AGENTS.md"] as const;
|
|
18
|
+
|
|
19
|
+
function onboardSnippet(): string {
|
|
20
|
+
return `## Issue Tracking (Sprout)
|
|
21
|
+
${VERSION_MARKER}
|
|
22
|
+
${SCHEMA_MARKER}
|
|
23
|
+
|
|
24
|
+
This project uses [Sprout](https://github.com/jayminwest/sprout) v${VERSION} for git-native issue tracking.
|
|
25
|
+
|
|
26
|
+
**At the start of every session**, run:
|
|
27
|
+
\`\`\`
|
|
28
|
+
sr prime
|
|
29
|
+
\`\`\`
|
|
30
|
+
|
|
31
|
+
This injects session context: rules, command reference, and workflows. Pass \`--format json|compact|markdown|plain|ids\` on any command for agent-friendly output.
|
|
32
|
+
|
|
33
|
+
**Quick reference:**
|
|
34
|
+
- \`sr ready\` — Find unblocked work
|
|
35
|
+
- \`sr search <query>\` — Full-text search across titles + descriptions
|
|
36
|
+
- \`sr create --title "..." --type task --priority 2\` — Create issue
|
|
37
|
+
- \`sr update <id> --status in_progress\` — Claim work
|
|
38
|
+
- \`sr close <id>\` — Complete work
|
|
39
|
+
- \`sr dep add <id> <depends-on>\` — Add dependency between issues
|
|
40
|
+
- \`sr sync\` — Sync with git (run before pushing)
|
|
41
|
+
|
|
42
|
+
### Planning
|
|
43
|
+
Use \`sr plan\` when work is large or ambiguous enough that an LLM benefits from structured decomposition. Submit spawns one child seed per step; \`step.blocks\` uses forward semantics (step i with \`blocks: [j]\` means step i blocks step j, and step j gets step i's id in its \`blockedBy\`).
|
|
44
|
+
|
|
45
|
+
- \`sr plan templates\` — List built-ins (\`feature\`, \`bug\`, \`refactor\`) plus custom templates
|
|
46
|
+
- \`sr plan prompt <seed-id>\` — Emit a structured prompt the LLM fills in
|
|
47
|
+
- \`sr plan submit <seed-id> --plan <file>\` — Validate + spawn child sprout
|
|
48
|
+
- \`sr plan show <pl-id>\` — View sections, children, sub-plans
|
|
49
|
+
- \`sr plan edit <id> [--name | --section <name> <text> | --step <i> --title/--priority/--type]\` — In-place field edits; bumps revision
|
|
50
|
+
- \`sr plan outcome <pl-id> --result success|partial|failure\` — Record outcome (storage-only)
|
|
51
|
+
- \`sr plan review <pl-id> --by <name>\` — Record reviewer (informational)
|
|
52
|
+
|
|
53
|
+
### Before You Finish
|
|
54
|
+
1. Close completed issues: \`sr close <id>\`
|
|
55
|
+
2. File issues for remaining work: \`sr create --title "..."\`
|
|
56
|
+
3. Sync and push: \`sr sync && git push\``;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function findTargetFile(projectRoot: string): string | null {
|
|
60
|
+
for (const candidate of CANDIDATE_FILES) {
|
|
61
|
+
const fullPath = join(projectRoot, candidate);
|
|
62
|
+
if (existsSync(fullPath)) {
|
|
63
|
+
return fullPath;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function detectStatus(content: string): "missing" | "current" | "outdated" {
|
|
70
|
+
if (!hasMarkerSection(content)) return "missing";
|
|
71
|
+
// Legacy snippets used `sprout-onboard-v:N`. Always treat them as outdated so
|
|
72
|
+
// the next run upgrades them to the new schema/version markers.
|
|
73
|
+
if (content.includes(LEGACY_VERSION_MARKER_PREFIX)) return "outdated";
|
|
74
|
+
if (content.includes(SCHEMA_MARKER)) return "current";
|
|
75
|
+
return "outdated";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function run(args: string[]): Promise<void> {
|
|
79
|
+
const jsonMode = args.includes("--json");
|
|
80
|
+
const stdoutMode = args.includes("--stdout");
|
|
81
|
+
const checkMode = args.includes("--check");
|
|
82
|
+
|
|
83
|
+
const sproutDir = await findSproutDir();
|
|
84
|
+
const projectRoot = projectRootFromSproutDir(sproutDir);
|
|
85
|
+
|
|
86
|
+
const targetPath = findTargetFile(projectRoot);
|
|
87
|
+
const snippet = onboardSnippet();
|
|
88
|
+
|
|
89
|
+
// --check mode: report status only
|
|
90
|
+
if (checkMode) {
|
|
91
|
+
if (!targetPath) {
|
|
92
|
+
if (jsonMode) {
|
|
93
|
+
await outputJson({ success: true, command: "onboard", status: "missing", file: null });
|
|
94
|
+
} else {
|
|
95
|
+
console.log("Status: missing (no CLAUDE.md found)");
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const content = await Bun.file(targetPath).text();
|
|
100
|
+
const status = detectStatus(content);
|
|
101
|
+
if (jsonMode) {
|
|
102
|
+
await outputJson({ success: true, command: "onboard", status, file: targetPath });
|
|
103
|
+
} else {
|
|
104
|
+
console.log(`Status: ${status} (${targetPath})`);
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// --stdout mode: print what would be written
|
|
110
|
+
if (stdoutMode) {
|
|
111
|
+
process.stdout.write(wrapInMarkers(snippet));
|
|
112
|
+
process.stdout.write("\n");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Default mode: write to file
|
|
117
|
+
const filePath = targetPath ?? join(projectRoot, "CLAUDE.md");
|
|
118
|
+
const fileExists = existsSync(filePath);
|
|
119
|
+
const wrappedSnippet = wrapInMarkers(snippet);
|
|
120
|
+
|
|
121
|
+
if (!fileExists) {
|
|
122
|
+
await Bun.write(filePath, `${wrappedSnippet}\n`);
|
|
123
|
+
if (jsonMode) {
|
|
124
|
+
await outputJson({ success: true, command: "onboard", action: "created", file: filePath });
|
|
125
|
+
} else {
|
|
126
|
+
printSuccess(`Created ${filePath} with sprout section`);
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const content = await Bun.file(filePath).text();
|
|
132
|
+
const status = detectStatus(content);
|
|
133
|
+
|
|
134
|
+
if (status === "current") {
|
|
135
|
+
if (jsonMode) {
|
|
136
|
+
await outputJson({
|
|
137
|
+
success: true,
|
|
138
|
+
command: "onboard",
|
|
139
|
+
action: "unchanged",
|
|
140
|
+
file: filePath,
|
|
141
|
+
});
|
|
142
|
+
} else {
|
|
143
|
+
printSuccess("Sprout section is already up to date");
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (status === "outdated") {
|
|
149
|
+
const updated = replaceMarkerSection(content, snippet);
|
|
150
|
+
if (!updated) {
|
|
151
|
+
// Defensive: detectStatus saw markers but replaceMarkerSection refused
|
|
152
|
+
// (e.g. markers out of order, truncated, or duplicated). Surface this
|
|
153
|
+
// instead of silently no-op'ing — agents need to know their snippet is stale.
|
|
154
|
+
const msg = `Found sprout markers in ${filePath} but could not replace the section (markers may be malformed, out of order, or duplicated). Fix the file manually or remove the sprout:start/sprout:end block and re-run.`;
|
|
155
|
+
if (jsonMode) {
|
|
156
|
+
await outputJson({
|
|
157
|
+
success: false,
|
|
158
|
+
command: "onboard",
|
|
159
|
+
action: "failed",
|
|
160
|
+
file: filePath,
|
|
161
|
+
error: msg,
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
printError(msg);
|
|
165
|
+
}
|
|
166
|
+
process.exitCode = 1;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
await Bun.write(filePath, updated);
|
|
170
|
+
if (jsonMode) {
|
|
171
|
+
await outputJson({
|
|
172
|
+
success: true,
|
|
173
|
+
command: "onboard",
|
|
174
|
+
action: "updated",
|
|
175
|
+
file: filePath,
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
printSuccess(`Updated sprout section in ${filePath}`);
|
|
179
|
+
}
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// status === "missing": append
|
|
184
|
+
const separator = content.endsWith("\n") ? "\n" : "\n\n";
|
|
185
|
+
await Bun.write(filePath, `${content}${separator}${wrappedSnippet}\n`);
|
|
186
|
+
if (jsonMode) {
|
|
187
|
+
await outputJson({ success: true, command: "onboard", action: "appended", file: filePath });
|
|
188
|
+
} else {
|
|
189
|
+
printSuccess(`Added sprout section to ${filePath}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function register(program: Command): void {
|
|
194
|
+
program
|
|
195
|
+
.command("onboard")
|
|
196
|
+
.description("Add sprout section to CLAUDE.md / AGENTS.md")
|
|
197
|
+
.option("--stdout", "Print what would be written to stdout")
|
|
198
|
+
.option("--check", "Check status without modifying files")
|
|
199
|
+
.option("--json", "Output as JSON")
|
|
200
|
+
.action(async (opts: { stdout?: boolean; check?: boolean; json?: boolean }) => {
|
|
201
|
+
const args: string[] = [];
|
|
202
|
+
if (opts.stdout) args.push("--stdout");
|
|
203
|
+
if (opts.check) args.push("--check");
|
|
204
|
+
if (opts.json) args.push("--json");
|
|
205
|
+
await run(args);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { findSproutDir, loadPlanTemplates, maxPlanDepth, readConfig } from "../config.ts";
|
|
2
|
+
import { accent, brand, muted, outputJson } from "../output.ts";
|
|
3
|
+
import { type ChildSummary, summarisePlanChildren } from "../plan-context.ts";
|
|
4
|
+
import { readIssues, readPlans } from "../store.ts";
|
|
5
|
+
import type { Issue, Plan, PlanTemplate, SectionSpec } from "../types.ts";
|
|
6
|
+
|
|
7
|
+
interface PlanTreeNode {
|
|
8
|
+
plan: Plan;
|
|
9
|
+
children: ChildSummary[];
|
|
10
|
+
children_plans: PlanTreeEntry[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface PlanTreeTruncation {
|
|
14
|
+
plan_id: string;
|
|
15
|
+
truncated: true;
|
|
16
|
+
hint: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type PlanTreeEntry = PlanTreeNode | PlanTreeTruncation;
|
|
20
|
+
|
|
21
|
+
function buildPlansBySeed(plans: Plan[]): Map<string, Plan> {
|
|
22
|
+
const out = new Map<string, Plan>();
|
|
23
|
+
for (const p of plans) {
|
|
24
|
+
const existing = out.get(p.seed);
|
|
25
|
+
if (!existing || existing.updatedAt < p.updatedAt) out.set(p.seed, p);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function truncationHint(planId: string): string {
|
|
31
|
+
return `depth limit reached — use \`sr plan show ${planId}\` to drill in`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// PLAN_SPEC.md:340, 425, 430 — recurse through nested plans up to max_plan_depth.
|
|
35
|
+
// Depth is 1-indexed: the root plan is at depth 1, nested plans start at 2.
|
|
36
|
+
function buildPlanTree(
|
|
37
|
+
plan: Plan,
|
|
38
|
+
issues: Issue[],
|
|
39
|
+
plansBySeed: Map<string, Plan>,
|
|
40
|
+
depth: number,
|
|
41
|
+
maxDepth: number,
|
|
42
|
+
): PlanTreeNode {
|
|
43
|
+
const childrenSummary = summarisePlanChildren(plan, issues);
|
|
44
|
+
const childrenPlans: PlanTreeEntry[] = [];
|
|
45
|
+
for (const childId of plan.children) {
|
|
46
|
+
const sub = plansBySeed.get(childId);
|
|
47
|
+
if (!sub) continue;
|
|
48
|
+
const nextDepth = depth + 1;
|
|
49
|
+
if (nextDepth > maxDepth) {
|
|
50
|
+
childrenPlans.push({
|
|
51
|
+
plan_id: sub.id,
|
|
52
|
+
truncated: true,
|
|
53
|
+
hint: truncationHint(sub.id),
|
|
54
|
+
});
|
|
55
|
+
} else {
|
|
56
|
+
childrenPlans.push(buildPlanTree(sub, issues, plansBySeed, nextDepth, maxDepth));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return { plan, children: childrenSummary, children_plans: childrenPlans };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function renderPlanSections(plan: Plan, template: PlanTemplate | undefined): void {
|
|
63
|
+
console.log(brand("Sections:"));
|
|
64
|
+
const order = ["context", "approach", "alternatives", "steps", "risks", "acceptance"];
|
|
65
|
+
const knownKeys = new Set(order);
|
|
66
|
+
const orderedKeys = [
|
|
67
|
+
...order.filter((k) => k in plan.sections),
|
|
68
|
+
...Object.keys(plan.sections).filter((k) => !knownKeys.has(k)),
|
|
69
|
+
];
|
|
70
|
+
for (const key of orderedKeys) {
|
|
71
|
+
const value = plan.sections[key];
|
|
72
|
+
const spec = template?.sections[key];
|
|
73
|
+
console.log(` ${accent.bold(key)}`);
|
|
74
|
+
if (value === undefined || value === null) {
|
|
75
|
+
console.log(muted(" (empty)"));
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (typeof value === "string") {
|
|
79
|
+
for (const line of value.split("\n")) console.log(` ${line}`);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
if (value.length === 0) {
|
|
84
|
+
console.log(muted(" (none)"));
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
renderListSection(value, spec);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
console.log(` ${JSON.stringify(value)}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function renderListSection(entries: unknown[], spec: SectionSpec | undefined): void {
|
|
95
|
+
const kind = spec?.kind;
|
|
96
|
+
const itemSpec = spec?.item;
|
|
97
|
+
entries.forEach((entry, i) => {
|
|
98
|
+
const marker = ` ${i + 1}.`;
|
|
99
|
+
if (typeof entry === "string") {
|
|
100
|
+
console.log(`${marker} ${entry}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (kind === "steps" && isPlainRecord(entry)) {
|
|
104
|
+
renderStepEntry(marker, entry);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (kind === "list" && isPlainRecord(entry) && isItemSchema(itemSpec)) {
|
|
108
|
+
renderListEntry(marker, entry, itemSpec);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
console.log(`${marker} ${JSON.stringify(entry)}`);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function renderStepEntry(marker: string, entry: Record<string, unknown>): void {
|
|
116
|
+
const title = typeof entry.title === "string" ? entry.title : JSON.stringify(entry);
|
|
117
|
+
console.log(`${marker} ${title}`);
|
|
118
|
+
const subIndent = " ".repeat(marker.length + 1);
|
|
119
|
+
const blocks = entry.blocks;
|
|
120
|
+
if (Array.isArray(blocks) && blocks.length > 0) {
|
|
121
|
+
// blocks values are stored 1-based (sprout-185f), so render verbatim.
|
|
122
|
+
const labels = blocks
|
|
123
|
+
.map((b) => (typeof b === "number" ? String(b) : JSON.stringify(b)))
|
|
124
|
+
.join(", ");
|
|
125
|
+
console.log(`${subIndent}${muted(`blocks: ${labels}`)}`);
|
|
126
|
+
}
|
|
127
|
+
if (entry.requires_plan === true) {
|
|
128
|
+
console.log(`${subIndent}${muted("requires_plan: true")}`);
|
|
129
|
+
}
|
|
130
|
+
if (typeof entry.plan_template === "string" && entry.plan_template.length > 0) {
|
|
131
|
+
console.log(`${subIndent}${muted(`plan_template: ${entry.plan_template}`)}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function renderListEntry(
|
|
136
|
+
marker: string,
|
|
137
|
+
entry: Record<string, unknown>,
|
|
138
|
+
itemSpec: Record<string, SectionSpec>,
|
|
139
|
+
): void {
|
|
140
|
+
const subIndent = " ".repeat(marker.length + 1);
|
|
141
|
+
const fieldNames = Object.keys(itemSpec);
|
|
142
|
+
let firstLineWritten = false;
|
|
143
|
+
for (const field of fieldNames) {
|
|
144
|
+
const fv = entry[field];
|
|
145
|
+
if (fv === undefined || fv === null || fv === "") continue;
|
|
146
|
+
const rendered = typeof fv === "string" ? fv : JSON.stringify(fv);
|
|
147
|
+
if (!firstLineWritten) {
|
|
148
|
+
console.log(`${marker} ${field}: ${rendered}`);
|
|
149
|
+
firstLineWritten = true;
|
|
150
|
+
} else {
|
|
151
|
+
console.log(`${subIndent}${field}: ${rendered}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!firstLineWritten) {
|
|
155
|
+
console.log(`${marker} ${JSON.stringify(entry)}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function isPlainRecord(v: unknown): v is Record<string, unknown> {
|
|
160
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function isItemSchema(item: SectionSpec["item"]): item is Record<string, SectionSpec> {
|
|
164
|
+
return typeof item === "object" && item !== null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function renderNestedPlanHuman(entry: PlanTreeEntry, indent: string): void {
|
|
168
|
+
if ("truncated" in entry) {
|
|
169
|
+
console.log(`${indent}${muted(entry.hint)}`);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const { plan, children, children_plans } = entry;
|
|
173
|
+
const nameLabel = plan.name ? ` ${plan.name}` : "";
|
|
174
|
+
console.log(
|
|
175
|
+
`${indent}${brand("Sub-plan:")} ${accent.bold(plan.id)}${nameLabel} ${muted(`[${plan.status}]`)} ${muted(`rev ${plan.revision}`)} ${muted(`seed=${plan.seed}`)}`,
|
|
176
|
+
);
|
|
177
|
+
console.log(`${indent}${muted(`Children (${children.length}):`)}`);
|
|
178
|
+
const childIndent = `${indent} `;
|
|
179
|
+
if (children.length === 0) {
|
|
180
|
+
console.log(`${childIndent}${muted("(none)")}`);
|
|
181
|
+
} else {
|
|
182
|
+
for (const c of children) {
|
|
183
|
+
const tag = c.adopted ? ` ${muted("(adopted)")}` : "";
|
|
184
|
+
console.log(`${childIndent}${accent(c.id)} ${muted(`[${c.status}]`)} ${c.title}${tag}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
for (const sub of children_plans) {
|
|
188
|
+
console.log("");
|
|
189
|
+
renderNestedPlanHuman(sub, childIndent);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Accept either a plan id (pl-xxxx) or a seed id; sprout resolve through
|
|
194
|
+
// seed.plan_id (PLAN_SPEC contract: "the seed knows its plan"). The shared
|
|
195
|
+
// helper keeps show/validate/outcome/review consistent so an agent that has a
|
|
196
|
+
// seed id in hand never has to round-trip through `sr plan list` for the
|
|
197
|
+
// pl-xxxx token.
|
|
198
|
+
export async function resolvePlanIdArg(arg: string, dir: string): Promise<string> {
|
|
199
|
+
if (arg.startsWith("pl-")) return arg;
|
|
200
|
+
const issues = await readIssues(dir);
|
|
201
|
+
const seed = issues.find((i) => i.id === arg);
|
|
202
|
+
if (!seed) {
|
|
203
|
+
throw new Error(`Plan not found: ${arg}. Run 'sr plan list' to see available plans.`);
|
|
204
|
+
}
|
|
205
|
+
if (!seed.plan_id) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
`Seed ${arg} has no plan. Submit one with 'sr plan submit ${arg} --plan <file>'.`,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
return seed.plan_id;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export async function runShow(idArg: string, jsonMode: boolean): Promise<void> {
|
|
214
|
+
const dir = await findSproutDir();
|
|
215
|
+
const planId = await resolvePlanIdArg(idArg, dir);
|
|
216
|
+
const config = await readConfig(dir);
|
|
217
|
+
const maxDepth = maxPlanDepth(config);
|
|
218
|
+
const plans = await readPlans(dir);
|
|
219
|
+
const plan = plans.find((p) => p.id === planId);
|
|
220
|
+
if (!plan) {
|
|
221
|
+
throw new Error(`Plan not found: ${planId}. Run 'sr plan list' to see available plans.`);
|
|
222
|
+
}
|
|
223
|
+
const issues = await readIssues(dir);
|
|
224
|
+
const plansBySeed = buildPlansBySeed(plans);
|
|
225
|
+
const tree = buildPlanTree(plan, issues, plansBySeed, 1, maxDepth);
|
|
226
|
+
const templates = await loadPlanTemplates(dir);
|
|
227
|
+
const template = templates[plan.template];
|
|
228
|
+
|
|
229
|
+
if (jsonMode) {
|
|
230
|
+
await outputJson({
|
|
231
|
+
success: true,
|
|
232
|
+
command: "plan show",
|
|
233
|
+
plan,
|
|
234
|
+
children: tree.children,
|
|
235
|
+
children_plans: tree.children_plans,
|
|
236
|
+
});
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
console.log(`${accent.bold(plan.id)} ${brand(plan.status)} ${muted(`rev ${plan.revision}`)}`);
|
|
241
|
+
if (plan.name) console.log(`Name: ${plan.name}`);
|
|
242
|
+
console.log(`Seed: ${accent(plan.seed)}`);
|
|
243
|
+
console.log(`Template: ${plan.template}`);
|
|
244
|
+
console.log(`Created: ${muted(plan.createdAt)}`);
|
|
245
|
+
console.log(`Updated: ${muted(plan.updatedAt)}`);
|
|
246
|
+
if (plan.outcome) {
|
|
247
|
+
const note = plan.outcomeNote ? ` — ${plan.outcomeNote}` : "";
|
|
248
|
+
console.log(`Outcome: ${plan.outcome}${note}`);
|
|
249
|
+
}
|
|
250
|
+
// PLAN_SPEC.md:404-413 — review hint is purely cosmetic and only relevant
|
|
251
|
+
// while a plan is awaiting work or in flight.
|
|
252
|
+
const reviewActionable = plan.status === "approved" || plan.status === "active";
|
|
253
|
+
if (!plan.reviewedBy && reviewActionable) {
|
|
254
|
+
console.log(muted("Review suggested (no reviewer recorded yet)"));
|
|
255
|
+
}
|
|
256
|
+
if (plan.reviewedBy) {
|
|
257
|
+
console.log(`Reviewed: ${plan.reviewedBy}`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
console.log("");
|
|
261
|
+
renderPlanSections(plan, template);
|
|
262
|
+
|
|
263
|
+
console.log("");
|
|
264
|
+
console.log(brand(`Children (${tree.children.length}):`));
|
|
265
|
+
if (tree.children.length === 0) {
|
|
266
|
+
console.log(muted(" (none)"));
|
|
267
|
+
} else {
|
|
268
|
+
for (const c of tree.children) {
|
|
269
|
+
const tag = c.adopted ? ` ${muted("(adopted)")}` : "";
|
|
270
|
+
console.log(` ${accent(c.id)} ${muted(`[${c.status}]`)} ${c.title}${tag}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
for (const sub of tree.children_plans) {
|
|
275
|
+
console.log("");
|
|
276
|
+
renderNestedPlanHuman(sub, " ");
|
|
277
|
+
}
|
|
278
|
+
}
|