@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
package/README.md CHANGED
@@ -138,21 +138,97 @@ cat .claude/cafekit.json
138
138
  cat .codex/cafekit.json
139
139
  ```
140
140
 
141
+ ### Statusline configuration
142
+
143
+ The Claude statusline reads three keys from `.claude/runtime.json`:
144
+
145
+ - `"statusline"`: render mode — `full` (default), `compact`, `minimal`, or `none`.
146
+ - `statuslineColors`: set `false` to disable ANSI colors (`NO_COLOR` also wins).
147
+ - `statuslineLayout`: optional custom layout. Global shape
148
+ `{ "lines": [["model", "context"], ["directory", "git"]] }` — each inner
149
+ array is one output line; modes only slice the line count (minimal = first
150
+ line, compact = first two, full = all). Valid section ids: `model`,
151
+ `context`, `quota`, `directory`, `git`, `plan`, `cost`, `changes`. Unknown
152
+ ids are ignored; an empty or invalid layout falls back to the default
153
+ renderers, and leaving the key out keeps the default output unchanged. The
154
+ `cost` section renders only when enabled here, billing mode is API, and cost
155
+ data exists. Quota shows five-hour and weekly windows only while the usage
156
+ cache is fresh.
157
+
141
158
  ## Core Skills
142
159
 
143
160
  CafeKit ships many skills, but the main release surface is:
144
161
 
145
- - `/hapo:question <question> [--repo|--web|--both|--brief|--deep]`: answer questions using repo evidence first, then external/current sources when local evidence is insufficient
146
- - `/hapo:brainstorm <idea-or-problem>`: scout the repo, clarify exact requirements, compare approaches, and hand off to specs
147
- - `/hapo:specs <feature-description>`: create or resume a structured spec workflow
148
- - `/hapo:develop <feature-name>`: implement from approved spec artifacts
149
- - `/hapo:debug <issue>`: diagnose bugs, incidents, CI failures, flaky tests, UI regressions, and performance issues before fixing
150
- - `/hapo:hotfix <issue>`: fix diagnosed bugs with root-cause, verification, prevention, and side-effect gates
151
- - `/hapo:docs [--init|--update|--summarize|--reconstruct]`: create project docs or reconstruct as-is system documentation from source code
152
- - `/hapo:test [scope|--full]`: run verification and return a structured verdict
153
- - `/hapo:code-review [scope|--pending]`: adversarial review focused on correctness, regressions, and security
162
+ - `/cf:ask <question> [--repo|--web|--both|--brief|--deep]`: answer questions using repo evidence first, then external/current sources when local evidence is insufficient
163
+ - `/cf:scout <search-target>`: discover relevant files locally first, delegating only for permitted broad independent scopes
164
+ - `/cf:brainstorm <idea-or-problem>`: scout the repo, clarify exact requirements, compare approaches, and hand off to specs
165
+ - `/cf:research <decision>`: choose proportional depth and return traceable evidence for an uncertain technical decision
166
+ - `/cf:route <material-request>`: classify ambiguous, multi-step, multi-domain, or elevated-risk work and compose the shortest valid installed chain
167
+ - `/cf:loop <bounded-experiment>`: run explicit-only numeric optimization in an isolated worktree and return a base-bound patch handoff
168
+ - `/cf:specs <feature-description>`: create or resume a structured spec workflow
169
+ - `/cf:develop <feature-name>`: implement from approved spec artifacts
170
+ - `/cf:debug <issue>`: run adaptive-depth, diagnostic-only root-cause analysis with elimination and prevention-aware handoff
171
+ - `/cf:fix <issue>`: repair the diagnosed root cause with proportional depth; Quick/local stays direct, while Standard and Incident/deep bound the repair and use post-diagnosis research, brainstorm, or staged planning only when evidence leaves a real decision; every path consumes the `cf:debug` handoff and reports shared `PASS | PASS_WITH_WARNINGS | FAIL | BLOCKED` verdicts through verification, prevention, and side-effect gates
172
+ - `/cf:test [scope|--full]`: run verification and return a structured verdict
173
+ - `/cf:code-review [scope|--pending]`: adversarial review focused on correctness, regressions, and security
174
+
175
+ ### Adaptive Brainstorm controls
176
+
177
+ Brainstorm stays proportional by default: Direct classification runs before any
178
+ analysis overlay, then non-direct work selects the smallest adequate Standard or
179
+ Deep depth. Controls are parsed only from the leading control segment. Combine
180
+ the single-use exact flags `--deep`, `--visual`, and `--advice` in any order;
181
+ an unknown or duplicate leading `--*` stops with usage and no action. `--` ends
182
+ controls, so literal flag content can start with `/cf:brainstorm -- --dry-run`.
183
+
184
+ `--deep` raises non-direct analysis depth only. `--visual` changes presentation
185
+ and falls back to text. `--advice` uses the advisory brainstormer only after a
186
+ material choice exists. External visual/adviser context is minimized and
187
+ redacted first; neither overlay writes, approves, persists, dispatches, or
188
+ completes work. Chat is the default output. A durable file needs explicit user
189
+ authority, and no Brainstorm output is live proof or Specs/Develop approval or
190
+ execution authority.
191
+
192
+ ### Adaptive Research and bounded Loop
193
+
194
+ Use `/cf:research` when the result is a decision: Quick, Standard, or Deep
195
+ research binds material claims to a URL or repository anchor, authority,
196
+ date/version, applicability, and `confirmed`, `inferred`, or `unresolved`
197
+ state. Research returns evidence and tradeoffs; it does not implement the
198
+ recommendation or guarantee correctness.
199
+
200
+ Use `/cf:loop` only by explicit request and only after its preflight freezes
201
+ Goal, isolated Scope, finite numeric Metric and Direction, reproducible
202
+ Baseline, distinct Guard, noise policy and minimum delta, budget, and stop
203
+ conditions. Each iteration stays in a detached worktree. The result is a
204
+ base-bound isolated patch handoff, never an automatic apply, commit, push, or
205
+ guarantee of improvement.
206
+
207
+ ```text
208
+ /cf:research Compare current local-first search libraries for this repository
209
+ /cf:loop Goal="reduce parser latency" Scope="packages/parser" Metric="median ms, lower" Baseline="pinned base" Guard="npm test" Noise="MAD; minimum delta 2%" Budget="10 iterations" Stop="budget, drift, or failed guard"
210
+ $cf-research Compare current local-first search libraries for this repository
211
+ $cf-loop Goal="reduce parser latency" Scope="packages/parser" Metric="median ms, lower" Baseline="pinned base" Guard="npm test" Noise="MAD; minimum delta 2%" Budget="10 iterations" Stop="budget, drift, or failed guard"
212
+ ```
213
+
214
+ Optional document skills are `docs`, `docx`, `pdf`, `pptx`, `xlsx`, and
215
+ `ai-multimodal`. Select them interactively or run:
154
216
 
155
- Common companion skills bundled in this package include `inspect`, `research`, `ai-multimodal`, `frontend-development`, `backend-development`, and `react-best-practices`.
217
+ ```bash
218
+ npx @haposoft/cafekit --with-document-skills
219
+ ```
220
+
221
+ Fresh non-interactive installs leave them out by default. Use
222
+ `--without-document-skills` to skip them or remove pristine CafeKit-owned
223
+ copies; user-modified files are preserved. Documentation validators, hooks,
224
+ and the `docs-keeper` agent remain part of the core runtime.
225
+
226
+ When installed, `cf:docs` consumes a post-task docs checkpoint from
227
+ Develop/Sync (`none | minor | major` — `none` reports only, `minor`/`major`
228
+ update only affected existing docs, and a checkpoint never invents a new
229
+ document), dispatches `docs-keeper` or parallel readers only through the
230
+ Delegation Gate, and keeps every reconstructed claim on the
231
+ `Observed | Inferred | Unknown` evidence taxonomy.
156
232
 
157
233
  CafeKit uses rule-based skill routing guidance instead of an automatic prompt-scoring hook. See `.claude/rules/skill-workflow-routing.md`, `.claude/rules/skill-domain-routing.md`, or run:
158
234
 
@@ -160,7 +236,16 @@ CafeKit uses rule-based skill routing guidance instead of an automatic prompt-sc
160
236
  node .claude/scripts/generate-skill-catalog.cjs --skills
161
237
  ```
