@xulthekl/team-flow 0.22.4

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.
Files changed (405) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.agents/skills +1 -0
  3. package/.claude/always/phase-guard.md +3 -0
  4. package/.claude-plugin/marketplace.json +20 -0
  5. package/.claude-plugin/plugin.json +31 -0
  6. package/.codex-plugin/plugin.json +45 -0
  7. package/.codexignore +6 -0
  8. package/.cursor-plugin/marketplace.json +17 -0
  9. package/.cursor-plugin/plugin.json +31 -0
  10. package/.github/copilot-instructions.md +15 -0
  11. package/.github/dependabot.yml +10 -0
  12. package/.github/plugin/marketplace.json +42 -0
  13. package/.github/workflows/ci.yml +98 -0
  14. package/.github/workflows/hol-plugin-scanner.yml +17 -0
  15. package/.opencode/INSTALL.md +61 -0
  16. package/.opencode/plugins/team-flow.js +70 -0
  17. package/AGENTS.md +280 -0
  18. package/CHANGELOG.md +635 -0
  19. package/CONTRIBUTING.md +115 -0
  20. package/GEMINI.md +14 -0
  21. package/HANDOFF.md +219 -0
  22. package/INSTALL.md +810 -0
  23. package/LICENSE +21 -0
  24. package/README.md +185 -0
  25. package/SECURITY.md +37 -0
  26. package/agents/bug-investigator.md +180 -0
  27. package/agents/change-split-auditor.md +257 -0
  28. package/agents/code-reviewer.md +171 -0
  29. package/agents/cross-change-consistency-checker.md +215 -0
  30. package/agents/prd-completeness-reviewer.md +197 -0
  31. package/agents/prototype-builder.md +230 -0
  32. package/agents/prototype-env-scout.md +156 -0
  33. package/agents/prototype-reviewer.md +226 -0
  34. package/assets/icon.svg +6 -0
  35. package/dist/index.d.ts +13 -0
  36. package/dist/index.js +5 -0
  37. package/dist/parsing/change-parser.d.ts +12 -0
  38. package/dist/parsing/change-parser.js +54 -0
  39. package/dist/parsing/requirement-blocks.d.ts +31 -0
  40. package/dist/parsing/requirement-blocks.js +192 -0
  41. package/dist/schema/base.d.ts +7 -0
  42. package/dist/schema/base.js +1 -0
  43. package/dist/schema/change.d.ts +25 -0
  44. package/dist/schema/change.js +1 -0
  45. package/dist/schema/index.d.ts +3 -0
  46. package/dist/schema/index.js +1 -0
  47. package/dist/schema/spec.d.ts +11 -0
  48. package/dist/schema/spec.js +1 -0
  49. package/dist/validation/constants.d.ts +42 -0
  50. package/dist/validation/constants.js +42 -0
  51. package/dist/validation/tokenizer.d.ts +17 -0
  52. package/dist/validation/tokenizer.js +173 -0
  53. package/dist/validation/types.d.ts +40 -0
  54. package/dist/validation/types.js +1 -0
  55. package/dist/validation/validator.d.ts +21 -0
  56. package/dist/validation/validator.js +489 -0
  57. package/docs/README_en.md +358 -0
  58. package/docs/artifact-contract.md +96 -0
  59. package/docs/decision-points.md +88 -0
  60. package/docs/e2e-integration-design.md +207 -0
  61. package/docs/examples/README.md +25 -0
  62. package/docs/examples/add-dark-mode/README.md +13 -0
  63. package/docs/examples/add-dark-mode/design.md +49 -0
  64. package/docs/examples/add-dark-mode/execution-contract.md +56 -0
  65. package/docs/examples/add-dark-mode/proposal.md +46 -0
  66. package/docs/examples/add-dark-mode/specs/ui-theme/spec.md +35 -0
  67. package/docs/examples/add-dark-mode/tasks.md +26 -0
  68. package/docs/examples/refactor-auth-boundary/README.md +15 -0
  69. package/docs/examples/refactor-auth-boundary/design.md +41 -0
  70. package/docs/examples/refactor-auth-boundary/execution-contract.md +61 -0
  71. package/docs/examples/refactor-auth-boundary/proposal.md +47 -0
  72. package/docs/examples/refactor-auth-boundary/specs/auth-boundary/spec.md +45 -0
  73. package/docs/examples/refactor-auth-boundary/tasks.md +25 -0
  74. package/docs/plans/2026-07-07-fix-batch-design.md +68 -0
  75. package/docs/plans/2026-07-20-001-refactor-skill-collaboration-protocol-plan.md +128 -0
  76. package/docs/platform-matrix.md +45 -0
  77. package/docs/prototype-design-research.md +206 -0
  78. package/docs/release-checklist.md +96 -0
  79. package/docs/showcase.html +699 -0
  80. package/docs/skill-rename-v0.8.0.md +49 -0
  81. package/docs/state-machine.md +162 -0
  82. package/gemini-extension.json +6 -0
  83. package/hooks/hooks-cursor.json +8 -0
  84. package/hooks/hooks.json +26 -0
  85. package/hooks/pre-tool-use-guard +116 -0
  86. package/hooks/session-start +14 -0
  87. package/llms.txt +51 -0
  88. package/package.json +48 -0
  89. package/plugin.json +27 -0
  90. package/prd/v1/plan.md +443 -0
  91. package/prd/v1/prd.md +580 -0
  92. package/scripts/check-update.mjs +91 -0
  93. package/scripts/check-version-consistency.mjs +345 -0
  94. package/scripts/ensure-branch.mjs +71 -0
  95. package/scripts/get-config +31 -0
  96. package/scripts/guard/checks/artifacts-exist.mjs +36 -0
  97. package/scripts/guard/checks/contract-current.mjs +33 -0
  98. package/scripts/guard/checks/contract-fresh.mjs +17 -0
  99. package/scripts/guard/checks/dp-gate-passed.mjs +35 -0
  100. package/scripts/guard/checks/dp3-approved.mjs +22 -0
  101. package/scripts/guard/checks/execution-plan-ready.mjs +40 -0
  102. package/scripts/guard/checks/execution-reviews-passed.mjs +36 -0
  103. package/scripts/guard/checks/schema-valid.mjs +63 -0
  104. package/scripts/guard/checks/specs-merged.mjs +51 -0
  105. package/scripts/guard/checks/tasks-complete.mjs +31 -0
  106. package/scripts/guard/checks/tests-passing.mjs +31 -0
  107. package/scripts/guard/design-token-guard.mjs +237 -0
  108. package/scripts/guard/guard.mjs +205 -0
  109. package/scripts/infer-workflow.mjs +136 -0
  110. package/scripts/install-amazon-q.mjs +9 -0
  111. package/scripts/install-cline.mjs +9 -0
  112. package/scripts/install-continue.mjs +9 -0
  113. package/scripts/install-cursor.mjs +265 -0
  114. package/scripts/install-git-hooks.mjs +82 -0
  115. package/scripts/install-kiro.mjs +9 -0
  116. package/scripts/install-pi.mjs +9 -0
  117. package/scripts/install-qoder.mjs +9 -0
  118. package/scripts/install-qwen.mjs +9 -0
  119. package/scripts/install-roocode.mjs +9 -0
  120. package/scripts/install-windsurf.mjs +9 -0
  121. package/scripts/install-zcode.mjs +265 -0
  122. package/scripts/lib/cmd-audit.mjs +127 -0
  123. package/scripts/lib/cmd-checkpoint.mjs +118 -0
  124. package/scripts/lib/cmd-config.mjs +88 -0
  125. package/scripts/lib/cmd-doctor.mjs +267 -0
  126. package/scripts/lib/cmd-execution.mjs +206 -0
  127. package/scripts/lib/cmd-handoff.mjs +94 -0
  128. package/scripts/lib/cmd-inject.mjs +310 -0
  129. package/scripts/lib/cmd-install-amazon-q.mjs +11 -0
  130. package/scripts/lib/cmd-install-cline.mjs +11 -0
  131. package/scripts/lib/cmd-install-continue.mjs +11 -0
  132. package/scripts/lib/cmd-install-cursor.mjs +14 -0
  133. package/scripts/lib/cmd-install-kiro.mjs +11 -0
  134. package/scripts/lib/cmd-install-pi.mjs +11 -0
  135. package/scripts/lib/cmd-install-qoder.mjs +11 -0
  136. package/scripts/lib/cmd-install-qwen.mjs +11 -0
  137. package/scripts/lib/cmd-install-roocode.mjs +11 -0
  138. package/scripts/lib/cmd-install-windsurf.mjs +11 -0
  139. package/scripts/lib/cmd-install-workbuddy.mjs +359 -0
  140. package/scripts/lib/cmd-install-zcode.mjs +14 -0
  141. package/scripts/lib/cmd-isolate.mjs +37 -0
  142. package/scripts/lib/cmd-list.mjs +71 -0
  143. package/scripts/lib/cmd-runtime.mjs +85 -0
  144. package/scripts/lib/cmd-solutions.mjs +71 -0
  145. package/scripts/lib/cmd-state.mjs +231 -0
  146. package/scripts/lib/cmd-sync.mjs +102 -0
  147. package/scripts/lib/cmd-validate.mjs +105 -0
  148. package/scripts/lib/cmd-version.mjs +148 -0
  149. package/scripts/lib/config-loader.mjs +107 -0
  150. package/scripts/lib/execution-plan.mjs +492 -0
  151. package/scripts/lib/execution-recommendation.mjs +221 -0
  152. package/scripts/lib/hash.mjs +74 -0
  153. package/scripts/lib/install.mjs +267 -0
  154. package/scripts/lib/platform-runtime-inventory.mjs +27 -0
  155. package/scripts/lib/platforms.mjs +165 -0
  156. package/scripts/lib/prototype-sync.mjs +192 -0
  157. package/scripts/lib/sdd-overlay.mjs +262 -0
  158. package/scripts/lib/shell-quote.mjs +4 -0
  159. package/scripts/lib/solutions-capture.mjs +102 -0
  160. package/scripts/lib/solutions-index-gen.mjs +112 -0
  161. package/scripts/lib/solutions-inject.mjs +77 -0
  162. package/scripts/lib/solutions-promote.mjs +145 -0
  163. package/scripts/lib/spec-paths.mjs +85 -0
  164. package/scripts/lib/state-loader.mjs +154 -0
  165. package/scripts/lint/lint-skills.mjs +149 -0
  166. package/scripts/lint/rules/behavior-consistency.mjs +56 -0
  167. package/scripts/lint/rules/dp-trigger-points.mjs +60 -0
  168. package/scripts/lint/rules/exception-handling.mjs +59 -0
  169. package/scripts/lint/rules/no-contradictory-instructions.mjs +67 -0
  170. package/scripts/lint/rules/no-redundant-checks.mjs +50 -0
  171. package/scripts/lint/rules/token-rules.mjs +122 -0
  172. package/scripts/review-package +44 -0
  173. package/scripts/task-brief +40 -0
  174. package/scripts/team-flow.mjs +164 -0
  175. package/scripts/token-baseline.mjs +158 -0
  176. package/scripts/validate-artifacts +96 -0
  177. package/scripts/verify-marketplace-release.mjs +59 -0
  178. package/skills/architecture-design/SKILL.md +140 -0
  179. package/skills/architecture-design/chapters/ch01-4a-domains.md +27 -0
  180. package/skills/architecture-design/chapters/ch02-change-cascade.md +27 -0
  181. package/skills/architecture-design/chapters/ch03-architecture-outputs.md +25 -0
  182. package/skills/architecture-design/chapters/ch04-entity-to-aggregate.md +27 -0
  183. package/skills/architecture-design/chapters/ch05-cqrs.md +32 -0
  184. package/skills/architecture-design/chapters/ch06-integration.md +54 -0
  185. package/skills/architecture-design/cheatsheet.md +51 -0
  186. package/skills/architecture-design/glossary.md +23 -0
  187. package/skills/architecture-design/patterns.md +32 -0
  188. package/skills/bug-investigator/SKILL.md +77 -0
  189. package/skills/build-executor/SKILL.md +163 -0
  190. package/skills/build-executor/implementer-prompt.md +162 -0
  191. package/skills/build-executor/references/execution-modes.md +86 -0
  192. package/skills/build-executor/task-reviewer-prompt.md +195 -0
  193. package/skills/ce-brainstorm/SKILL.md +415 -0
  194. package/skills/ce-brainstorm/references/agents/slack-researcher.md +127 -0
  195. package/skills/ce-brainstorm/references/blindspot-pass.md +70 -0
  196. package/skills/ce-brainstorm/references/brainstorm-sections.md +285 -0
  197. package/skills/ce-brainstorm/references/handoff.md +168 -0
  198. package/skills/ce-brainstorm/references/html-rendering.md +634 -0
  199. package/skills/ce-brainstorm/references/markdown-rendering.md +241 -0
  200. package/skills/ce-brainstorm/references/model-tiers.md +9 -0
  201. package/skills/ce-brainstorm/references/prd-mapping.md +71 -0
  202. package/skills/ce-brainstorm/references/product-pressure-test.md +42 -0
  203. package/skills/ce-brainstorm/references/reasoning-elevation.md +63 -0
  204. package/skills/ce-brainstorm/references/settled-decisions.md +45 -0
  205. package/skills/ce-brainstorm/references/synthesis-summary.md +282 -0
  206. package/skills/ce-brainstorm/references/universal-brainstorming.md +73 -0
  207. package/skills/ce-brainstorm/references/verdict-routing.md +26 -0
  208. package/skills/ce-brainstorm/references/visual-probes.md +158 -0
  209. package/skills/ce-brainstorm/scripts/visual-probe-server.js +418 -0
  210. package/skills/ce-compound/SKILL.md +114 -0
  211. package/skills/ce-compound/assets/resolution-template.md +94 -0
  212. package/skills/ce-compound/references/agents/best-practices-researcher.md +115 -0
  213. package/skills/ce-compound/references/agents/data-integrity-guardian.md +68 -0
  214. package/skills/ce-compound/references/agents/framework-docs-researcher.md +93 -0
  215. package/skills/ce-compound/references/agents/pattern-recognition-specialist.md +55 -0
  216. package/skills/ce-compound/references/agents/performance-oracle.md +108 -0
  217. package/skills/ce-compound/references/agents/security-sentinel.md +91 -0
  218. package/skills/ce-compound/references/agents/session-historian.md +83 -0
  219. package/skills/ce-compound/references/concepts-vocabulary.md +78 -0
  220. package/skills/ce-compound/references/full-mode-workflow.md +413 -0
  221. package/skills/ce-compound/references/grounding-validation.md +84 -0
  222. package/skills/ce-compound/references/lightweight-mode.md +53 -0
  223. package/skills/ce-compound/references/output-standards.md +182 -0
  224. package/skills/ce-compound/references/promotion-rules.md +38 -0
  225. package/skills/ce-compound/references/schema.yaml +231 -0
  226. package/skills/ce-compound/references/three-tier-index.md +55 -0
  227. package/skills/ce-compound/references/v0.5-upgrade.md +32 -0
  228. package/skills/ce-compound/references/write-flow.md +36 -0
  229. package/skills/ce-compound/references/yaml-schema.md +118 -0
  230. package/skills/ce-compound/scripts/session-history/discover-sessions.sh +130 -0
  231. package/skills/ce-compound/scripts/session-history/extract-errors.py +254 -0
  232. package/skills/ce-compound/scripts/session-history/extract-metadata.py +456 -0
  233. package/skills/ce-compound/scripts/session-history/extract-skeleton.py +575 -0
  234. package/skills/ce-compound/scripts/validate-doc-claims.py +346 -0
  235. package/skills/ce-compound/scripts/validate-frontmatter.py +137 -0
  236. package/skills/ce-ideate/SKILL.md +402 -0
  237. package/skills/ce-ideate/references/agents/issue-intelligence-analyst.md +200 -0
  238. package/skills/ce-ideate/references/agents/learnings-researcher.md +247 -0
  239. package/skills/ce-ideate/references/agents/slack-researcher.md +127 -0
  240. package/skills/ce-ideate/references/agents/web-researcher.md +121 -0
  241. package/skills/ce-ideate/references/divergent-ideation.md +89 -0
  242. package/skills/ce-ideate/references/html-rendering.md +634 -0
  243. package/skills/ce-ideate/references/ideation-sections.md +191 -0
  244. package/skills/ce-ideate/references/markdown-rendering.md +238 -0
  245. package/skills/ce-ideate/references/post-ideation-workflow.md +167 -0
  246. package/skills/ce-ideate/references/universal-ideation.md +107 -0
  247. package/skills/ce-ideate/references/web-research-cache.md +56 -0
  248. package/skills/ce-plan/SKILL.md +137 -0
  249. package/skills/ce-plan/references/agents/agent-native-planning-strategist.md +62 -0
  250. package/skills/ce-plan/references/agents/architecture-strategist.md +46 -0
  251. package/skills/ce-plan/references/agents/best-practices-researcher.md +114 -0
  252. package/skills/ce-plan/references/agents/data-integrity-guardian.md +68 -0
  253. package/skills/ce-plan/references/agents/data-migration-reviewer.md +103 -0
  254. package/skills/ce-plan/references/agents/deployment-verification-agent.md +157 -0
  255. package/skills/ce-plan/references/agents/framework-docs-researcher.md +93 -0
  256. package/skills/ce-plan/references/agents/git-history-analyzer.md +40 -0
  257. package/skills/ce-plan/references/agents/learnings-researcher.md +247 -0
  258. package/skills/ce-plan/references/agents/pattern-recognition-specialist.md +55 -0
  259. package/skills/ce-plan/references/agents/performance-oracle.md +108 -0
  260. package/skills/ce-plan/references/agents/repo-research-analyst.md +258 -0
  261. package/skills/ce-plan/references/agents/security-sentinel.md +91 -0
  262. package/skills/ce-plan/references/agents/slack-researcher.md +127 -0
  263. package/skills/ce-plan/references/agents/spec-flow-analyzer.md +80 -0
  264. package/skills/ce-plan/references/agents/web-researcher.md +121 -0
  265. package/skills/ce-plan/references/approach-altitude.md +55 -0
  266. package/skills/ce-plan/references/change-splitting.md +65 -0
  267. package/skills/ce-plan/references/completion-contract.md +33 -0
  268. package/skills/ce-plan/references/core-principles.md +40 -0
  269. package/skills/ce-plan/references/deepening-workflow.md +263 -0
  270. package/skills/ce-plan/references/dependency-graph.md +36 -0
  271. package/skills/ce-plan/references/html-rendering.md +634 -0
  272. package/skills/ce-plan/references/intake-routing.md +189 -0
  273. package/skills/ce-plan/references/markdown-rendering.md +238 -0
  274. package/skills/ce-plan/references/plan-handoff.md +150 -0
  275. package/skills/ce-plan/references/plan-sections.md +427 -0
  276. package/skills/ce-plan/references/plan-structure.md +120 -0
  277. package/skills/ce-plan/references/planning-modes.md +69 -0
  278. package/skills/ce-plan/references/reasoning-elevation.md +63 -0
  279. package/skills/ce-plan/references/research-workflow.md +165 -0
  280. package/skills/ce-plan/references/review-and-write.md +127 -0
  281. package/skills/ce-plan/references/settled-decisions.md +45 -0
  282. package/skills/ce-plan/references/synthesis-summary.md +418 -0
  283. package/skills/ce-plan/references/universal-planning.md +168 -0
  284. package/skills/ce-proof/SKILL.md +346 -0
  285. package/skills/ce-strategy/SKILL.md +97 -0
  286. package/skills/ce-strategy/references/interview.md +143 -0
  287. package/skills/ce-strategy/references/strategy-template.md +89 -0
  288. package/skills/code-reviewer/SKILL.md +84 -0
  289. package/skills/code-reviewer/code-reviewer-prompt.md +195 -0
  290. package/skills/contract-builder/SKILL.md +72 -0
  291. package/skills/design-system/SKILL.md +75 -0
  292. package/skills/design-system/references/agents/design-system-architect.md +138 -0
  293. package/skills/design-system/references/creation-flow.md +170 -0
  294. package/skills/design-system/references/preview-template.html +319 -0
  295. package/skills/design-system/references/token-derivation.md +115 -0
  296. package/skills/design-system/references/variant-schema.md +60 -0
  297. package/skills/e2e/SKILL.md +56 -0
  298. package/skills/e2e/references/test-verifier.md +40 -0
  299. package/skills/need-explorer/SKILL.md +79 -0
  300. package/skills/prototype/SKILL.md +98 -0
  301. package/skills/prototype/references/agents/design-system-architect.md +122 -0
  302. package/skills/prototype/references/checklist.md +82 -0
  303. package/skills/prototype/references/craft/accessibility-baseline.md +71 -0
  304. package/skills/prototype/references/craft/anti-ai-slop.md +87 -0
  305. package/skills/prototype/references/craft/laws-of-ux.md +60 -0
  306. package/skills/prototype/references/craft/state-coverage.md +81 -0
  307. package/skills/prototype/references/craft/typography-hierarchy.md +50 -0
  308. package/skills/prototype/references/layouts.md +223 -0
  309. package/skills/prototype/references/orchestration-flow.md +101 -0
  310. package/skills/prototype/references/prototype-scaffold/assets/design-tokens.css +19 -0
  311. package/skills/prototype/references/prototype-scaffold/components/button.html +3 -0
  312. package/skills/prototype/references/prototype-scaffold/design-system.md +7 -0
  313. package/skills/prototype/references/prototype-scaffold/flow.md +11 -0
  314. package/skills/prototype/references/prototype-scaffold/index.html +20 -0
  315. package/skills/prototype/references/prototype-scaffold/pages/index.html +11 -0
  316. package/skills/prototype/references/template.html +396 -0
  317. package/skills/release-archivist/SKILL.md +166 -0
  318. package/skills/release-archivist/references/closing-procedures.md +81 -0
  319. package/skills/session-handoff/SKILL.md +110 -0
  320. package/skills/session-handoff/references/context-extraction.md +70 -0
  321. package/skills/session-handoff/references/handoff-template.md +90 -0
  322. package/skills/session-handoff/references/skill-recommendation.md +43 -0
  323. package/skills/spec-merger/SKILL.md +66 -0
  324. package/skills/spec-writer/SKILL.md +149 -0
  325. package/skills/workflow-bootstrap/SKILL.md +148 -0
  326. package/skills/workflow-bootstrap/references/agents/codebase-recon-analyst.md +121 -0
  327. package/skills/workflow-bootstrap/references/b1-reconnaissance.md +80 -0
  328. package/skills/workflow-bootstrap/scripts/recon-probe.sh +328 -0
  329. package/skills/workflow-feedback/SKILL.md +120 -0
  330. package/skills/workflow-feedback/references/category-guide.md +121 -0
  331. package/skills/workflow-feedback/references/feedback-template.md +73 -0
  332. package/skills/workflow-feedback/references/review-mode.md +92 -0
  333. package/skills/workflow-orchestrator/SKILL.md +94 -0
  334. package/skills/workflow-orchestrator/references/feedback-loops.md +56 -0
  335. package/skills/workflow-orchestrator/references/s1-path-router.md +81 -0
  336. package/skills/workflow-orchestrator/references/s2-prd-prototype-loop.md +96 -0
  337. package/skills/workflow-orchestrator/references/s3-plan-pipeline.md +50 -0
  338. package/skills/workflow-orchestrator/references/s4-split-validate.md +108 -0
  339. package/skills/workflow-orchestrator/references/s5-monitoring.md +61 -0
  340. package/skills/workflow-orchestrator/references/state-model.md +185 -0
  341. package/skills/workflow-start/SKILL.md +147 -0
  342. package/skills/workflow-start/references/routing-rules.md +155 -0
  343. package/src/index.ts +16 -0
  344. package/src/parsing/change-parser.ts +79 -0
  345. package/src/parsing/requirement-blocks.ts +244 -0
  346. package/src/schema/base.ts +8 -0
  347. package/src/schema/change.ts +29 -0
  348. package/src/schema/index.ts +3 -0
  349. package/src/schema/spec.ts +12 -0
  350. package/src/validation/constants.ts +53 -0
  351. package/src/validation/tokenizer.ts +180 -0
  352. package/src/validation/types.ts +47 -0
  353. package/src/validation/validator.ts +552 -0
  354. package/templates/abandonment-summary.md +29 -0
  355. package/templates/design.md +37 -0
  356. package/templates/execution-contract.md +99 -0
  357. package/templates/plan.md +86 -0
  358. package/templates/prd.md +468 -0
  359. package/templates/proposal.md +37 -0
  360. package/templates/spec.md +31 -0
  361. package/templates/tasks.md +47 -0
  362. package/tests/e2e.test.mjs +266 -0
  363. package/tests/lib/cmd-audit.test.mjs +202 -0
  364. package/tests/lib/cmd-checkpoint.test.mjs +98 -0
  365. package/tests/lib/cmd-config.test.mjs +101 -0
  366. package/tests/lib/cmd-doctor.test.mjs +450 -0
  367. package/tests/lib/cmd-execution.test.mjs +647 -0
  368. package/tests/lib/cmd-handoff.test.mjs +137 -0
  369. package/tests/lib/cmd-inject.test.mjs +218 -0
  370. package/tests/lib/cmd-install-workbuddy.test.mjs +113 -0
  371. package/tests/lib/cmd-install-zcode.test.mjs +42 -0
  372. package/tests/lib/cmd-isolate.test.mjs +68 -0
  373. package/tests/lib/cmd-list.test.mjs +127 -0
  374. package/tests/lib/cmd-runtime.test.mjs +83 -0
  375. package/tests/lib/cmd-state-missing.test.mjs +65 -0
  376. package/tests/lib/cmd-state.test.mjs +365 -0
  377. package/tests/lib/cmd-sync-paths.test.mjs +84 -0
  378. package/tests/lib/cmd-validate-paths.test.mjs +90 -0
  379. package/tests/lib/config-loader.test.mjs +175 -0
  380. package/tests/lib/ensure-branch.test.mjs +59 -0
  381. package/tests/lib/execution-control-plane.test.mjs +168 -0
  382. package/tests/lib/execution-plan.test.mjs +474 -0
  383. package/tests/lib/guard-specs-merged.test.mjs +108 -0
  384. package/tests/lib/guard-tests-passing.test.mjs +112 -0
  385. package/tests/lib/guard-transitions.test.mjs +262 -0
  386. package/tests/lib/guard.test.mjs +611 -0
  387. package/tests/lib/hash.test.mjs +138 -0
  388. package/tests/lib/infer-workflow.test.mjs +161 -0
  389. package/tests/lib/install-git-hooks.test.mjs +20 -0
  390. package/tests/lib/marketplace-release-docs.test.mjs +31 -0
  391. package/tests/lib/minimality-discipline.test.mjs +37 -0
  392. package/tests/lib/model-profiles-docs.test.mjs +33 -0
  393. package/tests/lib/node20-compatibility.test.mjs +73 -0
  394. package/tests/lib/node20-test-entry.test.mjs +17 -0
  395. package/tests/lib/platform-runtime-distribution.test.mjs +150 -0
  396. package/tests/lib/raw-mode-smoke.test.mjs +42 -0
  397. package/tests/lib/sdd-overlay.test.mjs +118 -0
  398. package/tests/lib/spec-paths.test.mjs +80 -0
  399. package/tests/lib/state-loader.test.mjs +251 -0
  400. package/tests/lib/token-baseline.test.mjs +72 -0
  401. package/tests/lib/token-rules.test.mjs +94 -0
  402. package/tests/lib/verify-marketplace-release.test.mjs +128 -0
  403. package/tests/tsconfig.json +12 -0
  404. package/token-baseline.json +95 -0
  405. package/tsconfig.json +14 -0
