@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,399 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import type { Command } from "commander";
|
|
3
|
+
import { findSproutDir } from "../config.ts";
|
|
4
|
+
import { outputJson } from "../output.ts";
|
|
5
|
+
|
|
6
|
+
const PRIME_FILE = "PRIME.md";
|
|
7
|
+
|
|
8
|
+
export interface PrimeCommand {
|
|
9
|
+
command: string;
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface PrimeCommandGroup {
|
|
14
|
+
name: string;
|
|
15
|
+
commands: PrimeCommand[];
|
|
16
|
+
notes?: string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PrimeWorkflow {
|
|
20
|
+
name: string;
|
|
21
|
+
commands: string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PrimeSectionsFull {
|
|
25
|
+
mode: "full";
|
|
26
|
+
title: string;
|
|
27
|
+
contextRecovery: string;
|
|
28
|
+
closeProtocol: {
|
|
29
|
+
warning: string;
|
|
30
|
+
steps: string[];
|
|
31
|
+
footer: string;
|
|
32
|
+
};
|
|
33
|
+
rules: string[];
|
|
34
|
+
commandGroups: PrimeCommandGroup[];
|
|
35
|
+
workflows: PrimeWorkflow[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface PrimeSectionsCompact {
|
|
39
|
+
mode: "compact";
|
|
40
|
+
title: string;
|
|
41
|
+
commands: PrimeCommand[];
|
|
42
|
+
planningNote: string;
|
|
43
|
+
closingNote: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type PrimeSections = PrimeSectionsFull | PrimeSectionsCompact;
|
|
47
|
+
|
|
48
|
+
const FULL_SECTIONS: PrimeSectionsFull = {
|
|
49
|
+
mode: "full",
|
|
50
|
+
title: "Sprout Workflow Context",
|
|
51
|
+
contextRecovery: "Run `sr prime` after compaction, clear, or new session",
|
|
52
|
+
closeProtocol: {
|
|
53
|
+
warning: 'Before saying "done" or "complete", you MUST run this checklist:',
|
|
54
|
+
steps: [
|
|
55
|
+
"Close completed issues: sr close <id1> <id2> ...",
|
|
56
|
+
'File issues for remaining: sr create --title "..."',
|
|
57
|
+
"Run quality gates: bun test && bun run lint && bun run typecheck",
|
|
58
|
+
"Sync and push: sr sync && git push",
|
|
59
|
+
'Verify: git status (must show "up to date with origin")',
|
|
60
|
+
],
|
|
61
|
+
footer: "**NEVER skip this.** Work is not done until pushed.",
|
|
62
|
+
},
|
|
63
|
+
rules: [
|
|
64
|
+
"**Default**: Use sprout for ALL task tracking (`sr create`, `sr ready`, `sr close`)",
|
|
65
|
+
"**Prohibited**: Do NOT use TodoWrite, TaskCreate, or markdown files for task tracking",
|
|
66
|
+
"**Workflow**: Create issues BEFORE writing code, mark in_progress when starting",
|
|
67
|
+
"Git workflow: run `sr sync` at session end",
|
|
68
|
+
],
|
|
69
|
+
commandGroups: [
|
|
70
|
+
{
|
|
71
|
+
name: "Finding Work",
|
|
72
|
+
commands: [
|
|
73
|
+
{ command: "sr ready", description: "Show issues ready to work (no blockers)" },
|
|
74
|
+
{ command: "sr list --status=open", description: "All open issues" },
|
|
75
|
+
{ command: "sr list --status=in_progress", description: "Your active work" },
|
|
76
|
+
{
|
|
77
|
+
command: "sr show <id> [<id2> ...]",
|
|
78
|
+
description:
|
|
79
|
+
"Detailed issue view; multi-id shows each separated by a divider (`--json` returns `issues: [...]`)",
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "Creating & Updating",
|
|
85
|
+
commands: [
|
|
86
|
+
{
|
|
87
|
+
command: 'sr create --title="..." --type=task|bug|feature|epic --priority=2',
|
|
88
|
+
description: "New issue\n - Priority: 0-4 or P0-P4 (0=critical, 2=medium, 4=backlog)",
|
|
89
|
+
},
|
|
90
|
+
{ command: "sr update <id> --status=in_progress", description: "Claim work" },
|
|
91
|
+
{ command: "sr update <id> --assignee=username", description: "Assign to someone" },
|
|
92
|
+
{ command: "sr close <id>", description: "Mark complete" },
|
|
93
|
+
{ command: "sr close <id1> <id2> ...", description: "Close multiple issues at once" },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "Dependencies & Blocking",
|
|
98
|
+
commands: [
|
|
99
|
+
{ command: "sr dep add <issue> <depends-on>", description: "Add dependency" },
|
|
100
|
+
{ command: "sr dep remove <issue> <depends-on>", description: "Remove dependency" },
|
|
101
|
+
{ command: "sr blocked", description: "Show all blocked issues" },
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "Labels",
|
|
106
|
+
commands: [
|
|
107
|
+
{ command: "sr label add <id> bug ui", description: "Add labels to an issue" },
|
|
108
|
+
{ command: "sr label remove <id> bug", description: "Remove labels" },
|
|
109
|
+
{ command: "sr label list <id>", description: "List labels on an issue" },
|
|
110
|
+
{ command: "sr label list-all", description: "Show all labels in project" },
|
|
111
|
+
{
|
|
112
|
+
command: "sr list --label=bug",
|
|
113
|
+
description: "Filter by label (AND, comma-separated)",
|
|
114
|
+
},
|
|
115
|
+
{ command: "sr list --label-any=bug,ui", description: "Filter by label (OR)" },
|
|
116
|
+
{ command: "sr list --unlabeled", description: "Issues with no labels" },
|
|
117
|
+
{ command: 'sr create --title="..." --labels=bug,ui', description: "Create with labels" },
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "Sync & Project Health",
|
|
122
|
+
commands: [
|
|
123
|
+
{ command: "sr sync", description: "Stage and commit .sprout/ changes" },
|
|
124
|
+
{ command: "sr sync --status", description: "Check without committing" },
|
|
125
|
+
{ command: "sr stats", description: "Project statistics" },
|
|
126
|
+
{ command: "sr doctor", description: "Check for data integrity issues" },
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "Planning",
|
|
131
|
+
notes: [
|
|
132
|
+
'Use `sr plan` when work is large or ambiguous enough to benefit from structured decomposition. The plan spawns one child seed per step; `step.blocks` uses forward semantics (step i with `blocks: [j]` means step i blocks step j). Each step accepts an optional `labels: string[]` field (normalized lowercase/trim/dedup) that flows to the spawned child or merges additively into an adopted seed — useful for tagging agent-spawned children (e.g. `"labels": ["nightwatch"]`) without follow-up `sr label add` calls. For small, well-scoped tasks, just `sr create` directly.',
|
|
133
|
+
],
|
|
134
|
+
commands: [
|
|
135
|
+
{
|
|
136
|
+
command: "sr plan templates",
|
|
137
|
+
description: "List built-in templates (`feature`, `bug`, `refactor`) plus custom ones",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
command: "sr plan prompt <seed-id>",
|
|
141
|
+
description: "Emit prompt JSON for the LLM to fill",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
command: "sr plan submit <seed-id> --plan <file>",
|
|
145
|
+
description: "Validate + spawn children",
|
|
146
|
+
},
|
|
147
|
+
{ command: "sr plan show <pl-id>", description: "Sections, children, nested sub-plans" },
|
|
148
|
+
{
|
|
149
|
+
command: "sr plan create <seed-id>",
|
|
150
|
+
description:
|
|
151
|
+
"Adopt-only plan (zero spawned children); populate via 'sr plan adopt' + 'sr plan reorder'",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
command: "sr plan adopt <pl-id> <seed-id...> [--step|--at|--before|--after]",
|
|
155
|
+
description:
|
|
156
|
+
"Adopt existing sprout into a plan; --at/--before/--after control children position",
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
command: "sr plan reorder <pl-id> <seed-id...>",
|
|
160
|
+
description: "Set the exact plan.children order (permutation of current children)",
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
command:
|
|
164
|
+
"sr plan edit <id> [--name|--section <n> <t>|--step <i> --title/--priority/--type]",
|
|
165
|
+
description:
|
|
166
|
+
"In-place field edits; bumps revision. Structural changes still need --overwrite.",
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
command: "sr plan outcome <pl-id> --result success|partial|failure",
|
|
170
|
+
description: "Storage-only outcome",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
command: "sr plan review <pl-id> --by <name>",
|
|
174
|
+
description: "Optional reviewer (informational)",
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
workflows: [
|
|
180
|
+
{
|
|
181
|
+
name: "Starting work",
|
|
182
|
+
commands: [
|
|
183
|
+
"sr ready # Find available work",
|
|
184
|
+
"sr show <id> # Review issue details",
|
|
185
|
+
"sr update <id> --status=in_progress # Claim it",
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "Completing work",
|
|
190
|
+
commands: [
|
|
191
|
+
"sr close <id1> <id2> ... # Close all completed issues at once",
|
|
192
|
+
"sr sync # Stage + commit .sprout/",
|
|
193
|
+
"git push # Push to remote",
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "Creating dependent work",
|
|
198
|
+
commands: [
|
|
199
|
+
'sr create --title="Implement feature X" --type=feature',
|
|
200
|
+
'sr create --title="Write tests for X" --type=task',
|
|
201
|
+
"sr dep add <test-id> <feature-id> # Tests depend on feature",
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const COMPACT_SECTIONS: PrimeSectionsCompact = {
|
|
208
|
+
mode: "compact",
|
|
209
|
+
title: "Sprout Quick Reference",
|
|
210
|
+
commands: [
|
|
211
|
+
{ command: "sr ready", description: "Find unblocked work" },
|
|
212
|
+
{ command: "sr show <id> [id...]", description: "View one or more issues" },
|
|
213
|
+
{ command: 'sr create --title "..."', description: "Create issue (--type, --priority)" },
|
|
214
|
+
{ command: "sr update <id> --status in_progress", description: "Claim work" },
|
|
215
|
+
{ command: "sr close <id>", description: "Complete work" },
|
|
216
|
+
{ command: "sr dep add <a> <b>", description: "a depends on b" },
|
|
217
|
+
{ command: "sr blocked", description: "Show blocked issues" },
|
|
218
|
+
{ command: "sr label add <id> <l...>", description: "Add labels" },
|
|
219
|
+
{ command: "sr list --label=bug", description: "Filter by label" },
|
|
220
|
+
{
|
|
221
|
+
command: "sr plan prompt <seed>",
|
|
222
|
+
description: "Plan large/ambiguous work; spawns child sprout",
|
|
223
|
+
},
|
|
224
|
+
{ command: "sr plan submit <seed> --plan <file>", description: "Submit + spawn children" },
|
|
225
|
+
{ command: "sr sync", description: "Stage + commit .sprout/" },
|
|
226
|
+
],
|
|
227
|
+
planningNote:
|
|
228
|
+
"**Planning:** Use `sr plan` for ambiguous or large work — built-in templates: `feature`, `bug`, `refactor`.",
|
|
229
|
+
closingNote: "**Before finishing:** `sr close <ids> && sr sync && git push`",
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
function renderFull(s: PrimeSectionsFull): string {
|
|
233
|
+
const lines: string[] = [];
|
|
234
|
+
lines.push(`# ${s.title}`);
|
|
235
|
+
lines.push("");
|
|
236
|
+
lines.push(`> **Context Recovery**: ${s.contextRecovery}`);
|
|
237
|
+
lines.push("");
|
|
238
|
+
|
|
239
|
+
lines.push("# Session Close Protocol");
|
|
240
|
+
lines.push("");
|
|
241
|
+
lines.push(`**CRITICAL**: ${s.closeProtocol.warning}`);
|
|
242
|
+
lines.push("");
|
|
243
|
+
lines.push("```");
|
|
244
|
+
s.closeProtocol.steps.forEach((step, i) => {
|
|
245
|
+
lines.push(`[ ] ${i + 1}. ${step}`);
|
|
246
|
+
});
|
|
247
|
+
lines.push("```");
|
|
248
|
+
lines.push("");
|
|
249
|
+
lines.push(s.closeProtocol.footer);
|
|
250
|
+
lines.push("");
|
|
251
|
+
|
|
252
|
+
lines.push("## Core Rules");
|
|
253
|
+
for (const rule of s.rules) {
|
|
254
|
+
lines.push(`- ${rule}`);
|
|
255
|
+
}
|
|
256
|
+
lines.push("");
|
|
257
|
+
|
|
258
|
+
lines.push("## Essential Commands");
|
|
259
|
+
lines.push("");
|
|
260
|
+
for (const group of s.commandGroups) {
|
|
261
|
+
lines.push(`### ${group.name}`);
|
|
262
|
+
if (group.notes) {
|
|
263
|
+
for (const note of group.notes) {
|
|
264
|
+
lines.push(note);
|
|
265
|
+
lines.push("");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
for (const cmd of group.commands) {
|
|
269
|
+
lines.push(`- \`${cmd.command}\` — ${cmd.description}`);
|
|
270
|
+
}
|
|
271
|
+
lines.push("");
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
lines.push("## Common Workflows");
|
|
275
|
+
lines.push("");
|
|
276
|
+
for (const wf of s.workflows) {
|
|
277
|
+
lines.push(`**${wf.name}:**`);
|
|
278
|
+
lines.push("```bash");
|
|
279
|
+
for (const c of wf.commands) {
|
|
280
|
+
lines.push(c);
|
|
281
|
+
}
|
|
282
|
+
lines.push("```");
|
|
283
|
+
lines.push("");
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return `${lines.join("\n")}`;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function renderCompact(s: PrimeSectionsCompact): string {
|
|
290
|
+
const lines: string[] = [];
|
|
291
|
+
lines.push(`# ${s.title}`);
|
|
292
|
+
lines.push("");
|
|
293
|
+
lines.push("```");
|
|
294
|
+
// Align descriptions at a fixed column for readability.
|
|
295
|
+
const pad = 26;
|
|
296
|
+
for (const c of s.commands) {
|
|
297
|
+
const cmd = c.command.length >= pad ? `${c.command} ` : c.command.padEnd(pad);
|
|
298
|
+
lines.push(`${cmd}# ${c.description}`);
|
|
299
|
+
}
|
|
300
|
+
lines.push("```");
|
|
301
|
+
lines.push("");
|
|
302
|
+
lines.push(s.planningNote);
|
|
303
|
+
lines.push("");
|
|
304
|
+
lines.push(s.closingNote);
|
|
305
|
+
lines.push("");
|
|
306
|
+
return lines.join("\n");
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export function buildFullSections(): PrimeSectionsFull {
|
|
310
|
+
return FULL_SECTIONS;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function buildCompactSections(): PrimeSectionsCompact {
|
|
314
|
+
return COMPACT_SECTIONS;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function renderPrimeSections(sections: PrimeSections): string {
|
|
318
|
+
return sections.mode === "compact" ? renderCompact(sections) : renderFull(sections);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function defaultPrimeContent(compact: boolean): string {
|
|
322
|
+
return renderPrimeSections(compact ? COMPACT_SECTIONS : FULL_SECTIONS);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export async function run(args: string[]): Promise<void> {
|
|
326
|
+
const jsonMode = args.includes("--json");
|
|
327
|
+
const compact = args.includes("--compact");
|
|
328
|
+
const exportMode = args.includes("--export");
|
|
329
|
+
|
|
330
|
+
// --export always outputs the default template
|
|
331
|
+
if (exportMode) {
|
|
332
|
+
const sections = compact ? COMPACT_SECTIONS : FULL_SECTIONS;
|
|
333
|
+
const content = renderPrimeSections(sections);
|
|
334
|
+
if (jsonMode) {
|
|
335
|
+
await outputJson({ success: true, command: "prime", sections, content });
|
|
336
|
+
} else {
|
|
337
|
+
process.stdout.write(content);
|
|
338
|
+
}
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Try to find sprout dir for custom PRIME.md
|
|
343
|
+
let customContent: string | null = null;
|
|
344
|
+
try {
|
|
345
|
+
const sproutDir = await findSproutDir();
|
|
346
|
+
const customFile = Bun.file(join(sproutDir, PRIME_FILE));
|
|
347
|
+
if (await customFile.exists()) {
|
|
348
|
+
customContent = await customFile.text();
|
|
349
|
+
}
|
|
350
|
+
} catch {
|
|
351
|
+
// No sprout dir — that's fine, use default
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (customContent !== null) {
|
|
355
|
+
// Custom PRIME.md is opaque — we can't structurally parse it, so omit sections.
|
|
356
|
+
if (jsonMode) {
|
|
357
|
+
await outputJson({
|
|
358
|
+
success: true,
|
|
359
|
+
command: "prime",
|
|
360
|
+
sections: null,
|
|
361
|
+
content: customContent,
|
|
362
|
+
});
|
|
363
|
+
} else {
|
|
364
|
+
process.stdout.write(customContent);
|
|
365
|
+
}
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const sections = compact ? COMPACT_SECTIONS : FULL_SECTIONS;
|
|
370
|
+
const content = renderPrimeSections(sections);
|
|
371
|
+
if (jsonMode) {
|
|
372
|
+
await outputJson({ success: true, command: "prime", sections, content });
|
|
373
|
+
} else {
|
|
374
|
+
process.stdout.write(content);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export function register(program: Command): void {
|
|
379
|
+
program
|
|
380
|
+
.command("prime")
|
|
381
|
+
.description("Output AI agent context")
|
|
382
|
+
.option("--compact", "Condensed quick-reference output")
|
|
383
|
+
.option("--export", "Output the default template")
|
|
384
|
+
.option("--json", "Output as JSON")
|
|
385
|
+
.action(async (opts: { compact?: boolean; export?: boolean; json?: boolean }) => {
|
|
386
|
+
const args: string[] = [];
|
|
387
|
+
if (opts.compact) args.push("--compact");
|
|
388
|
+
if (opts.export) args.push("--export");
|
|
389
|
+
if (opts.json) args.push("--json");
|
|
390
|
+
await run(args);
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Internal exports for testing.
|
|
395
|
+
export const _internal = {
|
|
396
|
+
defaultPrimeContent,
|
|
397
|
+
FULL_SECTIONS,
|
|
398
|
+
COMPACT_SECTIONS,
|
|
399
|
+
};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { findSproutDir } from "../config.ts";
|
|
3
|
+
import { applyIssueFilters, filterOptionsFromFlags, parseLimitFlag } from "../filter.ts";
|
|
4
|
+
import { resolveFormat, stripAnsi, VALID_FORMATS } from "../format.ts";
|
|
5
|
+
import {
|
|
6
|
+
formatIssueOneLine,
|
|
7
|
+
formatIssueOneLineCompact,
|
|
8
|
+
outputJson,
|
|
9
|
+
printIssueOneLine,
|
|
10
|
+
} from "../output.ts";
|
|
11
|
+
import {
|
|
12
|
+
isPlanDraftBlocking,
|
|
13
|
+
issueJsonWithPlan,
|
|
14
|
+
loadPlanContext,
|
|
15
|
+
planForIssue,
|
|
16
|
+
planLineSuffix,
|
|
17
|
+
} from "../plan-context.ts";
|
|
18
|
+
import { isSortMode, sortIssues, VALID_SORT_MODES } from "../sort.ts";
|
|
19
|
+
import { readIssues } from "../store.ts";
|
|
20
|
+
import type { Issue, Plan } from "../types.ts";
|
|
21
|
+
|
|
22
|
+
// pl-c195 step 4: opt-in schedule filter. Two well-known extension keys:
|
|
23
|
+
// extensions.queued === true → not ready yet (intentionally parked)
|
|
24
|
+
// extensions.scheduledFor: ISO8601 in the future → not ready yet
|
|
25
|
+
// Malformed/past values fall through to ready as if the keys weren't set.
|
|
26
|
+
function isScheduledOut(issue: Issue, now: number): boolean {
|
|
27
|
+
const ext = issue.extensions;
|
|
28
|
+
if (!ext) return false;
|
|
29
|
+
if (ext.queued === true) return true;
|
|
30
|
+
const sched = ext.scheduledFor;
|
|
31
|
+
if (typeof sched === "string") {
|
|
32
|
+
const t = Date.parse(sched);
|
|
33
|
+
if (!Number.isNaN(t) && t > now) return true;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseArgs(args: string[]): Record<string, string | boolean> {
|
|
39
|
+
const flags: Record<string, string | boolean> = {};
|
|
40
|
+
let i = 0;
|
|
41
|
+
while (i < args.length) {
|
|
42
|
+
const arg = args[i];
|
|
43
|
+
if (!arg) {
|
|
44
|
+
i++;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (arg.startsWith("--")) {
|
|
48
|
+
const key = arg.slice(2);
|
|
49
|
+
const eqIdx = key.indexOf("=");
|
|
50
|
+
if (eqIdx !== -1) {
|
|
51
|
+
flags[key.slice(0, eqIdx)] = key.slice(eqIdx + 1);
|
|
52
|
+
i++;
|
|
53
|
+
} else {
|
|
54
|
+
const next = args[i + 1];
|
|
55
|
+
if (next !== undefined && !next.startsWith("--")) {
|
|
56
|
+
flags[key] = next;
|
|
57
|
+
i += 2;
|
|
58
|
+
} else {
|
|
59
|
+
flags[key] = true;
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
i++;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return flags;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function run(args: string[], sproutDir?: string): Promise<void> {
|
|
71
|
+
const fmt = resolveFormat(args);
|
|
72
|
+
const jsonMode = fmt.mode === "json";
|
|
73
|
+
if (fmt.error) {
|
|
74
|
+
if (jsonMode) {
|
|
75
|
+
await outputJson({ success: false, command: "ready", error: fmt.error });
|
|
76
|
+
} else {
|
|
77
|
+
console.error(fmt.error);
|
|
78
|
+
}
|
|
79
|
+
process.exitCode = 1;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const flags = parseArgs(args);
|
|
83
|
+
let limit: number;
|
|
84
|
+
try {
|
|
85
|
+
limit = parseLimitFlag(flags.limit);
|
|
86
|
+
} catch (e) {
|
|
87
|
+
const msg = (e as Error).message;
|
|
88
|
+
if (jsonMode) {
|
|
89
|
+
await outputJson({ success: false, command: "ready", error: msg });
|
|
90
|
+
} else {
|
|
91
|
+
console.error(msg);
|
|
92
|
+
}
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const dir = sproutDir ?? (await findSproutDir());
|
|
98
|
+
const issues = await readIssues(dir);
|
|
99
|
+
const planCtx = await loadPlanContext(dir);
|
|
100
|
+
|
|
101
|
+
const closedIds = new Set(issues.filter((i: Issue) => i.status === "closed").map((i) => i.id));
|
|
102
|
+
|
|
103
|
+
let ready = issues.filter((i: Issue) => {
|
|
104
|
+
if (i.status !== "open") return false;
|
|
105
|
+
// PLAN_SPEC.md:342 — sprout with requires_plan are excluded until their
|
|
106
|
+
// own sub-plan reaches `approved`. Lookup by seed-id since plan_id is
|
|
107
|
+
// not set on the spawned child until its sub-plan submit succeeds.
|
|
108
|
+
if (i.requires_plan === true) {
|
|
109
|
+
const sub = planCtx.plansBySeed.get(i.id);
|
|
110
|
+
if (!sub || sub.status === "draft") return false;
|
|
111
|
+
// approved/active/done: fall through to standard blocker check.
|
|
112
|
+
} else if (isPlanDraftBlocking(planForIssue(planCtx, i))) {
|
|
113
|
+
// Planning is the highest-priority work: surface sprout with a draft
|
|
114
|
+
// plan even if they would otherwise be blocked. (PLAN_SPEC.md:154)
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
const blockers = i.blockedBy ?? [];
|
|
118
|
+
return blockers.every((bid) => closedIds.has(bid));
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
ready = applyIssueFilters(ready, filterOptionsFromFlags(flags));
|
|
122
|
+
|
|
123
|
+
if (flags["respect-schedule"] === true) {
|
|
124
|
+
const nowMs = Date.now();
|
|
125
|
+
ready = ready.filter((i) => !isScheduledOut(i, nowMs));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const sortFlag = typeof flags.sort === "string" ? flags.sort : "priority";
|
|
129
|
+
if (!isSortMode(sortFlag)) {
|
|
130
|
+
const msg = `Invalid --sort value: ${sortFlag}. Valid: ${VALID_SORT_MODES.join("|")}`;
|
|
131
|
+
if (jsonMode) {
|
|
132
|
+
await outputJson({ success: false, command: "ready", error: msg });
|
|
133
|
+
} else {
|
|
134
|
+
console.error(msg);
|
|
135
|
+
}
|
|
136
|
+
process.exitCode = 1;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
ready = sortIssues(ready, sortFlag);
|
|
140
|
+
|
|
141
|
+
ready = ready.slice(0, limit);
|
|
142
|
+
|
|
143
|
+
const annotate = (issue: Issue): { issue: Issue; plan?: Plan } => ({
|
|
144
|
+
issue,
|
|
145
|
+
plan: planForIssue(planCtx, issue),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
switch (fmt.mode) {
|
|
149
|
+
case "json": {
|
|
150
|
+
const issuesWithPlan = ready.map((i) => issueJsonWithPlan(i, planForIssue(planCtx, i)));
|
|
151
|
+
await outputJson({
|
|
152
|
+
success: true,
|
|
153
|
+
command: "ready",
|
|
154
|
+
issues: issuesWithPlan,
|
|
155
|
+
count: ready.length,
|
|
156
|
+
});
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
case "ids":
|
|
160
|
+
for (const issue of ready) console.log(issue.id);
|
|
161
|
+
return;
|
|
162
|
+
case "compact":
|
|
163
|
+
for (const issue of ready) console.log(formatIssueOneLineCompact(issue, closedIds));
|
|
164
|
+
return;
|
|
165
|
+
case "plain":
|
|
166
|
+
if (ready.length === 0) {
|
|
167
|
+
console.log("No ready issues.");
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
for (const issue of ready) {
|
|
171
|
+
const { plan } = annotate(issue);
|
|
172
|
+
console.log(stripAnsi(formatIssueOneLine(issue, closedIds) + planLineSuffix(plan)));
|
|
173
|
+
}
|
|
174
|
+
console.log(`\n${ready.length} ready issue(s)`);
|
|
175
|
+
return;
|
|
176
|
+
default:
|
|
177
|
+
if (ready.length === 0) {
|
|
178
|
+
console.log("No ready issues.");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
for (const issue of ready) {
|
|
182
|
+
const { plan } = annotate(issue);
|
|
183
|
+
const suffix = planLineSuffix(plan);
|
|
184
|
+
if (suffix) {
|
|
185
|
+
process.stdout.write(`${formatIssueOneLine(issue, closedIds)}${suffix}\n`);
|
|
186
|
+
} else {
|
|
187
|
+
printIssueOneLine(issue, closedIds);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
console.log(`\n${ready.length} ready issue(s)`);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function register(program: Command): void {
|
|
196
|
+
program
|
|
197
|
+
.command("ready")
|
|
198
|
+
.description("Show open issues with no unresolved blockers")
|
|
199
|
+
.option("--type <type>", "Filter by type (task|bug|feature|epic)")
|
|
200
|
+
.option("--assignee <name>", "Filter by assignee")
|
|
201
|
+
.option("--label <labels>", "Filter: must have ALL labels (comma-separated, AND)")
|
|
202
|
+
.option("--label-any <labels>", "Filter: must have any label (comma-separated, OR)")
|
|
203
|
+
.option("--unlabeled", "Filter: issues with no labels")
|
|
204
|
+
.option("--priority <levels>", "Filter by priority (comma-separated, e.g. 0,1 or P0,P1)")
|
|
205
|
+
.option("--priority-max <n>", "Filter to priority <= n (e.g. --priority-max 1 = P0+P1)")
|
|
206
|
+
.option("--limit <n>", "Max issues to show", "50")
|
|
207
|
+
.option("--sort <mode>", "Sort order (priority|created|updated|id)", "priority")
|
|
208
|
+
.option("--format <mode>", `Output format (${VALID_FORMATS.join("|")})`)
|
|
209
|
+
.option("--json", "Output as JSON (alias for --format json)")
|
|
210
|
+
.option(
|
|
211
|
+
"--respect-schedule",
|
|
212
|
+
"Exclude issues with extensions.queued=true or future extensions.scheduledFor",
|
|
213
|
+
)
|
|
214
|
+
.action(
|
|
215
|
+
async (opts: {
|
|
216
|
+
type?: string;
|
|
217
|
+
assignee?: string;
|
|
218
|
+
label?: string;
|
|
219
|
+
labelAny?: string;
|
|
220
|
+
unlabeled?: boolean;
|
|
221
|
+
priority?: string;
|
|
222
|
+
priorityMax?: string;
|
|
223
|
+
limit?: string;
|
|
224
|
+
sort?: string;
|
|
225
|
+
format?: string;
|
|
226
|
+
json?: boolean;
|
|
227
|
+
respectSchedule?: boolean;
|
|
228
|
+
}) => {
|
|
229
|
+
const args: string[] = [];
|
|
230
|
+
if (opts.type) args.push("--type", opts.type);
|
|
231
|
+
if (opts.assignee) args.push("--assignee", opts.assignee);
|
|
232
|
+
if (opts.label) args.push("--label", opts.label);
|
|
233
|
+
if (opts.labelAny) args.push("--label-any", opts.labelAny);
|
|
234
|
+
if (opts.unlabeled) args.push("--unlabeled");
|
|
235
|
+
if (opts.priority) args.push("--priority", opts.priority);
|
|
236
|
+
if (opts.priorityMax) args.push("--priority-max", opts.priorityMax);
|
|
237
|
+
if (opts.limit) args.push("--limit", opts.limit);
|
|
238
|
+
if (opts.sort) args.push("--sort", opts.sort);
|
|
239
|
+
if (opts.format) args.push("--format", opts.format);
|
|
240
|
+
if (opts.json) args.push("--json");
|
|
241
|
+
if (opts.respectSchedule) args.push("--respect-schedule");
|
|
242
|
+
await run(args);
|
|
243
|
+
},
|
|
244
|
+
);
|
|
245
|
+
}
|