162
238
 
163
- On Codex, invoke the transformed native skill names as `$hapo-<name>` or browse
239
+ Routing uses progressive disclosure: live catalog metadata selects a candidate,
240
+ the selected `SKILL.md` supplies its contract, and only relevant references are
241
+ loaded. Invoke an installed skill directly for explicit or obvious low-risk
242
+ work; use `cf:route` only when classification or chaining is material. When a
243
+ capability or agent is absent, continue inline when safe or name the gap.
244
+ Hooks are not a skill router and never grant capability presence or authority. Source
245
+ and installed projections are verified; live-model adherence remains
246
+ `UNPROVEN`, not deterministic.
247
+
248
+ On Codex, invoke the transformed native skill names as `$cf-<name>` or browse
164
249
  them with `/skills`. Explicit custom-agent delegation uses snake_case agent
165
250
  names and `fork_turns: "none"`.
166
251
 
@@ -169,32 +254,36 @@ names and `fork_turns: "none"`.
169
254
  Claude Code:
170
255
 
171
256
  ```bash
172
- /hapo:question "Which files define the current CafeKit install/runtime behavior?" --repo
173
- /hapo:brainstorm Explore approaches for a Google Meet transcript extension
174
- /hapo:specs Build a Google Meet transcript extension with AI summaries
175
- /hapo:develop meet-transcript-mvp
176
- /hapo:test meet-transcript-mvp --full
177
- /hapo:code-review meet-transcript-mvp --pending
257
+ /cf:ask "Which files define the current CafeKit install/runtime behavior?" --repo
258
+ /cf:scout "Find the runtime entrypoints for skill installation"
259
+ /cf:brainstorm Explore approaches for a Google Meet transcript extension
260
+ /cf:research Compare current transcript storage options for this repository
261
+ /cf:specs Build a Google Meet transcript extension with AI summaries
262
+ /cf:develop meet-transcript-mvp
263
+ /cf:test meet-transcript-mvp --full
264
+ /cf:code-review meet-transcript-mvp --pending
178
265
  ```
