@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,112 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { c, errorOut, fmt, humanOut, jsonOut } from "../output.ts";
|
|
3
|
+
import { ExitError } from "../types.ts";
|
|
4
|
+
|
|
5
|
+
export default async function sync(args: string[], json: boolean): Promise<void> {
|
|
6
|
+
const cwd = process.cwd();
|
|
7
|
+
|
|
8
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
9
|
+
humanOut(`Usage: tl sync [options]
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
--status Check sync status without committing
|
|
13
|
+
--json Output as JSON`);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const statusOnly = args.includes("--status");
|
|
18
|
+
|
|
19
|
+
// Check git status of .trellis/
|
|
20
|
+
const statusResult = Bun.spawnSync(["git", "status", "--porcelain", ".trellis/"], { cwd });
|
|
21
|
+
|
|
22
|
+
if (statusResult.exitCode !== 0) {
|
|
23
|
+
const stderr = statusResult.stderr.toString();
|
|
24
|
+
if (json) {
|
|
25
|
+
jsonOut({ success: false, command: "sync", error: stderr });
|
|
26
|
+
} else {
|
|
27
|
+
errorOut(`git error: ${stderr}`);
|
|
28
|
+
}
|
|
29
|
+
throw new ExitError(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const statusOutput = statusResult.stdout.toString().trim();
|
|
33
|
+
const changedFiles = statusOutput
|
|
34
|
+
? statusOutput.split("\n").map((line) => line.trim().split(" ").pop() ?? "")
|
|
35
|
+
: [];
|
|
36
|
+
|
|
37
|
+
if (statusOnly) {
|
|
38
|
+
if (json) {
|
|
39
|
+
jsonOut({
|
|
40
|
+
success: true,
|
|
41
|
+
command: "sync",
|
|
42
|
+
uncommitted: changedFiles.length > 0,
|
|
43
|
+
files: changedFiles,
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
if (changedFiles.length === 0) {
|
|
47
|
+
humanOut(fmt.success(".trellis/ is clean (no uncommitted changes)"));
|
|
48
|
+
} else {
|
|
49
|
+
humanOut(fmt.warning(`${changedFiles.length} uncommitted file(s)`));
|
|
50
|
+
for (const f of changedFiles) {
|
|
51
|
+
humanOut(` ${f}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (changedFiles.length === 0) {
|
|
59
|
+
if (json) {
|
|
60
|
+
jsonOut({ success: true, command: "sync", committed: false, message: "Nothing to commit" });
|
|
61
|
+
} else {
|
|
62
|
+
humanOut(c.dim("Nothing to commit in .trellis/"));
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Stage .trellis/ changes
|
|
68
|
+
const addResult = Bun.spawnSync(["git", "add", ".trellis/"], { cwd });
|
|
69
|
+
if (addResult.exitCode !== 0) {
|
|
70
|
+
const err = addResult.stderr.toString();
|
|
71
|
+
if (json) {
|
|
72
|
+
jsonOut({ success: false, command: "sync", error: err });
|
|
73
|
+
} else {
|
|
74
|
+
errorOut(`git add failed: ${err}`);
|
|
75
|
+
}
|
|
76
|
+
throw new ExitError(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Commit
|
|
80
|
+
const msg = `trellis: sync ${new Date().toISOString().slice(0, 10)}`;
|
|
81
|
+
const commitResult = Bun.spawnSync(["git", "commit", "-m", msg], { cwd });
|
|
82
|
+
|
|
83
|
+
if (commitResult.exitCode !== 0) {
|
|
84
|
+
const err = commitResult.stderr.toString();
|
|
85
|
+
if (json) {
|
|
86
|
+
jsonOut({ success: false, command: "sync", error: err });
|
|
87
|
+
} else {
|
|
88
|
+
errorOut(`git commit failed: ${err}`);
|
|
89
|
+
}
|
|
90
|
+
throw new ExitError(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (json) {
|
|
94
|
+
jsonOut({ success: true, command: "sync", committed: true, files: changedFiles, message: msg });
|
|
95
|
+
} else {
|
|
96
|
+
humanOut(fmt.success(`Committed ${changedFiles.length} file(s): ${msg}`));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function registerSyncCommand(program: Command): void {
|
|
101
|
+
program
|
|
102
|
+
.command("sync")
|
|
103
|
+
.description("Stage and commit .trellis/ changes")
|
|
104
|
+
.option("--status", "Check sync status without committing")
|
|
105
|
+
.action(async (options: { status?: boolean }) => {
|
|
106
|
+
const json: boolean = program.opts().json ?? false;
|
|
107
|
+
const args: string[] = [];
|
|
108
|
+
if (options.status) args.push("--status");
|
|
109
|
+
if (json) args.push("--json");
|
|
110
|
+
await sync(args, json);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import type { Command } from "commander";
|
|
3
|
+
import { c, errorOut, humanOut, jsonOut } from "../output.ts";
|
|
4
|
+
import { dedupById, readJsonl } from "../store.ts";
|
|
5
|
+
import type { Prompt } from "../types.ts";
|
|
6
|
+
import { ExitError } from "../types.ts";
|
|
7
|
+
|
|
8
|
+
export default async function tree(args: string[], json: boolean): Promise<void> {
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const promptsPath = join(cwd, ".trellis", "prompts.jsonl");
|
|
11
|
+
|
|
12
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
13
|
+
humanOut(`Usage: tl tree <name> [options]
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--json Output as JSON`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const name = args.filter((a) => !a.startsWith("--"))[0];
|
|
21
|
+
if (!name) {
|
|
22
|
+
if (json) {
|
|
23
|
+
jsonOut({ success: false, command: "tree", error: "Prompt name required" });
|
|
24
|
+
} else {
|
|
25
|
+
errorOut("Usage: tl tree <name>");
|
|
26
|
+
}
|
|
27
|
+
throw new ExitError(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const allRecords = await readJsonl<Prompt>(promptsPath);
|
|
31
|
+
const current = dedupById(allRecords);
|
|
32
|
+
|
|
33
|
+
const prompt = current.find((p) => p.name === name);
|
|
34
|
+
if (!prompt) {
|
|
35
|
+
if (json) {
|
|
36
|
+
jsonOut({ success: false, command: "tree", error: `Prompt '${name}' not found` });
|
|
37
|
+
} else {
|
|
38
|
+
errorOut(`Prompt '${name}' not found`);
|
|
39
|
+
}
|
|
40
|
+
throw new ExitError(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Build ancestry chain (parents via extends)
|
|
44
|
+
const ancestors: string[] = [];
|
|
45
|
+
let cur: Prompt | undefined = prompt;
|
|
46
|
+
while (cur?.extends) {
|
|
47
|
+
const parentName: string = cur.extends;
|
|
48
|
+
if (ancestors.includes(parentName)) break; // cycle guard
|
|
49
|
+
ancestors.push(parentName);
|
|
50
|
+
cur = current.find((p) => p.name === parentName);
|
|
51
|
+
}
|
|
52
|
+
ancestors.reverse();
|
|
53
|
+
|
|
54
|
+
// Collect mixins for the focal prompt
|
|
55
|
+
const mixins: string[] = prompt.mixins ?? [];
|
|
56
|
+
|
|
57
|
+
// Find all descendants (via extends or mixins)
|
|
58
|
+
function getChildren(pname: string): string[] {
|
|
59
|
+
return current.filter((p) => p.extends === pname && p.name !== pname).map((p) => p.name);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getMixinUsers(pname: string): string[] {
|
|
63
|
+
return current.filter((p) => p.mixins?.includes(pname) && p.name !== pname).map((p) => p.name);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (json) {
|
|
67
|
+
const buildTree = (pname: string): object => ({
|
|
68
|
+
name: pname,
|
|
69
|
+
children: getChildren(pname).map(buildTree),
|
|
70
|
+
mixinUsers: getMixinUsers(pname),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
jsonOut({
|
|
74
|
+
success: true,
|
|
75
|
+
command: "tree",
|
|
76
|
+
name,
|
|
77
|
+
ancestors,
|
|
78
|
+
mixins,
|
|
79
|
+
tree: buildTree(name),
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Render ancestors
|
|
85
|
+
for (let i = 0; i < ancestors.length; i++) {
|
|
86
|
+
const indent = " ".repeat(i);
|
|
87
|
+
humanOut(`${indent}${c.dim(ancestors[i] ?? "")}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Render focal node
|
|
91
|
+
const focalIndent = " ".repeat(ancestors.length);
|
|
92
|
+
const mixinLabel = mixins.length > 0 ? c.dim(` + ${mixins.join(", ")}`) : "";
|
|
93
|
+
humanOut(`${focalIndent}${c.bold(c.cyan(name))} ${c.dim(`(v${prompt.version})`)}${mixinLabel}`);
|
|
94
|
+
|
|
95
|
+
// Render children recursively
|
|
96
|
+
function renderChildren(pname: string, depth: number) {
|
|
97
|
+
const children = getChildren(pname);
|
|
98
|
+
for (const child of children) {
|
|
99
|
+
const indent = " ".repeat(depth);
|
|
100
|
+
const childPrompt = current.find((p) => p.name === child);
|
|
101
|
+
const ver = childPrompt ? c.dim(` v${childPrompt.version}`) : "";
|
|
102
|
+
const childMixins = childPrompt?.mixins?.length
|
|
103
|
+
? c.dim(` + ${childPrompt.mixins.join(", ")}`)
|
|
104
|
+
: "";
|
|
105
|
+
humanOut(`${indent}├── ${child}${ver}${childMixins}`);
|
|
106
|
+
renderChildren(child, depth + 1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
renderChildren(name, ancestors.length + 1);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function registerTreeCommand(program: Command): void {
|
|
114
|
+
program
|
|
115
|
+
.command("tree")
|
|
116
|
+
.description("Show inheritance tree for a prompt")
|
|
117
|
+
.argument("<name>", "Prompt name")
|
|
118
|
+
.action(async (name: string) => {
|
|
119
|
+
const json: boolean = program.opts().json ?? false;
|
|
120
|
+
const args = [name, ...(json ? ["--json"] : [])];
|
|
121
|
+
await tree(args, json);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import type { Command } from "commander";
|
|
3
|
+
import { c, errorOut, fmt, humanOut, jsonOut } from "../output.ts";
|
|
4
|
+
import { acquireLock, appendJsonl, dedupById, readJsonl, releaseLock } from "../store.ts";
|
|
5
|
+
import type { Prompt } from "../types.ts";
|
|
6
|
+
import { ExitError } from "../types.ts";
|
|
7
|
+
|
|
8
|
+
export default async function update(args: string[], json: boolean): Promise<void> {
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const promptsPath = join(cwd, ".trellis", "prompts.jsonl");
|
|
11
|
+
|
|
12
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
13
|
+
humanOut(`Usage: tl update <name> [options]
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--name <name> Rename prompt
|
|
17
|
+
--description <text> Update description
|
|
18
|
+
--section <name> --body <text> Update section body
|
|
19
|
+
--section <name>=<text> Update section (shorthand)
|
|
20
|
+
--add-section <name> --body <text> Add new section with body (repeatable)
|
|
21
|
+
--add-section <name>=<text> Add new section (shorthand, repeatable)
|
|
22
|
+
--remove-section <name> Remove section (empty body, repeatable)
|
|
23
|
+
--tag <tag> Add tag (repeatable)
|
|
24
|
+
--untag <tag> Remove tag (repeatable)
|
|
25
|
+
--schema <name> Assign schema
|
|
26
|
+
--extends <name> Change parent
|
|
27
|
+
--mixin <name> Add mixin (repeatable)
|
|
28
|
+
--remove-mixin <name> Remove mixin (repeatable)
|
|
29
|
+
--emit-as <filename> Custom emit filename
|
|
30
|
+
--emit-dir <path> Custom emit directory
|
|
31
|
+
--fm <key=value> Set frontmatter field (repeatable)
|
|
32
|
+
--remove-fm <key> Remove frontmatter field (repeatable)
|
|
33
|
+
--status draft|active|archived Change status
|
|
34
|
+
--json Output as JSON`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const nameArg = args.filter((a) => !a.startsWith("--"))[0];
|
|
39
|
+
if (!nameArg) {
|
|
40
|
+
if (json) {
|
|
41
|
+
jsonOut({ success: false, command: "update", error: "Prompt name required" });
|
|
42
|
+
} else {
|
|
43
|
+
errorOut("Usage: tl update <name> [options]");
|
|
44
|
+
}
|
|
45
|
+
throw new ExitError(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Parse flags
|
|
49
|
+
let sectionName: string | undefined;
|
|
50
|
+
let sectionBody: string | undefined;
|
|
51
|
+
const addSections: Array<{ name: string; body: string }> = [];
|
|
52
|
+
const removeSections: string[] = [];
|
|
53
|
+
const addTags: string[] = [];
|
|
54
|
+
const removeTags: string[] = [];
|
|
55
|
+
let newDescription: string | undefined;
|
|
56
|
+
let newSchema: string | undefined;
|
|
57
|
+
let newExtends: string | undefined;
|
|
58
|
+
const addMixins: string[] = [];
|
|
59
|
+
const removeMixins: string[] = [];
|
|
60
|
+
let newEmitAs: string | undefined;
|
|
61
|
+
let newEmitDir: string | undefined;
|
|
62
|
+
let newStatus: string | undefined;
|
|
63
|
+
let newName: string | undefined;
|
|
64
|
+
const fmUpdates: Record<string, string> = {};
|
|
65
|
+
const fmRemovals: string[] = [];
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < args.length; i++) {
|
|
68
|
+
const arg = args[i];
|
|
69
|
+
if (arg === "--section" && args[i + 1]) {
|
|
70
|
+
const next = args[++i] ?? "";
|
|
71
|
+
const eqIdx = next.indexOf("=");
|
|
72
|
+
if (eqIdx !== -1) {
|
|
73
|
+
// --section name=body shorthand
|
|
74
|
+
sectionName = next.slice(0, eqIdx);
|
|
75
|
+
sectionBody = next.slice(eqIdx + 1);
|
|
76
|
+
} else {
|
|
77
|
+
sectionName = next;
|
|
78
|
+
}
|
|
79
|
+
} else if (arg === "--body" && args[i + 1] !== undefined) {
|
|
80
|
+
// body may be empty string
|
|
81
|
+
sectionBody = args[++i];
|
|
82
|
+
} else if (arg === "--add-section" && args[i + 1]) {
|
|
83
|
+
const next = args[++i] ?? "";
|
|
84
|
+
const eqIdx = next.indexOf("=");
|
|
85
|
+
if (eqIdx !== -1) {
|
|
86
|
+
// --add-section name=body shorthand
|
|
87
|
+
addSections.push({ name: next.slice(0, eqIdx), body: next.slice(eqIdx + 1) });
|
|
88
|
+
} else {
|
|
89
|
+
let body = "";
|
|
90
|
+
// lookahead for --body
|
|
91
|
+
if (args[i + 1] === "--body" && args[i + 2] !== undefined) {
|
|
92
|
+
i++; // skip --body
|
|
93
|
+
body = args[++i] ?? "";
|
|
94
|
+
}
|
|
95
|
+
addSections.push({ name: next, body });
|
|
96
|
+
}
|
|
97
|
+
} else if (arg === "--remove-section" && args[i + 1]) {
|
|
98
|
+
removeSections.push(args[++i] ?? "");
|
|
99
|
+
} else if (arg === "--tag" && args[i + 1]) {
|
|
100
|
+
addTags.push(args[++i] ?? "");
|
|
101
|
+
} else if (arg === "--untag" && args[i + 1]) {
|
|
102
|
+
removeTags.push(args[++i] ?? "");
|
|
103
|
+
} else if (arg === "--description" && args[i + 1]) {
|
|
104
|
+
newDescription = args[++i];
|
|
105
|
+
} else if (arg === "--schema" && args[i + 1]) {
|
|
106
|
+
newSchema = args[++i];
|
|
107
|
+
} else if (arg === "--extends" && args[i + 1]) {
|
|
108
|
+
newExtends = args[++i];
|
|
109
|
+
} else if (arg === "--mixin" && args[i + 1]) {
|
|
110
|
+
addMixins.push(args[++i] ?? "");
|
|
111
|
+
} else if (arg === "--remove-mixin" && args[i + 1]) {
|
|
112
|
+
removeMixins.push(args[++i] ?? "");
|
|
113
|
+
} else if (arg === "--emit-as" && args[i + 1]) {
|
|
114
|
+
newEmitAs = args[++i];
|
|
115
|
+
} else if (arg === "--emit-dir" && args[i + 1]) {
|
|
116
|
+
newEmitDir = args[++i];
|
|
117
|
+
} else if (arg === "--status" && args[i + 1]) {
|
|
118
|
+
newStatus = args[++i];
|
|
119
|
+
} else if (arg === "--name" && args[i + 1]) {
|
|
120
|
+
newName = args[++i];
|
|
121
|
+
} else if (arg === "--fm" && args[i + 1]) {
|
|
122
|
+
const fmArg = args[++i] ?? "";
|
|
123
|
+
const eqIdx = fmArg.indexOf("=");
|
|
124
|
+
if (eqIdx !== -1) {
|
|
125
|
+
fmUpdates[fmArg.slice(0, eqIdx)] = fmArg.slice(eqIdx + 1);
|
|
126
|
+
}
|
|
127
|
+
} else if (arg === "--remove-fm" && args[i + 1]) {
|
|
128
|
+
fmRemovals.push(args[++i] ?? "");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await acquireLock(promptsPath);
|
|
133
|
+
try {
|
|
134
|
+
const allRecords = await readJsonl<Prompt>(promptsPath);
|
|
135
|
+
const current = dedupById(allRecords);
|
|
136
|
+
|
|
137
|
+
const prompt = current.find((p) => p.name === nameArg);
|
|
138
|
+
if (!prompt) {
|
|
139
|
+
if (json) {
|
|
140
|
+
jsonOut({ success: false, command: "update", error: `Prompt '${nameArg}' not found` });
|
|
141
|
+
} else {
|
|
142
|
+
errorOut(`Prompt '${nameArg}' not found`);
|
|
143
|
+
}
|
|
144
|
+
throw new ExitError(1);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Clone and apply mutations
|
|
148
|
+
const updated: Prompt = {
|
|
149
|
+
...prompt,
|
|
150
|
+
sections: [...prompt.sections.map((s) => ({ ...s }))],
|
|
151
|
+
version: prompt.version + 1,
|
|
152
|
+
updatedAt: new Date().toISOString(),
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// Update section body
|
|
156
|
+
if (sectionName !== undefined && sectionBody !== undefined) {
|
|
157
|
+
const idx = updated.sections.findIndex((s) => s.name === sectionName);
|
|
158
|
+
if (idx !== -1) {
|
|
159
|
+
const existing = updated.sections[idx];
|
|
160
|
+
if (existing) updated.sections[idx] = { ...existing, body: sectionBody };
|
|
161
|
+
} else {
|
|
162
|
+
updated.sections.push({ name: sectionName, body: sectionBody });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Add new sections
|
|
167
|
+
for (const { name: addName, body: addBody } of addSections) {
|
|
168
|
+
const existingIdx = updated.sections.findIndex((s) => s.name === addName);
|
|
169
|
+
if (existingIdx !== -1) {
|
|
170
|
+
const existingSec = updated.sections[existingIdx];
|
|
171
|
+
if (existingSec) updated.sections[existingIdx] = { ...existingSec, body: addBody };
|
|
172
|
+
} else {
|
|
173
|
+
updated.sections.push({ name: addName, body: addBody });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Remove sections
|
|
178
|
+
for (const removeName of removeSections) {
|
|
179
|
+
const idx = updated.sections.findIndex((s) => s.name === removeName);
|
|
180
|
+
if (updated.extends) {
|
|
181
|
+
// Inheriting prompt: use empty body to suppress inherited section in render
|
|
182
|
+
if (idx !== -1) {
|
|
183
|
+
const existing = updated.sections[idx];
|
|
184
|
+
if (existing) updated.sections[idx] = { ...existing, body: "" };
|
|
185
|
+
} else {
|
|
186
|
+
updated.sections.push({ name: removeName, body: "" });
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
// Non-inheriting prompt: splice section out entirely
|
|
190
|
+
if (idx !== -1) {
|
|
191
|
+
updated.sections.splice(idx, 1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Tags
|
|
197
|
+
const currentTags = new Set(updated.tags ?? []);
|
|
198
|
+
for (const t of addTags) currentTags.add(t);
|
|
199
|
+
for (const t of removeTags) currentTags.delete(t);
|
|
200
|
+
updated.tags = currentTags.size > 0 ? Array.from(currentTags) : undefined;
|
|
201
|
+
|
|
202
|
+
// Frontmatter updates
|
|
203
|
+
const currentFm = { ...(updated.frontmatter ?? {}) };
|
|
204
|
+
for (const [k, v] of Object.entries(fmUpdates)) currentFm[k] = v;
|
|
205
|
+
for (const k of fmRemovals) delete currentFm[k];
|
|
206
|
+
updated.frontmatter = Object.keys(currentFm).length > 0 ? currentFm : undefined;
|
|
207
|
+
|
|
208
|
+
// Mixins
|
|
209
|
+
if (addMixins.length > 0 || removeMixins.length > 0) {
|
|
210
|
+
const currentMixins = new Set(updated.mixins ?? []);
|
|
211
|
+
for (const m of addMixins) currentMixins.add(m);
|
|
212
|
+
for (const m of removeMixins) currentMixins.delete(m);
|
|
213
|
+
updated.mixins = currentMixins.size > 0 ? Array.from(currentMixins) : undefined;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (newDescription !== undefined) updated.description = newDescription;
|
|
217
|
+
if (newSchema !== undefined) updated.schema = newSchema;
|
|
218
|
+
if (newExtends !== undefined) updated.extends = newExtends;
|
|
219
|
+
if (newEmitAs !== undefined) updated.emitAs = newEmitAs;
|
|
220
|
+
if (newEmitDir !== undefined) updated.emitDir = newEmitDir;
|
|
221
|
+
if (newStatus === "draft" || newStatus === "active" || newStatus === "archived") {
|
|
222
|
+
updated.status = newStatus;
|
|
223
|
+
}
|
|
224
|
+
if (newName !== undefined) updated.name = newName;
|
|
225
|
+
|
|
226
|
+
await appendJsonl(promptsPath, updated);
|
|
227
|
+
|
|
228
|
+
if (json) {
|
|
229
|
+
jsonOut({
|
|
230
|
+
success: true,
|
|
231
|
+
command: "update",
|
|
232
|
+
id: updated.id,
|
|
233
|
+
name: updated.name,
|
|
234
|
+
version: updated.version,
|
|
235
|
+
});
|
|
236
|
+
} else {
|
|
237
|
+
humanOut(`${fmt.success("Updated")} ${c.bold(updated.name)} → v${updated.version}`);
|
|
238
|
+
}
|
|
239
|
+
} finally {
|
|
240
|
+
releaseLock(promptsPath);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function registerUpdateCommand(program: Command): void {
|
|
245
|
+
program
|
|
246
|
+
.command("update")
|
|
247
|
+
.description("Update a prompt (creates new version)")
|
|
248
|
+
.argument("<name>", "Prompt name")
|
|
249
|
+
.option("--name <name>", "Rename prompt")
|
|
250
|
+
.option("--description <text>", "Update description")
|
|
251
|
+
.option("--section <name>", "Section to update (use with --body or name=body shorthand)")
|
|
252
|
+
.option("--body <text>", "New body for the section specified by --section")
|
|
253
|
+
.option(
|
|
254
|
+
"--add-section <name>",
|
|
255
|
+
"Add a new section (use name=body shorthand, repeatable)",
|
|
256
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
257
|
+
[] as string[],
|
|
258
|
+
)
|
|
259
|
+
.option(
|
|
260
|
+
"--remove-section <name>",
|
|
261
|
+
"Remove a section (sets body to empty, repeatable)",
|
|
262
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
263
|
+
[] as string[],
|
|
264
|
+
)
|
|
265
|
+
.option(
|
|
266
|
+
"--tag <tag>",
|
|
267
|
+
"Add tag (repeatable)",
|
|
268
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
269
|
+
[] as string[],
|
|
270
|
+
)
|
|
271
|
+
.option(
|
|
272
|
+
"--untag <tag>",
|
|
273
|
+
"Remove tag (repeatable)",
|
|
274
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
275
|
+
[] as string[],
|
|
276
|
+
)
|
|
277
|
+
.option("--schema <name>", "Assign schema")
|
|
278
|
+
.option("--extends <name>", "Change parent prompt")
|
|
279
|
+
.option(
|
|
280
|
+
"--mixin <name>",
|
|
281
|
+
"Add mixin (repeatable)",
|
|
282
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
283
|
+
[] as string[],
|
|
284
|
+
)
|
|
285
|
+
.option(
|
|
286
|
+
"--remove-mixin <name>",
|
|
287
|
+
"Remove mixin (repeatable)",
|
|
288
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
289
|
+
[] as string[],
|
|
290
|
+
)
|
|
291
|
+
.option("--emit-as <filename>", "Custom emit filename")
|
|
292
|
+
.option("--emit-dir <path>", "Custom emit directory")
|
|
293
|
+
.option("--status <status>", "Change status (draft|active|archived)")
|
|
294
|
+
.option(
|
|
295
|
+
"--fm <key=value>",
|
|
296
|
+
"Set frontmatter field (repeatable)",
|
|
297
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
298
|
+
[] as string[],
|
|
299
|
+
)
|
|
300
|
+
.option(
|
|
301
|
+
"--remove-fm <key>",
|
|
302
|
+
"Remove frontmatter field (repeatable)",
|
|
303
|
+
(v: string, a: string[]) => a.concat([v]),
|
|
304
|
+
[] as string[],
|
|
305
|
+
)
|
|
306
|
+
.action(async (nameArg: string, opts: Record<string, unknown>) => {
|
|
307
|
+
const json: boolean = program.opts().json ?? false;
|
|
308
|
+
const args: string[] = [nameArg];
|
|
309
|
+
if (opts.name) args.push("--name", opts.name as string);
|
|
310
|
+
if (opts.description) args.push("--description", opts.description as string);
|
|
311
|
+
if (opts.section) {
|
|
312
|
+
args.push("--section", opts.section as string);
|
|
313
|
+
if (opts.body !== undefined) args.push("--body", opts.body as string);
|
|
314
|
+
}
|
|
315
|
+
for (const sec of opts.addSection as string[]) args.push("--add-section", sec);
|
|
316
|
+
for (const sec of opts.removeSection as string[]) args.push("--remove-section", sec);
|
|
317
|
+
for (const tag of opts.tag as string[]) args.push("--tag", tag);
|
|
318
|
+
for (const tag of opts.untag as string[]) args.push("--untag", tag);
|
|
319
|
+
if (opts.schema) args.push("--schema", opts.schema as string);
|
|
320
|
+
if (opts.extends) args.push("--extends", opts.extends as string);
|
|
321
|
+
for (const mixin of opts.mixin as string[]) args.push("--mixin", mixin);
|
|
322
|
+
for (const mixin of opts.removeMixin as string[]) args.push("--remove-mixin", mixin);
|
|
323
|
+
if (opts.emitAs) args.push("--emit-as", opts.emitAs as string);
|
|
324
|
+
if (opts.emitDir) args.push("--emit-dir", opts.emitDir as string);
|
|
325
|
+
if (opts.status) args.push("--status", opts.status as string);
|
|
326
|
+
for (const fm of opts.fm as string[]) args.push("--fm", fm);
|
|
327
|
+
for (const key of opts.removeFm as string[]) args.push("--remove-fm", key);
|
|
328
|
+
await update(args, json);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import type { Command } from "commander";
|
|
3
|
+
import { VERSION } from "../../../version.ts";
|
|
4
|
+
import { humanOut, jsonOut } from "../output.ts";
|
|
5
|
+
|
|
6
|
+
// trellis is bundled in @ag-eco/agentplate-cli; upgrading is `ap upgrade`.
|
|
7
|
+
const PACKAGE_NAME = "@ag-eco/agentplate-cli";
|
|
8
|
+
|
|
9
|
+
async function getCurrentVersion(): Promise<string> {
|
|
10
|
+
return VERSION;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function fetchLatestVersion(): Promise<string> {
|
|
14
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`);
|
|
15
|
+
if (!res.ok) throw new Error(`Failed to fetch npm registry: ${res.status} ${res.statusText}`);
|
|
16
|
+
const data = (await res.json()) as { version: string };
|
|
17
|
+
return data.version;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function run(args: string[]): Promise<void> {
|
|
21
|
+
const jsonMode = args.includes("--json");
|
|
22
|
+
const checkOnly = args.includes("--check");
|
|
23
|
+
|
|
24
|
+
const [current, latest] = await Promise.all([getCurrentVersion(), fetchLatestVersion()]);
|
|
25
|
+
const upToDate = current === latest;
|
|
26
|
+
|
|
27
|
+
if (checkOnly) {
|
|
28
|
+
if (jsonMode) {
|
|
29
|
+
jsonOut({ success: true, command: "upgrade", current, latest, upToDate });
|
|
30
|
+
} else {
|
|
31
|
+
if (upToDate) {
|
|
32
|
+
humanOut(`${chalk.green("✔")} Already up to date (${current})`);
|
|
33
|
+
} else {
|
|
34
|
+
humanOut(`${chalk.yellow("!")} Update available: ${current} → ${latest}`);
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (upToDate) {
|
|
42
|
+
if (jsonMode) {
|
|
43
|
+
jsonOut({
|
|
44
|
+
success: true,
|
|
45
|
+
command: "upgrade",
|
|
46
|
+
current,
|
|
47
|
+
latest,
|
|
48
|
+
upToDate: true,
|
|
49
|
+
updated: false,
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
humanOut(`${chalk.green("✔")} Already up to date (${current})`);
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!jsonMode) {
|
|
58
|
+
humanOut(`Upgrading ${PACKAGE_NAME} from ${current} to ${latest}...`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const result = Bun.spawnSync(["bun", "install", "-g", `${PACKAGE_NAME}@latest`], {
|
|
62
|
+
stdout: "inherit",
|
|
63
|
+
stderr: "inherit",
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (result.exitCode !== 0) {
|
|
67
|
+
throw new Error(`bun install failed with exit code ${result.exitCode}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (jsonMode) {
|
|
71
|
+
jsonOut({
|
|
72
|
+
success: true,
|
|
73
|
+
command: "upgrade",
|
|
74
|
+
current,
|
|
75
|
+
latest,
|
|
76
|
+
upToDate: false,
|
|
77
|
+
updated: true,
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
humanOut(`${chalk.green("✔")} Upgraded to ${latest}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function registerUpgradeCommand(program: Command): void {
|
|
85
|
+
program
|
|
86
|
+
.command("upgrade")
|
|
87
|
+
.description("Upgrade trellis to the latest version from npm")
|
|
88
|
+
.option("--check", "Check for updates without installing")
|
|
89
|
+
.action(async (opts: { check?: boolean }) => {
|
|
90
|
+
const args: string[] = [];
|
|
91
|
+
if (opts.check) args.push("--check");
|
|
92
|
+
if (program.opts().json) args.push("--json");
|
|
93
|
+
await run(args);
|
|
94
|
+
});
|
|
95
|
+
}
|