@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,436 +0,0 @@
1
- """
2
- Tests for docker-optimize.py
3
-
4
- Run with: pytest test_docker_optimize.py -v
5
- """
6
-
7
- import pytest
8
- import json
9
- from pathlib import Path
10
- import sys
11
-
12
- # Add parent directory to path for imports
13
- sys.path.insert(0, str(Path(__file__).parent.parent))
14
-
15
- from docker_optimize import DockerfileAnalyzer
16
-
17
-
18
- @pytest.fixture
19
- def temp_dockerfile(tmp_path):
20
- """Create temporary Dockerfile"""
21
- dockerfile = tmp_path / "Dockerfile"
22
- return dockerfile
23
-
24
-
25
- def write_dockerfile(filepath, content):
26
- """Helper to write Dockerfile content"""
27
- with open(filepath, 'w') as f:
28
- f.write(content)
29
-
30
-
31
- class TestDockerfileAnalyzerInit:
32
- """Test DockerfileAnalyzer initialization"""
33
-
34
- def test_init(self, temp_dockerfile):
35
- write_dockerfile(temp_dockerfile, "FROM node:20\n")
36
- analyzer = DockerfileAnalyzer(temp_dockerfile)
37
-
38
- assert analyzer.dockerfile_path == temp_dockerfile
39
- assert analyzer.verbose is False
40
- assert analyzer.lines == []
41
- assert analyzer.issues == []
42
- assert analyzer.suggestions == []
43
-
44
-
45
- class TestLoadDockerfile:
46
- """Test Dockerfile loading"""
47
-
48
- def test_load_success(self, temp_dockerfile):
49
- content = "FROM node:20\nWORKDIR /app\n"
50
- write_dockerfile(temp_dockerfile, content)
51
-
52
- analyzer = DockerfileAnalyzer(temp_dockerfile)
53
- result = analyzer.load_dockerfile()
54
-
55
- assert result is True
56
- assert len(analyzer.lines) == 2
57
-
58
- def test_load_nonexistent(self, tmp_path):
59
- analyzer = DockerfileAnalyzer(tmp_path / "nonexistent")
60
-
61
- with pytest.raises(FileNotFoundError):
62
- analyzer.load_dockerfile()
63
-
64
-
65
- class TestAnalyzeBaseImage:
66
- """Test base image analysis"""
67
-
68
- def test_latest_tag(self, temp_dockerfile):
69
- write_dockerfile(temp_dockerfile, "FROM node:latest\n")
70
- analyzer = DockerfileAnalyzer(temp_dockerfile)
71
- analyzer.load_dockerfile()
72
- analyzer.analyze_base_image()
73
-
74
- assert len(analyzer.issues) == 1
75
- assert analyzer.issues[0]['category'] == 'base_image'
76
- assert 'latest' in analyzer.issues[0]['message']
77
-
78
- def test_no_tag(self, temp_dockerfile):
79
- write_dockerfile(temp_dockerfile, "FROM node\n")
80
- analyzer = DockerfileAnalyzer(temp_dockerfile)
81
- analyzer.load_dockerfile()
82
- analyzer.analyze_base_image()
83
-
84
- assert len(analyzer.issues) == 1
85
- assert 'no tag' in analyzer.issues[0]['message']
86
-
87
- def test_specific_tag(self, temp_dockerfile):
88
- write_dockerfile(temp_dockerfile, "FROM node:20-alpine\n")
89
- analyzer = DockerfileAnalyzer(temp_dockerfile)
90
- analyzer.load_dockerfile()
91
- analyzer.analyze_base_image()
92
-
93
- # Should have no issues with specific tag
94
- base_image_issues = [i for i in analyzer.issues if i['category'] == 'base_image']
95
- assert len(base_image_issues) == 0
96
-
97
- def test_non_alpine_suggestion(self, temp_dockerfile):
98
- write_dockerfile(temp_dockerfile, "FROM node:20\n")
99
- analyzer = DockerfileAnalyzer(temp_dockerfile)
100
- analyzer.load_dockerfile()
101
- analyzer.analyze_base_image()
102
-
103
- assert len(analyzer.suggestions) >= 1
104
- assert any('Alpine' in s['message'] for s in analyzer.suggestions)
105
-
106
-
107
- class TestAnalyzeMultiStage:
108
- """Test multi-stage build analysis"""
109
-
110
- def test_single_stage_with_build_tools(self, temp_dockerfile):
111
- content = """
112
- FROM node:20
113
- WORKDIR /app
114
- COPY package.json .
115
- RUN npm install
116
- COPY . .
117
- CMD ["node", "server.js"]
118
- """
119
- write_dockerfile(temp_dockerfile, content)
120
- analyzer = DockerfileAnalyzer(temp_dockerfile)
121
- analyzer.load_dockerfile()
122
- analyzer.analyze_multi_stage()
123
-
124
- assert len(analyzer.issues) == 1
125
- assert analyzer.issues[0]['category'] == 'optimization'
126
- assert 'multi-stage' in analyzer.issues[0]['message'].lower()
127
-
128
- def test_multi_stage_no_issues(self, temp_dockerfile):
129
- content = """
130
- FROM node:20 AS build
131
- WORKDIR /app
132
- COPY package.json .
133
- RUN npm install
134
- COPY . .
135
- RUN npm run build
136
-
137
- FROM node:20-alpine
138
- WORKDIR /app
139
- COPY --from=build /app/dist ./dist
140
- CMD ["node", "dist/server.js"]
141
- """
142
- write_dockerfile(temp_dockerfile, content)
143
- analyzer = DockerfileAnalyzer(temp_dockerfile)
144
- analyzer.load_dockerfile()
145
- analyzer.analyze_multi_stage()
146
-
147
- multi_stage_issues = [i for i in analyzer.issues if i['category'] == 'optimization']
148
- assert len(multi_stage_issues) == 0
149
-
150
-
151
- class TestAnalyzeLayerCaching:
152
- """Test layer caching analysis"""
153
-
154
- def test_source_before_dependencies(self, temp_dockerfile):
155
- content = """
156
- FROM node:20
157
- WORKDIR /app
158
- COPY . .
159
- RUN npm install
160
- """
161
- write_dockerfile(temp_dockerfile, content)
162
- analyzer = DockerfileAnalyzer(temp_dockerfile)
163
- analyzer.load_dockerfile()
164
- analyzer.analyze_layer_caching()
165
-
166
- assert len(analyzer.issues) == 1
167
- assert analyzer.issues[0]['category'] == 'caching'
168
-
169
- def test_correct_order(self, temp_dockerfile):
170
- content = """
171
- FROM node:20
172
- WORKDIR /app
173
- COPY package.json .
174
- RUN npm install
175
- COPY . .
176
- """
177
- write_dockerfile(temp_dockerfile, content)
178
- analyzer = DockerfileAnalyzer(temp_dockerfile)
179
- analyzer.load_dockerfile()
180
- analyzer.analyze_layer_caching()
181
-
182
- caching_issues = [i for i in analyzer.issues if i['category'] == 'caching']
183
- assert len(caching_issues) == 0
184
-
185
-
186
- class TestAnalyzeSecurity:
187
- """Test security analysis"""
188
-
189
- def test_no_user_instruction(self, temp_dockerfile):
190
- content = """
191
- FROM node:20
192
- WORKDIR /app
193
- COPY . .
194
- CMD ["node", "server.js"]
195
- """
196
- write_dockerfile(temp_dockerfile, content)
197
- analyzer = DockerfileAnalyzer(temp_dockerfile)
198
- analyzer.load_dockerfile()
199
- analyzer.analyze_security()
200
-
201
- assert len(analyzer.issues) >= 1
202
- security_issues = [i for i in analyzer.issues if i['category'] == 'security']
203
- assert any('root' in i['message'] for i in security_issues)
204
-
205
- def test_with_user_instruction(self, temp_dockerfile):
206
- content = """
207
- FROM node:20
208
- WORKDIR /app
209
- COPY . .
210
- USER node
211
- CMD ["node", "server.js"]
212
- """
213
- write_dockerfile(temp_dockerfile, content)
214
- analyzer = DockerfileAnalyzer(temp_dockerfile)
215
- analyzer.load_dockerfile()
216
- analyzer.analyze_security()
217
-
218
- # Should not have root user issue
219
- root_issues = [i for i in analyzer.issues
220
- if i['category'] == 'security' and 'root' in i['message']]
221
- assert len(root_issues) == 0
222
-
223
- def test_detect_secrets(self, temp_dockerfile):
224
- content = """
225
- FROM node:20
226
- ENV API_KEY=secret123
227
- ENV PASSWORD=mypassword
228
- """
229
- write_dockerfile(temp_dockerfile, content)
230
- analyzer = DockerfileAnalyzer(temp_dockerfile)
231
- analyzer.load_dockerfile()
232
- analyzer.analyze_security()
233
-
234
- secret_issues = [i for i in analyzer.issues
235
- if i['category'] == 'security' and 'secret' in i['message'].lower()]
236
- assert len(secret_issues) >= 1
237
-
238
-
239
- class TestAnalyzeAptCache:
240
- """Test apt cache cleanup analysis"""
241
-
242
- def test_apt_without_cleanup(self, temp_dockerfile):
243
- content = """
244
- FROM ubuntu:22.04
245
- RUN apt-get update && apt-get install -y curl
246
- """
247
- write_dockerfile(temp_dockerfile, content)
248
- analyzer = DockerfileAnalyzer(temp_dockerfile)
249
- analyzer.load_dockerfile()
250
- analyzer.analyze_apt_cache()
251
-
252
- assert len(analyzer.suggestions) >= 1
253
- assert any('apt cache' in s['message'] for s in analyzer.suggestions)
254
-
255
- def test_apt_with_cleanup(self, temp_dockerfile):
256
- content = """
257
- FROM ubuntu:22.04
258
- RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
259
- """
260
- write_dockerfile(temp_dockerfile, content)
261
- analyzer = DockerfileAnalyzer(temp_dockerfile)
262
- analyzer.load_dockerfile()
263
- analyzer.analyze_apt_cache()
264
-
265
- apt_suggestions = [s for s in analyzer.suggestions if 'apt cache' in s['message']]
266
- assert len(apt_suggestions) == 0
267
-
268
-
269
- class TestAnalyzeCombineRun:
270
- """Test RUN command combination analysis"""
271
-
272
- def test_consecutive_runs(self, temp_dockerfile):
273
- content = """
274
- FROM node:20
275
- RUN apt-get update
276
- RUN apt-get install -y curl
277
- RUN apt-get clean
278
- """
279
- write_dockerfile(temp_dockerfile, content)
280
- analyzer = DockerfileAnalyzer(temp_dockerfile)
281
- analyzer.load_dockerfile()
282
- analyzer.analyze_combine_run()
283
-
284
- assert len(analyzer.suggestions) >= 1
285
- assert any('consecutive' in s['message'] for s in analyzer.suggestions)
286
-
287
- def test_non_consecutive_runs(self, temp_dockerfile):
288
- content = """
289
- FROM node:20
290
- RUN apt-get update
291
- COPY package.json .
292
- RUN npm install
293
- """
294
- write_dockerfile(temp_dockerfile, content)
295
- analyzer = DockerfileAnalyzer(temp_dockerfile)
296
- analyzer.load_dockerfile()
297
- analyzer.analyze_combine_run()
298
-
299
- consecutive_suggestions = [s for s in analyzer.suggestions
300
- if 'consecutive' in s['message']]
301
- assert len(consecutive_suggestions) == 0
302
-
303
-
304
- class TestAnalyzeWorkdir:
305
- """Test WORKDIR analysis"""
306
-
307
- def test_no_workdir(self, temp_dockerfile):
308
- content = """
309
- FROM node:20
310
- COPY . /app
311
- CMD ["node", "/app/server.js"]
312
- """
313
- write_dockerfile(temp_dockerfile, content)
314
- analyzer = DockerfileAnalyzer(temp_dockerfile)
315
- analyzer.load_dockerfile()
316
- analyzer.analyze_workdir()
317
-
318
- assert len(analyzer.suggestions) >= 1
319
- assert any('WORKDIR' in s['message'] for s in analyzer.suggestions)
320
-
321
- def test_with_workdir(self, temp_dockerfile):
322
- content = """
323
- FROM node:20
324
- WORKDIR /app
325
- COPY . .
326
- CMD ["node", "server.js"]
327
- """
328
- write_dockerfile(temp_dockerfile, content)
329
- analyzer = DockerfileAnalyzer(temp_dockerfile)
330
- analyzer.load_dockerfile()
331
- analyzer.analyze_workdir()
332
-
333
- workdir_suggestions = [s for s in analyzer.suggestions if 'WORKDIR' in s['message']]
334
- assert len(workdir_suggestions) == 0
335
-
336
-
337
- class TestFullAnalyze:
338
- """Test complete analysis"""
339
-
340
- def test_analyze_poor_dockerfile(self, temp_dockerfile):
341
- content = """
342
- FROM node:latest
343
- COPY . .
344
- RUN npm install
345
- CMD ["node", "server.js"]
346
- """
347
- write_dockerfile(temp_dockerfile, content)
348
- analyzer = DockerfileAnalyzer(temp_dockerfile)
349
- results = analyzer.analyze()
350
-
351
- assert 'dockerfile' in results
352
- assert 'total_lines' in results
353
- assert 'issues' in results
354
- assert 'suggestions' in results
355
- assert 'summary' in results
356
-
357
- # Should have multiple issues and suggestions
358
- assert results['summary']['warnings'] > 0
359
- assert results['summary']['suggestions'] > 0
360
-
361
- def test_analyze_good_dockerfile(self, temp_dockerfile):
362
- content = """
363
- FROM node:20-alpine AS build
364
- WORKDIR /app
365
- COPY package.json .
366
- RUN npm ci --only=production
367
- COPY . .
368
- RUN npm run build
369
-
370
- FROM node:20-alpine
371
- WORKDIR /app
372
- COPY --from=build /app/dist ./dist
373
- COPY --from=build /app/node_modules ./node_modules
374
- USER node
375
- EXPOSE 3000
376
- CMD ["node", "dist/server.js"]
377
- """
378
- write_dockerfile(temp_dockerfile, content)
379
- analyzer = DockerfileAnalyzer(temp_dockerfile)
380
- results = analyzer.analyze()
381
-
382
- # Should have minimal issues
383
- assert results['summary']['errors'] == 0
384
- # May have some suggestions, but fewer issues overall
385
-
386
-
387
- class TestPrintResults:
388
- """Test results printing"""
389
-
390
- def test_print_results(self, temp_dockerfile, capsys):
391
- content = "FROM node:latest\n"
392
- write_dockerfile(temp_dockerfile, content)
393
-
394
- analyzer = DockerfileAnalyzer(temp_dockerfile)
395
- results = analyzer.analyze()
396
- analyzer.print_results(results)
397
-
398
- captured = capsys.readouterr()
399
- assert "Dockerfile Analysis" in captured.out
400
- assert "Summary:" in captured.out
401
- assert "ISSUES:" in captured.out or "SUGGESTIONS:" in captured.out
402
-
403
-
404
- class TestIntegration:
405
- """Integration tests"""
406
-
407
- def test_full_analysis_workflow(self, temp_dockerfile):
408
- content = """
409
- FROM python:3.11
410
- COPY . /app
411
- RUN pip install -r /app/requirements.txt
412
- ENV API_KEY=secret
413
- CMD ["python", "/app/app.py"]
414
- """
415
- write_dockerfile(temp_dockerfile, content)
416
-
417
- analyzer = DockerfileAnalyzer(temp_dockerfile, verbose=True)
418
- results = analyzer.analyze()
419
-
420
- # Verify all expected checks ran
421
- assert len(analyzer.issues) > 0
422
- assert len(analyzer.suggestions) > 0
423
-
424
- # Should flag multiple categories
425
- categories = {i['category'] for i in analyzer.issues}
426
- assert 'security' in categories
427
-
428
- # Verify summary calculations
429
- total_findings = (results['summary']['errors'] +
430
- results['summary']['warnings'] +
431
- results['summary']['suggestions'])
432
- assert total_findings > 0
433
-
434
-
435
- if __name__ == "__main__":
436
- pytest.main([__file__, "-v"])
@@ -1,135 +0,0 @@
1
- ---
2
- name: hapo:frontend-design
3
- description: Create polished frontend interfaces from designs/screenshots/videos. Use for web components, 3D experiences, replicating UI designs, quick prototypes, immersive interfaces, avoiding AI slop.
4
- license: MIT
5
- user-invocable: true
6
- when_to_use: "Invoke to translate mockups or screenshots into UI implementation."
7
- category: frontend
8
- keywords: [design, mockup, ui, replication]
9
- metadata:
10
- author: haposoft
11
- version: "1.0.0"
12
- ---
13
- This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.
14
-
15
- **IMPORTANT**: MUST follow Design Thinking, Frontend Aesthetics Guidelines, Asset & Analysis References, and Anti-Patterns (AI Slop) sections below. DO NOT skip these rules.
16
-
17
- ## Workflow Selection
18
-
19
- Choose workflow based on input type:
20
-
21
- | Input | Workflow | Reference |
22
- |-------|----------|-----------|
23
- | Screenshot | Replicate exactly | `./references/workflow-screenshot.md` |
24
- | Video | Replicate with animations | `./references/workflow-video.md` |
25
- | Screenshot/Video (describe only) | Document for devs | `./references/workflow-describe.md` |
26
- | 3D/WebGL request | Three.js immersive | `./references/workflow-3d.md` |
27
- | Quick task | Rapid implementation | `./references/workflow-quick.md` |
28
- | Complex/award-quality | Full immersive | `./references/workflow-immersive.md` |
29
- | Existing project upgrade | Redesign Audit | `./references/redesign-audit-checklist.md` |
30
- | From scratch | Design Thinking below | - |
31
-
32
- **All workflows**: Activate `hapo:ui-ux-pro-max` skill FIRST for design intelligence.
33
-
34
- **Precedence:** When anti-slop rules (below) conflict with `hapo:ui-ux-pro-max` recommendations (e.g., Inter font, AI Purple palette, Lucide-only icons), substitute with alternatives from `./references/anti-slop-rules.md` unless the user explicitly requested the conflicting choice.
35
-
36
- ## Screenshot/Video Replication (Quick Reference)
37
-
38
- 1. **Analyze** with `hapo:ai-multimodal` skill - extract colors, fonts, spacing, effects
39
- 2. **Plan** with `ui-ux-designer` subagent - create phased implementation
40
- 3. **Implement** - match source precisely
41
- 4. **Verify** - compare to original
42
- 5. **Document** - update `./docs/design-guidelines.md` if approved
43
-
44
- See specific workflow files for detailed steps.
45
-
46
- ## Design Dials
47
-
48
- Three configurable parameters that drive design decisions. Set defaults at session start or let user override via chat:
49
-
50
- | Dial | Default | Range | Low (1-3) | High (8-10) |
51
- |------|---------|-------|-----------|-------------|
52
- | `DESIGN_VARIANCE` | 8 | 1-10 | Perfect symmetry, centered layouts, equal grids | Asymmetric, masonry, massive empty zones, fractional CSS Grid |
53
- | `MOTION_INTENSITY` | 6 | 1-10 | CSS hover/active states only | Framer Motion scroll reveals, spring physics, perpetual micro-animations |
54
- | `VISUAL_DENSITY` | 4 | 1-10 | Art gallery — huge whitespace, expensive/clean | Cockpit — tiny paddings, 1px dividers, monospace numbers everywhere |
55
-
56
- **Usage:** These values drive specific rules. At `DESIGN_VARIANCE > 4`, centered heroes are overused — force split-screen or left-aligned layouts. At `MOTION_INTENSITY > 5`, embed perpetual micro-animations. At `VISUAL_DENSITY > 7`, remove generic cards and use spacing/dividers.
57
-
58
- See `./references/bento-motion-engine.md` for dial-driven SaaS dashboard implementation.
59
-
60
- ## Design Thinking
61
-
62
- Before coding, commit to a BOLD aesthetic direction:
63
- - **Purpose**: What problem does this interface solve? Who uses it?
64
- - **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
65
- - **Constraints**: Technical requirements (framework, performance, accessibility).
66
- - **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
67
-
68
- **CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
69
-
70
- Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is:
71
- - Production-grade and functional
72
- - Visually striking and memorable
73
- - Cohesive with a clear aesthetic point-of-view
74
- - Meticulously refined in every detail
75
-
76
- ## Frontend Aesthetics Guidelines
77
-
78
- Focus on:
79
- - **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
80
- - **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
81
- - **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
82
- - **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
83
- - **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.
84
-
85
- NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.
86
-
87
- Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.
88
-
89
- **IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
90
-
91
- **Remember:** Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.
92
-
93
- **Assets**: Analyze supplied visual assets with `hapo:ai-multimodal`; generate or process implementation assets with the project's existing image/CSS/build tooling and document output paths in the task report.
94
-
95
- ## Asset & Analysis References
96
-
97
- | Task | Reference |
98
- |------|-----------|
99
- | Generate assets | `./references/asset-generation.md` |
100
- | Analyze quality | `./references/visual-analysis-overview.md` |
101
- | Extract guidelines | `./references/design-extraction-overview.md` |
102
- | Optimization | `./references/technical-overview.md` |
103
- | Animations | `./references/animejs.md` |
104
- | Magic UI (80+ components) | `./references/magicui-components.md` |
105
- | Anti-slop forbidden patterns | `./references/anti-slop-rules.md` |
106
- | Redesign audit checklist | `./references/redesign-audit-checklist.md` |
107
- | Premium design patterns | `./references/premium-design-patterns.md` |
108
- | Performance guardrails | `./references/performance-guardrails.md` |
109
- | Bento motion engine (SaaS) | `./references/bento-motion-engine.md` |
110
-
111
- Quick start: `./references/ai-multimodal-overview.md`
112
-
113
- ## Anti-Patterns (AI Slop)
114
-
115
- Strongly prefer alternatives to these LLM defaults. Full rules: `./references/anti-slop-rules.md`
116
-
117
- **Typography** — Avoid Inter/Roboto/Arial. Prefer: Trending Google Fonts that supports Vietnamese characters, `Geist`, `Outfit`, `Cabinet Grotesk`, `Satoshi` (search for best matches)
118
-
119
- **Font size** — ALWAYS use font size larger than 16px for input fields to avoid zoom on mobile devices.
120
-
121
- **Color** — Avoid AI purple/blue gradient aesthetic, pure `#000000`, oversaturated accents. Use neutral bases with a single considered accent.
122
-
123
- **Layout** — Avoid 3-column equal card feature rows, centered heroes at high variance, `h-screen`. Use asymmetric grids, split-screen, `min-h-[100dvh]`. Mobile-first approach is a must.
124
-
125
- **Content** — Avoid "John Doe", "Acme Corp", round numbers, AI copy clichés ("Elevate", "Seamless", "Unleash"). Use realistic names, organic data, plain specific language.
126
-
127
- **Effects** — Avoid neon/outer glows, custom cursors, gradient text on headers (unless you're asked to do so). Use tinted inner shadows, spring physics.
128
-
129
- **Components** — Avoid default unstyled shadcn, Lucide-only icons, generic card-border-shadow pattern at high density. Always customize, try Phosphor/Heroicons, use spacing over cards.
130
-
131
- **Quick check:** See the "AI Tells" checklist in `./references/anti-slop-rules.md` before delivering any design.
132
-
133
- **Performance:** Animation and blur rules in `./references/performance-guardrails.md`
134
-
135
- Remember: Claude is capable of extraordinary creative work. Commit fully to distinctive visions.