@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,359 @@
1
+ // tf install-workbuddy — deploy team-flow as a WorkBuddy marketplace plugin.
2
+ //
3
+ // WorkBuddy's marketplace plugin model (verified from existing plugins like
4
+ // `finance` and `modern-webapp` in cb_teams_marketplace):
5
+ //
6
+ // ~/.workbuddy/plugins/marketplaces/<marketplace>/plugins/<plugin-name>/
7
+ // ├── .codebuddy-plugin/plugin.json ← manifest (name, version, skills[])
8
+ // ├── skills/<skill-name>/SKILL.md ← skills with ${CLAUDE_PLUGIN_ROOT} rewritten
9
+ // ├── rules/phase-guard.md ← phase-guard rule (auto-included)
10
+ // ├── scripts/ docs/ templates/ ← runtime deps (${CLAUDE_PLUGIN_ROOT})
11
+ // ├── dist/ hooks/ ← (continued)
12
+ //
13
+ // enabledPlugins key in ~/.workbuddy/settings.json: `<plugin-name>@<marketplace>`
14
+ //
15
+ // This installer mirrors the shared install.mjs logic (RUNTIME_DIRS copy,
16
+ // ${CLAUDE_PLUGIN_ROOT} rewrite, phase-guard rule) but targets the marketplace
17
+ // plugin structure instead of a project-local `.platform/` directory.
18
+
19
+ import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
20
+ import { cp, writeFile, mkdtemp } from 'node:fs/promises';
21
+ import { homedir } from 'node:os';
22
+ import { dirname, join, resolve } from 'node:path';
23
+ import { parseArgs } from 'node:util';
24
+ import { fileURLToPath } from 'node:url';
25
+ import { execFileSync } from 'node:child_process';
26
+ import { shellQuote } from './shell-quote.mjs';
27
+
28
+ const __dirname = dirname(fileURLToPath(import.meta.url));
29
+ const defaultPluginRoot = resolve(__dirname, '..', '..'); // repo root when run from clone
30
+
31
+ const DEFAULT_MARKETPLACE = 'cb_teams_marketplace';
32
+ const PLUGIN_NAME = 'team-flow';
33
+ const GITHUB_REPO = 'MageByte-Zero/team-flow';
34
+ const GITHUB_API_URL = `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`;
35
+ const RUNTIME_DIRS = ['scripts', 'docs', 'templates', 'dist', 'hooks'];
36
+
37
+ // ─── helpers ──────────────────────────────────────────────
38
+
39
+ function ensureDir(dir) {
40
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
41
+ }
42
+
43
+ function readJsonIfExists(filePath) {
44
+ if (!existsSync(filePath)) return {};
45
+ return JSON.parse(readFileSync(filePath, 'utf-8'));
46
+ }
47
+
48
+ function listSkillNames(skillsDir) {
49
+ if (!existsSync(skillsDir)) {
50
+ throw new Error(`skills/ directory not found at ${skillsDir}`);
51
+ }
52
+ return readdirSync(skillsDir)
53
+ .filter(name => {
54
+ const dir = join(skillsDir, name);
55
+ return statSync(dir).isDirectory() && existsSync(join(dir, 'SKILL.md'));
56
+ })
57
+ .sort();
58
+ }
59
+
60
+ /** Recursively copy a directory. */
61
+ async function copyDir(src, dst) {
62
+ if (!existsSync(src)) return 0;
63
+ ensureDir(dst);
64
+ const entries = readdirSync(src);
65
+ for (const name of entries) {
66
+ const srcPath = join(src, name);
67
+ const dstPath = join(dst, name);
68
+ const st = statSync(srcPath);
69
+ if (st.isDirectory()) {
70
+ await copyDir(srcPath, dstPath);
71
+ } else {
72
+ await cp(srcPath, dstPath, { force: true });
73
+ }
74
+ }
75
+ return entries.length;
76
+ }
77
+
78
+ /**
79
+ * Copy skills to <pluginRoot>/skills/, replacing ${CLAUDE_PLUGIN_ROOT}
80
+ * with the absolute plugin root path so skill instructions resolve.
81
+ */
82
+ async function copySkillsWithRoot(sourceSkills, targetSkills, pluginRootAbs) {
83
+ // Clean old skill directories.
84
+ if (existsSync(targetSkills)) {
85
+ for (const name of readdirSync(targetSkills)) {
86
+ rmSync(join(targetSkills, name), { recursive: true, force: true });
87
+ }
88
+ }
89
+ ensureDir(targetSkills);
90
+ const entries = readdirSync(sourceSkills).filter(name => {
91
+ try { return statSync(join(sourceSkills, name)).isDirectory(); } catch { return false; }
92
+ });
93
+
94
+ function rewriteRoot(filePath) {
95
+ if (!existsSync(filePath)) return;
96
+ let content = readFileSync(filePath, 'utf-8');
97
+ if (content.includes('${CLAUDE_PLUGIN_ROOT}')) {
98
+ content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRootAbs);
99
+ }
100
+ content = content.replace(
101
+ /npx --yes --package @xulthekl\/team-flow@\d+\.\d+\.\d+ tf/g,
102
+ `node ${shellQuote(join(pluginRootAbs, 'scripts', 'team-flow.mjs'))}`,
103
+ );
104
+ writeFileSync(filePath, content, 'utf-8');
105
+ }
106
+
107
+ for (const name of entries) {
108
+ const src = join(sourceSkills, name);
109
+ const dst = join(targetSkills, name);
110
+ await cp(src, dst, { recursive: true, force: true });
111
+ rewriteRoot(join(dst, 'SKILL.md'));
112
+ // Also fix sub-prompt / reference markdown files in the skill dir.
113
+ for (const sub of readdirSync(dst).filter(f => f.endsWith('.md') && f !== 'SKILL.md')) {
114
+ rewriteRoot(join(dst, sub));
115
+ }
116
+ }
117
+ return entries.length;
118
+ }
119
+
120
+ /** Phase-guard rule content for WorkBuddy (md format). */
121
+ function phaseGuardContent() {
122
+ return `# Phase Guard — team-flow (workbuddy)
123
+
124
+ ## 入口规则
125
+
126
+ - 所有工作必须从 "/workflow-start" 入口开始。
127
+ - 在 .team-flow.yaml 中确认当前 state 和 workflow 模式之前,不要开始写代码。
128
+
129
+ ## 全局禁止
130
+
131
+ - 没有 execution-contract.md 或未经用户明确批准,不得进入实现。
132
+ - full/hotfix 必须先运行 tf execution plan <change-dir> ...;没有 current execution plan 不得开始实现。
133
+ - 只有 all pass review receipts 后才可 closing;不得把未审查的 wave 当作完成。
134
+ - 上述 plan/receipt gates 仅适用于 full/hotfix;tweak 免除这些 gates (tweak exempt)。
135
+ - 执行过程中如果发现需求/范围变化,必须回退到 specifying 或 bridging,而不是直接改代码。
136
+ - 不要直接调用执行类 skill(如 "/build-executor"),必须通过入口路由。
137
+
138
+ ## 决策点协议
139
+
140
+ - DP-0:设计前确认
141
+ - DP-1:需求确认
142
+ - DP-2:工件审查
143
+ - DP-3:是否批准 execution contract?
144
+ - DP-4:先运行 tf execution recommend,展示可用模式与推荐;用户用 --confirm 确认,非推荐选择额外使用 --acknowledge-recommendation
145
+ - DP-5:调试升级
146
+ - DP-6:验证失败
147
+ - DP-7:是否收口归档?
148
+
149
+ > 本文件由 team-flow 安装脚本生成(platform: workbuddy);
150
+ > 对具体变更的 guard 内容请运行 \`tf inject <change-dir>\` 更新。
151
+ `;
152
+ }
153
+
154
+ /** Plugin manifest for the marketplace. */
155
+ function pluginManifest(skillNames, version) {
156
+ return {
157
+ name: PLUGIN_NAME,
158
+ version: version || '0.0.0',
159
+ description: 'Spec-Superflow — OpenSpec 规划引擎 + Superpowers 执行纪律的任务工作流。',
160
+ author: { name: 'MageByte-Zero' },
161
+ homepage: { url: `https://github.com/${GITHUB_REPO}`, type: 'github' },
162
+ license: 'MIT',
163
+ skills: skillNames.map(name => `./skills/${name}`),
164
+ };
165
+ }
166
+
167
+ // ─── release fetch / clone ────────────────────────────────
168
+
169
+ async function fetchLatestTag() {
170
+ const res = await fetch(GITHUB_API_URL);
171
+ if (!res.ok) throw new Error(`GitHub API failed: ${res.status} ${res.statusText}`);
172
+ const data = await res.json();
173
+ if (!data.tag_name) throw new Error('GitHub API response missing tag_name');
174
+ return data.tag_name;
175
+ }
176
+
177
+ async function cloneRelease(tag) {
178
+ const tmpDir = await mkdtemp(join('/tmp', 'team-flow-'));
179
+ const url = `https://github.com/${GITHUB_REPO}.git`;
180
+ console.log(`📥 Cloning ${tag} into ${tmpDir} ...`);
181
+ execFileSync('git', ['clone', '--depth', '1', '--branch', tag, url, tmpDir], {
182
+ stdio: 'inherit',
183
+ });
184
+ return tmpDir;
185
+ }
186
+
187
+ function readVersion(pluginRoot) {
188
+ try {
189
+ const pkg = JSON.parse(readFileSync(join(pluginRoot, 'package.json'), 'utf-8'));
190
+ return pkg.version || '0.0.0';
191
+ } catch {
192
+ return '0.0.0';
193
+ }
194
+ }
195
+
196
+ // ─── plan ─────────────────────────────────────────────────
197
+
198
+ function planInstall({ pluginRoot = defaultPluginRoot, homeDir = homedir(), marketplaceName = DEFAULT_MARKETPLACE } = {}) {
199
+ const root = resolve(pluginRoot);
200
+ const skillsDir = join(root, 'skills');
201
+ const skillNames = listSkillNames(skillsDir);
202
+ const workbuddyRoot = join(homeDir, '.workbuddy');
203
+ const pluginsDir = join(workbuddyRoot, 'plugins', 'marketplaces', marketplaceName, 'plugins');
204
+ const targetPluginDir = join(pluginsDir, PLUGIN_NAME);
205
+ const targetSkills = join(targetPluginDir, 'skills');
206
+ const targetRules = join(targetPluginDir, 'rules');
207
+ const manifestDir = join(targetPluginDir, '.codebuddy-plugin');
208
+ const settingsPath = join(workbuddyRoot, 'settings.json');
209
+ const enabledPluginKey = `${PLUGIN_NAME}@${marketplaceName}`;
210
+ const version = readVersion(root);
211
+ const pluginRootAbs = resolve(targetPluginDir);
212
+
213
+ return {
214
+ pluginRoot: root,
215
+ skillsDir,
216
+ skillNames,
217
+ workbuddyRoot,
218
+ pluginsDir,
219
+ targetPluginDir,
220
+ targetSkills,
221
+ targetRules,
222
+ manifestDir,
223
+ settingsPath,
224
+ marketplaceName,
225
+ enabledPluginKey,
226
+ version,
227
+ pluginRootAbs,
228
+ };
229
+ }
230
+
231
+ // ─── install ──────────────────────────────────────────────
232
+
233
+ async function installWorkBuddy({ pluginRoot, homeDir, marketplaceName }) {
234
+ const plan = planInstall({ pluginRoot, homeDir, marketplaceName });
235
+ const { skillNames, targetPluginDir, targetSkills, targetRules, manifestDir, settingsPath, enabledPluginKey, version, pluginRootAbs } = plan;
236
+
237
+ // 0. Clean old plugin dir.
238
+ if (existsSync(targetPluginDir)) {
239
+ rmSync(targetPluginDir, { recursive: true, force: true });
240
+ }
241
+ ensureDir(targetPluginDir);
242
+
243
+ // 1. Copy runtime dependencies (scripts/docs/templates/dist/hooks).
244
+ console.log('📋 Copying runtime dependencies...');
245
+ for (const dir of RUNTIME_DIRS) {
246
+ const src = join(plan.pluginRoot, dir);
247
+ const dst = join(targetPluginDir, dir);
248
+ if (existsSync(src)) {
249
+ const count = await copyDir(src, dst);
250
+ console.log(` ${dir}/ → ${dst} (${count} entries)`);
251
+ } else {
252
+ console.log(` ${dir}/ — skipped (not found)`);
253
+ }
254
+ }
255
+
256
+ // 2. Copy skills with ${CLAUDE_PLUGIN_ROOT} rewriting.
257
+ const count = await copySkillsWithRoot(plan.skillsDir, targetSkills, pluginRootAbs);
258
+ console.log(` skills/ → ${targetSkills} (${count} skills, paths rewritten)`);
259
+
260
+ // 3. Write phase-guard rule.
261
+ ensureDir(targetRules);
262
+ await writeFile(join(targetRules, 'phase-guard.md'), phaseGuardContent(), 'utf-8');
263
+ console.log(` phase-guard → ${join(targetRules, 'phase-guard.md')}`);
264
+
265
+ // 4. Write plugin manifest.
266
+ ensureDir(manifestDir);
267
+ await writeFile(join(manifestDir, 'plugin.json'), JSON.stringify(pluginManifest(skillNames, version), null, 2) + '\n', 'utf-8');
268
+ console.log(` manifest → ${join(manifestDir, 'plugin.json')}`);
269
+
270
+ // 5. Enable plugin in settings.json.
271
+ ensureDir(plan.workbuddyRoot);
272
+ const settings = readJsonIfExists(settingsPath);
273
+ settings.enabledPlugins = settings.enabledPlugins && typeof settings.enabledPlugins === 'object'
274
+ ? settings.enabledPlugins
275
+ : {};
276
+ // Remove old per-skill keys (migration from v0.8.13 and earlier).
277
+ for (const name of skillNames) {
278
+ delete settings.enabledPlugins[`${name}@${marketplaceName}`];
279
+ }
280
+ settings.enabledPlugins[enabledPluginKey] = true;
281
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
282
+ console.log(` settings → ${enabledPluginKey} enabled`);
283
+
284
+ return plan;
285
+ }
286
+
287
+ // ─── CLI entry ────────────────────────────────────────────
288
+
289
+ export async function run(args) {
290
+ const { values } = parseArgs({
291
+ args,
292
+ options: {
293
+ local: { type: 'string' },
294
+ home: { type: 'string' },
295
+ marketplace: { type: 'string' },
296
+ tag: { type: 'string' },
297
+ 'dry-run': { type: 'boolean' },
298
+ },
299
+ });
300
+
301
+ const marketplaceName = values.marketplace || DEFAULT_MARKETPLACE;
302
+
303
+ // Dry-run: show plan and exit.
304
+ if (values['dry-run']) {
305
+ const plan = planInstall({
306
+ pluginRoot: values.local || defaultPluginRoot,
307
+ homeDir: values.home || homedir(),
308
+ marketplaceName,
309
+ });
310
+ console.log('WorkBuddy install plan:');
311
+ console.log(` Plugin: ${PLUGIN_NAME} v${plan.version}`);
312
+ console.log(` Skills: ${plan.skillNames.length} (${plan.skillNames.join(', ')})`);
313
+ console.log(` Marketplace: ${plan.marketplaceName}`);
314
+ console.log(` Target: ${plan.targetPluginDir}`);
315
+ console.log(` Rules: ${plan.targetRules}/phase-guard.md`);
316
+ console.log(` Settings: ${plan.enabledPluginKey}`);
317
+ return;
318
+ }
319
+
320
+ // Resolve source: --local <path> | --tag <tag> | latest release.
321
+ let pluginRoot = defaultPluginRoot;
322
+ let isTemp = false;
323
+ let installedTag = null;
324
+
325
+ if (values.local) {
326
+ pluginRoot = resolve(values.local);
327
+ console.log(`📁 Using local repo: ${pluginRoot}`);
328
+ } else {
329
+ installedTag = values.tag || await fetchLatestTag();
330
+ console.log(`⬆️ Installing team-flow ${installedTag} for WorkBuddy ...`);
331
+ pluginRoot = await cloneRelease(installedTag);
332
+ isTemp = true;
333
+ }
334
+
335
+ try {
336
+ const plan = await installWorkBuddy({
337
+ pluginRoot,
338
+ homeDir: values.home || homedir(),
339
+ marketplaceName,
340
+ });
341
+
342
+ console.log(`\n✅ WorkBuddy install complete:`);
343
+ console.log(` Plugin: ${PLUGIN_NAME} v${plan.version}`);
344
+ console.log(` Skills: ${plan.skillNames.length}`);
345
+ console.log(` Marketplace: ${plan.marketplaceName}`);
346
+ console.log(` Target: ${plan.targetPluginDir}`);
347
+ console.log(` Rules: ${plan.targetRules}/phase-guard.md`);
348
+ if (installedTag) {
349
+ console.log(` Version: ${installedTag}`);
350
+ }
351
+ console.log(`\nNext: restart WorkBuddy and try "用 workflow-start 开始".`);
352
+ } finally {
353
+ if (isTemp) {
354
+ rmSync(pluginRoot, { recursive: true, force: true });
355
+ }
356
+ }
357
+ }
358
+
359
+ export { planInstall, installWorkBuddy, PLUGIN_NAME };
@@ -0,0 +1,14 @@
1
+ // tf install-zcode — deploy team-flow skills/rules/scripts for ZCODE
2
+ // Delegates to scripts/install-zcode.mjs
3
+ import { execFileSync } from 'node:child_process';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const installScript = join(__dirname, '..', 'install-zcode.mjs');
9
+
10
+ export async function run(args) {
11
+ execFileSync(process.execPath, [installScript, ...args], {
12
+ stdio: 'inherit',
13
+ });
14
+ }
@@ -0,0 +1,37 @@
1
+ // scripts/lib/cmd-isolate.mjs — `tf isolate` CLI wrapper around ensure-branch.mjs
2
+ import { execFileSync } from 'node:child_process';
3
+ import { parseArgs } from 'node:util';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const ENSURE = join(__dirname, '..', 'ensure-branch.mjs');
9
+
10
+ export async function run(args) {
11
+ const { positionals, values } = parseArgs({
12
+ args,
13
+ allowPositionals: true,
14
+ options: { force: { type: 'boolean', default: false } },
15
+ });
16
+ const changeDir = positionals[0];
17
+ const changeName = positionals[1];
18
+ if (!changeDir) {
19
+ console.error('Usage: tf isolate <change-dir> [change-name] [--force]');
20
+ process.exit(2);
21
+ }
22
+ const extra = values.force ? ['--force'] : [];
23
+ // Literal command ('node') + literal argument array, no shell — same safe form
24
+ // as cmd-install-*.mjs. execFileSync throws on non-zero exit; propagate its status.
25
+ const nodeArgs = [ENSURE, changeDir];
26
+ if (changeName !== undefined) nodeArgs.push(changeName);
27
+ for (const a of extra) nodeArgs.push(a);
28
+ try {
29
+ execFileSync('node', nodeArgs, {
30
+ stdio: 'inherit',
31
+ timeout: 15000,
32
+ });
33
+ process.exit(0);
34
+ } catch (e) {
35
+ process.exit(e.status ?? 1);
36
+ }
37
+ }
@@ -0,0 +1,71 @@
1
+ // tf list — scan changes/ and report status
2
+ import { readdirSync, existsSync, statSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { loadConfig } from './config-loader.mjs';
5
+ import { readState } from './state-loader.mjs';
6
+
7
+ function detectChangeStatus(changeDir) {
8
+ // Prefer the state file over file-existence heuristics.
9
+ // The state file is maintained by tf state transition and is the
10
+ // authoritative source for the current workflow phase.
11
+ const stateFile = join(changeDir, '.team-flow.yaml');
12
+ if (existsSync(stateFile)) {
13
+ const state = readState(changeDir);
14
+ const st = state.state || 'exploring';
15
+ const workflow = state.workflow || 'full';
16
+ const detail = workflow === 'full' ? '' : ` (${workflow})`;
17
+ const STATUS_MAP = {
18
+ exploring: 'EXPLORING',
19
+ specifying: 'SPECIFYING',
20
+ bridging: 'BRIDGED',
21
+ 'approved-for-build': 'APPROVED',
22
+ executing: 'EXECUTING',
23
+ debugging: 'DEBUGGING',
24
+ closing: 'CLOSED',
25
+ abandoned: 'ABANDONED',
26
+ };
27
+ return {
28
+ status: STATUS_MAP[st] || 'UNKNOWN',
29
+ detail: `${st}${detail}`,
30
+ };
31
+ }
32
+
33
+ // Fallback: infer from file existence when no state file exists
34
+ const hasProposal = existsSync(join(changeDir, 'proposal.md'));
35
+ const hasContract = existsSync(join(changeDir, 'execution-contract.md'));
36
+ const hasAbandonment = existsSync(join(changeDir, 'abandonment-summary.md'));
37
+
38
+ if (hasAbandonment) return { status: 'ABANDONED', detail: 'Change was abandoned' };
39
+ if (!hasProposal) return { status: 'INCOMPLETE', detail: 'Missing proposal.md' };
40
+ if (!hasContract) return { status: 'SPECIFYING', detail: 'Planning in progress (no state file)' };
41
+ return { status: 'UNKNOWN', detail: 'Has artifacts but no state file — run tf state init' };
42
+ }
43
+
44
+ export { detectChangeStatus };
45
+
46
+ export async function run(args) {
47
+ const config = loadConfig(process.cwd());
48
+ const changesDir = join(process.cwd(), 'changes');
49
+
50
+ if (!existsSync(changesDir)) {
51
+ console.log('No changes/ directory found.');
52
+ return;
53
+ }
54
+
55
+ const dirs = readdirSync(changesDir).filter(f => {
56
+ try { return statSync(join(changesDir, f)).isDirectory(); } catch { return false; }
57
+ });
58
+
59
+ if (dirs.length === 0) {
60
+ console.log('No changes found in changes/');
61
+ return;
62
+ }
63
+
64
+ console.log('Changes:');
65
+ for (const dir of dirs) {
66
+ const changeDir = join(changesDir, dir);
67
+ const { status, detail } = detectChangeStatus(changeDir);
68
+ const icon = status === 'CLOSED' ? '✅' : status === 'ABANDONED' ? '🚫' : status === 'APPROVED' ? '🔒' : status === 'EXECUTING' ? '⚡' : status === 'DEBUGGING' ? '🐛' : status === 'EXPLORING' ? '🔍' : status === 'SPECIFYING' ? '📝' : status === 'BRIDGED' ? '🌉' : status === 'UNKNOWN' ? '❓' : '⚠️';
69
+ console.log(` ${icon} ${dir} [${status}] ${detail}`);
70
+ }
71
+ }
@@ -0,0 +1,85 @@
1
+ // tf runtime — portable, root-independent operations used by canonical skills.
2
+ import { readFileSync } from 'node:fs';
3
+ import { spawnSync } from 'node:child_process';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const ROOT = join(__dirname, '..', '..');
9
+
10
+ const ASSETS = new Set([
11
+ 'docs/artifact-contract.md',
12
+ 'docs/decision-points.md',
13
+ 'docs/state-machine.md',
14
+ 'skills/build-executor/implementer-prompt.md',
15
+ 'skills/build-executor/task-reviewer-prompt.md',
16
+ 'templates/design.md',
17
+ 'templates/execution-contract.md',
18
+ 'templates/proposal.md',
19
+ 'templates/spec.md',
20
+ 'templates/tasks.md',
21
+ ]);
22
+
23
+ export async function run(args) {
24
+ const [operation, ...rest] = args;
25
+
26
+ switch (operation) {
27
+ case 'check-update':
28
+ return runScript('scripts/check-update.mjs', rest);
29
+ case 'infer':
30
+ return runScript('scripts/infer-workflow.mjs', rest);
31
+ case 'guard':
32
+ return runScript('scripts/guard/guard.mjs', rest);
33
+ case 'config':
34
+ return runReadOnlyConfig(rest);
35
+ case 'asset':
36
+ return readAsset(rest);
37
+ default:
38
+ return usage(`Unknown runtime operation: ${operation || '(missing)'}`);
39
+ }
40
+ }
41
+
42
+ function runScript(relativeScript, args) {
43
+ const result = spawnSync(process.execPath, [join(ROOT, relativeScript), ...args], {
44
+ cwd: process.cwd(),
45
+ env: process.env,
46
+ stdio: 'inherit',
47
+ });
48
+
49
+ if (result.error) throw result.error;
50
+ if (result.status !== 0) process.exitCode = result.status ?? 1;
51
+ }
52
+
53
+ async function runReadOnlyConfig(args) {
54
+ if (args.includes('--set')) {
55
+ return usage('runtime config is read-only; use the main tf config command to change configuration');
56
+ }
57
+ const { run: runConfig } = await import('./cmd-config.mjs');
58
+ await runConfig(args);
59
+ }
60
+
61
+ function readAsset(args) {
62
+ if (args[0] !== 'read' || args.length !== 2) {
63
+ return usage('Usage: tf runtime asset read <allowed-relative-path>');
64
+ }
65
+
66
+ const assetPath = args[1];
67
+ if (!ASSETS.has(assetPath)) {
68
+ return usage(`Asset is not in the runtime allowlist: ${assetPath}`);
69
+ }
70
+
71
+ process.stdout.write(readFileSync(join(ROOT, assetPath), 'utf8'));
72
+ }
73
+
74
+ function usage(message) {
75
+ console.error(message);
76
+ console.error(`Usage:
77
+ tf runtime check-update
78
+ tf runtime infer <change-dir>
79
+ tf runtime guard check <change-dir> <from-state> <to-state> [--json]
80
+ tf runtime config [--get <path>|--resolve-model <profile>]
81
+ tf runtime asset read <allowed-relative-path>`);
82
+ process.exitCode = 2;
83
+ }
84
+
85
+ export { ASSETS };
@@ -0,0 +1,71 @@
1
+ // scripts/lib/cmd-solutions.mjs - tf solutions 复利贯穿机制命令组(v0.5)
2
+ //
3
+ // 设计说明(v0.5 / 2026-07-21):
4
+ // - 与 checkpoint / handoff / execution 一致,采用「单 COMMANDS key + 内部子命令分发」模式。
5
+ // - 4 个底层脚本 solutions-{index-gen,inject,capture,promote}.mjs 的 run(args) 接收「对象」参数,
6
+ // 而 CLI 入口传入的是「字符串数组」。本分发器用 parseArgs 把数组解析成各脚本需要的对象后再调用,
7
+ // 完成 数组 → 对象 的桥接。
8
+ import { parseArgs } from 'node:util';
9
+
10
+ const USAGE = 'Usage: tf solutions <index-gen|inject|capture|promote> [options]';
11
+
12
+ export async function run(args) {
13
+ const { positionals, values } = parseArgs({
14
+ args,
15
+ allowPositionals: true,
16
+ options: {
17
+ dir: { type: 'string' },
18
+ phase: { type: 'string' },
19
+ domain: { type: 'string' },
20
+ type: { type: 'string' },
21
+ severity: { type: 'string' },
22
+ summary: { type: 'string' },
23
+ source: { type: 'string' },
24
+ },
25
+ });
26
+
27
+ const subcommand = positionals[0];
28
+ if (!subcommand) usage();
29
+
30
+ if (subcommand === 'index-gen') {
31
+ const mod = await import('./solutions-index-gen.mjs');
32
+ mod.run({ dir: values.dir });
33
+ return;
34
+ }
35
+
36
+ if (subcommand === 'inject') {
37
+ const mod = await import('./solutions-inject.mjs');
38
+ mod.run({ phase: values.phase, domain: values.domain, dir: values.dir });
39
+ return;
40
+ }
41
+
42
+ if (subcommand === 'capture') {
43
+ const mod = await import('./solutions-capture.mjs');
44
+ mod.run({
45
+ phase: values.phase,
46
+ domain: values.domain,
47
+ type: values.type,
48
+ severity: values.severity,
49
+ summary: values.summary,
50
+ source: values.source,
51
+ dir: values.dir,
52
+ });
53
+ return;
54
+ }
55
+
56
+ if (subcommand === 'promote') {
57
+ const changeDir = positionals[1];
58
+ if (!changeDir) usage('Usage: tf solutions promote <change-dir> [--dir <solutions-dir>]');
59
+ const mod = await import('./solutions-promote.mjs');
60
+ mod.run({ _: [changeDir], changeDir, dir: values.dir });
61
+ return;
62
+ }
63
+
64
+ console.error(`Unknown solutions subcommand: ${subcommand}. Valid: index-gen, inject, capture, promote`);
65
+ process.exit(2);
66
+ }
67
+
68
+ function usage(message = USAGE) {
69
+ console.error(message);
70
+ process.exit(2);
71
+ }