@haposoft/cafekit 0.16.0-rc.7 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/README.md +116 -27
  2. package/bin/__tests__/codex-hooks-ownership.test.js +239 -0
  3. package/bin/__tests__/codex-hooks.test.js +295 -0
  4. package/bin/__tests__/codex-native.test.js +2289 -34
  5. package/bin/__tests__/develop-contract.test.js +400 -23
  6. package/bin/__tests__/installer-safety.test.js +3 -3
  7. package/bin/__tests__/optional-skill-inventory.test.js +249 -0
  8. package/bin/__tests__/output-styles.test.js +214 -0
  9. package/bin/__tests__/package-inventory.test.js +2131 -16
  10. package/bin/__tests__/runtime-schema.test.js +111 -0
  11. package/bin/__tests__/secret-output-guardrail.test.js +122 -0
  12. package/bin/__tests__/skill-routing-source.test.js +172 -0
  13. package/bin/__tests__/specs-v2-execution-closeout.test.js +1 -1
  14. package/bin/install.js +10 -0
  15. package/bin/lib/codex-install.js +170 -5
  16. package/bin/lib/context.js +14 -0
  17. package/bin/lib/i18n.js +12 -6
  18. package/bin/lib/skill-deps.js +5 -5
  19. package/bin/phases/claude-runtime.js +23 -0
  20. package/bin/phases/claude-settings.js +8 -0
  21. package/bin/phases/codex-hooks.js +156 -0
  22. package/bin/phases/codex-runtime.js +29 -38
  23. package/bin/phases/copy-payload.js +8 -2
  24. package/bin/phases/select-skill-bundles.js +96 -0
  25. package/bin/phases/skill-inventory.js +71 -0
  26. package/bin/phases/skills-setup.js +9 -2
  27. package/bin/phases/write-metadata.js +8 -5
  28. package/package.json +8 -2
  29. package/src/claude/CLAUDE.md +3 -3
  30. package/src/claude/agents/brainstormer.md +52 -69
  31. package/src/claude/agents/code-auditor.md +32 -14
  32. package/src/claude/agents/debugger.md +35 -20
  33. package/src/claude/agents/deployer.md +12 -5
  34. package/src/claude/agents/docs-keeper.md +11 -1
  35. package/src/claude/agents/implementer.md +25 -13
  36. package/src/claude/agents/inspector.md +6 -3
  37. package/src/claude/agents/project-manager.md +1 -1
  38. package/src/claude/agents/researcher.md +26 -55
  39. package/src/claude/agents/spec-maker.md +24 -13
  40. package/src/claude/agents/strategist.md +52 -0
  41. package/src/claude/agents/test-runner.md +117 -132
  42. package/src/claude/agents/ui-ux-designer.md +1 -1
  43. package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -0
  44. package/src/claude/hooks/__tests__/precompact.test.js +158 -0
  45. package/src/claude/hooks/__tests__/spec-gate.test.js +87 -4
  46. package/src/claude/hooks/__tests__/state.test.js +254 -3
  47. package/src/claude/hooks/__tests__/statusline.test.js +196 -0
  48. package/src/claude/hooks/agent.cjs +1 -1
  49. package/src/claude/hooks/docs-sync.cjs +12 -10
  50. package/src/claude/hooks/inspect-block.cjs +1 -1
  51. package/src/claude/hooks/lib/config.cjs +3 -0
  52. package/src/claude/hooks/lib/hook-state-dir.cjs +39 -0
  53. package/src/claude/hooks/lib/secret-keywords.cjs +42 -0
  54. package/src/claude/hooks/precompact.cjs +105 -0
  55. package/src/claude/hooks/rules.cjs +1 -1
  56. package/src/claude/hooks/secret-output-guardrail.cjs +43 -0
  57. package/src/claude/hooks/session.cjs +27 -1
  58. package/src/claude/hooks/spec-gate.cjs +3 -3
  59. package/src/claude/hooks/spec-state.cjs +32 -5
  60. package/src/claude/hooks/state.cjs +1 -1
  61. package/src/claude/hooks/task-scaffold-guard.cjs +1 -1
  62. package/src/claude/hooks/usage.cjs +1 -1
  63. package/src/claude/migration-manifest.json +29 -15
  64. package/src/claude/output-styles/coding-level-0-eli5.md +103 -0
  65. package/src/claude/output-styles/coding-level-1-junior.md +124 -0
  66. package/src/claude/output-styles/coding-level-2-mid.md +146 -0
  67. package/src/claude/output-styles/coding-level-3-senior.md +148 -0
  68. package/src/claude/output-styles/coding-level-4-lead.md +159 -0
  69. package/src/claude/output-styles/coding-level-5-god.md +91 -0
  70. package/src/claude/references/debugger/core-philosophy.md +5 -3
  71. package/src/claude/references/debugger/frontend-verification.md +2 -2
  72. package/src/claude/references/debugger/log-ci-analysis.md +13 -1
  73. package/src/claude/references/debugger/parallel-agent-hydration.md +19 -34
  74. package/src/claude/references/debugger/performance-diagnostics.md +2 -2
  75. package/src/claude/references/debugger/root-cause-tracing.md +37 -6
  76. package/src/claude/references/debugger/side-effect-gate.md +3 -1
  77. package/src/claude/references/debugger/verification-protocol.md +13 -12
  78. package/src/claude/rules/orchestrator.md +7 -1
  79. package/src/claude/rules/process-management.md +39 -0
  80. package/src/claude/rules/review-audit-self-decision.md +48 -0
  81. package/src/claude/rules/skill-domain-routing.md +26 -24
  82. package/src/claude/rules/skill-workflow-routing.md +22 -14
  83. package/src/claude/rules/workflow.md +3 -3
  84. package/src/claude/runtime.json +1 -0
  85. package/src/claude/runtime.schema.json +205 -0
  86. package/src/claude/scripts/generate-skill-catalog.cjs +156 -122
  87. package/src/claude/scripts/provenance.cjs +18 -5
  88. package/src/claude/scripts/spec-receipt.cjs +76 -21
  89. package/src/claude/scripts/spec-resolver.cjs +144 -4
  90. package/src/claude/scripts/workflow-policy.cjs +1 -1
  91. package/src/claude/settings/settings.json +16 -0
  92. package/src/claude/skills/agent-browser/SKILL.md +1 -1
  93. package/src/claude/skills/ai-multimodal/SKILL.md +1 -1
  94. package/src/claude/skills/brainstorm/SKILL.md +193 -172
  95. package/src/claude/skills/brainstorm/references/question-framework.md +105 -167
  96. package/src/claude/skills/chrome-devtools/SKILL.md +1 -1
  97. package/src/claude/skills/code-review/SKILL.md +43 -25
  98. package/src/claude/skills/code-review/references/spec-compliance-review.md +3 -4
  99. package/src/claude/skills/code-review/references/verification-gate.md +1 -1
  100. package/src/claude/skills/debug/SKILL.md +48 -19
  101. package/src/claude/skills/delegate/SKILL.md +1 -1
  102. package/src/claude/skills/develop/SKILL.md +92 -65
  103. package/src/claude/skills/develop/references/parallel-waves.md +36 -63
  104. package/src/claude/skills/develop/references/quality-gate.md +31 -4
  105. package/src/claude/skills/develop/references/subagent-patterns.md +21 -7
  106. package/src/claude/skills/docs/SKILL.md +42 -23
  107. package/src/claude/skills/docs/references/init-workflow.md +4 -4
  108. package/src/claude/skills/docs/references/reconstruct-workflow.md +6 -6
  109. package/src/claude/skills/docs/references/standard-docs-workflow.md +6 -2
  110. package/src/claude/skills/docs/references/summarize-workflow.md +2 -2
  111. package/src/claude/skills/docs/references/update-workflow.md +9 -7
  112. package/src/claude/skills/docs/templates/requirements-as-is.md +1 -1
  113. package/src/claude/skills/docx/SKILL.md +1 -1
  114. package/src/claude/skills/git/SKILL.md +1 -1
  115. package/src/claude/skills/git/references/commit-protocols.md +1 -1
  116. package/src/claude/skills/git/references/finish-branch.md +1 -1
  117. package/src/claude/skills/hotfix/SKILL.md +159 -170
  118. package/src/claude/skills/hotfix/references/diagnosis-protocol.md +14 -9
  119. package/src/claude/skills/hotfix/references/parallel-patterns.md +27 -13
  120. package/src/claude/skills/hotfix/references/prevention-gate.md +5 -0
  121. package/src/claude/skills/hotfix/references/review-cycle.md +21 -15
  122. package/src/claude/skills/hotfix/references/workflow-specialized.md +53 -21
  123. package/src/claude/skills/inspect/SKILL.md +55 -46
  124. package/src/claude/skills/inspect/references/internal-inspection.md +21 -5
  125. package/src/claude/skills/loop/SKILL.md +114 -0
  126. package/src/claude/skills/loop/references/bounded-loop-protocol.md +104 -0
  127. package/src/claude/skills/loop/references/metric-and-guard-contract.md +76 -0
  128. package/src/claude/skills/pdf/SKILL.md +1 -1
  129. package/src/claude/skills/pptx/SKILL.md +1 -1
  130. package/src/claude/skills/question/SKILL.md +16 -13
  131. package/src/claude/skills/research/SKILL.md +70 -43
  132. package/src/claude/skills/route/SKILL.md +94 -0
  133. package/src/claude/skills/route/references/agent-timing.md +46 -0
  134. package/src/claude/skills/route/references/chaining-patterns.md +53 -0
  135. package/src/claude/skills/route/references/task-taxonomy.md +48 -0
  136. package/src/claude/skills/specs/SKILL.md +48 -57
  137. package/src/claude/skills/specs/references/review.md +26 -8
  138. package/src/claude/skills/specs/references/templates.md +76 -31
  139. package/src/claude/skills/specs/templates/requirements-init.md +1 -1
  140. package/src/claude/skills/specs/templates/research.md +2 -2
  141. package/src/claude/skills/sync/SKILL.md +6 -6
  142. package/src/claude/skills/sync/references/sync-protocols.md +1 -1
  143. package/src/claude/skills/test/SKILL.md +120 -120
  144. package/src/claude/skills/test/references/execution-strategy.md +208 -361
  145. package/src/claude/skills/test/references/failure-triage.md +55 -121
  146. package/src/claude/skills/test/references/test-memory.md +20 -34
  147. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  148. package/src/claude/skills/web-testing/SKILL.md +1 -1
  149. package/src/claude/skills/xlsx/SKILL.md +1 -1
  150. package/src/claude/status.cjs +135 -33
  151. package/src/codex/AGENTS.md +14 -4
  152. package/src/codex/hooks/docs-sync.cjs +8 -3
  153. package/src/codex/hooks/lib/hook-context.cjs +18 -4
  154. package/src/codex/hooks/rules.cjs +29 -1
  155. package/src/codex/hooks/secret-output-guardrail.cjs +30 -0
  156. package/src/codex/hooks/spec-gate.cjs +3 -8
  157. package/src/codex/hooks/spec-state.cjs +34 -5
  158. package/src/codex/hooks.json +5 -0
  159. package/src/codex/runtime.json +2 -0
  160. package/src/common/.env.example +1 -1
  161. package/src/claude/skills/backend-development/SKILL.md +0 -101
  162. package/src/claude/skills/backend-development/references/backend-api-design.md +0 -495
  163. package/src/claude/skills/backend-development/references/backend-architecture.md +0 -454
  164. package/src/claude/skills/backend-development/references/backend-authentication.md +0 -338
  165. package/src/claude/skills/backend-development/references/backend-code-quality.md +0 -659
  166. package/src/claude/skills/backend-development/references/backend-debugging.md +0 -904
  167. package/src/claude/skills/backend-development/references/backend-devops.md +0 -491
  168. package/src/claude/skills/backend-development/references/backend-mindset.md +0 -387
  169. package/src/claude/skills/backend-development/references/backend-performance.md +0 -397
  170. package/src/claude/skills/backend-development/references/backend-security.md +0 -342
  171. package/src/claude/skills/backend-development/references/backend-technologies.md +0 -256
  172. package/src/claude/skills/backend-development/references/backend-testing.md +0 -429
  173. package/src/claude/skills/devops/.env.example +0 -76
  174. package/src/claude/skills/devops/SKILL.md +0 -102
  175. package/src/claude/skills/devops/references/browser-rendering.md +0 -305
  176. package/src/claude/skills/devops/references/cloudflare-d1-kv.md +0 -123
  177. package/src/claude/skills/devops/references/cloudflare-platform.md +0 -271
  178. package/src/claude/skills/devops/references/cloudflare-r2-storage.md +0 -280
  179. package/src/claude/skills/devops/references/cloudflare-workers-advanced.md +0 -312
  180. package/src/claude/skills/devops/references/cloudflare-workers-apis.md +0 -309
  181. package/src/claude/skills/devops/references/cloudflare-workers-basics.md +0 -418
  182. package/src/claude/skills/devops/references/docker-basics.md +0 -297
  183. package/src/claude/skills/devops/references/docker-compose.md +0 -292
  184. package/src/claude/skills/devops/references/gcloud-platform.md +0 -297
  185. package/src/claude/skills/devops/references/gcloud-services.md +0 -304
  186. package/src/claude/skills/devops/references/kubernetes-basics.md +0 -95
  187. package/src/claude/skills/devops/references/kubernetes-helm-advanced.md +0 -70
  188. package/src/claude/skills/devops/references/kubernetes-helm.md +0 -81
  189. package/src/claude/skills/devops/references/kubernetes-kubectl.md +0 -74
  190. package/src/claude/skills/devops/references/kubernetes-security-advanced.md +0 -94
  191. package/src/claude/skills/devops/references/kubernetes-security.md +0 -89
  192. package/src/claude/skills/devops/references/kubernetes-troubleshooting-advanced.md +0 -74
  193. package/src/claude/skills/devops/references/kubernetes-troubleshooting.md +0 -49
  194. package/src/claude/skills/devops/references/kubernetes-workflows-advanced.md +0 -75
  195. package/src/claude/skills/devops/references/kubernetes-workflows.md +0 -76
  196. package/src/claude/skills/devops/scripts/cloudflare_deploy.py +0 -269
  197. package/src/claude/skills/devops/scripts/docker_optimize.py +0 -332
  198. package/src/claude/skills/devops/scripts/requirements.txt +0 -20
  199. package/src/claude/skills/devops/scripts/tests/requirements.txt +0 -3
  200. package/src/claude/skills/devops/scripts/tests/test_cloudflare_deploy.py +0 -285
  201. package/src/claude/skills/devops/scripts/tests/test_docker_optimize.py +0 -436
  202. package/src/claude/skills/frontend-design/SKILL.md +0 -135
  203. package/src/claude/skills/frontend-design/references/ai-multimodal-overview.md +0 -165
  204. package/src/claude/skills/frontend-design/references/analysis-best-practices.md +0 -80
  205. package/src/claude/skills/frontend-design/references/analysis-prompts.md +0 -141
  206. package/src/claude/skills/frontend-design/references/analysis-techniques.md +0 -118
  207. package/src/claude/skills/frontend-design/references/animejs.md +0 -396
  208. package/src/claude/skills/frontend-design/references/anti-slop-rules.md +0 -103
  209. package/src/claude/skills/frontend-design/references/asset-generation.md +0 -337
  210. package/src/claude/skills/frontend-design/references/bento-motion-engine.md +0 -142
  211. package/src/claude/skills/frontend-design/references/design-extraction-overview.md +0 -71
  212. package/src/claude/skills/frontend-design/references/extraction-best-practices.md +0 -141
  213. package/src/claude/skills/frontend-design/references/extraction-output-templates.md +0 -162
  214. package/src/claude/skills/frontend-design/references/extraction-prompts.md +0 -127
  215. package/src/claude/skills/frontend-design/references/magicui-components.md +0 -129
  216. package/src/claude/skills/frontend-design/references/performance-guardrails.md +0 -169
  217. package/src/claude/skills/frontend-design/references/premium-design-patterns.md +0 -93
  218. package/src/claude/skills/frontend-design/references/redesign-audit-checklist.md +0 -114
  219. package/src/claude/skills/frontend-design/references/technical-accessibility.md +0 -119
  220. package/src/claude/skills/frontend-design/references/technical-best-practices.md +0 -97
  221. package/src/claude/skills/frontend-design/references/technical-optimization.md +0 -44
  222. package/src/claude/skills/frontend-design/references/technical-overview.md +0 -90
  223. package/src/claude/skills/frontend-design/references/technical-workflows.md +0 -150
  224. package/src/claude/skills/frontend-design/references/visual-analysis-overview.md +0 -95
  225. package/src/claude/skills/frontend-design/references/workflow-3d.md +0 -102
  226. package/src/claude/skills/frontend-design/references/workflow-describe.md +0 -87
  227. package/src/claude/skills/frontend-design/references/workflow-immersive.md +0 -87
  228. package/src/claude/skills/frontend-design/references/workflow-quick.md +0 -57
  229. package/src/claude/skills/frontend-design/references/workflow-screenshot.md +0 -63
  230. package/src/claude/skills/frontend-design/references/workflow-video.md +0 -74
  231. package/src/claude/skills/frontend-development/SKILL.md +0 -406
  232. package/src/claude/skills/frontend-development/resources/common-patterns.md +0 -331
  233. package/src/claude/skills/frontend-development/resources/complete-examples.md +0 -872
  234. package/src/claude/skills/frontend-development/resources/component-patterns.md +0 -502
  235. package/src/claude/skills/frontend-development/resources/data-fetching.md +0 -767
  236. package/src/claude/skills/frontend-development/resources/file-organization.md +0 -502
  237. package/src/claude/skills/frontend-development/resources/loading-and-error-states.md +0 -501
  238. package/src/claude/skills/frontend-development/resources/performance.md +0 -406
  239. package/src/claude/skills/frontend-development/resources/routing-guide.md +0 -364
  240. package/src/claude/skills/frontend-development/resources/styling-guide.md +0 -428
  241. package/src/claude/skills/frontend-development/resources/typescript-standards.md +0 -418
  242. package/src/claude/skills/mobile-development/SKILL.md +0 -218
  243. package/src/claude/skills/mobile-development/references/mobile-android.md +0 -604
  244. package/src/claude/skills/mobile-development/references/mobile-best-practices.md +0 -544
  245. package/src/claude/skills/mobile-development/references/mobile-debugging.md +0 -1089
  246. package/src/claude/skills/mobile-development/references/mobile-frameworks.md +0 -465
  247. package/src/claude/skills/mobile-development/references/mobile-ios.md +0 -496
  248. package/src/claude/skills/mobile-development/references/mobile-mindset.md +0 -542
  249. package/src/claude/skills/react-best-practices/AGENTS.md +0 -2249
  250. package/src/claude/skills/react-best-practices/README.md +0 -123
  251. package/src/claude/skills/react-best-practices/SKILL.md +0 -128
  252. package/src/claude/skills/react-best-practices/metadata.json +0 -15
  253. package/src/claude/skills/react-best-practices/rules/_sections.md +0 -46
  254. package/src/claude/skills/react-best-practices/rules/_template.md +0 -28
  255. package/src/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  256. package/src/claude/skills/react-best-practices/rules/advanced-use-latest.md +0 -49
  257. package/src/claude/skills/react-best-practices/rules/async-api-routes.md +0 -38
  258. package/src/claude/skills/react-best-practices/rules/async-defer-await.md +0 -80
  259. package/src/claude/skills/react-best-practices/rules/async-dependencies.md +0 -36
  260. package/src/claude/skills/react-best-practices/rules/async-parallel.md +0 -28
  261. package/src/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
  262. package/src/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
  263. package/src/claude/skills/react-best-practices/rules/bundle-conditional.md +0 -31
  264. package/src/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
  265. package/src/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  266. package/src/claude/skills/react-best-practices/rules/bundle-preload.md +0 -50
  267. package/src/claude/skills/react-best-practices/rules/client-event-listeners.md +0 -74
  268. package/src/claude/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
  269. package/src/claude/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
  270. package/src/claude/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
  271. package/src/claude/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
  272. package/src/claude/skills/react-best-practices/rules/js-cache-storage.md +0 -70
  273. package/src/claude/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
  274. package/src/claude/skills/react-best-practices/rules/js-early-exit.md +0 -50
  275. package/src/claude/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
  276. package/src/claude/skills/react-best-practices/rules/js-index-maps.md +0 -37
  277. package/src/claude/skills/react-best-practices/rules/js-length-check-first.md +0 -49
  278. package/src/claude/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
  279. package/src/claude/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
  280. package/src/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
  281. package/src/claude/skills/react-best-practices/rules/rendering-activity.md +0 -26
  282. package/src/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  283. package/src/claude/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
  284. package/src/claude/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
  285. package/src/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  286. package/src/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  287. package/src/claude/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
  288. package/src/claude/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
  289. package/src/claude/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
  290. package/src/claude/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
  291. package/src/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
  292. package/src/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  293. package/src/claude/skills/react-best-practices/rules/rerender-memo.md +0 -44
  294. package/src/claude/skills/react-best-practices/rules/rerender-transitions.md +0 -40
  295. package/src/claude/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
  296. package/src/claude/skills/react-best-practices/rules/server-cache-lru.md +0 -41
  297. package/src/claude/skills/react-best-practices/rules/server-cache-react.md +0 -26
  298. package/src/claude/skills/react-best-practices/rules/server-parallel-fetching.md +0 -79
  299. package/src/claude/skills/react-best-practices/rules/server-serialization.md +0 -38
