@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,325 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { mkdir, mkdtemp } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { cleanupTempDir } from "../test-helpers.ts";
|
|
6
|
+
import type { ResolvedModel } from "../types.ts";
|
|
7
|
+
import { OpenCodeRuntime } from "./opencode.ts";
|
|
8
|
+
import type { SpawnOpts } from "./types.ts";
|
|
9
|
+
|
|
10
|
+
describe("OpenCodeRuntime", () => {
|
|
11
|
+
const runtime = new OpenCodeRuntime();
|
|
12
|
+
|
|
13
|
+
describe("id and instructionPath", () => {
|
|
14
|
+
test("id is 'opencode'", () => {
|
|
15
|
+
expect(runtime.id).toBe("opencode");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("instructionPath is AGENTS.md", () => {
|
|
19
|
+
expect(runtime.instructionPath).toBe("AGENTS.md");
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("buildSpawnCommand", () => {
|
|
24
|
+
test("includes --model flag", () => {
|
|
25
|
+
const opts: SpawnOpts = {
|
|
26
|
+
model: "sonnet",
|
|
27
|
+
permissionMode: "bypass",
|
|
28
|
+
cwd: "/tmp/worktree",
|
|
29
|
+
env: {},
|
|
30
|
+
};
|
|
31
|
+
const cmd = runtime.buildSpawnCommand(opts);
|
|
32
|
+
expect(cmd).toBe("opencode --model sonnet");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("permissionMode is ignored (opencode has no permission flag)", () => {
|
|
36
|
+
const bypass: SpawnOpts = {
|
|
37
|
+
model: "opus",
|
|
38
|
+
permissionMode: "bypass",
|
|
39
|
+
cwd: "/tmp",
|
|
40
|
+
env: {},
|
|
41
|
+
};
|
|
42
|
+
const ask: SpawnOpts = { ...bypass, permissionMode: "ask" };
|
|
43
|
+
expect(runtime.buildSpawnCommand(bypass)).toBe("opencode --model opus");
|
|
44
|
+
expect(runtime.buildSpawnCommand(ask)).toBe("opencode --model opus");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("appendSystemPrompt is ignored (opencode has no such flag)", () => {
|
|
48
|
+
const opts: SpawnOpts = {
|
|
49
|
+
model: "sonnet",
|
|
50
|
+
permissionMode: "bypass",
|
|
51
|
+
cwd: "/tmp/worktree",
|
|
52
|
+
env: {},
|
|
53
|
+
appendSystemPrompt: "You are a builder agent.",
|
|
54
|
+
};
|
|
55
|
+
const cmd = runtime.buildSpawnCommand(opts);
|
|
56
|
+
expect(cmd).toBe("opencode --model sonnet");
|
|
57
|
+
expect(cmd).not.toContain("append-system-prompt");
|
|
58
|
+
expect(cmd).not.toContain("You are a builder agent");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("appendSystemPromptFile is ignored (opencode has no such flag)", () => {
|
|
62
|
+
const opts: SpawnOpts = {
|
|
63
|
+
model: "opus",
|
|
64
|
+
permissionMode: "bypass",
|
|
65
|
+
cwd: "/project",
|
|
66
|
+
env: {},
|
|
67
|
+
appendSystemPromptFile: "/project/.agentplate/specs/task.md",
|
|
68
|
+
};
|
|
69
|
+
const cmd = runtime.buildSpawnCommand(opts);
|
|
70
|
+
expect(cmd).toBe("opencode --model opus");
|
|
71
|
+
expect(cmd).not.toContain("task.md");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("cwd and env are not embedded in command string", () => {
|
|
75
|
+
const opts: SpawnOpts = {
|
|
76
|
+
model: "sonnet",
|
|
77
|
+
permissionMode: "bypass",
|
|
78
|
+
cwd: "/some/specific/path",
|
|
79
|
+
env: { OPENAI_API_KEY: "sk-test-123" },
|
|
80
|
+
};
|
|
81
|
+
const cmd = runtime.buildSpawnCommand(opts);
|
|
82
|
+
expect(cmd).not.toContain("/some/specific/path");
|
|
83
|
+
expect(cmd).not.toContain("sk-test-123");
|
|
84
|
+
expect(cmd).not.toContain("OPENAI_API_KEY");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("all model names pass through unchanged", () => {
|
|
88
|
+
for (const model of ["sonnet", "opus", "haiku", "gpt-4o", "openrouter/gpt-5"]) {
|
|
89
|
+
const opts: SpawnOpts = {
|
|
90
|
+
model,
|
|
91
|
+
permissionMode: "bypass",
|
|
92
|
+
cwd: "/tmp",
|
|
93
|
+
env: {},
|
|
94
|
+
};
|
|
95
|
+
const cmd = runtime.buildSpawnCommand(opts);
|
|
96
|
+
expect(cmd).toContain(`--model ${model}`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("produces identical output for same inputs (deterministic)", () => {
|
|
101
|
+
const opts: SpawnOpts = {
|
|
102
|
+
model: "sonnet",
|
|
103
|
+
permissionMode: "bypass",
|
|
104
|
+
cwd: "/tmp/worktree",
|
|
105
|
+
env: {},
|
|
106
|
+
};
|
|
107
|
+
expect(runtime.buildSpawnCommand(opts)).toBe(runtime.buildSpawnCommand(opts));
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe("buildPrintCommand", () => {
|
|
112
|
+
test("basic command without model includes --prompt and --format json", () => {
|
|
113
|
+
const argv = runtime.buildPrintCommand("Summarize this diff");
|
|
114
|
+
expect(argv).toEqual(["opencode", "--prompt", "Summarize this diff", "--format", "json"]);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("command with model override appends --model flag", () => {
|
|
118
|
+
const argv = runtime.buildPrintCommand("Classify this error", "haiku");
|
|
119
|
+
expect(argv).toEqual([
|
|
120
|
+
"opencode",
|
|
121
|
+
"--prompt",
|
|
122
|
+
"Classify this error",
|
|
123
|
+
"--format",
|
|
124
|
+
"json",
|
|
125
|
+
"--model",
|
|
126
|
+
"haiku",
|
|
127
|
+
]);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("model undefined omits --model flag", () => {
|
|
131
|
+
const argv = runtime.buildPrintCommand("Hello", undefined);
|
|
132
|
+
expect(argv).not.toContain("--model");
|
|
133
|
+
expect(argv).toContain("--format");
|
|
134
|
+
expect(argv).toContain("json");
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("prompt is passed verbatim as a single argv element", () => {
|
|
138
|
+
const prompt = "Fix the bug in src/foo.ts line 42";
|
|
139
|
+
const argv = runtime.buildPrintCommand(prompt);
|
|
140
|
+
const promptIdx = argv.indexOf("--prompt");
|
|
141
|
+
expect(promptIdx).toBeGreaterThan(-1);
|
|
142
|
+
expect(argv[promptIdx + 1]).toBe(prompt);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe("detectReady (stub)", () => {
|
|
147
|
+
test("returns loading for empty pane", () => {
|
|
148
|
+
expect(runtime.detectReady("")).toEqual({ phase: "loading" });
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("returns loading for any content (stub always returns loading)", () => {
|
|
152
|
+
expect(runtime.detectReady("OpenCode v1.0\n> ")).toEqual({ phase: "loading" });
|
|
153
|
+
expect(runtime.detectReady("ready")).toEqual({ phase: "loading" });
|
|
154
|
+
expect(runtime.detectReady("opencode started")).toEqual({ phase: "loading" });
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("never returns dialog phase", () => {
|
|
158
|
+
const state = runtime.detectReady("trust this folder?");
|
|
159
|
+
expect(state.phase).not.toBe("dialog");
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe("parseTranscript (stub)", () => {
|
|
164
|
+
let tempDir: string;
|
|
165
|
+
|
|
166
|
+
beforeEach(async () => {
|
|
167
|
+
tempDir = await mkdtemp(join(tmpdir(), "agentplate-opencode-transcript-test-"));
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
afterEach(async () => {
|
|
171
|
+
await cleanupTempDir(tempDir);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("returns null for non-existent file", async () => {
|
|
175
|
+
const result = await runtime.parseTranscript(join(tempDir, "does-not-exist.jsonl"));
|
|
176
|
+
expect(result).toBeNull();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("returns null for existing file (format not yet verified)", async () => {
|
|
180
|
+
const transcriptPath = join(tempDir, "session.jsonl");
|
|
181
|
+
await Bun.write(transcriptPath, `${JSON.stringify({ type: "result", tokens: 100 })}\n`);
|
|
182
|
+
const result = await runtime.parseTranscript(transcriptPath);
|
|
183
|
+
expect(result).toBeNull();
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("returns null for empty file", async () => {
|
|
187
|
+
const transcriptPath = join(tempDir, "empty.jsonl");
|
|
188
|
+
await Bun.write(transcriptPath, "");
|
|
189
|
+
const result = await runtime.parseTranscript(transcriptPath);
|
|
190
|
+
expect(result).toBeNull();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe("getTranscriptDir (stub)", () => {
|
|
195
|
+
test("returns null (location not yet verified)", () => {
|
|
196
|
+
expect(runtime.getTranscriptDir("/some/project")).toBeNull();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("returns null regardless of project root", () => {
|
|
200
|
+
expect(runtime.getTranscriptDir("/home/user/project")).toBeNull();
|
|
201
|
+
expect(runtime.getTranscriptDir("/tmp/test")).toBeNull();
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe("buildEnv", () => {
|
|
206
|
+
test("returns empty object when model has no env", () => {
|
|
207
|
+
const model: ResolvedModel = { model: "sonnet" };
|
|
208
|
+
expect(runtime.buildEnv(model)).toEqual({});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("returns model.env when present", () => {
|
|
212
|
+
const model: ResolvedModel = {
|
|
213
|
+
model: "gpt-4o",
|
|
214
|
+
env: { OPENAI_API_KEY: "sk-test-123", OPENCODE_API_URL: "https://api.openai.com" },
|
|
215
|
+
};
|
|
216
|
+
expect(runtime.buildEnv(model)).toEqual({
|
|
217
|
+
OPENAI_API_KEY: "sk-test-123",
|
|
218
|
+
OPENCODE_API_URL: "https://api.openai.com",
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("returns empty object when model.env is undefined", () => {
|
|
223
|
+
const model: ResolvedModel = { model: "opus", env: undefined };
|
|
224
|
+
expect(runtime.buildEnv(model)).toEqual({});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test("env is safe to spread into session env", () => {
|
|
228
|
+
const model: ResolvedModel = { model: "sonnet" };
|
|
229
|
+
const env = runtime.buildEnv(model);
|
|
230
|
+
const combined = { ...env, AGENTPLATE_AGENT_NAME: "builder-1" };
|
|
231
|
+
expect(combined).toEqual({ AGENTPLATE_AGENT_NAME: "builder-1" });
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe("deployConfig", () => {
|
|
236
|
+
let tempDir: string;
|
|
237
|
+
|
|
238
|
+
beforeEach(async () => {
|
|
239
|
+
tempDir = await mkdtemp(join(tmpdir(), "agentplate-opencode-test-"));
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
afterEach(async () => {
|
|
243
|
+
await cleanupTempDir(tempDir);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
test("writes overlay to AGENTS.md when provided", async () => {
|
|
247
|
+
const worktreePath = join(tempDir, "worktree");
|
|
248
|
+
|
|
249
|
+
await runtime.deployConfig(
|
|
250
|
+
worktreePath,
|
|
251
|
+
{ content: "# Agent Instructions\nYou are a builder." },
|
|
252
|
+
{ agentName: "test-builder", capability: "builder", worktreePath },
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const content = await Bun.file(join(worktreePath, "AGENTS.md")).text();
|
|
256
|
+
expect(content).toBe("# Agent Instructions\nYou are a builder.");
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("creates worktree directory if it does not exist", async () => {
|
|
260
|
+
const worktreePath = join(tempDir, "new-worktree");
|
|
261
|
+
|
|
262
|
+
await runtime.deployConfig(
|
|
263
|
+
worktreePath,
|
|
264
|
+
{ content: "# Instructions" },
|
|
265
|
+
{ agentName: "test", capability: "builder", worktreePath },
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
const exists = await Bun.file(join(worktreePath, "AGENTS.md")).exists();
|
|
269
|
+
expect(exists).toBe(true);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
test("skips overlay write when overlay is undefined", async () => {
|
|
273
|
+
const worktreePath = join(tempDir, "worktree");
|
|
274
|
+
|
|
275
|
+
await runtime.deployConfig(worktreePath, undefined, {
|
|
276
|
+
agentName: "coordinator",
|
|
277
|
+
capability: "coordinator",
|
|
278
|
+
worktreePath,
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
const exists = await Bun.file(join(worktreePath, "AGENTS.md")).exists();
|
|
282
|
+
expect(exists).toBe(false);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test("does not write settings.local.json (no hook deployment)", async () => {
|
|
286
|
+
const worktreePath = join(tempDir, "worktree");
|
|
287
|
+
|
|
288
|
+
await runtime.deployConfig(
|
|
289
|
+
worktreePath,
|
|
290
|
+
{ content: "# Instructions" },
|
|
291
|
+
{ agentName: "test-builder", capability: "builder", worktreePath },
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const settingsExists = await Bun.file(
|
|
295
|
+
join(worktreePath, ".claude", "settings.local.json"),
|
|
296
|
+
).exists();
|
|
297
|
+
expect(settingsExists).toBe(false);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test("overwrites existing AGENTS.md", async () => {
|
|
301
|
+
const worktreePath = join(tempDir, "worktree");
|
|
302
|
+
await mkdir(worktreePath, { recursive: true });
|
|
303
|
+
await Bun.write(join(worktreePath, "AGENTS.md"), "old content");
|
|
304
|
+
|
|
305
|
+
await runtime.deployConfig(
|
|
306
|
+
worktreePath,
|
|
307
|
+
{ content: "new content" },
|
|
308
|
+
{ agentName: "test", capability: "builder", worktreePath },
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
const content = await Bun.file(join(worktreePath, "AGENTS.md")).text();
|
|
312
|
+
expect(content).toBe("new content");
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
describe("OpenCodeRuntime integration: registry resolves 'opencode'", () => {
|
|
318
|
+
test("getRuntime('opencode') returns OpenCodeRuntime", async () => {
|
|
319
|
+
const { getRuntime } = await import("./registry.ts");
|
|
320
|
+
const rt = getRuntime("opencode");
|
|
321
|
+
expect(rt).toBeInstanceOf(OpenCodeRuntime);
|
|
322
|
+
expect(rt.id).toBe("opencode");
|
|
323
|
+
expect(rt.instructionPath).toBe("AGENTS.md");
|
|
324
|
+
});
|
|
325
|
+
});
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// OpenCode runtime adapter for agentplate's AgentRuntime interface.
|
|
2
|
+
// Implements the AgentRuntime contract for the `opencode` CLI (SST OpenCode).
|
|
3
|
+
//
|
|
4
|
+
// Key differences from Claude/Pi adapters:
|
|
5
|
+
// - Uses `opencode` CLI for interactive sessions
|
|
6
|
+
// - Instruction file: AGENTS.md (unverified — needs confirmation against real OpenCode install)
|
|
7
|
+
// - No hooks: OpenCode does not support Claude Code's hook mechanism
|
|
8
|
+
// - detectReady is stubbed: real TUI patterns not yet observed
|
|
9
|
+
// - parseTranscript returns null: output format not yet verified
|
|
10
|
+
|
|
11
|
+
import { mkdir } from "node:fs/promises";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import type { ResolvedModel } from "../types.ts";
|
|
14
|
+
import type {
|
|
15
|
+
AgentRuntime,
|
|
16
|
+
HooksDef,
|
|
17
|
+
OverlayContent,
|
|
18
|
+
ReadyState,
|
|
19
|
+
SpawnOpts,
|
|
20
|
+
TranscriptSummary,
|
|
21
|
+
} from "./types.ts";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* OpenCode runtime adapter.
|
|
25
|
+
*
|
|
26
|
+
* Implements AgentRuntime for the `opencode` CLI (SST OpenCode coding agent).
|
|
27
|
+
* Key differences from Claude Code:
|
|
28
|
+
* - Uses `--model` flag for model selection
|
|
29
|
+
* - Instruction file lives at `AGENTS.md` (unverified — confirm against real install)
|
|
30
|
+
* - No hooks deployment (OpenCode has no Claude Code hook mechanism)
|
|
31
|
+
* - `detectReady` is a stub — real TUI ready patterns not yet observed in tmux
|
|
32
|
+
* - `parseTranscript` returns null — `opencode` output format not yet verified
|
|
33
|
+
*
|
|
34
|
+
* TODO: Once a real OpenCode installation is available:
|
|
35
|
+
* 1. Verify `instructionPath` — run `opencode` and check which file it reads
|
|
36
|
+
* 2. Fill in `detectReady` — capture tmux pane content and match actual strings
|
|
37
|
+
* 3. Fill in `parseTranscript` — run `opencode run --format json` and inspect output
|
|
38
|
+
* 4. Fill in `getTranscriptDir` — check where OpenCode writes session files
|
|
39
|
+
*/
|
|
40
|
+
export class OpenCodeRuntime implements AgentRuntime {
|
|
41
|
+
/** Unique identifier for this runtime. */
|
|
42
|
+
readonly id = "opencode";
|
|
43
|
+
|
|
44
|
+
/** Stability level. OpenCode adapter is experimental — not fully validated. */
|
|
45
|
+
readonly stability = "experimental" as const;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Relative path to the instruction file within a worktree.
|
|
49
|
+
*
|
|
50
|
+
* @stub Unverified — `AGENTS.md` is a common convention for terminal coding agents
|
|
51
|
+
* but has not been confirmed against a real OpenCode installation.
|
|
52
|
+
* Verify with `opencode --help` or OpenCode documentation before relying on this.
|
|
53
|
+
*/
|
|
54
|
+
readonly instructionPath = "AGENTS.md";
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Build the shell command string to spawn an interactive OpenCode agent in a tmux pane.
|
|
58
|
+
*
|
|
59
|
+
* Maps SpawnOpts to `opencode` CLI flags:
|
|
60
|
+
* - `model` → `--model <model>`
|
|
61
|
+
* - `permissionMode`, `appendSystemPrompt`, `appendSystemPromptFile` are IGNORED —
|
|
62
|
+
* the `opencode` CLI has no equivalent flags.
|
|
63
|
+
*
|
|
64
|
+
* The `cwd` and `env` fields of SpawnOpts are handled by the tmux session
|
|
65
|
+
* creator, not embedded in the command string.
|
|
66
|
+
*
|
|
67
|
+
* @param opts - Spawn options (model used; others ignored)
|
|
68
|
+
* @returns Shell command string suitable for tmux new-session -c
|
|
69
|
+
*/
|
|
70
|
+
buildSpawnCommand(opts: SpawnOpts): string {
|
|
71
|
+
// permissionMode, appendSystemPrompt, appendSystemPromptFile are intentionally ignored.
|
|
72
|
+
// OpenCode has no equivalent flags for these options.
|
|
73
|
+
return `opencode --model ${opts.model}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Build the argv array for a headless one-shot OpenCode invocation.
|
|
78
|
+
*
|
|
79
|
+
* Returns an argv array suitable for `Bun.spawn()`. The `--prompt` flag passes
|
|
80
|
+
* the prompt and `--format json` requests structured JSON output.
|
|
81
|
+
*
|
|
82
|
+
* Used by merge/resolver.ts and watchdog/triage.ts for AI-assisted operations.
|
|
83
|
+
*
|
|
84
|
+
* @stub `--prompt` and `--format json` flags are unverified against real OpenCode CLI.
|
|
85
|
+
* Run `opencode --help` to confirm flag names before use in production.
|
|
86
|
+
*
|
|
87
|
+
* @param prompt - The prompt to pass via `--prompt`
|
|
88
|
+
* @param model - Optional model override
|
|
89
|
+
* @returns Argv array for Bun.spawn
|
|
90
|
+
*/
|
|
91
|
+
buildPrintCommand(prompt: string, model?: string): string[] {
|
|
92
|
+
const cmd = ["opencode", "--prompt", prompt, "--format", "json"];
|
|
93
|
+
if (model !== undefined) {
|
|
94
|
+
cmd.push("--model", model);
|
|
95
|
+
}
|
|
96
|
+
return cmd;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Deploy per-agent instructions to a worktree.
|
|
101
|
+
*
|
|
102
|
+
* For OpenCode this writes only the instruction file:
|
|
103
|
+
* - `AGENTS.md` — the agent's task-specific overlay.
|
|
104
|
+
* Skipped when overlay is undefined.
|
|
105
|
+
*
|
|
106
|
+
* The `hooks` parameter is unused — OpenCode does not support Claude Code's
|
|
107
|
+
* hook mechanism, so no settings file is deployed.
|
|
108
|
+
*
|
|
109
|
+
* @param worktreePath - Absolute path to the agent's git worktree
|
|
110
|
+
* @param overlay - Overlay content to write as AGENTS.md, or undefined to skip
|
|
111
|
+
* @param _hooks - Unused for OpenCode runtime
|
|
112
|
+
*/
|
|
113
|
+
async deployConfig(
|
|
114
|
+
worktreePath: string,
|
|
115
|
+
overlay: OverlayContent | undefined,
|
|
116
|
+
_hooks: HooksDef,
|
|
117
|
+
): Promise<void> {
|
|
118
|
+
if (overlay) {
|
|
119
|
+
await mkdir(worktreePath, { recursive: true });
|
|
120
|
+
await Bun.write(join(worktreePath, "AGENTS.md"), overlay.content);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// No hook deployment for OpenCode — the runtime has no hook mechanism.
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Detect OpenCode TUI readiness from a tmux pane content snapshot.
|
|
128
|
+
*
|
|
129
|
+
* @stub This method always returns `{ phase: "loading" }` because the real
|
|
130
|
+
* TUI startup strings for OpenCode have not been observed in a live tmux session.
|
|
131
|
+
* To implement: run `opencode` in tmux, capture pane content at startup, and
|
|
132
|
+
* match strings unique to the ready state (version header, prompt character,
|
|
133
|
+
* status bar content, etc.).
|
|
134
|
+
*
|
|
135
|
+
* @param _paneContent - Captured tmux pane content (unused until patterns are known)
|
|
136
|
+
* @returns Always `{ phase: "loading" }` until real patterns are observed
|
|
137
|
+
*/
|
|
138
|
+
detectReady(_paneContent: string): ReadyState {
|
|
139
|
+
// STUB: Real OpenCode TUI ready patterns have not been observed.
|
|
140
|
+
// Fill in once someone runs OpenCode in tmux and captures the pane content.
|
|
141
|
+
return { phase: "loading" };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Parse an OpenCode session transcript into normalized token usage.
|
|
146
|
+
*
|
|
147
|
+
* @stub Returns null unconditionally because the `opencode run --format json`
|
|
148
|
+
* output format has not been verified. Do NOT guess at the format.
|
|
149
|
+
* To implement: run `opencode run --format json` against a real OpenCode install,
|
|
150
|
+
* inspect the NDJSON output, then add parsing logic here.
|
|
151
|
+
*
|
|
152
|
+
* @param _path - Path to transcript file (unused until format is known)
|
|
153
|
+
* @returns Always null until transcript format is verified
|
|
154
|
+
*/
|
|
155
|
+
async parseTranscript(_path: string): Promise<TranscriptSummary | null> {
|
|
156
|
+
// STUB: OpenCode transcript format not yet verified.
|
|
157
|
+
// Fill in once `opencode run --format json` output is inspected.
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Return the transcript directory for OpenCode sessions.
|
|
163
|
+
*
|
|
164
|
+
* @stub Returns null because the location of OpenCode session files has not
|
|
165
|
+
* been verified. Check where OpenCode writes session/history files
|
|
166
|
+
* (e.g. `~/.opencode/`, `<project>/.opencode/`, or similar).
|
|
167
|
+
*
|
|
168
|
+
* @param _projectRoot - Absolute path to the project root (unused until known)
|
|
169
|
+
* @returns Always null until transcript location is verified
|
|
170
|
+
*/
|
|
171
|
+
getTranscriptDir(_projectRoot: string): string | null {
|
|
172
|
+
// STUB: OpenCode transcript directory location not yet verified.
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Build runtime-specific environment variables for model/provider routing.
|
|
178
|
+
*
|
|
179
|
+
* Returns the provider environment variables from the resolved model, or an
|
|
180
|
+
* empty object if none are set.
|
|
181
|
+
*
|
|
182
|
+
* @param model - Resolved model with optional provider env vars
|
|
183
|
+
* @returns Environment variable map (may be empty)
|
|
184
|
+
*/
|
|
185
|
+
buildEnv(model: ResolvedModel): Record<string, string> {
|
|
186
|
+
return model.env ?? {};
|
|
187
|
+
}
|
|
188
|
+
}
|