@haposoft/cafekit 0.16.0-rc.8 → 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 (297) 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 +50 -0
  4. package/bin/__tests__/codex-native.test.js +1882 -70
  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 +1735 -98
  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 +12 -7
  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 +10 -3
  46. package/src/claude/hooks/__tests__/state.test.js +5 -0
  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 +2 -2
  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/workflow-policy.cjs +1 -1
  89. package/src/claude/settings/settings.json +16 -0
  90. package/src/claude/skills/agent-browser/SKILL.md +1 -1
  91. package/src/claude/skills/ai-multimodal/SKILL.md +1 -1
  92. package/src/claude/skills/brainstorm/SKILL.md +193 -172
  93. package/src/claude/skills/brainstorm/references/question-framework.md +105 -167
  94. package/src/claude/skills/chrome-devtools/SKILL.md +1 -1
  95. package/src/claude/skills/code-review/SKILL.md +43 -25
  96. package/src/claude/skills/code-review/references/spec-compliance-review.md +3 -4
  97. package/src/claude/skills/code-review/references/verification-gate.md +1 -1
  98. package/src/claude/skills/debug/SKILL.md +48 -19
  99. package/src/claude/skills/delegate/SKILL.md +1 -1
  100. package/src/claude/skills/develop/SKILL.md +92 -65
  101. package/src/claude/skills/develop/references/parallel-waves.md +36 -63
  102. package/src/claude/skills/develop/references/quality-gate.md +31 -4
  103. package/src/claude/skills/develop/references/subagent-patterns.md +21 -7
  104. package/src/claude/skills/docs/SKILL.md +42 -23
  105. package/src/claude/skills/docs/references/init-workflow.md +4 -4
  106. package/src/claude/skills/docs/references/reconstruct-workflow.md +6 -6
  107. package/src/claude/skills/docs/references/standard-docs-workflow.md +6 -2
  108. package/src/claude/skills/docs/references/summarize-workflow.md +2 -2
  109. package/src/claude/skills/docs/references/update-workflow.md +9 -7
  110. package/src/claude/skills/docs/templates/requirements-as-is.md +1 -1
  111. package/src/claude/skills/docx/SKILL.md +1 -1
  112. package/src/claude/skills/git/SKILL.md +1 -1
  113. package/src/claude/skills/git/references/commit-protocols.md +1 -1
  114. package/src/claude/skills/git/references/finish-branch.md +1 -1
  115. package/src/claude/skills/hotfix/SKILL.md +159 -170
  116. package/src/claude/skills/hotfix/references/diagnosis-protocol.md +14 -9
  117. package/src/claude/skills/hotfix/references/parallel-patterns.md +27 -13
  118. package/src/claude/skills/hotfix/references/prevention-gate.md +5 -0
  119. package/src/claude/skills/hotfix/references/review-cycle.md +21 -15
  120. package/src/claude/skills/hotfix/references/workflow-specialized.md +53 -21
  121. package/src/claude/skills/inspect/SKILL.md +55 -46
  122. package/src/claude/skills/inspect/references/internal-inspection.md +21 -5
  123. package/src/claude/skills/loop/SKILL.md +114 -0
  124. package/src/claude/skills/loop/references/bounded-loop-protocol.md +104 -0
  125. package/src/claude/skills/loop/references/metric-and-guard-contract.md +76 -0
  126. package/src/claude/skills/pdf/SKILL.md +1 -1
  127. package/src/claude/skills/pptx/SKILL.md +1 -1
  128. package/src/claude/skills/question/SKILL.md +16 -13
  129. package/src/claude/skills/research/SKILL.md +70 -43
  130. package/src/claude/skills/route/SKILL.md +94 -0
  131. package/src/claude/skills/route/references/agent-timing.md +46 -0
  132. package/src/claude/skills/route/references/chaining-patterns.md +53 -0
  133. package/src/claude/skills/route/references/task-taxonomy.md +48 -0
  134. package/src/claude/skills/specs/SKILL.md +41 -60
  135. package/src/claude/skills/specs/references/review.md +11 -8
  136. package/src/claude/skills/specs/references/templates.md +34 -18
  137. package/src/claude/skills/specs/templates/requirements-init.md +1 -1
  138. package/src/claude/skills/specs/templates/research.md +2 -2
  139. package/src/claude/skills/sync/SKILL.md +6 -6
  140. package/src/claude/skills/sync/references/sync-protocols.md +1 -1
  141. package/src/claude/skills/test/SKILL.md +120 -120
  142. package/src/claude/skills/test/references/execution-strategy.md +208 -361
  143. package/src/claude/skills/test/references/failure-triage.md +55 -121
  144. package/src/claude/skills/test/references/test-memory.md +20 -34
  145. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  146. package/src/claude/skills/web-testing/SKILL.md +1 -1
  147. package/src/claude/skills/xlsx/SKILL.md +1 -1
  148. package/src/claude/status.cjs +135 -33
  149. package/src/codex/AGENTS.md +14 -4
  150. package/src/codex/hooks/docs-sync.cjs +8 -3
  151. package/src/codex/hooks/lib/hook-context.cjs +18 -4
  152. package/src/codex/hooks/rules.cjs +29 -1
  153. package/src/codex/hooks/secret-output-guardrail.cjs +30 -0
  154. package/src/codex/hooks/spec-gate.cjs +3 -8
  155. package/src/codex/hooks/spec-state.cjs +2 -1
  156. package/src/codex/hooks.json +5 -0
  157. package/src/codex/runtime.json +2 -0
  158. package/src/common/.env.example +1 -1
  159. package/src/claude/skills/backend-development/SKILL.md +0 -101
  160. package/src/claude/skills/backend-development/references/backend-api-design.md +0 -495
  161. package/src/claude/skills/backend-development/references/backend-architecture.md +0 -454
  162. package/src/claude/skills/backend-development/references/backend-authentication.md +0 -338
  163. package/src/claude/skills/backend-development/references/backend-code-quality.md +0 -659
  164. package/src/claude/skills/backend-development/references/backend-debugging.md +0 -904
  165. package/src/claude/skills/backend-development/references/backend-devops.md +0 -491
  166. package/src/claude/skills/backend-development/references/backend-mindset.md +0 -387
  167. package/src/claude/skills/backend-development/references/backend-performance.md +0 -397
  168. package/src/claude/skills/backend-development/references/backend-security.md +0 -342
  169. package/src/claude/skills/backend-development/references/backend-technologies.md +0 -256
  170. package/src/claude/skills/backend-development/references/backend-testing.md +0 -429
  171. package/src/claude/skills/devops/.env.example +0 -76
  172. package/src/claude/skills/devops/SKILL.md +0 -102
  173. package/src/claude/skills/devops/references/browser-rendering.md +0 -305
  174. package/src/claude/skills/devops/references/cloudflare-d1-kv.md +0 -123
  175. package/src/claude/skills/devops/references/cloudflare-platform.md +0 -271
  176. package/src/claude/skills/devops/references/cloudflare-r2-storage.md +0 -280
  177. package/src/claude/skills/devops/references/cloudflare-workers-advanced.md +0 -312
  178. package/src/claude/skills/devops/references/cloudflare-workers-apis.md +0 -309
  179. package/src/claude/skills/devops/references/cloudflare-workers-basics.md +0 -418
  180. package/src/claude/skills/devops/references/docker-basics.md +0 -297
  181. package/src/claude/skills/devops/references/docker-compose.md +0 -292
  182. package/src/claude/skills/devops/references/gcloud-platform.md +0 -297
  183. package/src/claude/skills/devops/references/gcloud-services.md +0 -304
  184. package/src/claude/skills/devops/references/kubernetes-basics.md +0 -95
  185. package/src/claude/skills/devops/references/kubernetes-helm-advanced.md +0 -70
  186. package/src/claude/skills/devops/references/kubernetes-helm.md +0 -81
  187. package/src/claude/skills/devops/references/kubernetes-kubectl.md +0 -74
  188. package/src/claude/skills/devops/references/kubernetes-security-advanced.md +0 -94
  189. package/src/claude/skills/devops/references/kubernetes-security.md +0 -89
  190. package/src/claude/skills/devops/references/kubernetes-troubleshooting-advanced.md +0 -74
  191. package/src/claude/skills/devops/references/kubernetes-troubleshooting.md +0 -49
  192. package/src/claude/skills/devops/references/kubernetes-workflows-advanced.md +0 -75
  193. package/src/claude/skills/devops/references/kubernetes-workflows.md +0 -76
  194. package/src/claude/skills/devops/scripts/cloudflare_deploy.py +0 -269
  195. package/src/claude/skills/devops/scripts/docker_optimize.py +0 -332
  196. package/src/claude/skills/devops/scripts/requirements.txt +0 -20
  197. package/src/claude/skills/devops/scripts/tests/requirements.txt +0 -3
  198. package/src/claude/skills/devops/scripts/tests/test_cloudflare_deploy.py +0 -285
  199. package/src/claude/skills/devops/scripts/tests/test_docker_optimize.py +0 -436
  200. package/src/claude/skills/frontend-design/SKILL.md +0 -135
  201. package/src/claude/skills/frontend-design/references/ai-multimodal-overview.md +0 -165
  202. package/src/claude/skills/frontend-design/references/analysis-best-practices.md +0 -80
  203. package/src/claude/skills/frontend-design/references/analysis-prompts.md +0 -141
  204. package/src/claude/skills/frontend-design/references/analysis-techniques.md +0 -118
  205. package/src/claude/skills/frontend-design/references/animejs.md +0 -396
  206. package/src/claude/skills/frontend-design/references/anti-slop-rules.md +0 -103
  207. package/src/claude/skills/frontend-design/references/asset-generation.md +0 -337
  208. package/src/claude/skills/frontend-design/references/bento-motion-engine.md +0 -142
  209. package/src/claude/skills/frontend-design/references/design-extraction-overview.md +0 -71
  210. package/src/claude/skills/frontend-design/references/extraction-best-practices.md +0 -141
  211. package/src/claude/skills/frontend-design/references/extraction-output-templates.md +0 -162
  212. package/src/claude/skills/frontend-design/references/extraction-prompts.md +0 -127
  213. package/src/claude/skills/frontend-design/references/magicui-components.md +0 -129
  214. package/src/claude/skills/frontend-design/references/performance-guardrails.md +0 -169
  215. package/src/claude/skills/frontend-design/references/premium-design-patterns.md +0 -93
  216. package/src/claude/skills/frontend-design/references/redesign-audit-checklist.md +0 -114
  217. package/src/claude/skills/frontend-design/references/technical-accessibility.md +0 -119
  218. package/src/claude/skills/frontend-design/references/technical-best-practices.md +0 -97
  219. package/src/claude/skills/frontend-design/references/technical-optimization.md +0 -44
  220. package/src/claude/skills/frontend-design/references/technical-overview.md +0 -90
  221. package/src/claude/skills/frontend-design/references/technical-workflows.md +0 -150
  222. package/src/claude/skills/frontend-design/references/visual-analysis-overview.md +0 -95
  223. package/src/claude/skills/frontend-design/references/workflow-3d.md +0 -102
  224. package/src/claude/skills/frontend-design/references/workflow-describe.md +0 -87
  225. package/src/claude/skills/frontend-design/references/workflow-immersive.md +0 -87
  226. package/src/claude/skills/frontend-design/references/workflow-quick.md +0 -57
  227. package/src/claude/skills/frontend-design/references/workflow-screenshot.md +0 -63
  228. package/src/claude/skills/frontend-design/references/workflow-video.md +0 -74
  229. package/src/claude/skills/frontend-development/SKILL.md +0 -406
  230. package/src/claude/skills/frontend-development/resources/common-patterns.md +0 -331
  231. package/src/claude/skills/frontend-development/resources/complete-examples.md +0 -872
  232. package/src/claude/skills/frontend-development/resources/component-patterns.md +0 -502
  233. package/src/claude/skills/frontend-development/resources/data-fetching.md +0 -767
  234. package/src/claude/skills/frontend-development/resources/file-organization.md +0 -502
  235. package/src/claude/skills/frontend-development/resources/loading-and-error-states.md +0 -501
  236. package/src/claude/skills/frontend-development/resources/performance.md +0 -406
  237. package/src/claude/skills/frontend-development/resources/routing-guide.md +0 -364
  238. package/src/claude/skills/frontend-development/resources/styling-guide.md +0 -428
  239. package/src/claude/skills/frontend-development/resources/typescript-standards.md +0 -418
  240. package/src/claude/skills/mobile-development/SKILL.md +0 -218
  241. package/src/claude/skills/mobile-development/references/mobile-android.md +0 -604
  242. package/src/claude/skills/mobile-development/references/mobile-best-practices.md +0 -544
  243. package/src/claude/skills/mobile-development/references/mobile-debugging.md +0 -1089
  244. package/src/claude/skills/mobile-development/references/mobile-frameworks.md +0 -465
  245. package/src/claude/skills/mobile-development/references/mobile-ios.md +0 -496
  246. package/src/claude/skills/mobile-development/references/mobile-mindset.md +0 -542
  247. package/src/claude/skills/react-best-practices/AGENTS.md +0 -2249
  248. package/src/claude/skills/react-best-practices/README.md +0 -123
  249. package/src/claude/skills/react-best-practices/SKILL.md +0 -128
  250. package/src/claude/skills/react-best-practices/metadata.json +0 -15
  251. package/src/claude/skills/react-best-practices/rules/_sections.md +0 -46
  252. package/src/claude/skills/react-best-practices/rules/_template.md +0 -28
  253. package/src/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  254. package/src/claude/skills/react-best-practices/rules/advanced-use-latest.md +0 -49
  255. package/src/claude/skills/react-best-practices/rules/async-api-routes.md +0 -38
  256. package/src/claude/skills/react-best-practices/rules/async-defer-await.md +0 -80
  257. package/src/claude/skills/react-best-practices/rules/async-dependencies.md +0 -36
  258. package/src/claude/skills/react-best-practices/rules/async-parallel.md +0 -28
  259. package/src/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
  260. package/src/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
  261. package/src/claude/skills/react-best-practices/rules/bundle-conditional.md +0 -31
  262. package/src/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
  263. package/src/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  264. package/src/claude/skills/react-best-practices/rules/bundle-preload.md +0 -50
  265. package/src/claude/skills/react-best-practices/rules/client-event-listeners.md +0 -74
  266. package/src/claude/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
  267. package/src/claude/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
  268. package/src/claude/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
  269. package/src/claude/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
  270. package/src/claude/skills/react-best-practices/rules/js-cache-storage.md +0 -70
  271. package/src/claude/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
  272. package/src/claude/skills/react-best-practices/rules/js-early-exit.md +0 -50
  273. package/src/claude/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
  274. package/src/claude/skills/react-best-practices/rules/js-index-maps.md +0 -37
  275. package/src/claude/skills/react-best-practices/rules/js-length-check-first.md +0 -49
  276. package/src/claude/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
  277. package/src/claude/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
  278. package/src/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
  279. package/src/claude/skills/react-best-practices/rules/rendering-activity.md +0 -26
  280. package/src/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  281. package/src/claude/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
  282. package/src/claude/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
  283. package/src/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  284. package/src/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  285. package/src/claude/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
  286. package/src/claude/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
  287. package/src/claude/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
  288. package/src/claude/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
  289. package/src/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
  290. package/src/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  291. package/src/claude/skills/react-best-practices/rules/rerender-memo.md +0 -44
  292. package/src/claude/skills/react-best-practices/rules/rerender-transitions.md +0 -40
  293. package/src/claude/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
  294. package/src/claude/skills/react-best-practices/rules/server-cache-lru.md +0 -41
  295. package/src/claude/skills/react-best-practices/rules/server-cache-react.md +0 -26
  296. package/src/claude/skills/react-best-practices/rules/server-parallel-fetching.md +0 -79
  297. package/src/claude/skills/react-best-practices/rules/server-serialization.md +0 -38