179
266
 
180
267
  Codex CLI:
181
268
 
182
269
  ```text
183
- $hapo-question "Which files define the current CafeKit runtime?" --repo
184
- $hapo-brainstorm Explore approaches for a Google Meet transcript extension
185
- $hapo-specs Build a Google Meet transcript extension with AI summaries
186
- $hapo-develop meet-transcript-mvp
187
- $hapo-test meet-transcript-mvp --full
188
- $hapo-code-review meet-transcript-mvp --pending
270
+ $cf-ask "Which files define the current CafeKit runtime?" --repo
271
+ $cf-scout "Find the runtime entrypoints for skill installation"
272
+ $cf-brainstorm Explore approaches for a Google Meet transcript extension
273
+ $cf-research Compare current transcript storage options for this repository
274
+ $cf-specs Build a Google Meet transcript extension with AI summaries
275
+ $cf-develop meet-transcript-mvp
276
+ $cf-test meet-transcript-mvp --full
277
+ $cf-code-review meet-transcript-mvp --pending
189
278
  ```
190
279
 
191
280
  Reconstruct as-is docs from a legacy codebase:
192
281
 
193
282
  ```bash
194
- /hapo:docs --reconstruct apps/legacy-admin
283
+ /cf:docs --reconstruct apps/legacy-admin
195
284
  ```
196
285
 
197
- The reconstruct bundle includes as-is markdown/JSON evidence and a self-contained `overview.html` review dashboard before the approved docs are handed to `/hapo:specs`.
286
+ The reconstruct bundle includes as-is markdown/JSON evidence and a self-contained `overview.html` review dashboard before the approved docs are handed to `/cf:specs`.
198
287
 
199
288
  ## Codex hook safety
200
289
 
@@ -215,9 +304,9 @@ specs/<feature-name>/
215
304
  └── task-NN-<slug>.md
