@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,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the session compat shim (JSON -> SQLite migration).
|
|
3
|
+
*
|
|
4
|
+
* Uses real filesystem and bun:sqlite. No mocks.
|
|
5
|
+
* Tests file-based migration behavior, so temp files are required (not :memory:).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
9
|
+
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { cleanupTempDir } from "../test-helpers.ts";
|
|
13
|
+
import { openSessionStore } from "./compat.ts";
|
|
14
|
+
|
|
15
|
+
let tempDir: string;
|
|
16
|
+
let agentplateDir: string;
|
|
17
|
+
|
|
18
|
+
beforeEach(async () => {
|
|
19
|
+
tempDir = await mkdtemp(join(tmpdir(), "agentplate-compat-test-"));
|
|
20
|
+
agentplateDir = join(tempDir, ".agentplate");
|
|
21
|
+
const { mkdir } = await import("node:fs/promises");
|
|
22
|
+
await mkdir(agentplateDir, { recursive: true });
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(async () => {
|
|
26
|
+
await cleanupTempDir(tempDir);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
/** Create a sessions.json with the given entries. */
|
|
30
|
+
async function writeSessionsJson(sessions: Record<string, unknown>[]): Promise<void> {
|
|
31
|
+
const jsonPath = join(agentplateDir, "sessions.json");
|
|
32
|
+
await writeFile(jsonPath, `${JSON.stringify(sessions, null, "\t")}\n`, "utf-8");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A valid session object as it would appear in sessions.json. */
|
|
36
|
+
function makeJsonSession(overrides: Record<string, unknown> = {}): Record<string, unknown> {
|
|
37
|
+
return {
|
|
38
|
+
id: "session-001-test-agent",
|
|
39
|
+
agentName: "test-agent",
|
|
40
|
+
capability: "builder",
|
|
41
|
+
worktreePath: "/tmp/worktrees/test-agent",
|
|
42
|
+
branchName: "agentplate/test-agent/task-1",
|
|
43
|
+
taskId: "task-1",
|
|
44
|
+
tmuxSession: "agentplate-test-agent",
|
|
45
|
+
state: "working",
|
|
46
|
+
pid: 12345,
|
|
47
|
+
parentAgent: null,
|
|
48
|
+
depth: 0,
|
|
49
|
+
startedAt: "2026-01-15T10:00:00.000Z",
|
|
50
|
+
lastActivity: "2026-01-15T10:05:00.000Z",
|
|
51
|
+
escalationLevel: 0,
|
|
52
|
+
stalledSince: null,
|
|
53
|
+
...overrides,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// === Migration from sessions.json ===
|
|
58
|
+
|
|
59
|
+
describe("openSessionStore", () => {
|
|
60
|
+
test("creates empty DB when neither sessions.json nor sessions.db exist", () => {
|
|
61
|
+
const { store, migrated } = openSessionStore(agentplateDir);
|
|
62
|
+
|
|
63
|
+
expect(migrated).toBe(false);
|
|
64
|
+
expect(store.getAll()).toEqual([]);
|
|
65
|
+
store.close();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("imports sessions from sessions.json when sessions.db does not exist", async () => {
|
|
69
|
+
await writeSessionsJson([
|
|
70
|
+
makeJsonSession({ agentName: "agent-a", id: "s-a" }),
|
|
71
|
+
makeJsonSession({ agentName: "agent-b", id: "s-b", state: "completed" }),
|
|
72
|
+
]);
|
|
73
|
+
|
|
74
|
+
const { store, migrated } = openSessionStore(agentplateDir);
|
|
75
|
+
|
|
76
|
+
expect(migrated).toBe(true);
|
|
77
|
+
const all = store.getAll();
|
|
78
|
+
expect(all).toHaveLength(2);
|
|
79
|
+
|
|
80
|
+
const agentA = store.getByName("agent-a");
|
|
81
|
+
expect(agentA).not.toBeNull();
|
|
82
|
+
expect(agentA?.id).toBe("s-a");
|
|
83
|
+
expect(agentA?.state).toBe("working");
|
|
84
|
+
|
|
85
|
+
const agentB = store.getByName("agent-b");
|
|
86
|
+
expect(agentB).not.toBeNull();
|
|
87
|
+
expect(agentB?.state).toBe("completed");
|
|
88
|
+
|
|
89
|
+
store.close();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("migration adds runId=null when sessions.json entries lack runId", async () => {
|
|
93
|
+
// Write a session WITHOUT runId (old format)
|
|
94
|
+
const oldFormatSession = makeJsonSession();
|
|
95
|
+
(oldFormatSession as Record<string, unknown>).runId = undefined;
|
|
96
|
+
|
|
97
|
+
await writeSessionsJson([oldFormatSession]);
|
|
98
|
+
|
|
99
|
+
const { store, migrated } = openSessionStore(agentplateDir);
|
|
100
|
+
|
|
101
|
+
expect(migrated).toBe(true);
|
|
102
|
+
const session = store.getByName("test-agent");
|
|
103
|
+
expect(session).not.toBeNull();
|
|
104
|
+
expect(session?.runId).toBeNull();
|
|
105
|
+
|
|
106
|
+
store.close();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("does not re-migrate when sessions.db already exists", async () => {
|
|
110
|
+
// First call: create the DB with migration
|
|
111
|
+
await writeSessionsJson([makeJsonSession({ agentName: "original", id: "s-1" })]);
|
|
112
|
+
|
|
113
|
+
const { store: store1, migrated: migrated1 } = openSessionStore(agentplateDir);
|
|
114
|
+
expect(migrated1).toBe(true);
|
|
115
|
+
store1.close();
|
|
116
|
+
|
|
117
|
+
// Modify sessions.json to add a new entry
|
|
118
|
+
await writeSessionsJson([
|
|
119
|
+
makeJsonSession({ agentName: "original", id: "s-1" }),
|
|
120
|
+
makeJsonSession({ agentName: "new-agent", id: "s-2" }),
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
// Second call: DB exists, so no migration
|
|
124
|
+
const { store: store2, migrated: migrated2 } = openSessionStore(agentplateDir);
|
|
125
|
+
expect(migrated2).toBe(false);
|
|
126
|
+
|
|
127
|
+
// Should still have only the original session from the first migration
|
|
128
|
+
const all = store2.getAll();
|
|
129
|
+
expect(all).toHaveLength(1);
|
|
130
|
+
expect(all[0]?.agentName).toBe("original");
|
|
131
|
+
|
|
132
|
+
store2.close();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("imports from sessions.json when sessions.db exists but is empty", async () => {
|
|
136
|
+
// Simulate the scenario where sessions.db was created (e.g., by init) but
|
|
137
|
+
// no sessions were ever written to it, while sessions.json has records from
|
|
138
|
+
// a previous coordinator start that used the old code path (agentplate-036f).
|
|
139
|
+
const { store: emptyStore } = openSessionStore(agentplateDir);
|
|
140
|
+
expect(emptyStore.getAll()).toHaveLength(0);
|
|
141
|
+
emptyStore.close();
|
|
142
|
+
|
|
143
|
+
// Now write records to sessions.json (simulating old code path)
|
|
144
|
+
await writeSessionsJson([
|
|
145
|
+
makeJsonSession({ agentName: "orphaned-coordinator", id: "s-orphan", state: "booting" }),
|
|
146
|
+
]);
|
|
147
|
+
|
|
148
|
+
// Re-open: DB exists but is empty, so JSON records should be imported
|
|
149
|
+
const { store: store2, migrated } = openSessionStore(agentplateDir);
|
|
150
|
+
expect(migrated).toBe(true);
|
|
151
|
+
|
|
152
|
+
const all = store2.getAll();
|
|
153
|
+
expect(all).toHaveLength(1);
|
|
154
|
+
expect(all[0]?.agentName).toBe("orphaned-coordinator");
|
|
155
|
+
expect(all[0]?.state).toBe("booting");
|
|
156
|
+
store2.close();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("handles empty sessions.json (no migration needed)", async () => {
|
|
160
|
+
await writeSessionsJson([]);
|
|
161
|
+
|
|
162
|
+
const { store, migrated } = openSessionStore(agentplateDir);
|
|
163
|
+
|
|
164
|
+
expect(migrated).toBe(false);
|
|
165
|
+
expect(store.getAll()).toEqual([]);
|
|
166
|
+
store.close();
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("handles malformed sessions.json gracefully", async () => {
|
|
170
|
+
const jsonPath = join(agentplateDir, "sessions.json");
|
|
171
|
+
await writeFile(jsonPath, "this is not json", "utf-8");
|
|
172
|
+
|
|
173
|
+
const { store, migrated } = openSessionStore(agentplateDir);
|
|
174
|
+
|
|
175
|
+
expect(migrated).toBe(false);
|
|
176
|
+
expect(store.getAll()).toEqual([]);
|
|
177
|
+
store.close();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("handles sessions.json with non-array content gracefully", async () => {
|
|
181
|
+
const jsonPath = join(agentplateDir, "sessions.json");
|
|
182
|
+
await writeFile(jsonPath, '{"not": "an array"}', "utf-8");
|
|
183
|
+
|
|
184
|
+
const { store, migrated } = openSessionStore(agentplateDir);
|
|
185
|
+
|
|
186
|
+
expect(migrated).toBe(false);
|
|
187
|
+
expect(store.getAll()).toEqual([]);
|
|
188
|
+
store.close();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// === Data integrity after migration ===
|
|
193
|
+
|
|
194
|
+
describe("data integrity", () => {
|
|
195
|
+
test("all fields from sessions.json are preserved in SQLite", async () => {
|
|
196
|
+
const fullSession = makeJsonSession({
|
|
197
|
+
id: "session-full",
|
|
198
|
+
agentName: "full-agent",
|
|
199
|
+
capability: "scout",
|
|
200
|
+
worktreePath: "/tmp/worktrees/full-agent",
|
|
201
|
+
branchName: "agentplate/full-agent/task-42",
|
|
202
|
+
taskId: "task-42",
|
|
203
|
+
tmuxSession: "agentplate-full-agent",
|
|
204
|
+
state: "stalled",
|
|
205
|
+
pid: 99999,
|
|
206
|
+
parentAgent: "lead-agent",
|
|
207
|
+
depth: 2,
|
|
208
|
+
startedAt: "2026-02-01T08:00:00.000Z",
|
|
209
|
+
lastActivity: "2026-02-01T09:00:00.000Z",
|
|
210
|
+
escalationLevel: 3,
|
|
211
|
+
stalledSince: "2026-02-01T08:50:00.000Z",
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
await writeSessionsJson([fullSession]);
|
|
215
|
+
|
|
216
|
+
const { store } = openSessionStore(agentplateDir);
|
|
217
|
+
const result = store.getByName("full-agent");
|
|
218
|
+
|
|
219
|
+
expect(result).not.toBeNull();
|
|
220
|
+
expect(result?.id).toBe("session-full");
|
|
221
|
+
expect(result?.agentName).toBe("full-agent");
|
|
222
|
+
expect(result?.capability).toBe("scout");
|
|
223
|
+
expect(result?.worktreePath).toBe("/tmp/worktrees/full-agent");
|
|
224
|
+
expect(result?.branchName).toBe("agentplate/full-agent/task-42");
|
|
225
|
+
expect(result?.taskId).toBe("task-42");
|
|
226
|
+
expect(result?.tmuxSession).toBe("agentplate-full-agent");
|
|
227
|
+
expect(result?.state).toBe("stalled");
|
|
228
|
+
expect(result?.pid).toBe(99999);
|
|
229
|
+
expect(result?.parentAgent).toBe("lead-agent");
|
|
230
|
+
expect(result?.depth).toBe(2);
|
|
231
|
+
expect(result?.runId).toBeNull(); // Not in old JSON format
|
|
232
|
+
expect(result?.startedAt).toBe("2026-02-01T08:00:00.000Z");
|
|
233
|
+
expect(result?.lastActivity).toBe("2026-02-01T09:00:00.000Z");
|
|
234
|
+
expect(result?.escalationLevel).toBe(3);
|
|
235
|
+
expect(result?.stalledSince).toBe("2026-02-01T08:50:00.000Z");
|
|
236
|
+
|
|
237
|
+
store.close();
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("migrated store supports all SessionStore operations", async () => {
|
|
241
|
+
await writeSessionsJson([
|
|
242
|
+
makeJsonSession({ agentName: "agent-a", id: "s-a", state: "working" }),
|
|
243
|
+
makeJsonSession({ agentName: "agent-b", id: "s-b", state: "completed" }),
|
|
244
|
+
]);
|
|
245
|
+
|
|
246
|
+
const { store } = openSessionStore(agentplateDir);
|
|
247
|
+
|
|
248
|
+
// getActive should return only "working" sessions
|
|
249
|
+
const active = store.getActive();
|
|
250
|
+
expect(active).toHaveLength(1);
|
|
251
|
+
expect(active[0]?.agentName).toBe("agent-a");
|
|
252
|
+
|
|
253
|
+
// updateState should work on migrated data
|
|
254
|
+
store.updateState("agent-a", "completed");
|
|
255
|
+
expect(store.getByName("agent-a")?.state).toBe("completed");
|
|
256
|
+
|
|
257
|
+
// remove should work on migrated data
|
|
258
|
+
store.remove("agent-b");
|
|
259
|
+
expect(store.getByName("agent-b")).toBeNull();
|
|
260
|
+
|
|
261
|
+
store.close();
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test("multiple sessions with same agent name in JSON: last one wins", async () => {
|
|
265
|
+
// This edge case shouldn't happen in practice, but test defensive behavior
|
|
266
|
+
await writeSessionsJson([
|
|
267
|
+
makeJsonSession({ agentName: "dupe", id: "s-1", state: "booting" }),
|
|
268
|
+
makeJsonSession({ agentName: "dupe", id: "s-2", state: "working" }),
|
|
269
|
+
]);
|
|
270
|
+
|
|
271
|
+
const { store } = openSessionStore(agentplateDir);
|
|
272
|
+
|
|
273
|
+
const all = store.getAll();
|
|
274
|
+
expect(all).toHaveLength(1);
|
|
275
|
+
// Last upsert wins (s-2)
|
|
276
|
+
expect(all[0]?.id).toBe("s-2");
|
|
277
|
+
expect(all[0]?.state).toBe("working");
|
|
278
|
+
|
|
279
|
+
store.close();
|
|
280
|
+
});
|
|
281
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backward-compatible session reader.
|
|
3
|
+
*
|
|
4
|
+
* On first call, if sessions.json exists and sessions.db does not,
|
|
5
|
+
* imports all entries from JSON into SQLite. After migration,
|
|
6
|
+
* SQLite is the authoritative source.
|
|
7
|
+
*
|
|
8
|
+
* This module does NOT modify consumers -- it provides a migration
|
|
9
|
+
* bridge that can be called by consumers when they are ready to switch.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import type { AgentSession } from "../types.ts";
|
|
15
|
+
import { createSessionStore, type SessionStore } from "./store.ts";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Normalize a session object that may have been parsed from JSON
|
|
19
|
+
* and is missing the `runId` field (added after sessions.json was designed).
|
|
20
|
+
*/
|
|
21
|
+
function normalizeSession(raw: Record<string, unknown>): AgentSession {
|
|
22
|
+
return {
|
|
23
|
+
id: raw.id as string,
|
|
24
|
+
agentName: raw.agentName as string,
|
|
25
|
+
capability: raw.capability as string,
|
|
26
|
+
worktreePath: raw.worktreePath as string,
|
|
27
|
+
branchName: raw.branchName as string,
|
|
28
|
+
taskId: raw.taskId as string,
|
|
29
|
+
tmuxSession: raw.tmuxSession as string,
|
|
30
|
+
state: raw.state as AgentSession["state"],
|
|
31
|
+
pid: (raw.pid as number | null) ?? null,
|
|
32
|
+
parentAgent: (raw.parentAgent as string | null) ?? null,
|
|
33
|
+
depth: (raw.depth as number) ?? 0,
|
|
34
|
+
runId: (raw.runId as string | null) ?? null,
|
|
35
|
+
startedAt: raw.startedAt as string,
|
|
36
|
+
lastActivity: raw.lastActivity as string,
|
|
37
|
+
escalationLevel: (raw.escalationLevel as number) ?? 0,
|
|
38
|
+
stalledSince: (raw.stalledSince as string | null) ?? null,
|
|
39
|
+
transcriptPath: (raw.transcriptPath as string | null) ?? null,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Load sessions from a sessions.json file.
|
|
45
|
+
* Returns an empty array if the file does not exist or is malformed.
|
|
46
|
+
*/
|
|
47
|
+
function loadJsonSessions(jsonPath: string): AgentSession[] {
|
|
48
|
+
if (!existsSync(jsonPath)) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const text = readFileSync(jsonPath, "utf-8");
|
|
53
|
+
const parsed: unknown = JSON.parse(text);
|
|
54
|
+
if (!Array.isArray(parsed)) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
return parsed.map((entry) => normalizeSession(entry as Record<string, unknown>));
|
|
58
|
+
} catch {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Open or create a SessionStore at the given .agentplate directory root.
|
|
65
|
+
*
|
|
66
|
+
* Migration logic:
|
|
67
|
+
* 1. If sessions.db exists AND has rows, open it directly (SQLite is authoritative).
|
|
68
|
+
* 2. If sessions.db exists but is empty, check sessions.json for importable records.
|
|
69
|
+
* 3. If sessions.db does NOT exist but sessions.json does, create sessions.db
|
|
70
|
+
* and import all entries from sessions.json.
|
|
71
|
+
* 4. If neither exists, create an empty sessions.db.
|
|
72
|
+
*
|
|
73
|
+
* @param agentplateDir - Path to the .agentplate directory (e.g., /project/.agentplate)
|
|
74
|
+
* @returns An object with the SessionStore and whether a migration occurred.
|
|
75
|
+
*/
|
|
76
|
+
export function openSessionStore(agentplateDir: string): {
|
|
77
|
+
store: SessionStore;
|
|
78
|
+
migrated: boolean;
|
|
79
|
+
} {
|
|
80
|
+
const dbPath = join(agentplateDir, "sessions.db");
|
|
81
|
+
const jsonPath = join(agentplateDir, "sessions.json");
|
|
82
|
+
|
|
83
|
+
const dbExists = existsSync(dbPath);
|
|
84
|
+
|
|
85
|
+
const store = createSessionStore(dbPath);
|
|
86
|
+
|
|
87
|
+
// If the DB already existed AND has data, it is authoritative -- no migration needed.
|
|
88
|
+
// If the DB file exists but is empty (e.g., created by init before any sessions were
|
|
89
|
+
// recorded), fall through to check sessions.json for importable records (agentplate-036f).
|
|
90
|
+
if (dbExists && store.count() > 0) {
|
|
91
|
+
return { store, migrated: false };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// DB was just created. If sessions.json exists, import its entries.
|
|
95
|
+
const jsonSessions = loadJsonSessions(jsonPath);
|
|
96
|
+
if (jsonSessions.length === 0) {
|
|
97
|
+
return { store, migrated: false };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for (const session of jsonSessions) {
|
|
101
|
+
store.upsert(session);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { store, migrated: true };
|
|
105
|
+
}
|