@@ -1,128 +1,62 @@
1
- # Failure Triage
1
+ # Failure triage
2
2
 
3
- Classify every test failure into a category, then apply the matching action.
4
- Referenced by `SKILL.md` Phase 3 and by the `test-runner` agent.
3
+ Classify observed failures, preserve real output, and return the cause to the
4
+ implementation owner. Testing never edits implementation or tests.
5
5
 
6
- ---
6
+ ## Categories
7
7
 
8
- ## Failure Categories
9
-
10
- | # | Category | Description | Source |
11
- |---|---|---|---|
12
- | 1 | **Compile Error** | Syntax, type, or import errors preventing test execution | Pre-flight (tsc, eslint, flake8...) |
13
- | 2 | **Logic Error** | Test ran but assertion failed — expected vs actual mismatch | Unit / Integration test output |
14
- | 3 | **Environment Error** | Missing env vars, DB not running, port conflict, network unreachable | Integration / E2E test output |
15
- | 4 | **Flaky Test** | Pass/fail intermittently — indicates race condition or shared state | Observed across multiple runs |
16
- | 5 | **Coverage Gap** | Tests pass but coverage drops below threshold | Coverage report |
17
- | 6 | **Build Error** | Code compiles but production build fails | Build step output |
18
- | 7 | **UI Console Error** | JavaScript errors or pageerrors captured during browser session | `console.js` output |
19
- | 8 | **UI Network Error** | API responses with 4xx or 5xx status during page load | `network.js` output |
20
- | 9 | **UI Performance** | Core Web Vitals exceed acceptable thresholds, or memory leak | `performance.js` |
21
- | 10 | **Accessibility Error** | Interactive elements missing accessible names or labels | `aria-snapshot.js` |
22
- | 11 | **User Flow Error** | E2E form submission failed, unexpected redirect | `click.js` + `fill.js` |
23
- | 12 | **SEO Error** | Missing meta tags, H1 issues, broken canonical | `evaluate.js` |
24
- | 13 | **Security Warning** | Missing HTTP security headers, exposed secrets | `network.js` / source |
25
- | 14 | **Broken Links** | Internal crawler found 404s on discovered pages | Phase 0.5 Crawler |
26
- | 15 | **UI Visual Error** | AI visual analysis detected layout break, overlap | `gemini_batch_process.py` |
27
-
28
- ---
29
-
30
- ## Triage Decision Tree
31
-
32
- ```
33
- Failure detected
34
- │
35
- ├─ Compile Error (#1)
36
- │ → STOP immediately. Do NOT run further tests.
37
- │ → Report: file, line, error message.
38
- │ → Action: return to implementer. Fix compile errors first.
39
- │
40
- ├─ Logic Error (#2)
41
- │ → Report: test name, file:line, expected value, actual value.
42
- │ → Action: return to implementer with precise location.
43
- │ → Do NOT modify test to make it pass.
44
- │
45
- ├─ Environment Error (#3)
46
- │ → Report: which service/env var is missing.
47
- │ → Action: escalate to USER (not implementer).
48
- │ "Environment issue: [DB/service] not reachable. Please start it."
49
- │
50
- ├─ Flaky Test (#4)
51
- │ → Report: test name + "intermittent failure observed".
52
- │ → Action: flag for implementer review.
53
- │ Likely cause: shared state, async timing, or test ordering.
54
- │
55
- ├─ Coverage Gap (#5)
56
- │ → Report: specific uncovered files and functions (not just %).
57
- │ → Action: flag as PARTIAL verdict. Do not block PASS.
58
- │ "Coverage gap in: src/auth/refresh.ts — add tests for error path"
59
- │
60
- ├─ Build Error (#6)
61
- │ → Report: build command, error output (last 20 lines).
62
- │ → Action: return to implementer.
63
- │
64
- ├─ UI Console Error (#7)
65
- │ → Report: error message, source file, line number.
66
- │ → Action: return to implementer if JS error.
67
- │ If external script error: flag as warning only.
68
- │
69
- ├─ UI Network Error (#8)
70
- │ → Report: endpoint URL, status code, response body excerpt.
71
- │ → Action: 404 → implementer (missing route/resource).
72
- │ 500 → implementer (server error). 401/403 → auth issue (user).
73
- │
74
- ├─ UI Performance (#9)
75
- │ → Report: specific metric name + actual value + threshold.
76
- │ → Action: flag as warning. Block PASS only if LCP > 4s or CLS > 0.25.
77
- │
78
- ├─ Accessibility Error (#10)
79
- │ → Report: element role + missing attribute.
80
- │ → Action: return to implementer. Add aria-label / alt / for attributes.
81
- │
82
- ├─ User Flow Error (#11)
83
- │ → Report: step failed (e.g., login submit), expected vs actual URL/state.
84
- │ → Action: return to implementer to fix E2E UI flow.
85
- │
86
- ├─ SEO Error (#12)
87
- │ → Report: missing tag or invalid setup (e.g., no H1, bad canonical).
88
- │ → Action: return to implementer. Add missing HTML meta tags.
89
- │
90
- ├─ Security Warning (#13)
91
- │ → Report: missing header names or exposed secret pattern.
92
- │ → Action: return to implementer. Add helmet/headers or remove secrets.
93
- │
94
- ├─ Broken Links (#14)
95
- │ → Report: crawler source URL → broken target URL (404).
96
- │ → Action: return to implementer to fix href paths.
97
- │
98
- └─ UI Visual Error (#15)
99
- → Report: AI parsed visual issue (e.g., button overlapping text).
100
- → Action: return to implementer to fix CSS/layout issues.
101
- ```
102
-
103
- ---
104
-
105
- ## Escalation Protocol
106
-
107
- | Failure count | Verdict | Action |
8
+ | Category | Evidence | Default result |
108
9
  |---|---|---|
