@haposoft/cafekit 0.16.0-rc.8 → 0.16.1

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 (323) hide show
  1. package/README.md +117 -28
  2. package/bin/__tests__/codex-hooks-ownership.test.js +239 -0
  3. package/bin/__tests__/codex-hooks.test.js +175 -0
  4. package/bin/__tests__/codex-native.test.js +1882 -70
  5. package/bin/__tests__/develop-contract.test.js +442 -23
  6. package/bin/__tests__/grok-envelope.test.js +271 -0
  7. package/bin/__tests__/grok-platform.test.js +133 -0
  8. package/bin/__tests__/hook-payload.test.js +194 -0
  9. package/bin/__tests__/installer-safety.test.js +3 -3
  10. package/bin/__tests__/omp-bridge.test.js +168 -0
  11. package/bin/__tests__/omp-hooks.test.js +178 -0
  12. package/bin/__tests__/omp-runtime.test.js +150 -0
  13. package/bin/__tests__/optional-skill-inventory.test.js +249 -0
  14. package/bin/__tests__/output-styles.test.js +214 -0
  15. package/bin/__tests__/package-inventory.test.js +1735 -98
  16. package/bin/__tests__/runtime-dir.test.js +158 -0
  17. package/bin/__tests__/runtime-schema.test.js +113 -0
  18. package/bin/__tests__/secret-output-guardrail.test.js +122 -0
  19. package/bin/__tests__/skill-routing-source.test.js +172 -0
  20. package/bin/__tests__/specs-v2-execution-closeout.test.js +28 -1
  21. package/bin/install.js +15 -5
  22. package/bin/lib/codex-install.js +170 -5
  23. package/bin/lib/context.js +64 -3
  24. package/bin/lib/i18n.js +15 -36
  25. package/bin/lib/skill-deps.js +5 -5
  26. package/bin/phases/claude-runtime.js +23 -0
  27. package/bin/phases/claude-settings.js +8 -0
  28. package/bin/phases/codex-hooks.js +156 -0
  29. package/bin/phases/codex-runtime.js +29 -38
  30. package/bin/phases/copy-payload.js +15 -2
  31. package/bin/phases/omp-runtime.js +140 -0
  32. package/bin/phases/root-config.js +3 -0
  33. package/bin/phases/select-platform.js +22 -1
  34. package/bin/phases/select-skill-bundles.js +96 -0
  35. package/bin/phases/skill-inventory.js +71 -0
  36. package/bin/phases/skills-setup.js +9 -2
  37. package/bin/phases/summary.js +0 -4
  38. package/bin/phases/write-metadata.js +8 -5
  39. package/package.json +8 -2
  40. package/src/claude/CLAUDE.md +3 -3
  41. package/src/claude/agents/brainstormer.md +52 -69
  42. package/src/claude/agents/code-auditor.md +32 -14
  43. package/src/claude/agents/debugger.md +35 -20
  44. package/src/claude/agents/deployer.md +12 -5
  45. package/src/claude/agents/docs-keeper.md +11 -1
  46. package/src/claude/agents/implementer.md +25 -13
  47. package/src/claude/agents/inspector.md +6 -3
  48. package/src/claude/agents/project-manager.md +1 -1
  49. package/src/claude/agents/researcher.md +26 -55
  50. package/src/claude/agents/spec-maker.md +12 -7
  51. package/src/claude/agents/strategist.md +52 -0
  52. package/src/claude/agents/test-runner.md +117 -132
  53. package/src/claude/agents/ui-ux-designer.md +1 -1
  54. package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -0
  55. package/src/claude/hooks/__tests__/precompact.test.js +158 -0
  56. package/src/claude/hooks/__tests__/semantic-review-authority.test.js +2 -0
  57. package/src/claude/hooks/__tests__/spec-gate.test.js +348 -3
  58. package/src/claude/hooks/__tests__/state.test.js +7 -0
  59. package/src/claude/hooks/__tests__/statusline.test.js +196 -0
  60. package/src/claude/hooks/agent.cjs +13 -8
  61. package/src/claude/hooks/completion-authority.cjs +10 -4
  62. package/src/claude/hooks/docs-sync.cjs +14 -11
  63. package/src/claude/hooks/inspect-block.cjs +28 -8
  64. package/src/claude/hooks/lib/config.cjs +8 -2
  65. package/src/claude/hooks/lib/counter.cjs +7 -5
  66. package/src/claude/hooks/lib/hook-payload.cjs +160 -0
  67. package/src/claude/hooks/lib/hook-state-dir.cjs +39 -0
  68. package/src/claude/hooks/lib/runtime-dir.cjs +49 -0
  69. package/src/claude/hooks/lib/secret-keywords.cjs +42 -0
  70. package/src/claude/hooks/precompact.cjs +106 -0
  71. package/src/claude/hooks/privacy-block.cjs +4 -2
  72. package/src/claude/hooks/rules.cjs +5 -3
  73. package/src/claude/hooks/secret-output-guardrail.cjs +44 -0
  74. package/src/claude/hooks/semantic-review-authority.cjs +6 -4
  75. package/src/claude/hooks/session.cjs +37 -9
  76. package/src/claude/hooks/spec-gate.cjs +21 -11
  77. package/src/claude/hooks/spec-state.cjs +11 -7
  78. package/src/claude/hooks/state.cjs +7 -5
  79. package/src/claude/hooks/task-scaffold-guard.cjs +30 -9
  80. package/src/claude/hooks/usage.cjs +6 -5
  81. package/src/claude/migration-manifest.json +31 -15
  82. package/src/claude/output-styles/coding-level-0-eli5.md +103 -0
  83. package/src/claude/output-styles/coding-level-1-junior.md +124 -0
  84. package/src/claude/output-styles/coding-level-2-mid.md +146 -0
  85. package/src/claude/output-styles/coding-level-3-senior.md +148 -0
  86. package/src/claude/output-styles/coding-level-4-lead.md +159 -0
  87. package/src/claude/output-styles/coding-level-5-god.md +91 -0
  88. package/src/claude/references/debugger/core-philosophy.md +5 -3
  89. package/src/claude/references/debugger/frontend-verification.md +2 -2
  90. package/src/claude/references/debugger/log-ci-analysis.md +13 -1
  91. package/src/claude/references/debugger/parallel-agent-hydration.md +19 -34
  92. package/src/claude/references/debugger/performance-diagnostics.md +2 -2
  93. package/src/claude/references/debugger/root-cause-tracing.md +37 -6
  94. package/src/claude/references/debugger/side-effect-gate.md +3 -1
  95. package/src/claude/references/debugger/verification-protocol.md +13 -12
  96. package/src/claude/rules/orchestrator.md +7 -1
  97. package/src/claude/rules/process-management.md +39 -0
  98. package/src/claude/rules/review-audit-self-decision.md +48 -0
  99. package/src/claude/rules/skill-domain-routing.md +26 -24
  100. package/src/claude/rules/skill-workflow-routing.md +22 -14
  101. package/src/claude/rules/state-sync.md +7 -1
  102. package/src/claude/rules/workflow.md +5 -3
  103. package/src/claude/runtime.json +1 -0
  104. package/src/claude/runtime.schema.json +205 -0
  105. package/src/claude/scripts/generate-skill-catalog.cjs +156 -122
  106. package/src/claude/scripts/provenance.cjs +29 -9
  107. package/src/claude/scripts/spec-receipt.cjs +65 -4
  108. package/src/claude/scripts/workflow-policy.cjs +1 -1
  109. package/src/claude/settings/settings.json +16 -0
  110. package/src/claude/skills/agent-browser/SKILL.md +1 -1
  111. package/src/claude/skills/ai-multimodal/SKILL.md +1 -1
  112. package/src/claude/skills/brainstorm/SKILL.md +193 -172
  113. package/src/claude/skills/brainstorm/references/question-framework.md +105 -167
  114. package/src/claude/skills/chrome-devtools/SKILL.md +1 -1
  115. package/src/claude/skills/code-review/SKILL.md +43 -25
  116. package/src/claude/skills/code-review/references/spec-compliance-review.md +3 -4
  117. package/src/claude/skills/code-review/references/verification-gate.md +1 -1
  118. package/src/claude/skills/debug/SKILL.md +48 -19
  119. package/src/claude/skills/delegate/SKILL.md +1 -1
  120. package/src/claude/skills/develop/SKILL.md +92 -65
  121. package/src/claude/skills/develop/references/parallel-waves.md +36 -63
  122. package/src/claude/skills/develop/references/quality-gate.md +31 -4
  123. package/src/claude/skills/develop/references/subagent-patterns.md +21 -7
  124. package/src/claude/skills/docs/SKILL.md +42 -23
  125. package/src/claude/skills/docs/references/init-workflow.md +4 -4
  126. package/src/claude/skills/docs/references/reconstruct-workflow.md +6 -6
  127. package/src/claude/skills/docs/references/standard-docs-workflow.md +6 -2
  128. package/src/claude/skills/docs/references/summarize-workflow.md +2 -2
  129. package/src/claude/skills/docs/references/update-workflow.md +9 -7
  130. package/src/claude/skills/docs/templates/requirements-as-is.md +1 -1
  131. package/src/claude/skills/docx/SKILL.md +1 -1
  132. package/src/claude/skills/git/SKILL.md +1 -1
  133. package/src/claude/skills/git/references/commit-protocols.md +1 -1
  134. package/src/claude/skills/git/references/finish-branch.md +1 -1
  135. package/src/claude/skills/hotfix/SKILL.md +159 -170
  136. package/src/claude/skills/hotfix/references/diagnosis-protocol.md +14 -9
  137. package/src/claude/skills/hotfix/references/parallel-patterns.md +27 -13
  138. package/src/claude/skills/hotfix/references/prevention-gate.md +5 -0
  139. package/src/claude/skills/hotfix/references/review-cycle.md +21 -15
  140. package/src/claude/skills/hotfix/references/workflow-specialized.md +53 -21
  141. package/src/claude/skills/inspect/SKILL.md +55 -46
  142. package/src/claude/skills/inspect/references/internal-inspection.md +21 -5
  143. package/src/claude/skills/loop/SKILL.md +114 -0
  144. package/src/claude/skills/loop/references/bounded-loop-protocol.md +104 -0
  145. package/src/claude/skills/loop/references/metric-and-guard-contract.md +76 -0
  146. package/src/claude/skills/pdf/SKILL.md +1 -1
  147. package/src/claude/skills/pptx/SKILL.md +1 -1
  148. package/src/claude/skills/question/SKILL.md +16 -13
  149. package/src/claude/skills/research/SKILL.md +70 -43
  150. package/src/claude/skills/route/SKILL.md +94 -0
  151. package/src/claude/skills/route/references/agent-timing.md +46 -0
  152. package/src/claude/skills/route/references/chaining-patterns.md +53 -0
  153. package/src/claude/skills/route/references/task-taxonomy.md +48 -0
  154. package/src/claude/skills/specs/SKILL.md +51 -71
  155. package/src/claude/skills/specs/references/review.md +11 -8
  156. package/src/claude/skills/specs/references/templates.md +34 -18
  157. package/src/claude/skills/specs/templates/requirements-init.md +1 -1
  158. package/src/claude/skills/specs/templates/research.md +2 -2
  159. package/src/claude/skills/sync/SKILL.md +6 -6
  160. package/src/claude/skills/sync/references/sync-protocols.md +1 -1
  161. package/src/claude/skills/test/SKILL.md +120 -120
  162. package/src/claude/skills/test/references/execution-strategy.md +208 -361
  163. package/src/claude/skills/test/references/failure-triage.md +55 -121
  164. package/src/claude/skills/test/references/test-memory.md +20 -34
  165. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  166. package/src/claude/skills/web-testing/SKILL.md +1 -1
  167. package/src/claude/skills/xlsx/SKILL.md +1 -1
  168. package/src/claude/status.cjs +135 -33
  169. package/src/codex/AGENTS.md +14 -4
  170. package/src/codex/hooks/docs-sync.cjs +8 -3
  171. package/src/codex/hooks/lib/hook-context.cjs +18 -4
  172. package/src/codex/hooks/rules.cjs +29 -1
  173. package/src/codex/hooks/secret-output-guardrail.cjs +30 -0
  174. package/src/codex/hooks/spec-gate.cjs +3 -8
  175. package/src/codex/hooks/spec-state.cjs +3 -2
  176. package/src/codex/hooks.json +5 -0
  177. package/src/codex/rules/state-sync.md +7 -1
  178. package/src/codex/runtime.json +2 -0
  179. package/src/common/.env.example +1 -1
  180. package/src/omp/extensions/cafekit-bridge.mjs +233 -0
  181. package/src/omp/hooks/privacy-block.cjs +250 -0
  182. package/src/omp/runtime.json +33 -0
  183. package/bin/lib/rtk-run.js +0 -28
  184. package/bin/phases/setup-rtk.js +0 -159
  185. package/src/claude/skills/backend-development/SKILL.md +0 -101
  186. package/src/claude/skills/backend-development/references/backend-api-design.md +0 -495
  187. package/src/claude/skills/backend-development/references/backend-architecture.md +0 -454
  188. package/src/claude/skills/backend-development/references/backend-authentication.md +0 -338
  189. package/src/claude/skills/backend-development/references/backend-code-quality.md +0 -659
  190. package/src/claude/skills/backend-development/references/backend-debugging.md +0 -904
  191. package/src/claude/skills/backend-development/references/backend-devops.md +0 -491
  192. package/src/claude/skills/backend-development/references/backend-mindset.md +0 -387
  193. package/src/claude/skills/backend-development/references/backend-performance.md +0 -397
  194. package/src/claude/skills/backend-development/references/backend-security.md +0 -342
  195. package/src/claude/skills/backend-development/references/backend-technologies.md +0 -256
  196. package/src/claude/skills/backend-development/references/backend-testing.md +0 -429
  197. package/src/claude/skills/devops/.env.example +0 -76
  198. package/src/claude/skills/devops/SKILL.md +0 -102
  199. package/src/claude/skills/devops/references/browser-rendering.md +0 -305
  200. package/src/claude/skills/devops/references/cloudflare-d1-kv.md +0 -123
  201. package/src/claude/skills/devops/references/cloudflare-platform.md +0 -271
  202. package/src/claude/skills/devops/references/cloudflare-r2-storage.md +0 -280
  203. package/src/claude/skills/devops/references/cloudflare-workers-advanced.md +0 -312
  204. package/src/claude/skills/devops/references/cloudflare-workers-apis.md +0 -309
  205. package/src/claude/skills/devops/references/cloudflare-workers-basics.md +0 -418
  206. package/src/claude/skills/devops/references/docker-basics.md +0 -297
  207. package/src/claude/skills/devops/references/docker-compose.md +0 -292
  208. package/src/claude/skills/devops/references/gcloud-platform.md +0 -297
  209. package/src/claude/skills/devops/references/gcloud-services.md +0 -304
  210. package/src/claude/skills/devops/references/kubernetes-basics.md +0 -95
  211. package/src/claude/skills/devops/references/kubernetes-helm-advanced.md +0 -70
  212. package/src/claude/skills/devops/references/kubernetes-helm.md +0 -81
  213. package/src/claude/skills/devops/references/kubernetes-kubectl.md +0 -74
  214. package/src/claude/skills/devops/references/kubernetes-security-advanced.md +0 -94
  215. package/src/claude/skills/devops/references/kubernetes-security.md +0 -89
  216. package/src/claude/skills/devops/references/kubernetes-troubleshooting-advanced.md +0 -74
  217. package/src/claude/skills/devops/references/kubernetes-troubleshooting.md +0 -49
  218. package/src/claude/skills/devops/references/kubernetes-workflows-advanced.md +0 -75
  219. package/src/claude/skills/devops/references/kubernetes-workflows.md +0 -76
  220. package/src/claude/skills/devops/scripts/cloudflare_deploy.py +0 -269
  221. package/src/claude/skills/devops/scripts/docker_optimize.py +0 -332
  222. package/src/claude/skills/devops/scripts/requirements.txt +0 -20
  223. package/src/claude/skills/devops/scripts/tests/requirements.txt +0 -3
  224. package/src/claude/skills/devops/scripts/tests/test_cloudflare_deploy.py +0 -285
  225. package/src/claude/skills/devops/scripts/tests/test_docker_optimize.py +0 -436
  226. package/src/claude/skills/frontend-design/SKILL.md +0 -135
  227. package/src/claude/skills/frontend-design/references/ai-multimodal-overview.md +0 -165
  228. package/src/claude/skills/frontend-design/references/analysis-best-practices.md +0 -80
  229. package/src/claude/skills/frontend-design/references/analysis-prompts.md +0 -141
  230. package/src/claude/skills/frontend-design/references/analysis-techniques.md +0 -118
  231. package/src/claude/skills/frontend-design/references/animejs.md +0 -396
  232. package/src/claude/skills/frontend-design/references/anti-slop-rules.md +0 -103
  233. package/src/claude/skills/frontend-design/references/asset-generation.md +0 -337
  234. package/src/claude/skills/frontend-design/references/bento-motion-engine.md +0 -142
  235. package/src/claude/skills/frontend-design/references/design-extraction-overview.md +0 -71
  236. package/src/claude/skills/frontend-design/references/extraction-best-practices.md +0 -141
  237. package/src/claude/skills/frontend-design/references/extraction-output-templates.md +0 -162
  238. package/src/claude/skills/frontend-design/references/extraction-prompts.md +0 -127
  239. package/src/claude/skills/frontend-design/references/magicui-components.md +0 -129
  240. package/src/claude/skills/frontend-design/references/performance-guardrails.md +0 -169
  241. package/src/claude/skills/frontend-design/references/premium-design-patterns.md +0 -93
  242. package/src/claude/skills/frontend-design/references/redesign-audit-checklist.md +0 -114
  243. package/src/claude/skills/frontend-design/references/technical-accessibility.md +0 -119
  244. package/src/claude/skills/frontend-design/references/technical-best-practices.md +0 -97
  245. package/src/claude/skills/frontend-design/references/technical-optimization.md +0 -44
  246. package/src/claude/skills/frontend-design/references/technical-overview.md +0 -90
  247. package/src/claude/skills/frontend-design/references/technical-workflows.md +0 -150
  248. package/src/claude/skills/frontend-design/references/visual-analysis-overview.md +0 -95
  249. package/src/claude/skills/frontend-design/references/workflow-3d.md +0 -102
  250. package/src/claude/skills/frontend-design/references/workflow-describe.md +0 -87
  251. package/src/claude/skills/frontend-design/references/workflow-immersive.md +0 -87
  252. package/src/claude/skills/frontend-design/references/workflow-quick.md +0 -57
  253. package/src/claude/skills/frontend-design/references/workflow-screenshot.md +0 -63
  254. package/src/claude/skills/frontend-design/references/workflow-video.md +0 -74
  255. package/src/claude/skills/frontend-development/SKILL.md +0 -406
  256. package/src/claude/skills/frontend-development/resources/common-patterns.md +0 -331
  257. package/src/claude/skills/frontend-development/resources/complete-examples.md +0 -872
  258. package/src/claude/skills/frontend-development/resources/component-patterns.md +0 -502
  259. package/src/claude/skills/frontend-development/resources/data-fetching.md +0 -767
  260. package/src/claude/skills/frontend-development/resources/file-organization.md +0 -502
  261. package/src/claude/skills/frontend-development/resources/loading-and-error-states.md +0 -501
  262. package/src/claude/skills/frontend-development/resources/performance.md +0 -406
  263. package/src/claude/skills/frontend-development/resources/routing-guide.md +0 -364
  264. package/src/claude/skills/frontend-development/resources/styling-guide.md +0 -428
  265. package/src/claude/skills/frontend-development/resources/typescript-standards.md +0 -418
  266. package/src/claude/skills/mobile-development/SKILL.md +0 -218
  267. package/src/claude/skills/mobile-development/references/mobile-android.md +0 -604
  268. package/src/claude/skills/mobile-development/references/mobile-best-practices.md +0 -544
  269. package/src/claude/skills/mobile-development/references/mobile-debugging.md +0 -1089
  270. package/src/claude/skills/mobile-development/references/mobile-frameworks.md +0 -465
  271. package/src/claude/skills/mobile-development/references/mobile-ios.md +0 -496
  272. package/src/claude/skills/mobile-development/references/mobile-mindset.md +0 -542
  273. package/src/claude/skills/react-best-practices/AGENTS.md +0 -2249
  274. package/src/claude/skills/react-best-practices/README.md +0 -123
  275. package/src/claude/skills/react-best-practices/SKILL.md +0 -128
  276. package/src/claude/skills/react-best-practices/metadata.json +0 -15
  277. package/src/claude/skills/react-best-practices/rules/_sections.md +0 -46
  278. package/src/claude/skills/react-best-practices/rules/_template.md +0 -28
  279. package/src/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  280. package/src/claude/skills/react-best-practices/rules/advanced-use-latest.md +0 -49
  281. package/src/claude/skills/react-best-practices/rules/async-api-routes.md +0 -38
  282. package/src/claude/skills/react-best-practices/rules/async-defer-await.md +0 -80
  283. package/src/claude/skills/react-best-practices/rules/async-dependencies.md +0 -36
  284. package/src/claude/skills/react-best-practices/rules/async-parallel.md +0 -28
  285. package/src/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
  286. package/src/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
  287. package/src/claude/skills/react-best-practices/rules/bundle-conditional.md +0 -31
  288. package/src/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
  289. package/src/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  290. package/src/claude/skills/react-best-practices/rules/bundle-preload.md +0 -50
  291. package/src/claude/skills/react-best-practices/rules/client-event-listeners.md +0 -74
  292. package/src/claude/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
  293. package/src/claude/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
  294. package/src/claude/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
  295. package/src/claude/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
  296. package/src/claude/skills/react-best-practices/rules/js-cache-storage.md +0 -70
  297. package/src/claude/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
  298. package/src/claude/skills/react-best-practices/rules/js-early-exit.md +0 -50
  299. package/src/claude/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
  300. package/src/claude/skills/react-best-practices/rules/js-index-maps.md +0 -37
  301. package/src/claude/skills/react-best-practices/rules/js-length-check-first.md +0 -49
  302. package/src/claude/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
  303. package/src/claude/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
  304. package/src/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
  305. package/src/claude/skills/react-best-practices/rules/rendering-activity.md +0 -26
  306. package/src/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  307. package/src/claude/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
  308. package/src/claude/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
  309. package/src/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  310. package/src/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  311. package/src/claude/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
  312. package/src/claude/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
  313. package/src/claude/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
  314. package/src/claude/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
  315. package/src/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
  316. package/src/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  317. package/src/claude/skills/react-best-practices/rules/rerender-memo.md +0 -44
  318. package/src/claude/skills/react-best-practices/rules/rerender-transitions.md +0 -40
  319. package/src/claude/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
  320. package/src/claude/skills/react-best-practices/rules/server-cache-lru.md +0 -41
  321. package/src/claude/skills/react-best-practices/rules/server-cache-react.md +0 -26
  322. package/src/claude/skills/react-best-practices/rules/server-parallel-fetching.md +0 -79
  323. package/src/claude/skills/react-best-practices/rules/server-serialization.md +0 -38