@@ -0,0 +1,265 @@
1
+ #!/usr/bin/env node
2
+ // scripts/install-zcode.mjs — deploy team-flow for ZCODE Agent
3
+ //
4
+ // Copies the full plugin tree (skills + scripts + docs + templates + dist + hooks)
5
+ // to .zcode/team-flow/ so that skill instructions referencing
6
+ // ${CLAUDE_PLUGIN_ROOT}/scripts/... and ${CLAUDE_PLUGIN_ROOT}/docs/... resolve
7
+ // correctly. Also copies skills to .zcode/skills/ (where ZCODE reads them).
8
+ //
9
+ // Defaults to the latest GitHub release; use --local <path> to deploy from a local repo.
10
+ import { existsSync, mkdirSync, readdirSync, statSync, rmSync, readFileSync, writeFileSync } from 'node:fs';
11
+ import { cp, writeFile, mkdtemp } from 'node:fs/promises';
12
+ import { dirname, join, resolve } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { execFileSync } from 'node:child_process';
15
+ import { parseArgs } from 'node:util';
16
+ import { shellQuote } from './lib/shell-quote.mjs';
17
+
18
+ const __dirname = dirname(fileURLToPath(import.meta.url));
19
+ const defaultPluginRoot = dirname(__dirname); // repository root when running from clone
20
+ const targetRoot = process.cwd();
21
+
22
+ const GITHUB_REPO = 'MageByte-Zero/team-flow';
23
+ const GITHUB_API_URL = `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`;
24
+
25
+ // Directories needed by local installer-rewritten runtime commands.
26
+ const RUNTIME_DIRS = ['scripts', 'docs', 'templates', 'dist', 'hooks'];
27
+
28
+ function ensureDir(dir) {
29
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
30
+ }
31
+
32
+ async function fetchLatestTag() {
33
+ const res = await fetch(GITHUB_API_URL);
34
+ if (!res.ok) {
35
+ throw new Error(`GitHub API failed: ${res.status} ${res.statusText}`);
36
+ }
37
+ const data = await res.json();
38
+ if (!data.tag_name) {
39
+ throw new Error('GitHub API response missing tag_name');
40
+ }
41
+ return data.tag_name;
42
+ }
43
+
44
+ async function cloneRelease(tag) {
45
+ const tmpDir = await mkdtemp(join('/tmp', 'team-flow-'));
46
+ const url = `https://github.com/${GITHUB_REPO}.git`;
47
+ console.log(`📥 Cloning ${tag} into ${tmpDir} ...`);
48
+ execFileSync('git', ['clone', '--depth', '1', '--branch', tag, url, tmpDir], {
49
+ stdio: 'inherit',
50
+ });
51
+ return tmpDir;
52
+ }
53
+
54
+ /**
55
+ * Recursively copy a directory.
56
+ */
57
+ async function copyDir(src, dst) {
58
+ if (!existsSync(src)) return 0;
59
+ ensureDir(dst);
60
+ const entries = readdirSync(src);
61
+ for (const name of entries) {
62
+ const srcPath = join(src, name);
63
+ const dstPath = join(dst, name);
64
+ const st = statSync(srcPath);
65
+ if (st.isDirectory()) {
66
+ await copyDir(srcPath, dstPath);
67
+ } else {
68
+ await cp(srcPath, dstPath, { force: true });
69
+ }
70
+ }
71
+ return entries.length;
72
+ }
73
+
74
+ /**
75
+ * Copy skills to target, replacing ${CLAUDE_PLUGIN_ROOT} with the actual
76
+ * plugin root path so skill instructions work in ZCODE's environment.
77
+ */
78
+ async function copySkillsWithRoot(sourceSkills, targetSkills, pluginRootAbs) {
79
+ // Clean old skill directories before copying
80
+ if (existsSync(targetSkills)) {
81
+ const oldEntries = readdirSync(targetSkills).filter(name => {
82
+ const full = join(targetSkills, name);
83
+ try { return statSync(full).isDirectory(); } catch { return false; }
84
+ });
85
+ for (const name of oldEntries) {
86
+ rmSync(join(targetSkills, name), { recursive: true, force: true });
87
+ }
88
+ }
89
+ ensureDir(targetSkills);
90
+ const entries = readdirSync(sourceSkills).filter(name => {
91
+ const full = join(sourceSkills, name);
92
+ try { return statSync(full).isDirectory(); } catch { return false; }
93
+ });
94
+
95
+ for (const name of entries) {
96
+ const src = join(sourceSkills, name);
97
+ const dst = join(targetSkills, name);
98
+ await cp(src, dst, { recursive: true, force: true });
99
+
100
+ // Replace ${CLAUDE_PLUGIN_ROOT} with the absolute path so commands work
101
+ const skillMd = join(dst, 'SKILL.md');
102
+ if (existsSync(skillMd)) {
103
+ let content = readFileSync(skillMd, 'utf-8');
104
+ if (content.includes('${CLAUDE_PLUGIN_ROOT}')) {
105
+ content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRootAbs);
106
+ }
107
+ content = content.replace(
108
+ /npx --yes --package @xulthekl\/team-flow@\d+\.\d+\.\d+ tf/g,
109
+ `node ${shellQuote(join(pluginRootAbs, 'scripts', 'team-flow.mjs'))}`,
110
+ );
111
+ writeFileSync(skillMd, content, 'utf-8');
112
+ }
113
+ // Also fix sub-prompt files (implementer-prompt.md, etc.)
114
+ const subFiles = readdirSync(dst).filter(f => f.endsWith('.md') && f !== 'SKILL.md');
115
+ for (const sub of subFiles) {
116
+ const subPath = join(dst, sub);
117
+ let content = readFileSync(subPath, 'utf-8');
118
+ if (content.includes('${CLAUDE_PLUGIN_ROOT}')) {
119
+ content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRootAbs);
120
+ }
121
+ content = content.replace(
122
+ /npx --yes --package @xulthekl\/team-flow@\d+\.\d+\.\d+ tf/g,
123
+ `node ${shellQuote(join(pluginRootAbs, 'scripts', 'team-flow.mjs'))}`,
124
+ );
125
+ writeFileSync(subPath, content, 'utf-8');
126
+ }
127
+ }
128
+
129
+ return entries.length;
130
+ }
131
+
132
+ async function writePhaseGuard(targetRules) {
133
+ ensureDir(targetRules);
134
+ const content = `---
135
+ description: team-flow phase guard — 防止阶段漂移和未授权实现
136
+ alwaysApply: true
137
+ ---
138
+
139
+ # Phase Guard
140
+
141
+ ## 入口规则
142
+
143
+ - 所有工作必须从 "/workflow-start" 入口开始。
144
+ - 在 .team-flow.yaml 中确认当前 state 和 workflow 模式之前,不要开始写代码。
145
+
146
+ ## 全局禁止
147
+
148
+ - 没有 execution-contract.md 或未经用户明确批准,不得进入实现。
149
+ - full/hotfix 必须先运行 tf execution plan <change-dir> ...;没有 current execution plan 不得开始实现。
150
+ - 只有 all pass review receipts 后才可 closing;不得把未审查的 wave 当作完成。
151
+ - 上述 plan/receipt gates 仅适用于 full/hotfix;tweak 免除这些 gates (tweak exempt)。
152
+ - 执行过程中如果发现需求/范围变化,必须回退到 specifying 或 bridging,而不是直接改代码。
153
+ - 不要直接调用执行类 skill(如 "/build-executor"),必须通过入口路由。
154
+
155
+ ## 决策点协议
156
+
157
+ - DP-0:设计前确认
158
+ - DP-1:需求确认
159
+ - DP-2:工件审查
160
+ - DP-3:是否批准 execution contract?
161
+ - DP-4:先运行 tf execution recommend,展示可用模式与推荐;用户用 --confirm 确认,非推荐选择额外使用 --acknowledge-recommendation
162
+ - DP-5:调试升级
163
+ - DP-6:验证失败
164
+ - DP-7:是否收口归档?
165
+
166
+ > 本文件由 scripts/install-zcode.mjs 生成;对具体变更的 guard 内容请运行 tf inject <change-dir> 更新。
167
+ `;
168
+ await writeFile(join(targetRules, 'phase-guard.mdc'), content, 'utf-8');
169
+ }
170
+
171
+ async function writeZCODEHooks(hooksDir) {
172
+ ensureDir(join(targetRoot, '.zcode'));
173
+ const hooksJson = {
174
+ hooks: [
175
+ {
176
+ event: 'sessionStart',
177
+ command: `bash ${join(hooksDir, 'session-start')}`,
178
+ },
179
+ ],
180
+ };
181
+ await writeFile(
182
+ join(targetRoot, '.zcode', 'hooks.json'),
183
+ JSON.stringify(hooksJson, null, 2) + '\n',
184
+ 'utf-8',
185
+ );
186
+ }
187
+
188
+ async function main() {
189
+ const { values } = parseArgs({
190
+ options: {
191
+ local: { type: 'string' },
192
+ tag: { type: 'string' },
193
+ },
194
+ });
195
+
196
+ let pluginRoot = defaultPluginRoot;
197
+ let isTemp = false;
198
+ let installedTag = null;
199
+
200
+ if (values.local) {
201
+ pluginRoot = resolve(values.local);
202
+ console.log(`📁 Using local repo: ${pluginRoot}`);
203
+ } else {
204
+ installedTag = values.tag || await fetchLatestTag();
205
+ console.log(`⬆️ Installing team-flow ${installedTag} ...`);
206
+ pluginRoot = await cloneRelease(installedTag);
207
+ isTemp = true;
208
+ }
209
+
210
+ const sourceSkills = join(pluginRoot, 'skills');
211
+ if (!existsSync(sourceSkills)) {
212
+ console.error(`❌ skills/ directory not found at ${pluginRoot}`);
213
+ if (isTemp) rmSync(pluginRoot, { recursive: true, force: true });
214
+ process.exit(1);
215
+ }
216
+
217
+ // Target paths
218
+ const targetPluginDir = join(targetRoot, '.zcode', 'team-flow');
219
+ const targetSkills = join(targetRoot, '.zcode', 'skills');
220
+ const targetRules = join(targetRoot, '.zcode', 'rules');
221
+ const pluginRootAbs = resolve(targetPluginDir);
222
+
223
+ try {
224
+ // 1. Copy runtime dependencies to .zcode/team-flow/
225
+ console.log('📋 Copying runtime dependencies...');
226
+ for (const dir of RUNTIME_DIRS) {
227
+ const src = join(pluginRoot, dir);
228
+ const dst = join(targetPluginDir, dir);
229
+ if (existsSync(src)) {
230
+ const count = await copyDir(src, dst);
231
+ console.log(` ${dir}/ → ${dst} (${count} entries)`);
232
+ } else {
233
+ console.log(` ${dir}/ — skipped (not found)`);
234
+ }
235
+ }
236
+
237
+ // 2. Copy skills to .zcode/skills/ with CLAUDE_PLUGIN_ROOT replaced
238
+ const count = await copySkillsWithRoot(sourceSkills, targetSkills, pluginRootAbs);
239
+ console.log(` skills/ → ${targetSkills} (${count} skills, paths rewritten)`);
240
+
241
+ // 3. Write phase guard rule
242
+ await writePhaseGuard(targetRules);
243
+ console.log(` phase guard → ${join(targetRules, 'phase-guard.mdc')}`);
244
+
245
+ // 4. Write .zcode/hooks.json for session-start
246
+ await writeZCODEHooks(join(targetPluginDir, 'hooks'));
247
+ console.log(` hooks.json → ${join(targetRoot, '.zcode', 'hooks.json')}`);
248
+
249
+ console.log(`\n✅ ZCODE install complete:`);
250
+ console.log(` Plugin root: ${pluginRootAbs}`);
251
+ if (installedTag) {
252
+ console.log(` Version: ${installedTag}`);
253
+ }
254
+ console.log(`\nNext: open ZCODE Agent and try "/workflow-start".`);
255
+ } finally {
256
+ if (isTemp) {
257
+ rmSync(pluginRoot, { recursive: true, force: true });
258
+ }
259
+ }
260
+ }
261
+
262
+ main().catch(err => {
263
+ console.error(`❌ ${err.message}`);
264
+ process.exit(1);
265
+ });
@@ -0,0 +1,127 @@
1
+ // scripts/lib/cmd-audit.mjs — tf audit: generate decision-point audit report
2
+ import { existsSync } from 'node:fs';
3
+ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
4
+ import { join, dirname } from 'node:path';
5
+ import { parseArgs } from 'node:util';
6
+ import { readState } from './state-loader.mjs';
7
+
8
+ const DP_NAMES = {
9
+ 0: '用户确认门禁',
10
+ 1: '需求确认',
11
+ 2: '工件审查',
12
+ 3: '契约批准',
13
+ 4: '执行模式选择',
14
+ 5: '调试升级',
15
+ 6: '验证失败',
16
+ 7: '归档确认',
17
+ };
18
+
19
+ function formatResult(result) {
20
+ if (result === null || result === undefined || result === '') return 'not recorded';
21
+ return String(result);
22
+ }
23
+
24
+ function formatTimestamp(ts) {
25
+ if (ts === null || ts === undefined || ts === '') return '—';
26
+ return String(ts);
27
+ }
28
+
29
+ function isConfirmed(value) {
30
+ return value === true || value === 'true';
31
+ }
32
+
33
+ function formatDpResult(state, dp) {
34
+ const result = formatResult(state[`dp_${dp}_result`]);
35
+ if (dp === 0 && result === 'not recorded' && isConfirmed(state.dp_0_confirmed)) {
36
+ return 'confirmed';
37
+ }
38
+ return result;
39
+ }
40
+
41
+ function generateReport(changeDir, state) {
42
+ const rows = [];
43
+ for (let i = 0; i <= 7; i++) {
44
+ const result = formatDpResult(state, i);
45
+ const timestamp = formatTimestamp(state[`dp_${i}_timestamp`]);
46
+ rows.push({ dp: i, name: DP_NAMES[i], result, timestamp });
47
+ }
48
+
49
+ const recordedCount = rows.filter(r => r.result !== 'not recorded').length;
50
+ const missingCount = rows.length - recordedCount;
51
+
52
+ let md = `# Decision-Point Audit Report\n\n`;
53
+ md += `**变更**: ${state.change_name || basename(changeDir)} \n`;
54
+ md += `**生成时间**: ${new Date().toISOString()} \n`;
55
+ md += `**当前状态**: ${state.state || 'unknown'} \n\n`;
56
+
57
+ md += `## 汇总表\n\n`;
58
+ md += `| DP | 名称 | 结果 | 时间戳 |\n`;
59
+ md += `|----|------|------|--------|\n`;
60
+ for (const r of rows) {
61
+ md += `| DP-${r.dp} | ${r.name} | ${r.result} | ${r.timestamp} |\n`;
62
+ }
63
+
64
+ md += `\n**统计**: ${recordedCount}/8 已记录,${missingCount}/8 未记录。\n\n`;
65
+
66
+ md += `## 逐决策点说明\n\n`;
67
+ for (const r of rows) {
68
+ md += `### DP-${r.dp}: ${r.name}\n\n`;
69
+ md += `- **结果**: ${r.result}\n`;
70
+ md += `- **时间戳**: ${r.timestamp}\n`;
71
+ if (r.result === 'not recorded') {
72
+ md += '- **解读**: 该决策点尚未记录结果。如果工作流已经经过该阶段,请检查是否漏记。\n';
73
+ } else {
74
+ md += `- **解读**: 决策点 DP-${r.dp} 已记录为 "${r.result}"。\n`;
75
+ }
76
+ md += '\n';
77
+ }
78
+
79
+ md += `---\n\n`;
80
+ md += `*本报告由 \`tf audit\` 自动生成,仅供审计与归档参考。*\n`;
81
+
82
+ return md;
83
+ }
84
+
85
+ function basename(p) {
86
+ const parts = p.replace(/\\/g, '/').split('/').filter(Boolean);
87
+ return parts[parts.length - 1] || 'unknown';
88
+ }
89
+
90
+ export { generateReport, DP_NAMES };
91
+
92
+ export async function run(args) {
93
+ const { values, positionals } = parseArgs({
94
+ args,
95
+ options: {
96
+ output: { type: 'string' },
97
+ json: { type: 'boolean', default: false },
98
+ },
99
+ allowPositionals: true,
100
+ });
101
+
102
+ const changeDir = positionals[0];
103
+ if (!changeDir) {
104
+ console.error('Usage: tf audit <change-dir> [--output <file>] [--json]');
105
+ process.exit(2);
106
+ }
107
+
108
+ const stateFile = join(changeDir, '.team-flow.yaml');
109
+ if (!existsSync(stateFile)) {
110
+ console.error(`No .team-flow.yaml found in ${changeDir}`);
111
+ process.exit(1);
112
+ }
113
+
114
+ const state = readState(changeDir);
115
+ const report = generateReport(changeDir, state);
116
+ const outputPath = values.output || join(changeDir, 'decision-point-audit.md');
117
+
118
+ mkdirSync(dirname(outputPath), { recursive: true });
119
+ writeFileSync(outputPath, report, 'utf-8');
120
+
121
+ if (values.json) {
122
+ console.log(JSON.stringify({ ok: true, output: outputPath, change_name: state.change_name, state: state.state }));
123
+ } else {
124
+ console.log(`✅ Audit report written to ${outputPath}`);
125
+ console.log(` Change: ${state.change_name} | State: ${state.state}`);
126
+ }
127
+ }
@@ -0,0 +1,118 @@
1
+ // scripts/lib/cmd-checkpoint.mjs - tf checkpoint recovery records
2
+ import { parseArgs } from 'node:util';
3
+ import { getCheckpoint, listCheckpoints, saveCheckpoint } from './sdd-overlay.mjs';
4
+
5
+ const USAGE = 'Usage: tf checkpoint <save|list|show> <change-dir> [options]';
6
+
7
+ export async function run(args) {
8
+ const { positionals, values } = parseArgs({
9
+ args,
10
+ allowPositionals: true,
11
+ options: {
12
+ task: { type: 'string' }, next: { type: 'string' }, completed: { type: 'string' },
13
+ verification: { type: 'string' }, review: { type: 'string' }, risk: { type: 'string' },
14
+ 'commit-start': { type: 'string' }, 'commit-end': { type: 'string' },
15
+ json: { type: 'boolean', default: false },
16
+ },
17
+ });
18
+
19
+ const subcommand = positionals[0];
20
+ const changeDir = positionals[1];
21
+ if (!subcommand || !changeDir) usage();
22
+
23
+ if (!['save', 'list', 'show'].includes(subcommand)) {
24
+ console.error(`Unknown checkpoint subcommand: ${subcommand}. Valid: save, list, show`);
25
+ process.exit(2);
26
+ }
27
+
28
+ if (subcommand === 'save') {
29
+ if (!hasText(values.task) || !hasText(values.next)) {
30
+ console.error('Usage: tf checkpoint save <change-dir> --task <id> --next <text>');
31
+ process.exit(2);
32
+ }
33
+
34
+ const checkpoint = saveCheckpoint(changeDir, {
35
+ taskId: values.task,
36
+ next: values.next,
37
+ completed: values.completed,
38
+ evidence: values.verification,
39
+ review: values.review,
40
+ risk: values.risk,
41
+ commitStart: values['commit-start'],
42
+ commitEnd: values['commit-end'],
43
+ });
44
+ if (values.json) {
45
+ console.log(JSON.stringify({ ok: true, checkpoint }));
46
+ } else {
47
+ console.log(`Checkpoint saved: ${checkpoint.task_id}`);
48
+ }
49
+ return;
50
+ }
51
+
52
+ if (subcommand === 'list') {
53
+ const checkpoints = listCheckpoints(changeDir);
54
+ if (values.json) {
55
+ console.log(JSON.stringify({ ok: true, checkpoints }));
56
+ } else if (checkpoints.length === 0) {
57
+ console.log('No checkpoints found.');
58
+ } else {
59
+ for (const checkpoint of checkpoints) {
60
+ console.log(`${checkpoint.task_id} status=${checkpoint.stale ? 'stale' : 'current'} stale=${checkpoint.stale}`);
61
+ }
62
+ }
63
+ return;
64
+ }
65
+
66
+ const taskId = positionals[2];
67
+ if (!taskId) usage('Usage: tf checkpoint show <change-dir> <id>');
68
+ const checkpoint = getCheckpoint(changeDir, taskId);
69
+ if (!checkpoint) {
70
+ console.error(`Checkpoint '${taskId}' was not found`);
71
+ process.exit(1);
72
+ }
73
+
74
+ if (values.json) {
75
+ console.log(JSON.stringify({ ok: true, checkpoint }));
76
+ } else {
77
+ console.log(renderCheckpoint(checkpoint));
78
+ }
79
+ }
80
+
81
+ function hasText(value) {
82
+ return typeof value === 'string' && value.trim().length > 0;
83
+ }
84
+
85
+ function usage(message = USAGE) {
86
+ console.error(message);
87
+ process.exit(2);
88
+ }
89
+
90
+ function renderCheckpoint(checkpoint) {
91
+ return [
92
+ `# Checkpoint: ${checkpoint.task_id}`,
93
+ '',
94
+ `Status: ${checkpoint.stale ? 'stale' : 'current'}`,
95
+ `Created: ${checkpoint.created_at}`,
96
+ '',
97
+ '## Next',
98
+ checkpoint.next,
99
+ '',
100
+ '## Completed',
101
+ checkpoint.completed,
102
+ '',
103
+ '## Evidence',
104
+ checkpoint.evidence,
105
+ '',
106
+ '## Review',
107
+ checkpoint.review,
108
+ '',
109
+ '## Risk',
110
+ checkpoint.risk,
111
+ '',
112
+ '## Commit Start',
113
+ checkpoint.commit_start,
114
+ '',
115
+ '## Commit End',
116
+ checkpoint.commit_end,
117
+ ].join('\n');
118
+ }
@@ -0,0 +1,88 @@
1
+ // tf config — display or modify configuration
2
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { loadConfig, getDefaults, resolveModelProfile } from './config-loader.mjs';
5
+
6
+ export async function run(args) {
7
+ const config = loadConfig(process.cwd());
8
+
9
+ // No args → display full effective config
10
+ if (args.length === 0) {
11
+ console.log('Effective configuration:');
12
+ console.log(JSON.stringify(config, null, 2));
13
+ return;
14
+ }
15
+
16
+ if (args[0] === '--resolve-model') {
17
+ if (!args[1]) {
18
+ console.error('Usage: tf config --resolve-model <profile>');
19
+ process.exit(2);
20
+ }
21
+ try {
22
+ console.log(JSON.stringify(resolveModelProfile(config, args[1])));
23
+ } catch (error) {
24
+ console.error(error.message);
25
+ process.exit(1);
26
+ }
27
+ return;
28
+ }
29
+
30
+ // --get <path>
31
+ if (args[0] === '--get' && args[1]) {
32
+ const parts = args[1].split('.');
33
+ let val = config;
34
+ for (const p of parts) {
35
+ if (val === undefined || val === null) { val = undefined; break; }
36
+ val = val[p];
37
+ }
38
+ if (val !== undefined) {
39
+ console.log(typeof val === 'object' ? JSON.stringify(val, null, 2) : String(val));
40
+ } else {
41
+ console.error(`Config path not found: ${args[1]}`);
42
+ process.exit(1);
43
+ }
44
+ return;
45
+ }
46
+
47
+ // --set <path>=<value>
48
+ if (args[0] === '--set' && args[1]) {
49
+ const eqIdx = args[1].indexOf('=');
50
+ if (eqIdx === -1) {
51
+ console.error('Usage: tf config [--get <path>] [--set <path>=<value>] [--resolve-model <profile>]');
52
+ process.exit(2);
53
+ }
54
+ const path = args[1].slice(0, eqIdx);
55
+ const rawValue = args[1].slice(eqIdx + 1);
56
+ // Parse value: try number, boolean, then string
57
+ let value;
58
+ if (rawValue === 'true') value = true;
59
+ else if (rawValue === 'false') value = false;
60
+ else if (/^\d+$/.test(rawValue)) value = parseInt(rawValue, 10);
61
+ else value = rawValue;
62
+
63
+ // Load existing config file or start from empty
64
+ const configPath = join(process.cwd(), 'team-flow.config.json');
65
+ let fileConfig = {};
66
+ if (existsSync(configPath)) {
67
+ fileConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
68
+ }
69
+
70
+ // Set the nested value
71
+ const parts = path.split('.');
72
+ let target = fileConfig;
73
+ for (let i = 0; i < parts.length - 1; i++) {
74
+ if (!target[parts[i]] || typeof target[parts[i]] !== 'object') {
75
+ target[parts[i]] = {};
76
+ }
77
+ target = target[parts[i]];
78
+ }
79
+ target[parts[parts.length - 1]] = value;
80
+
81
+ writeFileSync(configPath, JSON.stringify(fileConfig, null, 2) + '\n');
82
+ console.log(`Set ${path} = ${JSON.stringify(value)}`);
83
+ return;
84
+ }
85
+
86
+ console.error('Usage: tf config [--get <path>] [--set <path>=<value>] [--resolve-model <profile>]');
87
+ process.exit(2);
88
+ }