216
305
  ```
217
306
 
218
- The process-first workflow has three human decision gates. `hapo:specs` opens
307
+ The process-first workflow has three human decision gates. `cf:specs` opens
219
308
  C1 to fix scope before authoring and C2 to resolve adversarial findings, then
220
- stops. A later explicit `hapo:develop` invocation executes the tasks and
309
+ stops. A later explicit `cf:develop` invocation executes the tasks and
221
310
  presents C3 for closeout only after real execution proof. Each task has one
222
311
  `Status:` field and keeps its canonical `## Receipt` inline, including the
223
312
  exact Verification Plan command, `Exit: 0`, `Verification: PASS`,
@@ -0,0 +1,239 @@
1
+ 'use strict';
2
+
3
+ // `.codex/hooks.json` is a shared configuration file, not a CafeKit payload. It used to be
4
+ // copied verbatim, so a single user-added hook turned the whole file into a user-modified
5
+ // artifact: a normal install then preserved CafeKit's stale hooks, and `--force-overwrite`
6
+ // destroyed the user's. These tests pin the merge that replaced that copy, mirroring how
7
+ // `.claude/settings.json` has always been handled.
8
+
9
+ const assert = require('node:assert/strict');
10
+ const fs = require('node:fs');
11
+ const os = require('node:os');
12
+ const path = require('node:path');
13
+ const { spawnSync } = require('node:child_process');
14
+ const { test } = require('node:test');
15
+
16
+ const PACKAGE_ROOT = path.join(__dirname, '../..');
17
+ const INSTALLER = path.join(PACKAGE_ROOT, 'bin/install.js');
18
+ const TEMPLATE = path.join(PACKAGE_ROOT, 'src/codex/hooks.json');
19
+ const MANIFEST = require(path.join(PACKAGE_ROOT, 'src/claude/migration-manifest.json'));
20
+ const { hookScript } = require(path.join(PACKAGE_ROOT, 'bin/phases/codex-hooks.js'));
21
+
22
+ const USER_STOP_COMMAND = 'node "$(git rev-parse --show-toplevel)/scripts/my-own-stop.js"';
23
+ const USER_PRETOOL_COMMAND = 'echo user-owned-pretooluse';
24
+
25
+ function inTempProject(run) {
26
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'cafekit-codex-hooks-own-'));
27
+ try {
28
+ return run(root);
29
+ } finally {
30
+ fs.rmSync(root, { recursive: true, force: true });
31
+ }
32
+ }
33
+
34
+ function install(root, extraArgs = []) {
35
+ return spawnSync(
36
+ process.execPath,
37
+ [INSTALLER, '--platform', 'codex', '--yes', ...extraArgs],
38
+ { cwd: root, encoding: 'utf8', env: { ...process.env, PATH: '/usr/bin:/bin' } }
39
+ );
40
+ }
41
+
42
+ function hooksPath(root) {
43
+ return path.join(root, '.codex', 'hooks.json');
44
+ }
45
+
46
+ function readHooks(root) {
47
+ return JSON.parse(fs.readFileSync(hooksPath(root), 'utf8'));
48
+ }
49
+
50
+ /** Every handler across every event, flattened. */
51
+ function allHandlers(config) {
52
+ return Object.values(config.hooks || {})
53
+ .flatMap((groups) => (Array.isArray(groups) ? groups : []))
54
+ .flatMap((group) => (Array.isArray(group?.hooks) ? group.hooks : []));
55
+ }
56
+
57
+ function allCommands(config) {
58
+ return allHandlers(config).map((handler) => handler?.command).filter(Boolean);
59
+ }
60
+
61
+ /** The CafeKit hook scripts the template registers, per event. */
62
+ function managedScripts() {
63
+ const template = JSON.parse(fs.readFileSync(TEMPLATE, 'utf8'));
64
+ const byEvent = {};
65
+ for (const [eventName, groups] of Object.entries(template.hooks || {})) {
66
+ byEvent[eventName] = groups
67
+ .flatMap((group) => group.hooks || [])
68
+ .map((handler) => hookScript(handler.command))
69
+ .filter(Boolean);
70
+ }
71
+ return byEvent;
72
+ }
73
+
74
+ /** Add two hooks CafeKit does not author: one under an event it owns, one under a new event. */
75
+ function addUserHooks(root) {
76
+ const config = readHooks(root);
77
+ config.hooks.Stop.push({ matcher: '*', hooks: [{ type: 'command', command: USER_STOP_COMMAND }] });
78
+ config.hooks.PreToolUse.push({ matcher: 'Bash', hooks: [{ type: 'command', command: USER_PRETOOL_COMMAND }] });
79
+ fs.writeFileSync(hooksPath(root), `${JSON.stringify(config, null, 2)}\n`);
80
+ }
81
+
82
+ test('a fresh install registers every CafeKit hook under its own event', () => {
83
+ inTempProject((root) => {
84
+ const result = install(root);
85
+ assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
86
+
87
+ const installed = readHooks(root);
88
+ for (const [eventName, scripts] of Object.entries(managedScripts())) {
89
+ const registered = (installed.hooks[eventName] || [])
90
+ .flatMap((group) => group.hooks || [])
91
+ .map((handler) => hookScript(handler.command))
92
+ .filter(Boolean);
93
+ for (const script of scripts) {
94
+ assert.ok(registered.includes(script), `${script} missing from ${eventName}`);
95
+ }
96
+ }
97
+ });
98
+ });
99
+
100
+ test('a reinstall preserves user-added hooks instead of overwriting them', () => {
101
+ inTempProject((root) => {
102
+ assert.equal(install(root).status, 0);
103
+ addUserHooks(root);
104
+
105
+ const second = install(root);
106
+ assert.equal(second.status, 0, `${second.stdout}\n${second.stderr}`);
107
+
108
+ const commands = allCommands(readHooks(root));
109
+ assert.ok(commands.includes(USER_STOP_COMMAND), 'user Stop hook was erased by the reinstall');
110
+ assert.ok(commands.includes(USER_PRETOOL_COMMAND), 'user PreToolUse hook was erased by the reinstall');
111
+ });
112
+ });
113
+
114
+ test('--force-overwrite does not destroy hooks CafeKit did not author', () => {
115
+ inTempProject((root) => {
116
+ assert.equal(install(root).status, 0);
117
+ addUserHooks(root);
118
+
119
+ const forced = install(root, ['--force-overwrite']);
120
+ assert.equal(forced.status, 0, `${forced.stdout}\n${forced.stderr}`);
121
+
122
+ const commands = allCommands(readHooks(root));
123
+ assert.ok(commands.includes(USER_STOP_COMMAND), '--force-overwrite erased the user Stop hook');
124
+ assert.ok(commands.includes(USER_PRETOOL_COMMAND), '--force-overwrite erased the user PreToolUse hook');
125
+ });
126
+ });
127
+
128
+ test('repeated installs never duplicate a CafeKit hook', () => {
129
+ inTempProject((root) => {
130
+ assert.equal(install(root).status, 0);
131
+ const afterFirst = allHandlers(readHooks(root)).length;
132
+
133
+ assert.equal(install(root).status, 0);
134
+ assert.equal(install(root).status, 0);
135
+
136
+ const config = readHooks(root);
137
+ assert.equal(allHandlers(config).length, afterFirst, 'a reinstall added handlers that were already registered');
138
+
139
+ // Uniqueness is per event, not global: state.cjs and completion-authority.cjs each
140
+ // register under several events by design.
141
+ for (const [eventName, groups] of Object.entries(config.hooks)) {
142
+ const scripts = groups
143
+ .flatMap((group) => group.hooks || [])
144
+ .map((handler) => hookScript(handler.command))
145
+ .filter(Boolean);
146
+ assert.equal(
147
+ new Set(scripts).size, scripts.length,
148
+ `duplicate hook scripts under ${eventName}: ${scripts.join(', ')}`
149
+ );
150
+ }
151
+ });
152
+ });
153
+
154
+ test('a hook the user moved to another event is not re-added to the one CafeKit chose', () => {
155
+ inTempProject((root) => {
156
+ assert.equal(install(root).status, 0);
157
+
158
+ // Move a CafeKit hook out of the group the template put it in, the way a user editing
159
+ // matchers would. Re-adding it on the next install would fire it twice.
160
+ const config = readHooks(root);
161
+ let moved = null;
162
+ for (const group of config.hooks.PreToolUse) {
163
+ const index = (group.hooks || []).findIndex((handler) => hookScript(handler.command) === 'inspect-block.cjs');
164
+ if (index >= 0) { moved = group.hooks.splice(index, 1)[0]; break; }
165
+ }
166
+ assert.ok(moved, 'fixture expects inspect-block.cjs under PreToolUse');
167
+ config.hooks.PreToolUse.push({ matcher: 'Read|Grep', hooks: [moved] });
168
+ fs.writeFileSync(hooksPath(root), `${JSON.stringify(config, null, 2)}\n`);
169
+
170
+ assert.equal(install(root).status, 0);
171
+
172
+ const scripts = allCommands(readHooks(root)).map(hookScript).filter(Boolean);
173
+ assert.equal(
174
+ scripts.filter((script) => script === 'inspect-block.cjs').length, 1,
175
+ 'the moved hook was re-added under its original matcher'
176
+ );
177
+ });
178
+ });
179
+
180
+ test('obsolete CafeKit hooks are pruned while similarly named foreign hooks stay', () => {
181
+ const obsolete = MANIFEST.obsolete.settingsHookCommandSubstrings;
182
+ assert.ok(obsolete.length > 0, 'fixture requires at least one retired hook substring');
183
+
184
+ inTempProject((root) => {
185
+ assert.equal(install(root).status, 0);
186
+
187
+ const config = readHooks(root);
188
+ const retired = `node ".codex/${obsolete[0]}"`;
189
+ const foreign = 'node "scripts/my-skill-router.cjs"';
190
+ config.hooks.UserPromptSubmit.push({
191
+ matcher: '*',
192
+ hooks: [{ type: 'command', command: retired }, { type: 'command', command: foreign }]
193
+ });
194
+ fs.writeFileSync(hooksPath(root), `${JSON.stringify(config, null, 2)}\n`);
195
+
196
+ const second = install(root);
197
+ assert.equal(second.status, 0, `${second.stdout}\n${second.stderr}`);
198
+
199
+ const commands = allCommands(readHooks(root));
200
+ assert.ok(!commands.includes(retired), 'retired CafeKit hook survived the prune');
201
+ assert.ok(commands.includes(foreign), 'prune removed a hook CafeKit never authored');
202
+ });
203
+ });
204
+
205
+ test('a malformed hooks.json is reported and left byte-identical, never overwritten', () => {
206
+ inTempProject((root) => {
207
+ fs.mkdirSync(path.join(root, '.codex'), { recursive: true });
208
+ const broken = '{ "hooks": { "Stop": [ }\n';
209
+ fs.writeFileSync(hooksPath(root), broken);
210
+
211
+ const result = install(root);
212
+ assert.notEqual(result.status, 0, 'a malformed hooks.json must fail the install, not pass silently');
213
+ assert.match(`${result.stdout}${result.stderr}`, /not valid JSON/);
214
+ assert.equal(fs.readFileSync(hooksPath(root), 'utf8'), broken, 'the malformed file was overwritten');
215
+ });
216
+ });
217
+
218
+ test('a dry run reports the merge without writing hooks.json', () => {
219
+ inTempProject((root) => {
220
+ const result = install(root, ['--dry-run']);
221
+ assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
222
+ assert.match(result.stdout, /Codex hooks/);
223
+ assert.equal(fs.existsSync(hooksPath(root)), false, 'a dry run wrote hooks.json');
224
+ });
225
+ });
226
+
227
+ test('hooks.json stays outside the ownership manifest, like settings.json', () => {
228
+ inTempProject((root) => {
229
+ assert.equal(install(root).status, 0);
230
+
231
+ const manifestPath = path.join(root, '.codex', 'cafekit-manifest.json');
232
+ assert.equal(fs.existsSync(manifestPath), true, 'the install manifest is missing');
233
+ const tracked = Object.keys(JSON.parse(fs.readFileSync(manifestPath, 'utf8')).files || {});
234
+ assert.ok(
235
+ !tracked.some((file) => file.endsWith('hooks.json')),
236
+ 'hooks.json is tracked as a payload file, so a user edit would be classified user-modified again'
237
+ );
238
+ });
239
+ });