@@ -0,0 +1,249 @@
1
+ const assert = require('node:assert/strict');
2
+ const fs = require('node:fs');
3
+ const os = require('node:os');
4
+ const path = require('node:path');
5
+ const test = require('node:test');
6
+ const { spawnSync } = require('node:child_process');
7
+
8
+ const {
9
+ loadClaudeMigrationManifest,
10
+ parseInstallerArgs,
11
+ PLATFORMS
12
+ } = require('../lib/context');
13
+ const manifestLib = require('../lib/manifest');
14
+ const { selectDocumentSkills } = require('../phases/select-skill-bundles');
15
+ const { reconcileSkillInventory } = require('../phases/skill-inventory');
16
+ const installerPath = path.resolve(__dirname, '..', 'install.js');
17
+
18
+ function withTempProject(run) {
19
+ const previous = process.cwd();
20
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'cafekit-optional-skills-'));
21
+ process.chdir(root);
22
+ try {
23
+ return run(root);
24
+ } finally {
25
+ process.chdir(previous);
26
+ fs.rmSync(root, { recursive: true, force: true });
27
+ }
28
+ }
29
+
30
+ async function withTempProjectAsync(run) {
31
+ const previous = process.cwd();
32
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'cafekit-optional-skills-'));
33
+ process.chdir(root);
34
+ try {
35
+ return await run(root);
36
+ } finally {
37
+ process.chdir(previous);
38
+ fs.rmSync(root, { recursive: true, force: true });
39
+ }
40
+ }
41
+
42
+ function silentUi() {
43
+ return {
44
+ confirm: async (_options, fallback) => fallback,
45
+ isCancel: () => false,
46
+ warn: () => {},
47
+ detail: () => {}
48
+ };
49
+ }
50
+
51
+ test('manifest separates core, optional documents, and retired skills', () => {
52
+ const manifest = loadClaudeMigrationManifest();
53
+ assert.equal(manifest.skills.required.includes('route'), true);
54
+ assert.deepEqual(manifest.skills.bundles.documentSkills, [
55
+ 'ai-multimodal', 'docs', 'docx', 'pdf', 'pptx', 'xlsx'
56
+ ]);
57
+ for (const skill of manifest.skills.bundles.documentSkills) {
58
+ assert.equal(manifest.skills.required.includes(skill), false);
59
+ }
60
+ assert.deepEqual(manifest.obsolete.skills, [
61
+ 'backend-development', 'frontend-development', 'frontend-design',
62
+ 'mobile-development', 'devops', 'react-best-practices'
63
+ ]);
64
+ });
65
+
66
+ test('document skill flags are mutually exclusive', () => {
67
+ assert.throws(
68
+ () => parseInstallerArgs(['node', 'install', '--with-document-skills', '--without-document-skills']),
69
+ /cannot be used together/
70
+ );
71
+ });
72
+
73
+ test('selection defaults fresh non-interactive OFF and preserves legacy upgrade ON', async () => {
74
+ await withTempProjectAsync(async () => {
75
+ const base = {
76
+ platforms: ['claude', 'codex'],
77
+ options: {},
78
+ documentSkills: {},
79
+ interactive: false,
80
+ ui: silentUi(),
81
+ t: (key) => key
82
+ };
83
+ fs.mkdirSync('.codex', { recursive: true });
84
+ fs.writeFileSync('.codex/cafekit.json', '{"schemaVersion":1,"platform":"codex"}\n');
85
+
86
+ await selectDocumentSkills(base);
87
+ assert.deepEqual(base.documentSkills.claude, {
88
+ enabled: false,
89
+ selectionSource: 'default-fresh'
90
+ });
91
+ assert.deepEqual(base.documentSkills.codex, {
92
+ enabled: true,
93
+ selectionSource: 'legacy-upgrade'
94
+ });
95
+ });
96
+ });
97
+
98
+ test('interactive cancellation stops before selecting a fresh bundle', async () => {
99
+ await withTempProjectAsync(async () => {
100
+ const ctx = {
101
+ platforms: ['claude'],
102
+ options: {},
103
+ documentSkills: {},
104
+ interactive: true,
105
+ cancelled: false,
106
+ ui: {
107
+ confirm: async () => 'cancel',
108
+ isCancel: (value) => value === 'cancel'
109
+ },
110
+ t: (key) => key
111
+ };
112
+ await selectDocumentSkills(ctx);
113
+ assert.equal(ctx.cancelled, true);
114
+ assert.equal(ctx.documentSkills.claude, undefined);
115
+ });
116
+ });
117
+
118
+ for (const platformKey of ['claude', 'codex']) {
119
+ test(`${platformKey} prunes pristine optional skills and preserves modified skills`, () => {
120
+ withTempProject(() => {
121
+ const platform = PLATFORMS[platformKey];
122
+ const docsFile = path.join(platform.skillsDir, 'docs', 'SKILL.md');
123
+ const pdfFile = path.join(platform.skillsDir, 'pdf', 'SKILL.md');
124
+ fs.mkdirSync(path.dirname(docsFile), { recursive: true });
125
+ fs.mkdirSync(path.dirname(pdfFile), { recursive: true });
126
+ fs.writeFileSync(docsFile, 'owned\n');
127
+ fs.writeFileSync(pdfFile, 'owned then edited\n');
128
+
129
+ const ownership = {
130
+ schemaVersion: 1,
131
+ version: 'old',
132
+ files: {}
133
+ };
134
+ const recordRoot = platform.ownership?.recordRoot || platform.folder;
135
+ const key = (file) => path.relative(recordRoot, file).replace(/\\/g, '/');
136
+ ownership.files[key(docsFile)] = { sha256: manifestLib.hashFile(docsFile), version: 'old' };
137
+ ownership.files[key(pdfFile)] = { sha256: manifestLib.sha256('before edit\n'), version: 'old' };
138
+
139
+ const ctx = {
140
+ manifest: { obsolete: { skills: [] }, skills: { bundles: { documentSkills: ['docs', 'pdf'] } } },
141
+ documentSkills: { [platformKey]: { enabled: false, selectionSource: 'cli-opt-out' } },
142
+ ownership: { [platform.folder]: ownership },
143
+ trackers: {
144
+ [platformKey]: manifestLib.createTracker(platform.folder, 'next', platform.ownership)
145
+ },
146
+ dryRun: false,
147
+ ui: silentUi(),
148
+ results: { updated: 0, preserved: 0, preservedFiles: [] }
149
+ };
150
+
151
+ reconcileSkillInventory(ctx, platformKey);
152
+ assert.equal(fs.existsSync(path.dirname(docsFile)), false);
153
+ assert.equal(fs.existsSync(path.dirname(pdfFile)), true);
154
+ assert.equal(ctx.results.updated, 1);
155
+ assert.equal(ctx.results.preserved, 1);
156
+ });
157
+ });
158
+ }
159
+
160
+ test('fresh combined install defaults optional bundle OFF', () => {
161
+ withTempProject((root) => {
162
+ const result = spawnSync(process.execPath, [
163
+ installerPath, '--platform', 'claude,codex', '--yes'
164
+ ], { cwd: root, encoding: 'utf8' });
165
+ assert.equal(result.status, 0, result.stderr || result.stdout);
166
+
167
+ for (const platformKey of ['claude', 'codex']) {
168
+ const platform = PLATFORMS[platformKey];
169
+ assert.equal(fs.existsSync(path.join(platform.skillsDir, 'docs')), false);
170
+ assert.equal(fs.existsSync(path.join(platform.skillsDir, 'route', 'SKILL.md')), true);
171
+ const metadata = JSON.parse(fs.readFileSync(path.join(platform.folder, 'cafekit.json'), 'utf8'));
172
+ assert.equal(metadata.schemaVersion, 2);
173
+ assert.equal(metadata.documentSkills.enabled, false);
174
+ }
175
+ });
176
+ });
177
+
178
+ test('explicit opt-in installs all six optional skills on both runtimes', () => {
179
+ withTempProject((root) => {
180
+ const result = spawnSync(process.execPath, [
181
+ installerPath, '--platform', 'claude,codex', '--yes', '--with-document-skills'
182
+ ], { cwd: root, encoding: 'utf8' });
183
+ assert.equal(result.status, 0, result.stderr || result.stdout);
184
+
185
+ const optional = loadClaudeMigrationManifest().skills.bundles.documentSkills;
186
+ for (const platformKey of ['claude', 'codex']) {
187
+ const platform = PLATFORMS[platformKey];
188
+ for (const skill of optional) {
189
+ assert.equal(fs.existsSync(path.join(platform.skillsDir, skill, 'SKILL.md')), true, `${platformKey}:${skill}`);
190
+ }
191
+ const catalog = spawnSync(process.execPath, [
192
+ path.join(platform.folder, 'scripts', 'generate-skill-catalog.cjs'), '--json'
193
+ ], { cwd: root, encoding: 'utf8' });
194
+ assert.equal(catalog.status, 0, catalog.stderr);
195
+ const catalogData = JSON.parse(catalog.stdout);
196
+ assert.equal(catalogData.skills.some((skill) => skill.public_id === 'cf:route'), true);
197
+ assert.equal(catalogData.skills.some((skill) => skill.public_id === 'cf:docs'), true);
198
+ const metadata = JSON.parse(fs.readFileSync(path.join(platform.folder, 'cafekit.json'), 'utf8'));
199
+ assert.deepEqual(metadata.documentSkills, {
200
+ enabled: true,
201
+ selectionSource: 'cli-opt-in'
202
+ });
203
+ }
204
+ });
205
+ });
206
+
207
+ test('corrupt metadata preserves an installed document bundle', () => {
208
+ withTempProject((root) => {
209
+ const install = (...args) => spawnSync(process.execPath, [
210
+ installerPath, '--platform', 'claude', '--yes', ...args
211
+ ], { cwd: root, encoding: 'utf8' });
212
+ assert.equal(install('--with-document-skills').status, 0);
213
+ fs.writeFileSync(path.join(root, '.claude', 'cafekit.json'), '{broken\n');
214
+
215
+ const recovered = install();
216
+ assert.equal(recovered.status, 0, recovered.stderr || recovered.stdout);
217
+ assert.equal(fs.existsSync(path.join(root, '.claude', 'skills', 'docs', 'SKILL.md')), true);
218
+ const metadata = JSON.parse(fs.readFileSync(path.join(root, '.claude', 'cafekit.json'), 'utf8'));
219
+ assert.deepEqual(metadata.documentSkills, {
220
+ enabled: true,
221
+ selectionSource: 'metadata-recovery'
222
+ });
223
+ });
224
+ });
225
+
226
+ test('modified retired skill is preserved but excluded from automatic routing', () => {
227
+ withTempProject((root) => {
228
+ const retiredRoot = path.join(root, '.claude', 'skills', 'backend-development');
229
+ fs.mkdirSync(retiredRoot, { recursive: true });
230
+ fs.writeFileSync(path.join(retiredRoot, 'SKILL.md'), [
231
+ '---', 'name: cf:backend-development',
232
+ 'description: "User-modified retired skill."', '---', '# Preserved', '',
233
+ ].join('\n'));
234
+ const result = spawnSync(process.execPath, [
235
+ installerPath, '--platform', 'claude', '--yes'
236
+ ], { cwd: root, encoding: 'utf8' });
237
+ assert.equal(result.status, 0, result.stderr || result.stdout);
238
+ assert.equal(fs.existsSync(path.join(retiredRoot, 'SKILL.md')), true);
239
+
240
+ const catalog = spawnSync(process.execPath, [
241
+ path.join(root, '.claude', 'scripts', 'generate-skill-catalog.cjs'), '--json'
242
+ ], { cwd: root, encoding: 'utf8' });
243
+ assert.equal(catalog.status, 0, catalog.stderr);
244
+ const parsed = JSON.parse(catalog.stdout);
245
+ assert.equal(parsed.skills.some((skill) => skill.directory === 'backend-development'), false);
246
+ assert.ok(parsed.diagnostics.some((item) =>
247
+ item.directory === 'backend-development' && item.code === 'retired_skill'));
248
+ });
249
+ });
@@ -0,0 +1,214 @@
1
+ 'use strict';
2
+
3
+ // Output styles are a Claude Code surface: Claude Code discovers .claude/output-styles/
4
+ // alongside agents, skills and rules, and Codex CLI has no equivalent. These tests pin
5
+ // what installs where, and that every style stays loadable — a style with broken
6
+ // frontmatter is silently unavailable rather than loudly wrong.
7
+
8
+ const assert = require('node:assert/strict');
9
+ const fs = require('node:fs');
10
+ const os = require('node:os');
11
+ const path = require('node:path');
12
+ const { spawnSync } = require('node:child_process');
13
+ const { test } = require('node:test');
14
+
15
+ const PACKAGE_ROOT = path.join(__dirname, '../..');
16
+ const INSTALLER = path.join(PACKAGE_ROOT, 'bin/install.js');
17
+ const SOURCE_DIR = path.join(PACKAGE_ROOT, 'src/claude/output-styles');
18
+ const EXPECTED = [
19
+ 'coding-level-0-eli5.md',
20
+ 'coding-level-1-junior.md',
21
+ 'coding-level-2-mid.md',
22
+ 'coding-level-3-senior.md',
23
+ 'coding-level-4-lead.md',
24
+ 'coding-level-5-god.md',
25
+ ];
26
+
27
+ function inTempProject(run) {
28
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'cafekit-output-styles-'));
29
+ try {
30
+ return run(root);
31
+ } finally {
32
+ fs.rmSync(root, { recursive: true, force: true });
33
+ }
34
+ }
35
+
36
+ function install(root, platform) {
37
+ return spawnSync(
38
+ process.execPath,
39
+ [INSTALLER, '--platform', platform, '--yes'],
40
+ { cwd: root, encoding: 'utf8', env: { ...process.env, PATH: '/usr/bin:/bin' } }
41
+ );
42
+ }
43
+
44
+ /** Parse the leading `---` frontmatter block into a flat key/value map. */
45
+ function frontmatter(content) {
46
+ const match = content.match(/^---\n([\s\S]*?)\n---\n/);
47
+ if (!match) return null;
48
+ const fields = {};
49
+ for (const line of match[1].split('\n')) {
50
+ const pair = line.match(/^([a-z][a-z0-9-]*):\s*(.*)$/i);
51
+ if (pair) fields[pair[1]] = pair[2].trim();
52
+ }
53
+ return fields;
54
+ }
55
+
56
+ test('the source ships exactly the six coding levels', () => {
57
+ const found = fs.readdirSync(SOURCE_DIR).filter((name) => name.endsWith('.md')).sort();
58
+ assert.deepEqual(found, EXPECTED);
59
+ });
60
+
61
+ test('every style carries the frontmatter Claude Code reads', () => {
62
+ for (const name of EXPECTED) {
63
+ const fields = frontmatter(fs.readFileSync(path.join(SOURCE_DIR, name), 'utf8'));
64
+ assert.ok(fields, `${name} has no frontmatter block, so it cannot load`);
65
+ assert.ok(fields.name, `${name} has no name`);
66
+ assert.ok(fields.description, `${name} has no description`);
67
+ // These styles change how answers are written, not what the agent is allowed to do.
68
+ assert.equal(
69
+ fields['keep-coding-instructions'], 'true',
70
+ `${name} must keep the base coding instructions, or the style would replace them`
71
+ );
72
+ }
73
+ });
74
+
75
+ test('each level declares a distinct name and description', () => {
76
+ const names = new Set();
77
+ const descriptions = new Set();
78
+ for (const file of EXPECTED) {
79
+ const fields = frontmatter(fs.readFileSync(path.join(SOURCE_DIR, file), 'utf8'));
80
+ names.add(fields.name);
81
+ descriptions.add(fields.description);
82
+ }
83
+ assert.equal(names.size, EXPECTED.length, 'two styles share a name and would be indistinguishable');
84
+ assert.equal(descriptions.size, EXPECTED.length, 'two styles share a description');
85
+ });
86
+
87
+ test('a Claude install places every style where Claude Code discovers them', () => {
88
+ inTempProject((root) => {
89
+ const result = install(root, 'claude');
90
+ assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
91
+ const installed = path.join(root, '.claude', 'output-styles');
92
+ for (const name of EXPECTED) {
93
+ assert.equal(fs.existsSync(path.join(installed, name)), true, `missing ${name}`);
94
+ assert.equal(
95
+ fs.readFileSync(path.join(installed, name), 'utf8'),
96
+ fs.readFileSync(path.join(SOURCE_DIR, name), 'utf8'),
97
+ `${name} was altered on the way in`
98
+ );
99
+ }
100
+ });
101
+ });
102
+
103
+ test('a Codex install ships the same styles, since its rules hook injects them', () => {
104
+ inTempProject((root) => {
105
+ const result = install(root, 'codex');
106
+ assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
107
+ const installed = path.join(root, '.codex', 'output-styles');
108
+ for (const name of EXPECTED) {
109
+ assert.equal(
110
+ fs.readFileSync(path.join(installed, name), 'utf8'),
111
+ fs.readFileSync(path.join(SOURCE_DIR, name), 'utf8'),
112
+ `${name} differs from the one canonical source`
113
+ );
114
+ }
115
+ assert.equal(JSON.parse(fs.readFileSync(path.join(root, '.codex', 'runtime.json'), 'utf8')).codingLevel, 1);
116
+ });
117
+ });
118
+
119
+ /** Run the installed Codex rules hook and return what it injects. */
120
+ function runRulesHook(root, sessionId) {
121
+ const result = spawnSync(process.execPath, [path.join(root, '.codex', 'hooks', 'rules.cjs')], {
122
+ cwd: root,
123
+ input: JSON.stringify({ session_id: sessionId, cwd: root }),
124
+ encoding: 'utf8',
125
+ });
126
+ assert.equal(result.status, 0, result.stderr);
127
+ return result.stdout;
128
+ }
129
+
130
+ function setCodingLevel(root, level) {
131
+ const file = path.join(root, '.codex', 'runtime.json');
132
+ const runtime = JSON.parse(fs.readFileSync(file, 'utf8'));
133
+ runtime.codingLevel = level;
134
+ fs.writeFileSync(file, `${JSON.stringify(runtime, null, 2)}\n`);
135
+ }
136
+
137
+ test('the Codex rules hook injects the style the coding level names', () => {
138
+ inTempProject((root) => {
139
+ assert.equal(install(root, 'codex').status, 0);
140
+
141
+ const junior = runRulesHook(root, 'session-junior');
142
+ assert.match(junior, /## Communication style/);
143
+ assert.match(junior, /Junior Developer Communication Mode/);
144
+ // The body uses `---` as a horizontal rule, so check a frontmatter-only marker.
145
+ assert.doesNotMatch(junior, /keep-coding-instructions/, 'the frontmatter must be stripped, not injected');
146
+ assert.doesNotMatch(junior, /^description:/m, 'the frontmatter must be stripped, not injected');
147
+ assert.match(junior, /## Rules/, 'the existing rules injection must survive');
148
+
149
+ setCodingLevel(root, 5);
150
+ const expert = runRulesHook(root, 'session-expert');
151
+ assert.match(expert, /God Mode Communication/);
152
+ assert.doesNotMatch(expert, /Junior Developer Communication Mode/);
153
+ });
154
+ });
155
+
156
+ test('the Codex style is injected once per session, not once per turn', () => {
157
+ inTempProject((root) => {
158
+ assert.equal(install(root, 'codex').status, 0);
159
+ const first = runRulesHook(root, 'one-session');
160
+ assert.match(first, /## Communication style/);
161
+ assert.equal(runRulesHook(root, 'one-session'), '', 'a second turn in the same session must inject nothing');
162
+ assert.match(runRulesHook(root, 'another-session'), /## Communication style/);
163
+ });
164
+ });
165
+
166
+ test('an absent or out-of-range coding level injects no style but keeps the rules', () => {
167
+ inTempProject((root) => {
168
+ assert.equal(install(root, 'codex').status, 0);
169
+ for (const [level, label] of [[null, 'null'], [9, 'out of range'], ['1', 'a string']]) {
170
+ setCodingLevel(root, level);
171
+ const out = runRulesHook(root, `session-${label.replace(/\s/g, '-')}`);
172
+ assert.doesNotMatch(out, /## Communication style/, `${label} must not select a style`);
173
+ assert.match(out, /## Rules/, `${label} must not break the existing rules injection`);
174
+ }
175
+ });
176
+ });
177
+
178
+ test('a Claude install seeds the default style but never overwrites the user choice', () => {
179
+ inTempProject((root) => {
180
+ assert.equal(install(root, 'claude').status, 0);
181
+ const settingsPath = path.join(root, '.claude', 'settings.json');
182
+ const seeded = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
183
+ assert.equal(seeded.outputStyle, 'Junior Developer Mode (Level 1)');
184
+
185
+ seeded.outputStyle = 'God Mode (Level 5)';
186
+ fs.writeFileSync(settingsPath, `${JSON.stringify(seeded, null, 2)}\n`);
187
+
188
+ assert.equal(install(root, 'claude').status, 0);
189
+ assert.equal(
190
+ JSON.parse(fs.readFileSync(settingsPath, 'utf8')).outputStyle, 'God Mode (Level 5)',
191
+ 'a reinstall reset a preference the user had chosen'
192
+ );
193
+
194
+ const forced = spawnSync(process.execPath, [INSTALLER, '--platform', 'claude', '--force-overwrite', '--yes'],
195
+ { cwd: root, encoding: 'utf8', env: { ...process.env, PATH: '/usr/bin:/bin' } });
196
+ assert.equal(forced.status, 0, `${forced.stdout}\n${forced.stderr}`);
197
+ assert.equal(
198
+ JSON.parse(fs.readFileSync(settingsPath, 'utf8')).outputStyle, 'God Mode (Level 5)',
199
+ '--force-overwrite repairs managed files; it must not reset taste'
200
+ );
201
+ });
202
+ });
203
+
204
+ test('a style edited by the user survives a reinstall', () => {
205
+ inTempProject((root) => {
206
+ assert.equal(install(root, 'claude').status, 0);
207
+ const target = path.join(root, '.claude', 'output-styles', 'coding-level-5-god.md');
208
+ const edited = `${fs.readFileSync(target, 'utf8')}\n\nAlways answer in Vietnamese.\n`;
209
+ fs.writeFileSync(target, edited);
210
+
211
+ assert.equal(install(root, 'claude').status, 0);
212
+ assert.equal(fs.readFileSync(target, 'utf8'), edited, 'the reinstall discarded a user edit');
213
+ });
214
+ });