109
- | 0 failures | **PASS** | Proceed to hapo:code-review |
110
- | 1–2 failures | **FAIL** | Return to implementer with targeted fix list |
111
- | 3–10 failures | **FAIL** | Return to implementer, flag as "significant failures" |
112
- | > 10 failures OR 0 tests pass | **COLLAPSE** | Call `AskUserQuestion`: "Test suite critically broken. User intervention required." |
113
- | Only coverage gaps | **PARTIAL** | Proceed to hapo:code-review, attach coverage gap list |
114
- | Environment errors only | **BLOCKED** | Escalate to user (not implementer) |
115
-
116
- ---
117
-
118
- ## Report Format per Failure
10
+ | Compilation or packaging | command, exit, relevant file/line | `FAIL` |
11
+ | Logic/contract | named probe, expected, observed | `FAIL` |
12
+ | Environment/prerequisite | missing tool, service, variable, permission | `BLOCKED` before execution; otherwise `FAIL` after an attempted command |
13
+ | Flaky/nondeterministic | repeated current runs with differing outcomes | `FAIL` |
14
+ | Coverage/reachability gap | exact uncovered branch or unreachable surface | `FAIL`, or `PASS_WITH_WARNINGS` only when explicitly non-required |
15
+ | UI console/network/flow | URL path, safe status, redacted error | `FAIL` when required |
16
+ | Accessibility/visual/performance/SEO | metric or element plus declared threshold | requirement decides `FAIL` or `PASS_WITH_WARNINGS` |
17
+ | Security/auth safety | unsafe origin, redirect, action, or disclosure risk | `BLOCKED` before execution; otherwise `FAIL` |
18
+ | Proof integrity | malformed, duplicate, stale, skipped, contradictory, zero-test, or unknown proof | `BLOCKED` |
19
+
20
+ ## Canonical verdicts
21
+
22
+ Use only `PASS | PASS_WITH_WARNINGS | FAIL | BLOCKED`.
23
+
24
+ - `PASS`: every required branch executed and passed under the exact current
25
+ command/provenance with no skips or warnings.
26
+ - `PASS_WITH_WARNINGS`: required proof passed, but a real non-required warning
27
+ remains. It does not close a process-first task.
28
+ - `FAIL`: execution was attempted and a required assertion, command,
29
+ reachability check, artifact, redaction check, or safety expectation failed.
30
+ - `BLOCKED`: safe execution could not begin or proof structure/identity cannot
31
+ be trusted. State the changed prerequisite; do not blind-retry.
32
+
33
+ Do not emit `PARTIAL`, `COLLAPSE`, `NO_TESTS`, or an unknown result. Normalize
34
+ those legacy diagnostics to one of the four verdicts and keep work unfinished.
35
+ Failure count never changes the lattice: aggregation remains
36
+ `FAIL` > `BLOCKED` > `PASS_WITH_WARNINGS` > `PASS`.
37
+
38
+ ## Triage sequence
39
+
40
+ 1. Record the exact redacted command, exit, counts, named probe, expected, and
41
+ observed result.
42
+ 2. Separate product failure from environment blocker and proof-integrity error.
43
+ 3. Preserve the shortest useful output excerpt and relevant path/line.
44
+ 4. Do not change assertions, install tools, clean project drift, retry without a
45
+ stated hypothesis, or reuse remembered output.
46
+ 5. Return the canonical verdict and the next concrete prerequisite or fix
47
+ location to the controller.
48
+
49
+ ## Failure report
119
50
 