@@ -70,16 +70,138 @@ function candidateError(reason, code = 'malformed') {
70
70
 
71
71
  const WORKFLOW_STATUSES = new Set(['pending', 'in_progress', 'paused', 'blocked', 'done']);
72
72
  const WORKFLOW_TASK_NAME = /^task-[A-Za-z0-9][A-Za-z0-9._-]*\.md$/;
73
+ const WORKFLOW_CONTRACT = 'process-first-ready-v1';
74
+
75
+ function annotatedMarkdownLines(content) {
76
+ let fence = null;
77
+ return String(content || '').split(/\r?\n/).map((line, index) => {
78
+ const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
79
+ const outsideFence = fence === null && !fenceMatch;
80
+ let fenceEvent = null;
81
+ if (fenceMatch) {
82
+ const marker = fenceMatch[1];
83
+ if (!fence) {
84
+ fence = { char: marker[0], length: marker.length };
85
+ fenceEvent = 'open';
86
+ } else if (marker[0] === fence.char && marker.length >= fence.length && fenceMatch[2].trim() === '') {
87
+ fence = null;
88
+ fenceEvent = 'close';
89
+ }
90
+ }
91
+ return { index, line, outsideFence, fenceEvent };
92
+ });
93
+ }
94
+
95
+ function workflowPlanContract(content) {
96
+ const markers = annotatedMarkdownLines(content)
97
+ .filter(({ line, outsideFence }) => outsideFence && /^\s*Specs-Contract\s*:/i.test(line))
98
+ .map(({ line }) => line);
99
+ if (markers.length === 0) return { workflowContract: null, queueReady: false };
100
+ if (markers.length !== 1 || markers[0] !== `Specs-Contract: ${WORKFLOW_CONTRACT}`) {
101
+ throw candidateError(`plan.md must contain exactly one Specs-Contract: ${WORKFLOW_CONTRACT} marker`);
102
+ }
103
+ return { workflowContract: WORKFLOW_CONTRACT, queueReady: true };
104
+ }
73
105
 
74
106
  function workflowTaskStatus(content, taskName) {
75
- const matches = String(content || '').matchAll(/^\s*(?:\*\*)?Status(?:\*\*)?\s*:\s*(?:\*\*)?\s*([A-Za-z_-]+)(?:\*\*)?\s*$/gim);
76
- const values = [...matches].map((match) => match[1].toLowerCase().replaceAll('-', '_'));
107
+ const values = annotatedMarkdownLines(content)
108
+ .filter(({ outsideFence }) => outsideFence)
109
+ .map(({ line }) => line.match(/^\s*(?:\*\*)?Status(?:\*\*)?\s*:\s*(?:\*\*)?\s*([A-Za-z_-]+)(?:\*\*)?\s*$/i))
110
+ .filter(Boolean)
111
+ .map((match) => match[1].toLowerCase().replaceAll('-', '_'));
77
112
  if (values.length !== 1 || !WORKFLOW_STATUSES.has(values[0])) {
78
113
  throw candidateError(`${taskName} must contain exactly one supported Status field`);
79
114
  }
80
115
  return values[0];
81
116
  }
82
117
 
118
+ function workflowTaskNumericPrefix(taskName) {
119
+ const match = taskName.match(/^task-(\d+)(?:-|\.md$)/);
120
+ return match ? match[1].replace(/^0+(?=\d)/, '') : null;
121
+ }
122
+
123
+ function workflowTaskDependencies(content, taskName, taskNames, queueReady) {
124
+ const lines = annotatedMarkdownLines(content);
125
+ let sectionStart = -1;
126
+ let sectionEnd = lines.length;
127
+ let sectionCount = 0;
128
+
129
+ for (let index = 0; index < lines.length; index += 1) {
130
+ if (!lines[index].outsideFence) continue;
131
+
132
+ const heading = lines[index].line.match(/^(#{1,6})\s+(.+?)\s*$/);
133
+ if (!heading || heading[1].length > 2) continue;
134
+ const title = heading[2].trim().toLowerCase();
135
+ if (heading[1].length === 2 && title === 'dependencies') {
136
+ sectionCount += 1;
137
+ if (sectionStart < 0) sectionStart = index + 1;
138
+ continue;
139
+ }
140
+ if (sectionStart >= 0 && sectionEnd === lines.length) sectionEnd = index;
141
+ }
142
+
143
+ if (!queueReady && sectionCount === 0) return [];
144
+ if (sectionCount !== 1 || sectionStart < 0) {
145
+ throw candidateError(`${taskName} must contain exactly one ## Dependencies section`);
146
+ }
147
+
148
+ const entries = lines.slice(sectionStart, sectionEnd)
149
+ .filter(({ outsideFence }) => outsideFence)
150
+ .map(({ line }) => line.trim())
151
+ .filter(Boolean)
152
+ .map((line) => {
153
+ const bullet = line.match(/^-\s+(.+?)\s*$/);
154
+ if (!bullet) throw candidateError(`${taskName} Dependencies must contain only bullet entries`);
155
+ const value = bullet[1].replace(/^`([^`]+)`$/, '$1').trim();
156
+ if (!value) throw candidateError(`${taskName} contains an empty dependency`);
157
+ return value;
158
+ });
159
+
160
+ if (entries.length === 1 && entries[0].toLowerCase() === 'none') return [];
161
+ if (entries.length === 0 || entries.some((entry) => entry.toLowerCase() === 'none')) {
162
+ throw candidateError(`${taskName} must use either - none or exact task basenames`);
163
+ }
164
+ const resolved = entries.map((entry) => {
165
+ if (WORKFLOW_TASK_NAME.test(entry)) return entry;
166
+ const legacy = !queueReady && entry.match(/^(?:Task\s+)?(\d+)$/i);
167
+ if (!legacy) throw candidateError(`${taskName} dependencies must be exact flat task basenames`);
168
+ const numericId = legacy[1].replace(/^0+(?=\d)/, '');
169
+ const matches = taskNames.filter((candidate) => workflowTaskNumericPrefix(candidate) === numericId);
170
+ if (matches.length !== 1) {
171
+ throw candidateError(`${taskName} legacy dependency ${entry} maps to ${matches.length} task basenames`);
172
+ }
173
+ return matches[0];
174
+ });
175
+ if (new Set(resolved).size !== resolved.length) {
176
+ throw candidateError(`${taskName} contains duplicate dependencies`);
177
+ }
178
+ return resolved;
179
+ }
180
+
181
+ function assertAcyclicWorkflow(tasks) {
182
+ const dependencies = new Map(tasks.map((task) => [task.path, [...task.dependencies].sort()]));
183
+ const state = new Map();
184
+ const stack = [];
185
+
186
+ function visit(taskPath) {
187
+ state.set(taskPath, 'visiting');
188
+ stack.push(taskPath);
189
+ for (const dependency of dependencies.get(taskPath) || []) {
190
+ if (state.get(dependency) === 'visiting') {
191
+ const start = stack.indexOf(dependency);
192
+ throw candidateError(`dependency cycle detected: ${[...stack.slice(start), dependency].join(' -> ')}`);
193
+ }
194
+ if (state.get(dependency) !== 'visited') visit(dependency);
195
+ }
196
+ stack.pop();
197
+ state.set(taskPath, 'visited');
198
+ }
199
+
200
+ for (const taskPath of [...dependencies.keys()].sort()) {
201
+ if (!state.has(taskPath)) visit(taskPath);
202
+ }
203
+ }
204
+
83
205
  function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
84
206
  const featureDir = path.join(specsDir, requestedName);
85
207
  let featureLstat;
@@ -114,6 +236,7 @@ function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
114
236
  if (planLstat.isSymbolicLink() || !planLstat.isFile() || fs.realpathSync(planFile) !== planFile) {
115
237
  throw candidateError('plan.md must be a regular non-symlink file in the workflow feature directory');
116
238
  }
239
+ const { workflowContract, queueReady } = workflowPlanContract(fs.readFileSync(planFile, 'utf8'));
117
240
 
118
241
  const taskNames = fs.readdirSync(canonicalFeature, { withFileTypes: true })
119
242
  .filter((entry) => WORKFLOW_TASK_NAME.test(entry.name))
@@ -129,12 +252,26 @@ function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
129
252
  if (taskLstat.isSymbolicLink() || !taskLstat.isFile() || fs.realpathSync(taskFile) !== taskFile) {
130
253
  throw candidateError(`${taskName} must be a regular non-symlink file in the workflow feature directory`);
131
254
  }
255
+ const taskContent = fs.readFileSync(taskFile, 'utf8');
132
256
  return {
133
257
  path: taskName,
134
- status: workflowTaskStatus(fs.readFileSync(taskFile, 'utf8'), taskName),
258
+ status: workflowTaskStatus(taskContent, taskName),
259
+ dependencies: workflowTaskDependencies(taskContent, taskName, taskNames, queueReady),
135
260
  };
136
261
  });
137
- const taskRegistry = Object.fromEntries(tasks.map((task) => [task.path, { status: task.status }]));
262
+ const taskNameSet = new Set(taskNames);
263
+ for (const task of tasks) {
264
+ if (task.dependencies.includes(task.path)) {
265
+ throw candidateError(`${task.path} cannot depend on itself`);
266
+ }
267
+ const missing = task.dependencies.find((dependency) => !taskNameSet.has(dependency));
268
+ if (missing) throw candidateError(`${task.path} references missing dependency ${missing}`);
269
+ }
270
+ assertAcyclicWorkflow(tasks);
271
+ const taskRegistry = Object.fromEntries(tasks.map((task) => [task.path, {
272
+ status: task.status,
273
+ dependencies: task.dependencies,
274
+ }]));
138
275
  const allTasksDone = tasks.every((task) => task.status === 'done');
139
276
  return {
140
277
  layoutKind: 'process-v3',
@@ -147,6 +284,8 @@ function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
147
284
  taskRegistry,
148
285
  tasks,
149
286
  allTasksDone,
287
+ workflowContract,
288
+ queueReady,
150
289
  };
151
290
  }
152
291
 
@@ -778,6 +917,7 @@ function refineWorkflowGateResolution(resolved) {
778
917
  }
779
918
 
780
919
  module.exports = {
920
+ annotatedMarkdownLines,
781
921
  specsDirectory,
782
922
  findAllActiveSpecs,
783
923
  findAllSpecCandidates,
@@ -1733,7 +1733,7 @@ function evaluateFlashPromotion(task, verdict, proof = 'Verification: PASS', cap
1733
1733
  status: 'in_progress',
1734
1734
  receipt: 'FLASH_UNVERIFIED',
1735
1735
  blocker: normalized.diagnostic === 'NO_TESTS'
1736
- ? 'awaiting test proof from /hapo:test <feature>'
1736
+ ? 'awaiting test proof from /cf:test <feature>'
1737
1737
  : normalized.diagnostic === 'PARTIAL'
1738
1738
  ? 'verification is partial; awaiting complete test proof'
1739
1739
  : `verification returned ${normalized.verdict}`,
@@ -4,6 +4,7 @@
4
4
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/status.cjs\"",
5
5
  "padding": 0
6
6
  },
7
+ "outputStyle": "Junior Developer Mode (Level 1)",
7
8
  "hooks": {
8
9
  "SessionStart": [
9
10
  {
@@ -35,9 +36,24 @@
35
36
  ]
36
37
  }
37
38
  ],
39
+ "PreCompact": [
40
+ {
41
+ "matcher": "*",
42
+ "hooks": [
43
+ {
44
+ "type": "command",
45
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/precompact.cjs\""
46
+ }
47
+ ]
48
+ }
49
+ ],
38
50
  "UserPromptSubmit": [
39
51
  {
40
52
  "hooks": [
53
+ {
54
+ "type": "command",
55
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/secret-output-guardrail.cjs\""
56
+ },
41
57
  {
42
58
  "type": "command",
43
59
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/rules.cjs\""
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: hapo:agent-browser
2
+ name: cf:agent-browser
3
3
  description: AI-optimized browser automation CLI with context-efficient snapshots. Use for long autonomous sessions, self-verifying workflows, video recording, and cloud browser testing (Browserbase).
4
4
  license: Apache-2.0
5
5
  user-invocable: true
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: hapo:ai-multimodal
2
+ name: cf:ai-multimodal
3
3
  description: Analyze images/audio/video/documentation with Gemini API. Use for vision analysis, transcription, OCR, design extraction, and deep multimodal understanding.
4
4
  license: MIT
5
5
  user-invocable: true