@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,272 @@
|
|
|
1
|
+
import { resolveBackend, trackerCliName } from "../tracker/factory.ts";
|
|
2
|
+
import type { DoctorCheck, DoctorCheckFn } from "./types.ts";
|
|
3
|
+
|
|
4
|
+
interface ToolSpec {
|
|
5
|
+
name: string;
|
|
6
|
+
versionFlag: string;
|
|
7
|
+
required: boolean;
|
|
8
|
+
/** Short alias to check if the primary tool is available. */
|
|
9
|
+
alias?: string;
|
|
10
|
+
/** npm package name for install hint (e.g. "@ag-eco/loam-cli"). */
|
|
11
|
+
installHint?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* External dependency checks.
|
|
16
|
+
* Validates that required CLI tools (git, bun, tmux, tracker, loam, agentplate)
|
|
17
|
+
* and optional tools (tl) are available, including short alias availability.
|
|
18
|
+
*/
|
|
19
|
+
export const checkDependencies: DoctorCheckFn = async (
|
|
20
|
+
config,
|
|
21
|
+
_agentplateDir,
|
|
22
|
+
): Promise<DoctorCheck[]> => {
|
|
23
|
+
// Determine which tracker CLI to check based on config backend (resolve "auto")
|
|
24
|
+
const resolvedBackend = await resolveBackend(config.taskTracker.backend, config.project.root);
|
|
25
|
+
const trackerName = trackerCliName(resolvedBackend);
|
|
26
|
+
|
|
27
|
+
const tools: ToolSpec[] = [
|
|
28
|
+
{ name: "git", versionFlag: "--version", required: true },
|
|
29
|
+
{ name: "bun", versionFlag: "--version", required: true },
|
|
30
|
+
{ name: "tmux", versionFlag: "-V", required: true },
|
|
31
|
+
{
|
|
32
|
+
name: trackerName,
|
|
33
|
+
versionFlag: "--version",
|
|
34
|
+
required: true,
|
|
35
|
+
installHint: trackerName === "sr" ? "@ag-eco/agentplate-cli" : undefined,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "loam",
|
|
39
|
+
versionFlag: "--version",
|
|
40
|
+
required: true,
|
|
41
|
+
alias: "lm",
|
|
42
|
+
installHint: "@ag-eco/agentplate-cli",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "ap",
|
|
46
|
+
versionFlag: "--version",
|
|
47
|
+
required: true,
|
|
48
|
+
alias: "agentplate",
|
|
49
|
+
installHint: "@ag-eco/agentplate-cli",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "tl",
|
|
53
|
+
versionFlag: "--version",
|
|
54
|
+
required: false,
|
|
55
|
+
installHint: "@ag-eco/agentplate-cli",
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const checks: DoctorCheck[] = [];
|
|
60
|
+
|
|
61
|
+
for (const tool of tools) {
|
|
62
|
+
const check = await checkTool(tool.name, tool.versionFlag, tool.required, tool.installHint);
|
|
63
|
+
checks.push(check);
|
|
64
|
+
|
|
65
|
+
// Check short alias availability if the main tool is available
|
|
66
|
+
if (tool.alias && check.status === "pass") {
|
|
67
|
+
const aliasCheck = await checkAlias(tool.name, tool.alias, tool.installHint);
|
|
68
|
+
checks.push(aliasCheck);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// If bd is available, probe for CGO/Dolt backend functionality.
|
|
73
|
+
// Only run for beads backend (CGO check is beads-specific).
|
|
74
|
+
if (trackerName === "bd") {
|
|
75
|
+
const bdCheck = checks.find((c) => c.name === "bd availability");
|
|
76
|
+
if (bdCheck?.status === "pass") {
|
|
77
|
+
const cgoCheck = await checkBdCgoSupport();
|
|
78
|
+
checks.push(cgoCheck);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return checks;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Probe whether bd's Dolt database backend is functional.
|
|
87
|
+
* The npm-distributed bd binary may be built without CGO, which causes
|
|
88
|
+
* `bd init` and all database operations to fail even though `bd --version` succeeds.
|
|
89
|
+
* We detect this by running `bd status` in a temp directory and checking for
|
|
90
|
+
* the characteristic "without CGO support" error message.
|
|
91
|
+
*/
|
|
92
|
+
async function checkBdCgoSupport(): Promise<DoctorCheck> {
|
|
93
|
+
const { mkdtemp, rm } = await import("node:fs/promises");
|
|
94
|
+
const { join } = await import("node:path");
|
|
95
|
+
const { tmpdir } = await import("node:os");
|
|
96
|
+
|
|
97
|
+
let tempDir: string | undefined;
|
|
98
|
+
try {
|
|
99
|
+
tempDir = await mkdtemp(join(tmpdir(), "agentplate-bd-cgo-"));
|
|
100
|
+
const proc = Bun.spawn(["bd", "status"], {
|
|
101
|
+
cwd: tempDir,
|
|
102
|
+
stdout: "pipe",
|
|
103
|
+
stderr: "pipe",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const exitCode = await proc.exited;
|
|
107
|
+
const stderr = await new Response(proc.stderr).text();
|
|
108
|
+
|
|
109
|
+
if (stderr.includes("without CGO support")) {
|
|
110
|
+
return {
|
|
111
|
+
name: "bd CGO support",
|
|
112
|
+
category: "dependencies",
|
|
113
|
+
status: "fail",
|
|
114
|
+
message: "bd binary was built without CGO — Dolt database operations will fail",
|
|
115
|
+
details: [
|
|
116
|
+
"The installed bd binary lacks CGO support required by its Dolt backend.",
|
|
117
|
+
"Workaround: rebuild bd from source with CGO_ENABLED=1 and ICU headers.",
|
|
118
|
+
"See: https://github.com/hgoudat/agentplate/issues/10",
|
|
119
|
+
],
|
|
120
|
+
fixable: true,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Any other exit code is fine — bd status may fail for other reasons
|
|
125
|
+
// (no .beads/ dir, etc.) but those aren't CGO issues
|
|
126
|
+
if (exitCode === 0 || !stderr.includes("CGO")) {
|
|
127
|
+
return {
|
|
128
|
+
name: "bd CGO support",
|
|
129
|
+
category: "dependencies",
|
|
130
|
+
status: "pass",
|
|
131
|
+
message: "bd has functional database backend",
|
|
132
|
+
details: ["Dolt backend operational"],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
name: "bd CGO support",
|
|
138
|
+
category: "dependencies",
|
|
139
|
+
status: "warn",
|
|
140
|
+
message: `bd status returned unexpected error (exit code ${exitCode})`,
|
|
141
|
+
details: [stderr.trim().split("\n")[0] || "unknown error"],
|
|
142
|
+
};
|
|
143
|
+
} catch (error) {
|
|
144
|
+
return {
|
|
145
|
+
name: "bd CGO support",
|
|
146
|
+
category: "dependencies",
|
|
147
|
+
status: "warn",
|
|
148
|
+
message: "Could not verify bd CGO support",
|
|
149
|
+
details: [error instanceof Error ? error.message : String(error)],
|
|
150
|
+
};
|
|
151
|
+
} finally {
|
|
152
|
+
if (tempDir) {
|
|
153
|
+
await rm(tempDir, { recursive: true }).catch(() => {});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check if a short alias for a CLI tool is available.
|
|
160
|
+
* @internal Exported for testing.
|
|
161
|
+
*/
|
|
162
|
+
export async function checkAlias(
|
|
163
|
+
toolName: string,
|
|
164
|
+
alias: string,
|
|
165
|
+
installHint?: string,
|
|
166
|
+
): Promise<DoctorCheck> {
|
|
167
|
+
try {
|
|
168
|
+
const proc = Bun.spawn([alias, "--version"], {
|
|
169
|
+
stdout: "pipe",
|
|
170
|
+
stderr: "pipe",
|
|
171
|
+
});
|
|
172
|
+
const exitCode = await proc.exited;
|
|
173
|
+
|
|
174
|
+
if (exitCode === 0) {
|
|
175
|
+
return {
|
|
176
|
+
name: `${alias} alias`,
|
|
177
|
+
category: "dependencies",
|
|
178
|
+
status: "pass",
|
|
179
|
+
message: `${alias} alias for ${toolName} is available`,
|
|
180
|
+
details: [`Short alias '${alias}' is configured`],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const hint = installHint
|
|
185
|
+
? `Reinstall ${installHint} to get the '${alias}' alias.`
|
|
186
|
+
: `Ensure '${alias}' alias is in your PATH.`;
|
|
187
|
+
return {
|
|
188
|
+
name: `${alias} alias`,
|
|
189
|
+
category: "dependencies",
|
|
190
|
+
status: "warn",
|
|
191
|
+
message: `${alias} alias for ${toolName} not working`,
|
|
192
|
+
details: [hint],
|
|
193
|
+
fixable: true,
|
|
194
|
+
};
|
|
195
|
+
} catch {
|
|
196
|
+
const hint = installHint
|
|
197
|
+
? `Reinstall ${installHint} to get the '${alias}' alias.`
|
|
198
|
+
: `Ensure '${alias}' alias is in your PATH.`;
|
|
199
|
+
return {
|
|
200
|
+
name: `${alias} alias`,
|
|
201
|
+
category: "dependencies",
|
|
202
|
+
status: "warn",
|
|
203
|
+
message: `${alias} alias for ${toolName} is not available`,
|
|
204
|
+
details: [`'${toolName}' works but short alias '${alias}' was not found.`, hint],
|
|
205
|
+
fixable: true,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Check if a CLI tool is available by attempting to run it with a version flag.
|
|
212
|
+
* @internal Exported for testing.
|
|
213
|
+
*/
|
|
214
|
+
export async function checkTool(
|
|
215
|
+
name: string,
|
|
216
|
+
versionFlag: string,
|
|
217
|
+
required: boolean,
|
|
218
|
+
installHint?: string,
|
|
219
|
+
): Promise<DoctorCheck> {
|
|
220
|
+
try {
|
|
221
|
+
const proc = Bun.spawn([name, versionFlag], {
|
|
222
|
+
stdout: "pipe",
|
|
223
|
+
stderr: "pipe",
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const exitCode = await proc.exited;
|
|
227
|
+
|
|
228
|
+
if (exitCode === 0) {
|
|
229
|
+
const stdout = await new Response(proc.stdout).text();
|
|
230
|
+
const version = stdout.split("\n")[0]?.trim() || "version unknown";
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
name: `${name} availability`,
|
|
234
|
+
category: "dependencies",
|
|
235
|
+
status: "pass",
|
|
236
|
+
message: `${name} is available`,
|
|
237
|
+
details: [version],
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Non-zero exit code
|
|
242
|
+
const stderr = await new Response(proc.stderr).text();
|
|
243
|
+
const details: string[] = [];
|
|
244
|
+
if (stderr) details.push(stderr.trim());
|
|
245
|
+
if (installHint) details.push(`Install: npm install -g ${installHint}`);
|
|
246
|
+
return {
|
|
247
|
+
name: `${name} availability`,
|
|
248
|
+
category: "dependencies",
|
|
249
|
+
status: required ? "fail" : "warn",
|
|
250
|
+
message: `${name} command failed (exit code ${exitCode})`,
|
|
251
|
+
details: details.length > 0 ? details : undefined,
|
|
252
|
+
fixable: true,
|
|
253
|
+
};
|
|
254
|
+
} catch (error) {
|
|
255
|
+
// Command not found or spawn failed
|
|
256
|
+
const details: string[] = [];
|
|
257
|
+
if (installHint) {
|
|
258
|
+
details.push(`Install: npm install -g ${installHint}`);
|
|
259
|
+
} else {
|
|
260
|
+
details.push(`Install ${name} or ensure it is in your PATH`);
|
|
261
|
+
}
|
|
262
|
+
details.push(error instanceof Error ? error.message : String(error));
|
|
263
|
+
return {
|
|
264
|
+
name: `${name} availability`,
|
|
265
|
+
category: "dependencies",
|
|
266
|
+
status: required ? "fail" : "warn",
|
|
267
|
+
message: `${name} is not installed or not in PATH`,
|
|
268
|
+
details,
|
|
269
|
+
fixable: true,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the ecosystem doctor check module.
|
|
3
|
+
*
|
|
4
|
+
* We inject a mock spawner instead of using mock.module() to avoid cross-test
|
|
5
|
+
* leakage (see loam record mx-56558b on why mock.module() is avoided).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, expect, test } from "bun:test";
|
|
9
|
+
import type { AgentplateConfig } from "../types.ts";
|
|
10
|
+
import { makeCheckEcosystem, parseSemver } from "./ecosystem.ts";
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Minimal config fixture
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
const mockConfig: AgentplateConfig = {
|
|
17
|
+
project: {
|
|
18
|
+
name: "test-project",
|
|
19
|
+
root: "/tmp/test",
|
|
20
|
+
canonicalBranch: "main",
|
|
21
|
+
},
|
|
22
|
+
agents: {
|
|
23
|
+
manifestPath: "/tmp/.agentplate/agent-manifest.json",
|
|
24
|
+
baseDir: "/tmp/.agentplate/agents",
|
|
25
|
+
maxConcurrent: 5,
|
|
26
|
+
staggerDelayMs: 1000,
|
|
27
|
+
maxDepth: 2,
|
|
28
|
+
maxSessionsPerRun: 0,
|
|
29
|
+
maxAgentsPerLead: 5,
|
|
30
|
+
},
|
|
31
|
+
worktrees: {
|
|
32
|
+
baseDir: "/tmp/.agentplate/worktrees",
|
|
33
|
+
},
|
|
34
|
+
taskTracker: {
|
|
35
|
+
backend: "auto",
|
|
36
|
+
enabled: false,
|
|
37
|
+
},
|
|
38
|
+
loam: {
|
|
39
|
+
enabled: false,
|
|
40
|
+
domains: [],
|
|
41
|
+
primeFormat: "markdown",
|
|
42
|
+
},
|
|
43
|
+
merge: {
|
|
44
|
+
aiResolveEnabled: false,
|
|
45
|
+
reimagineEnabled: false,
|
|
46
|
+
},
|
|
47
|
+
providers: {
|
|
48
|
+
anthropic: { type: "native" },
|
|
49
|
+
},
|
|
50
|
+
watchdog: {
|
|
51
|
+
tier0Enabled: false,
|
|
52
|
+
tier0IntervalMs: 30000,
|
|
53
|
+
tier1Enabled: false,
|
|
54
|
+
tier2Enabled: false,
|
|
55
|
+
staleThresholdMs: 300000,
|
|
56
|
+
zombieThresholdMs: 600000,
|
|
57
|
+
nudgeIntervalMs: 60000,
|
|
58
|
+
},
|
|
59
|
+
models: {},
|
|
60
|
+
logging: {
|
|
61
|
+
verbose: false,
|
|
62
|
+
redactSecrets: true,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Mock spawner helpers
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
type SpawnResponse = { exitCode: number; stdout: string; stderr: string };
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Build a mock spawner that dispatches by binary name (first arg).
|
|
74
|
+
*/
|
|
75
|
+
function makeMockSpawner(responses: Record<string, SpawnResponse>) {
|
|
76
|
+
return async (args: string[]): Promise<SpawnResponse> => {
|
|
77
|
+
const bin = args[0] ?? "";
|
|
78
|
+
return (
|
|
79
|
+
responses[bin] ?? {
|
|
80
|
+
exitCode: 127,
|
|
81
|
+
stdout: "",
|
|
82
|
+
stderr: `${bin}: command not found`,
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// parseSemver unit tests
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
describe("parseSemver", () => {
|
|
93
|
+
test("extracts bare semver", () => {
|
|
94
|
+
expect(parseSemver("1.2.3")).toBe("1.2.3");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("extracts semver from prefixed output", () => {
|
|
98
|
+
expect(parseSemver("loam v1.0.0")).toBe("1.0.0");
|
|
99
|
+
expect(parseSemver("sprout version 2.3.4")).toBe("2.3.4");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("extracts semver with prerelease", () => {
|
|
103
|
+
expect(parseSemver("1.2.3-alpha.1")).toBe("1.2.3-alpha.1");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("extracts semver with build metadata", () => {
|
|
107
|
+
expect(parseSemver("1.2.3+build.42")).toBe("1.2.3+build.42");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("returns null for non-semver strings", () => {
|
|
111
|
+
expect(parseSemver("not-a-version")).toBeNull();
|
|
112
|
+
expect(parseSemver("")).toBeNull();
|
|
113
|
+
expect(parseSemver("v2.0")).toBeNull();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("extracts first semver when multiple exist", () => {
|
|
117
|
+
expect(parseSemver("tool 1.0.0 requires node 18.0.0")).toBe("1.0.0");
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// checkEcosystem integration tests
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
describe("checkEcosystem", () => {
|
|
126
|
+
test("returns exactly 3 checks (one per tool)", async () => {
|
|
127
|
+
const spawner = makeMockSpawner({
|
|
128
|
+
lm: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
129
|
+
sr: { exitCode: 0, stdout: "2.0.0\n", stderr: "" },
|
|
130
|
+
tl: { exitCode: 0, stdout: "3.0.0\n", stderr: "" },
|
|
131
|
+
});
|
|
132
|
+
const check = makeCheckEcosystem(spawner);
|
|
133
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
134
|
+
|
|
135
|
+
expect(results).toHaveLength(3);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("check names match tool names", async () => {
|
|
139
|
+
const spawner = makeMockSpawner({
|
|
140
|
+
lm: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
141
|
+
sr: { exitCode: 0, stdout: "2.0.0\n", stderr: "" },
|
|
142
|
+
tl: { exitCode: 0, stdout: "3.0.0\n", stderr: "" },
|
|
143
|
+
});
|
|
144
|
+
const check = makeCheckEcosystem(spawner);
|
|
145
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
146
|
+
|
|
147
|
+
const names = results.map((r) => r.name);
|
|
148
|
+
expect(names).toContain("loam semver");
|
|
149
|
+
expect(names).toContain("sprout semver");
|
|
150
|
+
expect(names).toContain("trellis semver");
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test("all checks report category 'ecosystem'", async () => {
|
|
154
|
+
const spawner = makeMockSpawner({
|
|
155
|
+
lm: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
156
|
+
sr: { exitCode: 0, stdout: "2.0.0\n", stderr: "" },
|
|
157
|
+
tl: { exitCode: 0, stdout: "3.0.0\n", stderr: "" },
|
|
158
|
+
});
|
|
159
|
+
const check = makeCheckEcosystem(spawner);
|
|
160
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
161
|
+
|
|
162
|
+
for (const r of results) {
|
|
163
|
+
expect(r.category).toBe("ecosystem");
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("pass when all tools report valid semver", async () => {
|
|
168
|
+
const spawner = makeMockSpawner({
|
|
169
|
+
lm: { exitCode: 0, stdout: "loam v1.2.3\n", stderr: "" },
|
|
170
|
+
sr: { exitCode: 0, stdout: "sprout 0.5.0\n", stderr: "" },
|
|
171
|
+
tl: { exitCode: 0, stdout: "0.1.0\n", stderr: "" },
|
|
172
|
+
});
|
|
173
|
+
const check = makeCheckEcosystem(spawner);
|
|
174
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
175
|
+
|
|
176
|
+
for (const r of results) {
|
|
177
|
+
expect(r.status).toBe("pass");
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("warn when a tool is not available (non-zero exit code)", async () => {
|
|
182
|
+
const spawner = makeMockSpawner({
|
|
183
|
+
lm: { exitCode: 127, stdout: "", stderr: "lm: command not found" },
|
|
184
|
+
sr: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
185
|
+
tl: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
186
|
+
});
|
|
187
|
+
const check = makeCheckEcosystem(spawner);
|
|
188
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
189
|
+
|
|
190
|
+
const loam = results.find((r) => r.name === "loam semver");
|
|
191
|
+
expect(loam?.status).toBe("warn");
|
|
192
|
+
expect(loam?.fixable).toBe(true);
|
|
193
|
+
expect(typeof loam?.fix).toBe("function");
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("warn when version output is not valid semver", async () => {
|
|
197
|
+
const spawner = makeMockSpawner({
|
|
198
|
+
lm: { exitCode: 0, stdout: "loam dev-build\n", stderr: "" },
|
|
199
|
+
sr: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
200
|
+
tl: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
201
|
+
});
|
|
202
|
+
const check = makeCheckEcosystem(spawner);
|
|
203
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
204
|
+
|
|
205
|
+
const loam = results.find((r) => r.name === "loam semver");
|
|
206
|
+
expect(loam?.status).toBe("warn");
|
|
207
|
+
expect(loam?.message).toContain("not parseable semver");
|
|
208
|
+
expect(loam?.fixable).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("passing checks include version in message", async () => {
|
|
212
|
+
const spawner = makeMockSpawner({
|
|
213
|
+
lm: { exitCode: 0, stdout: "1.2.3\n", stderr: "" },
|
|
214
|
+
sr: { exitCode: 0, stdout: "1.2.3\n", stderr: "" },
|
|
215
|
+
tl: { exitCode: 0, stdout: "1.2.3\n", stderr: "" },
|
|
216
|
+
});
|
|
217
|
+
const check = makeCheckEcosystem(spawner);
|
|
218
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
219
|
+
|
|
220
|
+
for (const r of results) {
|
|
221
|
+
expect(r.status).toBe("pass");
|
|
222
|
+
expect(r.message).toContain("1.2.3");
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test("passing checks include raw output in details", async () => {
|
|
227
|
+
const spawner = makeMockSpawner({
|
|
228
|
+
lm: { exitCode: 0, stdout: "loam v1.0.0\n", stderr: "" },
|
|
229
|
+
sr: { exitCode: 0, stdout: "sprout 1.0.0\n", stderr: "" },
|
|
230
|
+
tl: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
231
|
+
});
|
|
232
|
+
const check = makeCheckEcosystem(spawner);
|
|
233
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
234
|
+
|
|
235
|
+
const loam = results.find((r) => r.name === "loam semver");
|
|
236
|
+
expect(loam?.details).toContain("loam v1.0.0");
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
test("unavailable tool details include install hint", async () => {
|
|
240
|
+
const spawner = makeMockSpawner({
|
|
241
|
+
lm: { exitCode: 127, stdout: "", stderr: "not found" },
|
|
242
|
+
sr: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
243
|
+
tl: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
244
|
+
});
|
|
245
|
+
const check = makeCheckEcosystem(spawner);
|
|
246
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
247
|
+
|
|
248
|
+
const loam = results.find((r) => r.name === "loam semver");
|
|
249
|
+
const hasHint = loam?.details?.some((d) => d.includes("@ag-eco/loam-cli"));
|
|
250
|
+
expect(hasHint).toBe(true);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("all checks have required DoctorCheck fields", async () => {
|
|
254
|
+
const spawner = makeMockSpawner({
|
|
255
|
+
lm: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
256
|
+
sr: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
257
|
+
tl: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
258
|
+
});
|
|
259
|
+
const check = makeCheckEcosystem(spawner);
|
|
260
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
261
|
+
|
|
262
|
+
for (const r of results) {
|
|
263
|
+
expect(typeof r.name).toBe("string");
|
|
264
|
+
expect(r.name.length).toBeGreaterThan(0);
|
|
265
|
+
expect(r.category).toBe("ecosystem");
|
|
266
|
+
expect(["pass", "warn", "fail"]).toContain(r.status);
|
|
267
|
+
expect(typeof r.message).toBe("string");
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test("failing checks are marked fixable and have a fix closure", async () => {
|
|
272
|
+
const spawner = makeMockSpawner({}); // all tools unavailable
|
|
273
|
+
const check = makeCheckEcosystem(spawner);
|
|
274
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
275
|
+
|
|
276
|
+
for (const r of results) {
|
|
277
|
+
expect(r.status).toBe("warn");
|
|
278
|
+
expect(r.fixable).toBe(true);
|
|
279
|
+
expect(typeof r.fix).toBe("function");
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test("handles version in stderr when stdout is empty", async () => {
|
|
284
|
+
const spawner = makeMockSpawner({
|
|
285
|
+
lm: { exitCode: 0, stdout: "", stderr: "1.0.0" },
|
|
286
|
+
sr: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
287
|
+
tl: { exitCode: 0, stdout: "1.0.0\n", stderr: "" },
|
|
288
|
+
});
|
|
289
|
+
const check = makeCheckEcosystem(spawner);
|
|
290
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
291
|
+
|
|
292
|
+
const loam = results.find((r) => r.name === "loam semver");
|
|
293
|
+
expect(loam?.status).toBe("pass");
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
test("handles spawn exception gracefully", async () => {
|
|
297
|
+
const errorSpawner = async (_args: string[]) => {
|
|
298
|
+
throw new Error("spawn failed");
|
|
299
|
+
};
|
|
300
|
+
const check = makeCheckEcosystem(errorSpawner);
|
|
301
|
+
const results = await check(mockConfig, "/tmp/.agentplate");
|
|
302
|
+
|
|
303
|
+
expect(results).toHaveLength(3);
|
|
304
|
+
for (const r of results) {
|
|
305
|
+
expect(r.status).toBe("warn");
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|