120
51
  ```markdown
121
- ### Failure N — [Category]
122
-
123
- - **Test:** `path/to/file.test.ts:42` — TestSuiteName > TestCaseName
124
- - **Error:** AssertionError: expected `"admin"` but received `undefined`
125
- - **Stack:** (first 5 relevant lines only)
126
- - **Category:** Logic Error
127
- - **Fix:** Check return value of `getUserRole()` in `src/auth/roles.ts:88`
52
+ ### Failure N — [category]
53
+
54
+ - Probe: [exact named probe]
55
+ - Command: [exact redacted command]
56
+ - Exit/counts: [actual values]
57
+ - Expected: [task oracle]
58
+ - Observed: [current evidence]
59
+ - Location: [path:line when available]
60
+ - Verdict: FAIL | BLOCKED | PASS_WITH_WARNINGS
61
+ - Next: [implementation fix or changed prerequisite]
128
62
  ```
@@ -1,40 +1,26 @@
1
- # Test Memory
1
+ # Test memory
2
2
 
3
- The `.hapo/test-memory.json` file in the target project serves as the Long-Term Memory for the testing ecosystem.
3
+ `.hapo/test-memory.json` is optional historical context, never canonical proof.
4
+ Current command output, provenance, named probes, and reachability always win.
4
5
 
