@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,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command: ap logs [--agent <name>] [--level <level>] [--since <time>] [--until <time>] [--limit <n>] [--follow] [--json]
|
|
3
|
+
*
|
|
4
|
+
* Queries NDJSON log files from .agentplate/logs/{agent-name}/{session-timestamp}/events.ndjson
|
|
5
|
+
* and presents a unified timeline view.
|
|
6
|
+
*
|
|
7
|
+
* Unlike trace/errors/replay which query events.db (SQLite), this command reads raw NDJSON files
|
|
8
|
+
* on disk — the source of truth written by each agent logger.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readdir, stat } from "node:fs/promises";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { Command } from "commander";
|
|
14
|
+
import { loadConfig } from "../config.ts";
|
|
15
|
+
import { ValidationError } from "../errors.ts";
|
|
16
|
+
import { jsonOutput } from "../json.ts";
|
|
17
|
+
import { color } from "../logging/color.ts";
|
|
18
|
+
import { formatAbsoluteTime, formatDate, logLevelColor, logLevelLabel } from "../logging/format.ts";
|
|
19
|
+
import { renderHeader } from "../logging/theme.ts";
|
|
20
|
+
import type { LogEvent } from "../types.ts";
|
|
21
|
+
import { parseRelativeTime } from "../utils/time.ts";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Build a detail string for a log event based on its data.
|
|
25
|
+
* @internal Exported for testing.
|
|
26
|
+
*/
|
|
27
|
+
export function buildLogDetail(event: LogEvent): string {
|
|
28
|
+
const parts: string[] = [];
|
|
29
|
+
|
|
30
|
+
for (const [key, value] of Object.entries(event.data)) {
|
|
31
|
+
if (value !== null && value !== undefined) {
|
|
32
|
+
const strValue = typeof value === "string" ? value : JSON.stringify(value);
|
|
33
|
+
// Truncate long values
|
|
34
|
+
const truncated = strValue.length > 80 ? `${strValue.slice(0, 77)}...` : strValue;
|
|
35
|
+
parts.push(`${key}=${truncated}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return parts.join(" ");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Discover all events.ndjson files in the logs directory.
|
|
44
|
+
* Returns array of { agentName, sessionTimestamp, path }.
|
|
45
|
+
* @internal Exported for testing.
|
|
46
|
+
*/
|
|
47
|
+
export async function discoverLogFiles(
|
|
48
|
+
logsDir: string,
|
|
49
|
+
agentFilter?: string,
|
|
50
|
+
): Promise<
|
|
51
|
+
Array<{
|
|
52
|
+
agentName: string;
|
|
53
|
+
sessionTimestamp: string;
|
|
54
|
+
path: string;
|
|
55
|
+
}>
|
|
56
|
+
> {
|
|
57
|
+
const discovered: Array<{
|
|
58
|
+
agentName: string;
|
|
59
|
+
sessionTimestamp: string;
|
|
60
|
+
path: string;
|
|
61
|
+
}> = [];
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const agentDirs = await readdir(logsDir);
|
|
65
|
+
|
|
66
|
+
for (const agentName of agentDirs) {
|
|
67
|
+
if (agentFilter !== undefined && agentName !== agentFilter) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const agentDir = join(logsDir, agentName);
|
|
72
|
+
let agentStat: Awaited<ReturnType<typeof stat>>;
|
|
73
|
+
try {
|
|
74
|
+
agentStat = await stat(agentDir);
|
|
75
|
+
} catch {
|
|
76
|
+
continue; // Not a directory or doesn't exist
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!agentStat.isDirectory()) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const sessionDirs = await readdir(agentDir);
|
|
84
|
+
|
|
85
|
+
for (const sessionTimestamp of sessionDirs) {
|
|
86
|
+
const eventsPath = join(agentDir, sessionTimestamp, "events.ndjson");
|
|
87
|
+
let eventsStat: Awaited<ReturnType<typeof stat>>;
|
|
88
|
+
try {
|
|
89
|
+
eventsStat = await stat(eventsPath);
|
|
90
|
+
} catch {
|
|
91
|
+
continue; // File doesn't exist
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (eventsStat.isFile()) {
|
|
95
|
+
discovered.push({
|
|
96
|
+
agentName,
|
|
97
|
+
sessionTimestamp,
|
|
98
|
+
path: eventsPath,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} catch {
|
|
104
|
+
// Logs directory doesn't exist or can't be read
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Sort by session timestamp (chronological)
|
|
109
|
+
discovered.sort((a, b) => a.sessionTimestamp.localeCompare(b.sessionTimestamp));
|
|
110
|
+
|
|
111
|
+
return discovered;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Parse a single NDJSON file and return log events.
|
|
116
|
+
* Silently skips invalid lines.
|
|
117
|
+
* @internal Exported for testing.
|
|
118
|
+
*/
|
|
119
|
+
export async function parseLogFile(path: string): Promise<LogEvent[]> {
|
|
120
|
+
const events: LogEvent[] = [];
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const file = Bun.file(path);
|
|
124
|
+
const text = await file.text();
|
|
125
|
+
const lines = text.split("\n");
|
|
126
|
+
|
|
127
|
+
for (const line of lines) {
|
|
128
|
+
if (line.trim() === "") {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const parsed: unknown = JSON.parse(line);
|
|
134
|
+
// Validate that it has required LogEvent fields
|
|
135
|
+
if (
|
|
136
|
+
typeof parsed === "object" &&
|
|
137
|
+
parsed !== null &&
|
|
138
|
+
"timestamp" in parsed &&
|
|
139
|
+
"event" in parsed
|
|
140
|
+
) {
|
|
141
|
+
events.push(parsed as LogEvent);
|
|
142
|
+
}
|
|
143
|
+
} catch {
|
|
144
|
+
// Invalid JSON line, skip silently
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} catch {
|
|
148
|
+
// File can't be read, return empty array
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return events;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Apply filters to log events.
|
|
157
|
+
* @internal Exported for testing.
|
|
158
|
+
*/
|
|
159
|
+
export function filterEvents(
|
|
160
|
+
events: LogEvent[],
|
|
161
|
+
filters: {
|
|
162
|
+
level?: string;
|
|
163
|
+
since?: Date;
|
|
164
|
+
until?: Date;
|
|
165
|
+
},
|
|
166
|
+
): LogEvent[] {
|
|
167
|
+
return events.filter((event) => {
|
|
168
|
+
if (filters.level !== undefined && event.level !== filters.level) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const eventTime = new Date(event.timestamp).getTime();
|
|
173
|
+
|
|
174
|
+
if (filters.since !== undefined && eventTime < filters.since.getTime()) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (filters.until !== undefined && eventTime > filters.until.getTime()) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return true;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Print log events with ANSI colors and date separators.
|
|
188
|
+
*/
|
|
189
|
+
function printLogs(events: LogEvent[]): void {
|
|
190
|
+
const w = process.stdout.write.bind(process.stdout);
|
|
191
|
+
|
|
192
|
+
w(`${renderHeader("Logs")}\n`);
|
|
193
|
+
|
|
194
|
+
if (events.length === 0) {
|
|
195
|
+
w(`${color.dim("No log files found.")}\n`);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
w(`${color.dim(`${events.length} ${events.length === 1 ? "entry" : "entries"}`)}\n\n`);
|
|
200
|
+
|
|
201
|
+
let lastDate = "";
|
|
202
|
+
|
|
203
|
+
for (const event of events) {
|
|
204
|
+
// Print date separator when the date changes
|
|
205
|
+
const date = formatDate(event.timestamp);
|
|
206
|
+
if (date && date !== lastDate) {
|
|
207
|
+
if (lastDate !== "") {
|
|
208
|
+
w("\n");
|
|
209
|
+
}
|
|
210
|
+
w(`${color.dim(`--- ${date} ---`)}\n`);
|
|
211
|
+
lastDate = date;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const time = formatAbsoluteTime(event.timestamp);
|
|
215
|
+
const levelColorFn = logLevelColor(event.level);
|
|
216
|
+
const levelStr = logLevelLabel(event.level);
|
|
217
|
+
|
|
218
|
+
const agentLabel = event.agentName ? `[${event.agentName}]` : "[unknown]";
|
|
219
|
+
const detail = buildLogDetail(event);
|
|
220
|
+
const detailSuffix = detail ? ` ${color.dim(detail)}` : "";
|
|
221
|
+
|
|
222
|
+
w(
|
|
223
|
+
`${time} ${levelColorFn(levelStr)} ` +
|
|
224
|
+
`${event.event} ${color.dim(agentLabel)}${detailSuffix}\n`,
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Process one poll tick of log tailing: scan discovered log files for new data
|
|
231
|
+
* since lastKnownSizes, parse new lines, apply filters, and return the count
|
|
232
|
+
* of new events found.
|
|
233
|
+
* @internal Exported for testing.
|
|
234
|
+
*
|
|
235
|
+
* @param logFiles - Array of discovered log file paths
|
|
236
|
+
* @param lastKnownSizes - Map of file path to last-seen byte offset (mutated in place)
|
|
237
|
+
* @param filters - Level filter to apply
|
|
238
|
+
* @returns Number of new events emitted
|
|
239
|
+
*/
|
|
240
|
+
export async function pollLogTick(
|
|
241
|
+
logFiles: Array<{ path: string }>,
|
|
242
|
+
lastKnownSizes: Map<string, number>,
|
|
243
|
+
filters: { level?: string },
|
|
244
|
+
): Promise<number> {
|
|
245
|
+
const w = process.stdout.write.bind(process.stdout);
|
|
246
|
+
let emitted = 0;
|
|
247
|
+
|
|
248
|
+
for (const { path } of logFiles) {
|
|
249
|
+
const file = Bun.file(path);
|
|
250
|
+
let fileSize: number;
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
const fileStat = await stat(path);
|
|
254
|
+
fileSize = fileStat.size;
|
|
255
|
+
} catch {
|
|
256
|
+
continue; // File disappeared
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const lastPosition = lastKnownSizes.get(path) ?? 0;
|
|
260
|
+
|
|
261
|
+
if (fileSize > lastPosition) {
|
|
262
|
+
// New data available
|
|
263
|
+
try {
|
|
264
|
+
const fullText = await file.text();
|
|
265
|
+
const newText = fullText.slice(lastPosition);
|
|
266
|
+
const lines = newText.split("\n");
|
|
267
|
+
|
|
268
|
+
for (const line of lines) {
|
|
269
|
+
if (line.trim() === "") {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
const parsed: unknown = JSON.parse(line);
|
|
275
|
+
if (
|
|
276
|
+
typeof parsed === "object" &&
|
|
277
|
+
parsed !== null &&
|
|
278
|
+
"timestamp" in parsed &&
|
|
279
|
+
"event" in parsed
|
|
280
|
+
) {
|
|
281
|
+
const event = parsed as LogEvent;
|
|
282
|
+
|
|
283
|
+
// Apply level filter
|
|
284
|
+
if (filters.level !== undefined && event.level !== filters.level) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Print immediately
|
|
289
|
+
const time = formatAbsoluteTime(event.timestamp);
|
|
290
|
+
const levelColorFn = logLevelColor(event.level);
|
|
291
|
+
const levelStr = logLevelLabel(event.level);
|
|
292
|
+
|
|
293
|
+
const agentLabel = event.agentName ? `[${event.agentName}]` : "[unknown]";
|
|
294
|
+
const detail = buildLogDetail(event);
|
|
295
|
+
const detailSuffix = detail ? ` ${color.dim(detail)}` : "";
|
|
296
|
+
|
|
297
|
+
w(
|
|
298
|
+
`${time} ${levelColorFn(levelStr)} ` +
|
|
299
|
+
`${event.event} ${color.dim(agentLabel)}${detailSuffix}\n`,
|
|
300
|
+
);
|
|
301
|
+
emitted++;
|
|
302
|
+
}
|
|
303
|
+
} catch {
|
|
304
|
+
// Invalid JSON line, skip
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
lastKnownSizes.set(path, fileSize);
|
|
309
|
+
} catch {
|
|
310
|
+
// File read error, skip
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return emitted;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Follow mode: tail logs in real time.
|
|
320
|
+
*/
|
|
321
|
+
async function followLogs(
|
|
322
|
+
logsDir: string,
|
|
323
|
+
filters: {
|
|
324
|
+
agent?: string;
|
|
325
|
+
level?: string;
|
|
326
|
+
},
|
|
327
|
+
): Promise<void> {
|
|
328
|
+
const w = process.stdout.write.bind(process.stdout);
|
|
329
|
+
|
|
330
|
+
w(`${color.bold("Following logs (Ctrl+C to stop)")}\n\n`);
|
|
331
|
+
|
|
332
|
+
// Track file positions for tailing
|
|
333
|
+
const filePositions = new Map<string, number>();
|
|
334
|
+
|
|
335
|
+
while (true) {
|
|
336
|
+
const discovered = await discoverLogFiles(logsDir, filters.agent);
|
|
337
|
+
await pollLogTick(discovered, filePositions, { level: filters.level });
|
|
338
|
+
|
|
339
|
+
// Sleep for 1 second before next poll
|
|
340
|
+
await Bun.sleep(1000);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
interface LogsOpts {
|
|
345
|
+
agent?: string;
|
|
346
|
+
level?: string;
|
|
347
|
+
since?: string;
|
|
348
|
+
until?: string;
|
|
349
|
+
limit?: string;
|
|
350
|
+
follow?: boolean;
|
|
351
|
+
json?: boolean;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function executeLogs(opts: LogsOpts): Promise<void> {
|
|
355
|
+
const json = opts.json ?? false;
|
|
356
|
+
const follow = opts.follow ?? false;
|
|
357
|
+
const agentName = opts.agent;
|
|
358
|
+
const level = opts.level;
|
|
359
|
+
const sinceStr = opts.since;
|
|
360
|
+
const untilStr = opts.until;
|
|
361
|
+
const limitStr = opts.limit;
|
|
362
|
+
const limit = limitStr ? Number.parseInt(limitStr, 10) : 100;
|
|
363
|
+
|
|
364
|
+
if (Number.isNaN(limit) || limit < 1) {
|
|
365
|
+
throw new ValidationError("--limit must be a positive integer", {
|
|
366
|
+
field: "limit",
|
|
367
|
+
value: limitStr,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Validate level if provided
|
|
372
|
+
if (level !== undefined && !["debug", "info", "warn", "error"].includes(level)) {
|
|
373
|
+
throw new ValidationError("--level must be one of: debug, info, warn, error", {
|
|
374
|
+
field: "level",
|
|
375
|
+
value: level,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Parse time filters
|
|
380
|
+
let since: Date | undefined;
|
|
381
|
+
let until: Date | undefined;
|
|
382
|
+
|
|
383
|
+
if (sinceStr !== undefined) {
|
|
384
|
+
since = parseRelativeTime(sinceStr);
|
|
385
|
+
if (Number.isNaN(since.getTime())) {
|
|
386
|
+
throw new ValidationError("--since must be a valid ISO 8601 timestamp or relative time", {
|
|
387
|
+
field: "since",
|
|
388
|
+
value: sinceStr,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (untilStr !== undefined) {
|
|
394
|
+
until = new Date(untilStr);
|
|
395
|
+
if (Number.isNaN(until.getTime())) {
|
|
396
|
+
throw new ValidationError("--until must be a valid ISO 8601 timestamp", {
|
|
397
|
+
field: "until",
|
|
398
|
+
value: untilStr,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const cwd = process.cwd();
|
|
404
|
+
const config = await loadConfig(cwd);
|
|
405
|
+
const logsDir = join(config.project.root, ".agentplate", "logs");
|
|
406
|
+
|
|
407
|
+
// Follow mode: tail logs in real time
|
|
408
|
+
if (follow) {
|
|
409
|
+
await followLogs(logsDir, { agent: agentName, level });
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Discovery phase: find all events.ndjson files
|
|
414
|
+
const discovered = await discoverLogFiles(logsDir, agentName);
|
|
415
|
+
|
|
416
|
+
if (discovered.length === 0) {
|
|
417
|
+
if (json) {
|
|
418
|
+
process.stdout.write("[]\n");
|
|
419
|
+
} else {
|
|
420
|
+
process.stdout.write("No log files found.\n");
|
|
421
|
+
}
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Parsing phase: read and parse all files
|
|
426
|
+
const allEvents: LogEvent[] = [];
|
|
427
|
+
|
|
428
|
+
for (const { path } of discovered) {
|
|
429
|
+
const events = await parseLogFile(path);
|
|
430
|
+
allEvents.push(...events);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Apply filters
|
|
434
|
+
const filtered = filterEvents(allEvents, { level, since, until });
|
|
435
|
+
|
|
436
|
+
// Sort by timestamp chronologically
|
|
437
|
+
filtered.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
438
|
+
|
|
439
|
+
// Apply limit: take the LAST N entries (most recent)
|
|
440
|
+
const limited = filtered.slice(-limit);
|
|
441
|
+
|
|
442
|
+
if (json) {
|
|
443
|
+
jsonOutput("logs", { entries: limited });
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
printLogs(limited);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export function createLogsCommand(): Command {
|
|
451
|
+
return new Command("logs")
|
|
452
|
+
.description("Query NDJSON logs across agents")
|
|
453
|
+
.option("--agent <name>", "Filter logs by agent name")
|
|
454
|
+
.option("--level <level>", "Filter by log level: debug, info, warn, error")
|
|
455
|
+
.option("--since <time>", "Start time filter (ISO 8601 or relative: 1h, 30m, 2d, 10s)")
|
|
456
|
+
.option("--until <time>", "End time filter (ISO 8601)")
|
|
457
|
+
.option("--limit <n>", "Max entries to show (default: 100, returns most recent)")
|
|
458
|
+
.option("--follow", "Tail logs in real time (poll every 1s, Ctrl+C to stop)")
|
|
459
|
+
.option("--json", "Output as JSON array of LogEvent objects")
|
|
460
|
+
.action(async (opts: LogsOpts) => {
|
|
461
|
+
await executeLogs(opts);
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export async function logsCommand(args: string[]): Promise<void> {
|
|
466
|
+
const cmd = createLogsCommand();
|
|
467
|
+
cmd.exitOverride();
|
|
468
|
+
try {
|
|
469
|
+
await cmd.parseAsync(args, { from: "user" });
|
|
470
|
+
} catch (err: unknown) {
|
|
471
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
472
|
+
const code = (err as { code: string }).code;
|
|
473
|
+
if (code === "commander.helpDisplayed" || code === "commander.version") {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
if (code.startsWith("commander.")) {
|
|
477
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
478
|
+
throw new ValidationError(message, { field: "args" });
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
throw err;
|
|
482
|
+
}
|
|
483
|
+
}
|