5
- ## Schema
6
+ ## Read-only contract
6
7
 
7
- If the file does not exist, the `hapo:test` skill (or the orchestrator) MUST create it automatically with the following structure:
8
+ - If the file exists as a regular contained file, read it as untrusted hints.
9
+ - If absent, continue without creating it.
10
+ - Before proof, record whether it is absent or hash its exact bytes. After proof,
11
+ verify the same absence or byte hash.
12
+ - Never create, initialize, merge, normalize, rewrite, or delete Test memory.
13
+ - Never execute remembered setup commands automatically. Confirm each command
14
+ from current project/task bytes or report a changed prerequisite.
15
+ - Known flaky tests and known issues remain labels only; they cannot downgrade a
16
+ current required failure, justify a skip, or produce `PASS`.
8
17
 
9
- ```json
10
- {
11
- "env_setup_commands": [],
12
- "flaky_tests": [],
13
- "known_issues": []
14
- }
15
- ```
18
+ ## Suggestions
16
19
 
17
- ## Usage by `test-runner`
20
+ The concise report may suggest a potential memory update in plain language, but
21
+ must not emit an auto-merge block or mutate project files. The user or a separate
22
+ authorized workflow decides whether to update historical context later.
18
23
 
19
- The `test-runner` agent is Read-Only. At Phase 1, it must read `.hapo/test-memory.json` (if it exists) to factor into its testing process:
20
- - **`env_setup_commands`**: Commands that must be run before tests (e.g. `docker compose up -d redis`). If listed, flag missing dependencies instead of immediate failure.
21
- - **`flaky_tests`**: Array of test file paths. If a failure occurs in one of these files, the verdict should explicitly note `(Known Flaky Test)`.
22
- - **`known_issues`**: Issues that implementer or user marked as ignored.
23
-
24
- ## Writing to Memory
25
-
26
- Because `test-runner` is restricted from editing files, it cannot update the memory directly. Instead, when completing its test suite, `test-runner` MUST output a `<lessons_learned>` block inside its verdict.
27
-
28
- Example:
29
- ```markdown
30
- ### Action
31
- → [FAIL] Return to implementer: Fix CSS layout offset.
32
-
33
- <lessons_learned>
34
- {
35
- "flaky_tests_added": ["src/e2e/payment.test.ts"]
36
- }
37
- </lessons_learned>
38
- ```
39
-
40
- The orchestrating `hapo:test` skill (Phase 4) then intercepts this block and automatically merges it into `.hapo/test-memory.json`.
24
+ Hashing memory alone is insufficient for side-effect proof. Also observe and
25
+ report tracked, untracked, and ignored project-command drift; preserve all
26
+ user-owned changes and never silently clean them.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: hapo:ui-ux-pro-max
2
+ name: cf:ui-ux-pro-max
3
3
  description: "UI/UX design intelligence for web and mobile. Includes 50+ styles, 161 color palettes, 57 font pairings, 161 product types, 99 UX guidelines, and 25 chart types across 10 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui, and HTML/CSS). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, and check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, and mobile app. Elements: button, modal, navbar, sidebar, card, table, form, and chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, and flat design. Topics: color systems, accessibility, animation, layout, typography, font pairing, spacing, interaction states, shadow, and gradient. Integrations: shadcn/ui MCP for component search and examples."
4
4
  user-invocable: true
5
5
  when_to_use: "Invoke to choose colors, fonts, layout, and design systems."
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: hapo:web-testing
2
+ name: cf:web-testing
3
3
  description: Web testing with Playwright, Vitest, k6. E2E/unit/integration/load/security/visual/a11y testing. Use for test automation, flakiness, Core Web Vitals, mobile gestures, cross-browser.
4
4
  license: Apache-2.0
5
5
  user-invocable: true
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: hapo:xlsx
2
+ name: cf:xlsx
3
3
  description: Create, edit, analyze spreadsheets (.xlsx, .csv, .tsv). Use for Excel formulas, data analysis, visualization, formatting, pivot tables, charts, formula recalculation.
4
4
  license: Proprietary. LICENSE.txt has complete terms
5
5
  user-invocable: true
@@ -26,6 +26,10 @@ const { getGitInfo } = require('./hooks/lib/git.cjs');
26
26
  // ratio so 1M-context models are not treated as if they were 200k.
27
27
  const AUTOCOMPACT_BUFFER_RATIO = 0.225;
28
28
 
29
+ // Usage cache freshness gate: a cache older than this hides the quota area
30
+ // instead of rendering stale numbers.
31
+ const USAGE_CACHE_TTL_MS = 300000;
32
+
29
33
  /**
30
34
  * Expand home directory to ~
31
35
  */
@@ -111,6 +115,21 @@ function buildUsageString(ctx) {
111
115
  * Combines parts based on content length vs terminal width
112
116
  * Tries to minimize lines while keeping content readable
113
117
  */
118
+ function buildBranchPart(ctx) {
119
+ if (!ctx.gitBranch) return '';
120
+ let branchPart = `🌿 ${ctx.gitBranch}`;
121
+ // Build git status indicators: (unstaged, +staged, ahead↑, behind↓)
122
+ const gitIndicators = [];
123
+ if (ctx.gitUnstaged > 0) gitIndicators.push(`${ctx.gitUnstaged}`);
124
+ if (ctx.gitStaged > 0) gitIndicators.push(`+${ctx.gitStaged}`);
125
+ if (ctx.gitAhead > 0) gitIndicators.push(`${ctx.gitAhead}↑`);
126
+ if (ctx.gitBehind > 0) gitIndicators.push(`${ctx.gitBehind}↓`);
127
+ if (gitIndicators.length > 0) {
128
+ branchPart += ` ${yellow(`(${gitIndicators.join(', ')})`)}`;
129
+ }
130
+ return branchPart;
131
+ }
132
+
114
133
  function renderSessionLines(ctx) {
115
134
  const lines = [];
116
135
  const termWidth = getTerminalWidth();
@@ -118,20 +137,7 @@ function renderSessionLines(ctx) {
118
137
 
119
138
  // Build all atomic parts for flexible composition (no colors on static text)
120
139
  const dirPart = `📁 ${ctx.currentDir}`;
121
-
122
- let branchPart = '';
123
- if (ctx.gitBranch) {
124
- branchPart = `🌿 ${ctx.gitBranch}`;
125
- // Build git status indicators: (unstaged, +staged, ahead↑, behind↓)
126
- const gitIndicators = [];
127
- if (ctx.gitUnstaged > 0) gitIndicators.push(`${ctx.gitUnstaged}`);
128
- if (ctx.gitStaged > 0) gitIndicators.push(`+${ctx.gitStaged}`);
129
- if (ctx.gitAhead > 0) gitIndicators.push(`${ctx.gitAhead}↑`);
130
- if (ctx.gitBehind > 0) gitIndicators.push(`${ctx.gitBehind}↓`);
131
- if (gitIndicators.length > 0) {
132
- branchPart += ` ${yellow(`(${gitIndicators.join(', ')})`)}`;
133
- }
134
- }
140
+ const branchPart = buildBranchPart(ctx);
135
141
 
136
142
  // Active plan indicator (disabled for now - code preserved)
137
143
  // const planPart = ctx.activePlan ? `📋 ${ctx.activePlan}` : '';
@@ -150,6 +156,7 @@ function renderSessionLines(ctx) {
150
156
  const usageStr = buildUsageString(ctx);
151
157
  if (usageStr) {
152
158
  sessionPart += ` ⌛ ${usageStr.replace(/\)$/, ' used)')}`;
159
+ if (ctx.weeklyText) sessionPart += ` ${ctx.weeklyText}`;
153
160
  }
154
161
 
155
162
  // Build stats part (only lines changed now)
@@ -313,7 +320,7 @@ function renderMinimal(ctx) {
313
320
  parts.push(`${batteryIcon} ${ctx.contextPercent}%`);
314
321
  }
315
322
  const usageStr = buildUsageString(ctx);
316
- if (usageStr) parts.push(`⏰ ${usageStr}`);
323
+ if (usageStr) parts.push(`⏰ ${usageStr}${ctx.weeklyText ? ` ${ctx.weeklyText}` : ''}`);
317
324
  if (ctx.gitBranch) parts.push(`🌿 ${ctx.gitBranch}`);
318
325
  parts.push(`📁 ${ctx.currentDir}`);
319
326
  console.log(parts.join(' '));
@@ -329,7 +336,7 @@ function renderCompact(ctx) {
329
336
  line1 += ` ${coloredBar(ctx.contextPercent, 12)} ${ctx.contextPercent}%`;
330
337
  }
331
338
  const usageStr = buildUsageString(ctx);
332
- if (usageStr) line1 += ` ⌛ ${usageStr}`;
339
+ if (usageStr) line1 += ` ⌛ ${usageStr}${ctx.weeklyText ? ` ${ctx.weeklyText}` : ''}`;
333
340
  console.log(line1.replace(/ /g, '\u00A0'));
334
341
 
335
342
  // Line 2: Location (branch + directory)
@@ -359,13 +366,84 @@ function render(ctx, singleLineMode = false) {
359
366
  if (todosLine) lines.push(todosLine);
360
367
  }
361
368
 
362
- // Output all lines with non-breaking spaces for alignment
369
+ writeStyledLines(lines);
370
+ }
371
+
372
+ /**
373
+ * Output lines with non-breaking spaces for alignment
374
+ */
375
+ function writeStyledLines(lines) {
363
376
  for (const line of lines) {
364
377
  const outputLine = colors.shouldUseColor ? `${RESET}${line.replace(/ /g, '\u00A0')}` : line;
365
378
  console.log(outputLine);
366
379
  }
367
380
  }
368
381
 
382
+ // ============================================================================
383
+ // CONFIGURABLE LAYOUT
384
+ // Global shape: { lines: [[sectionId, ...], ...] } — each inner array is one
385
+ // output line; modes only slice the line count (minimal = 1, compact = 2,
386
+ // full = all). Agents/todos stay outside `lines` behind their own flags.
387
+ // ============================================================================
388
+
389
+ const LAYOUT_SECTION_IDS = ['model', 'context', 'quota', 'directory', 'git', 'plan', 'cost', 'changes'];
390
+
391
+ const LAYOUT_SECTIONS = {
392
+ model: (ctx) => `🤖 ${ctx.modelName}`,
393
+ context: (ctx) => ctx.contextPercent > 0
394
+ ? `${coloredBar(ctx.contextPercent, 12)} ${ctx.contextPercent}%`
395
+ : null,
396
+ quota: (ctx) => {
397
+ const usageStr = buildUsageString(ctx);
398
+ if (!usageStr) return null;
399
+ let out = `\u231B ${usageStr.replace(/\)$/, ' used)')}`;
400
+ if (ctx.weeklyText) out += ` ${ctx.weeklyText}`;
401
+ return out;
402
+ },
403
+ directory: (ctx) => `📁 ${ctx.currentDir}`,
404
+ git: (ctx) => buildBranchPart(ctx) || null,
405
+ plan: (ctx) => ctx.activePlan ? `📋 ${ctx.activePlan}` : null,
406
+ cost: (ctx) => ctx.costText ? `💵 ${ctx.costText.replace(/(\.\d{2})\d+/, '$1')}` : null,
407
+ changes: (ctx) => (ctx.linesAdded > 0 || ctx.linesRemoved > 0)
408
+ ? `📝 ${green(`+${ctx.linesAdded}`)} ${red(`-${ctx.linesRemoved}`)}`
409
+ : null,
410
+ };
411
+
412
+ /**
413
+ * Normalize a raw statuslineLayout config value.
414
+ * Unknown section ids are ignored; an empty or invalid layout returns null so
415
+ * rendering falls back to the default renderers.
416
+ */
417
+ function normalizeStatuslineLayout(raw) {
418
+ if (!raw || typeof raw !== 'object' || !Array.isArray(raw.lines)) return null;
419
+ const lines = raw.lines
420
+ .filter((line) => Array.isArray(line))
421
+ .map((line) => line.filter((id) => LAYOUT_SECTION_IDS.includes(id)))
422
+ .filter((line) => line.length > 0);
423
+ if (lines.length === 0) return null;
424
+ return { lines, agents: raw.agents !== false, todos: raw.todos !== false };
425
+ }
426
+
427
+ /**
428
+ * Render with a user-configured layout. Modes only slice the line count.
429
+ */
430
+ function renderLayout(ctx, layout, mode) {
431
+ const lineLimit = mode === 'minimal' ? 1 : mode === 'compact' ? 2 : layout.lines.length;
432
+ const lines = [];
433
+ for (const ids of layout.lines.slice(0, lineLimit)) {
434
+ const parts = ids.map((id) => LAYOUT_SECTIONS[id](ctx)).filter(Boolean);
435
+ if (parts.length > 0) lines.push(parts.join(' '));
436
+ }
437
+ if (mode !== 'minimal' && mode !== 'compact') {
438
+ if (layout.agents) lines.push(...renderAgentsLines(ctx.transcript));
439
+ if (layout.todos) {
440
+ const todosLine = renderTodosLine(ctx.transcript);
441
+ if (todosLine) lines.push(todosLine);
442
+ }
443
+ }
444
+ writeStyledLines(lines);
445
+ }
446
+
369
447
  // ============================================================================
370
448
  // MAIN
371
449
  // ============================================================================
@@ -446,6 +524,7 @@ async function main() {
446
524
 
447
525
  // Session timer - read actual reset time from usage limits cache
448
526
  let sessionText = '';
527
+ let weeklyText = '';
449
528
  const transcriptPath = data.transcript_path;
450
529
 
451
530
  // Parse transcript for tools/agents/todos
@@ -459,9 +538,11 @@ async function main() {
459
538
  const cache = JSON.parse(fs.readFileSync(usageCachePath, 'utf8'));
460
539
 
461
540
  // Check status flag for fallback (non-OAuth scenarios)
541
+ const fresh = typeof cache.timestamp === 'number'
542
+ && Date.now() - cache.timestamp < USAGE_CACHE_TTL_MS;
462
543
  if (cache.status === 'unavailable') {
463
544
  sessionText = 'N/A';
464
- } else {
545
+ } else if (cache.status === 'available' && fresh) {
465
546
  const fiveHour = cache.data?.five_hour;
466
547
  usagePercent = fiveHour?.utilization ?? null;
467
548
  const resetAt = fiveHour?.resets_at;
@@ -474,6 +555,19 @@ async function main() {
474
555
  sessionText = `${rh}h ${rm}m until reset`;
475
556
  }
476
557
  }
558
+ const sevenDay = cache.data?.seven_day;
559
+ if (sevenDay?.utilization != null) {
560
+ weeklyText = `wk ${Math.round(sevenDay.utilization)}%`;
561
+ const wkResetAt = sevenDay.resets_at;
562
+ if (wkResetAt) {
563
+ const wkRemaining = Math.floor(new Date(wkResetAt).getTime() / 1000) - Math.floor(Date.now() / 1000);
564
+ if (wkRemaining > 0) {
565
+ const wd = Math.floor(wkRemaining / 86400);
566
+ const wh = Math.floor((wkRemaining % 86400) / 3600);
567
+ weeklyText += ` (${wd}d ${wh}h)`;
568
+ }
569
+ }
570
+ }
477
571
  }
478
572
  }
479
573
  } catch {}
@@ -502,6 +596,7 @@ async function main() {
502
596
  activePlan,
503
597
  contextPercent,
504
598
  sessionText,
599
+ weeklyText,
505
600
  usagePercent,
506
601
  costText,
507
602
  linesAdded,
@@ -515,21 +610,28 @@ async function main() {
515
610
  const statuslineMode = config.statusline || 'full';
516
611
  colors.setColorEnabled(config.statuslineColors !== false);
517
612
 
518
- // Render based on mode
519
- switch (statuslineMode) {
520
- case 'none':
521
- console.log('');
522
- break;
523
- case 'minimal':
524
- renderMinimal(ctx);
525
- break;
526
- case 'compact':
527
- renderCompact(ctx);
528
- break;
529
- case 'full':
530
- default:
531
- render(ctx, false);
532
- break;
613
+ // Render based on mode. A valid statuslineLayout takes over line
614
+ // composition; an absent, empty, or invalid layout falls back to the
615
+ // default renderers below.
616
+ const layout = normalizeStatuslineLayout(config.statuslineLayout);
617
+ if (statuslineMode !== 'none' && layout) {
618
+ renderLayout(ctx, layout, statuslineMode);
619
+ } else {
620
+ switch (statuslineMode) {
621
+ case 'none':
622
+ console.log('');
623
+ break;
624
+ case 'minimal':
625
+ renderMinimal(ctx);
626
+ break;
627
+ case 'compact':
628
+ renderCompact(ctx);
629
+ break;
630
+ case 'full':
631
+ default:
632
+ render(ctx, false);
633
+ break;
634
+ }
533
635
  }
534
636
 
535
637
  } catch (err) {
@@ -1,20 +1,30 @@
1
1
  ## Codex runtime
2
2
 
3
3
  - Repository instructions live in `AGENTS.md`.
4
- - CafeKit skills live in `.agents/skills/`; invoke them as `$hapo-<name>` or browse with `/skills`. Edit skills in the project, not in a global skills directory.
4
+ - CafeKit skills live in `.agents/skills/`; invoke them as `$cf-<name>` or browse with `/skills`. Edit skills in the project, not in a global skills directory.
5
5
  - Run Python skill scripts with the project venv:
6
6
  - macOS/Linux: `.agents/skills/.venv/bin/python3 scripts/<script>.py`
7
7
  - Windows: `.agents\\skills\\.venv\\Scripts\\python.exe scripts\\<script>.py`
8
8
  - CafeKit agents live in `.codex/agents/*.toml` and are auto-discovered after the repository is trusted.
9
9
  - Runtime support lives in `.codex/rules/`, `.codex/scripts/`, `.codex/references/`, and `.codex/runtime.json`.
10
+ - For skill selection, read `.codex/rules/skill-workflow-routing.md` and
11
+ `.codex/rules/skill-domain-routing.md`. When capability presence is uncertain,
12
+ run `node .codex/scripts/generate-skill-catalog.cjs --skills`; its Codex-bound
13
+ root is `.agents/skills`. Use `$cf-route` only for ambiguous, multi-step,
14
+ multi-domain, or risk-elevated work; explicit, obvious, and factual intents
15
+ stay direct.
16
+ - Consult `.codex/rules/review-audit-self-decision.md` before applying audit
17
+ feedback, reversing a verified or user decision, or cutting scope, and
18
+ `.codex/rules/process-management.md` whenever a task starts, reuses, or ends
19
+ long-running processes.
10
20
  - Project hooks live in `.codex/hooks.json`; review trusted hooks with `/hooks`.
11
- - New Specs work uses the process-first flow. `$hapo-specs` opens C1, writes
21
+ - New Specs work uses the process-first flow. `$cf-specs` opens C1, writes
12
22
  `specs/<feature>/plan.md` with flat `task-NN-*.md` files beside it, then opens
13
23
  C2 after adversarial review. It never starts implementation.
14
- - Start implementation only through a new explicit `$hapo-develop` invocation.
24
+ - Start implementation only through a new explicit `$cf-develop` invocation.
15
25
  Execute one unblocked task at a time; each task has exactly one `Status:`
16
26
  field and the controller is its sole state-and-proof writer.
17
- - Use `$hapo-sync` for surgical updates to observed file state. A done task
27
+ - Use `$cf-sync` for surgical updates to observed file state. A done task
18
28
  requires a canonical final inline `## Receipt` with the exact command,
19
29
  `Exit: 0`, `Verification: PASS`, runtime-derived Base and Head values, and
20
30
  non-empty fenced current output.
@@ -11,11 +11,14 @@ const {
11
11
  resolveProjectPath
12
12
  } = require('./lib/hook-context.cjs');
13
13
 
14
- function latestSourceHash(projectRoot, docsRelative) {
14
+ function latestSourceHash(projectRoot, excludedRelatives) {
15
15
  try {
16
16
  return execFileSync(
17
17
  'git',
18
- ['log', '-1', '--format=%H', '--', '.', `:(exclude)${docsRelative}`],
18
+ [
19
+ 'log', '-1', '--format=%H', '--', '.',
20
+ ...excludedRelatives.map((relative) => `:(exclude,literal)${relative}`)
21
+ ],
19
22
  {
20
23
  cwd: projectRoot,
21
24
  encoding: 'utf8',
@@ -32,7 +35,9 @@ try {
32
35
  if (!payload) process.exit(0);
33
36
  const { projectRoot, runtime } = getHookContext(payload);
34
37
  const docsDir = resolveProjectPath(projectRoot, runtime.paths?.docs, 'docs');
38
+ const specsDir = resolveProjectPath(projectRoot, runtime.paths?.specs, 'specs');
35
39
  const docsRelative = path.relative(projectRoot, docsDir).replace(/\\/g, '/');
40
+ const specsRelative = path.relative(projectRoot, specsDir).replace(/\\/g, '/');
36
41
  const hasCode = [
37
42
  'src', 'app', 'lib', 'package.json', 'index.js', 'main.py'
38
43
  ].some((candidate) => fs.existsSync(path.join(projectRoot, candidate)));
@@ -46,7 +51,7 @@ try {
46
51
  '> Create baseline architecture and project-overview docs, then record the source Git hash in `docs/.sync_hash`.'
47
52
  );
48
53
  } else {
49
- const currentHash = latestSourceHash(projectRoot, docsRelative);
54
+ const currentHash = latestSourceHash(projectRoot, [docsRelative, specsRelative]);
50
55
  const trackingFile = path.join(docsDir, '.sync_hash');
51
56
  const previousHash = fs.existsSync(trackingFile)
52
57
  ? fs.readFileSync(trackingFile, 'utf8').trim()
@@ -113,12 +113,25 @@ function atomicWrite(file, content, mode = 0o600) {
113
113
  fs.renameSync(temp, file);
114
114
  }
115
115
 
116
+ /**
117
+ * Where a hook keeps its own generated state: crash logs, session reservations
118
+ * and the gate/tollgate caches.
119
+ *
120
+ * Installed, that is `<project>/.codex/hooks/.logs/`. Under this package's own
121
+ * tests PROJECT_ROOT resolves to `packages/spec/src`, so the same write lands in
122
+ * the source tree; it accumulated silently there because the repository ignores
123
+ * `.codex` at any depth. Source-tree runs therefore write to a temp directory.
124
+ */
125
+ function hookStateDir(projectRoot) {
126
+ const root = projectRoot || PROJECT_ROOT;
127
+ return String(root).includes(`${path.sep}packages${path.sep}spec${path.sep}src`)
128
+ ? path.join(require('os').tmpdir(), 'cafekit-hook-logs', 'codex')
129
+ : path.join(root, '.codex', 'hooks', '.logs');
130
+ }
131
+
116
132
  function logCrash(hook, error) {
117
133
  try {
118
- const isSourceTree = PROJECT_ROOT.includes(`${path.sep}packages${path.sep}spec${path.sep}src`);
119
- const dir = isSourceTree
120
- ? path.join(require('os').tmpdir(), 'cafekit-hook-logs', 'codex', hook)
121
- : path.join(PROJECT_ROOT, '.codex', 'hooks', '.logs');
134
+ const dir = hookStateDir(PROJECT_ROOT);
122
135
  fs.mkdirSync(dir, { recursive: true });
123
136
  fs.appendFileSync(
124
137
  path.join(dir, 'hook-log.jsonl'),
@@ -138,6 +151,7 @@ module.exports = {
138
151
  PROJECT_ROOT,
139
152
  atomicWrite,
140
153
  getHookContext,
154
+ hookStateDir,
141
155
  logCrash,
142
156
  readPayload,
143
157
  readRuntime,