@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.
- package/README.md +116 -27
- package/bin/__tests__/codex-hooks-ownership.test.js +239 -0
- package/bin/__tests__/codex-hooks.test.js +50 -0
- package/bin/__tests__/codex-native.test.js +1882 -70
- package/bin/__tests__/develop-contract.test.js +400 -23
- package/bin/__tests__/installer-safety.test.js +3 -3
- package/bin/__tests__/optional-skill-inventory.test.js +249 -0
- package/bin/__tests__/output-styles.test.js +214 -0
- package/bin/__tests__/package-inventory.test.js +1735 -98
- package/bin/__tests__/runtime-schema.test.js +111 -0
- package/bin/__tests__/secret-output-guardrail.test.js +122 -0
- package/bin/__tests__/skill-routing-source.test.js +172 -0
- package/bin/__tests__/specs-v2-execution-closeout.test.js +1 -1
- package/bin/install.js +10 -0
- package/bin/lib/codex-install.js +170 -5
- package/bin/lib/context.js +14 -0
- package/bin/lib/i18n.js +12 -6
- package/bin/lib/skill-deps.js +5 -5
- package/bin/phases/claude-runtime.js +23 -0
- package/bin/phases/claude-settings.js +8 -0
- package/bin/phases/codex-hooks.js +156 -0
- package/bin/phases/codex-runtime.js +29 -38
- package/bin/phases/copy-payload.js +8 -2
- package/bin/phases/select-skill-bundles.js +96 -0
- package/bin/phases/skill-inventory.js +71 -0
- package/bin/phases/skills-setup.js +9 -2
- package/bin/phases/write-metadata.js +8 -5
- package/package.json +8 -2
- package/src/claude/CLAUDE.md +3 -3
- package/src/claude/agents/brainstormer.md +52 -69
- package/src/claude/agents/code-auditor.md +32 -14
- package/src/claude/agents/debugger.md +35 -20
- package/src/claude/agents/deployer.md +12 -5
- package/src/claude/agents/docs-keeper.md +11 -1
- package/src/claude/agents/implementer.md +25 -13
- package/src/claude/agents/inspector.md +6 -3
- package/src/claude/agents/project-manager.md +1 -1
- package/src/claude/agents/researcher.md +26 -55
- package/src/claude/agents/spec-maker.md +12 -7
- package/src/claude/agents/strategist.md +52 -0
- package/src/claude/agents/test-runner.md +117 -132
- package/src/claude/agents/ui-ux-designer.md +1 -1
- package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -0
- package/src/claude/hooks/__tests__/precompact.test.js +158 -0
- package/src/claude/hooks/__tests__/spec-gate.test.js +10 -3
- package/src/claude/hooks/__tests__/state.test.js +5 -0
- package/src/claude/hooks/__tests__/statusline.test.js +196 -0
- package/src/claude/hooks/agent.cjs +1 -1
- package/src/claude/hooks/docs-sync.cjs +12 -10
- package/src/claude/hooks/inspect-block.cjs +1 -1
- package/src/claude/hooks/lib/config.cjs +3 -0
- package/src/claude/hooks/lib/hook-state-dir.cjs +39 -0
- package/src/claude/hooks/lib/secret-keywords.cjs +42 -0
- package/src/claude/hooks/precompact.cjs +105 -0
- package/src/claude/hooks/rules.cjs +1 -1
- package/src/claude/hooks/secret-output-guardrail.cjs +43 -0
- package/src/claude/hooks/session.cjs +27 -1
- package/src/claude/hooks/spec-gate.cjs +3 -3
- package/src/claude/hooks/spec-state.cjs +2 -2
- package/src/claude/hooks/state.cjs +1 -1
- package/src/claude/hooks/task-scaffold-guard.cjs +1 -1
- package/src/claude/hooks/usage.cjs +1 -1
- package/src/claude/migration-manifest.json +29 -15
- package/src/claude/output-styles/coding-level-0-eli5.md +103 -0
- package/src/claude/output-styles/coding-level-1-junior.md +124 -0
- package/src/claude/output-styles/coding-level-2-mid.md +146 -0
- package/src/claude/output-styles/coding-level-3-senior.md +148 -0
- package/src/claude/output-styles/coding-level-4-lead.md +159 -0
- package/src/claude/output-styles/coding-level-5-god.md +91 -0
- package/src/claude/references/debugger/core-philosophy.md +5 -3
- package/src/claude/references/debugger/frontend-verification.md +2 -2
- package/src/claude/references/debugger/log-ci-analysis.md +13 -1
- package/src/claude/references/debugger/parallel-agent-hydration.md +19 -34
- package/src/claude/references/debugger/performance-diagnostics.md +2 -2
- package/src/claude/references/debugger/root-cause-tracing.md +37 -6
- package/src/claude/references/debugger/side-effect-gate.md +3 -1
- package/src/claude/references/debugger/verification-protocol.md +13 -12
- package/src/claude/rules/orchestrator.md +7 -1
- package/src/claude/rules/process-management.md +39 -0
- package/src/claude/rules/review-audit-self-decision.md +48 -0
- package/src/claude/rules/skill-domain-routing.md +26 -24
- package/src/claude/rules/skill-workflow-routing.md +22 -14
- package/src/claude/rules/workflow.md +3 -3
- package/src/claude/runtime.json +1 -0
- package/src/claude/runtime.schema.json +205 -0
- package/src/claude/scripts/generate-skill-catalog.cjs +156 -122
- package/src/claude/scripts/provenance.cjs +18 -5
- package/src/claude/scripts/workflow-policy.cjs +1 -1
- package/src/claude/settings/settings.json +16 -0
- package/src/claude/skills/agent-browser/SKILL.md +1 -1
- package/src/claude/skills/ai-multimodal/SKILL.md +1 -1
- package/src/claude/skills/brainstorm/SKILL.md +193 -172
- package/src/claude/skills/brainstorm/references/question-framework.md +105 -167
- package/src/claude/skills/chrome-devtools/SKILL.md +1 -1
- package/src/claude/skills/code-review/SKILL.md +43 -25
- package/src/claude/skills/code-review/references/spec-compliance-review.md +3 -4
- package/src/claude/skills/code-review/references/verification-gate.md +1 -1
- package/src/claude/skills/debug/SKILL.md +48 -19
- package/src/claude/skills/delegate/SKILL.md +1 -1
- package/src/claude/skills/develop/SKILL.md +92 -65
- package/src/claude/skills/develop/references/parallel-waves.md +36 -63
- package/src/claude/skills/develop/references/quality-gate.md +31 -4
- package/src/claude/skills/develop/references/subagent-patterns.md +21 -7
- package/src/claude/skills/docs/SKILL.md +42 -23
- package/src/claude/skills/docs/references/init-workflow.md +4 -4
- package/src/claude/skills/docs/references/reconstruct-workflow.md +6 -6
- package/src/claude/skills/docs/references/standard-docs-workflow.md +6 -2
- package/src/claude/skills/docs/references/summarize-workflow.md +2 -2
- package/src/claude/skills/docs/references/update-workflow.md +9 -7
- package/src/claude/skills/docs/templates/requirements-as-is.md +1 -1
- package/src/claude/skills/docx/SKILL.md +1 -1
- package/src/claude/skills/git/SKILL.md +1 -1
- package/src/claude/skills/git/references/commit-protocols.md +1 -1
- package/src/claude/skills/git/references/finish-branch.md +1 -1
- package/src/claude/skills/hotfix/SKILL.md +159 -170
- package/src/claude/skills/hotfix/references/diagnosis-protocol.md +14 -9
- package/src/claude/skills/hotfix/references/parallel-patterns.md +27 -13
- package/src/claude/skills/hotfix/references/prevention-gate.md +5 -0
- package/src/claude/skills/hotfix/references/review-cycle.md +21 -15
- package/src/claude/skills/hotfix/references/workflow-specialized.md +53 -21
- package/src/claude/skills/inspect/SKILL.md +55 -46
- package/src/claude/skills/inspect/references/internal-inspection.md +21 -5
- package/src/claude/skills/loop/SKILL.md +114 -0
- package/src/claude/skills/loop/references/bounded-loop-protocol.md +104 -0
- package/src/claude/skills/loop/references/metric-and-guard-contract.md +76 -0
- package/src/claude/skills/pdf/SKILL.md +1 -1
- package/src/claude/skills/pptx/SKILL.md +1 -1
- package/src/claude/skills/question/SKILL.md +16 -13
- package/src/claude/skills/research/SKILL.md +70 -43
- package/src/claude/skills/route/SKILL.md +94 -0
- package/src/claude/skills/route/references/agent-timing.md +46 -0
- package/src/claude/skills/route/references/chaining-patterns.md +53 -0
- package/src/claude/skills/route/references/task-taxonomy.md +48 -0
- package/src/claude/skills/specs/SKILL.md +41 -60
- package/src/claude/skills/specs/references/review.md +11 -8
- package/src/claude/skills/specs/references/templates.md +34 -18
- package/src/claude/skills/specs/templates/requirements-init.md +1 -1
- package/src/claude/skills/specs/templates/research.md +2 -2
- package/src/claude/skills/sync/SKILL.md +6 -6
- package/src/claude/skills/sync/references/sync-protocols.md +1 -1
- package/src/claude/skills/test/SKILL.md +120 -120
- package/src/claude/skills/test/references/execution-strategy.md +208 -361
- package/src/claude/skills/test/references/failure-triage.md +55 -121
- package/src/claude/skills/test/references/test-memory.md +20 -34
- package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
- package/src/claude/skills/web-testing/SKILL.md +1 -1
- package/src/claude/skills/xlsx/SKILL.md +1 -1
- package/src/claude/status.cjs +135 -33
- package/src/codex/AGENTS.md +14 -4
- package/src/codex/hooks/docs-sync.cjs +8 -3
- package/src/codex/hooks/lib/hook-context.cjs +18 -4
- package/src/codex/hooks/rules.cjs +29 -1
- package/src/codex/hooks/secret-output-guardrail.cjs +30 -0
- package/src/codex/hooks/spec-gate.cjs +3 -8
- package/src/codex/hooks/spec-state.cjs +2 -1
- package/src/codex/hooks.json +5 -0
- package/src/codex/runtime.json +2 -0
- package/src/common/.env.example +1 -1
- package/src/claude/skills/backend-development/SKILL.md +0 -101
- package/src/claude/skills/backend-development/references/backend-api-design.md +0 -495
- package/src/claude/skills/backend-development/references/backend-architecture.md +0 -454
- package/src/claude/skills/backend-development/references/backend-authentication.md +0 -338
- package/src/claude/skills/backend-development/references/backend-code-quality.md +0 -659
- package/src/claude/skills/backend-development/references/backend-debugging.md +0 -904
- package/src/claude/skills/backend-development/references/backend-devops.md +0 -491
- package/src/claude/skills/backend-development/references/backend-mindset.md +0 -387
- package/src/claude/skills/backend-development/references/backend-performance.md +0 -397
- package/src/claude/skills/backend-development/references/backend-security.md +0 -342
- package/src/claude/skills/backend-development/references/backend-technologies.md +0 -256
- package/src/claude/skills/backend-development/references/backend-testing.md +0 -429
- package/src/claude/skills/devops/.env.example +0 -76
- package/src/claude/skills/devops/SKILL.md +0 -102
- package/src/claude/skills/devops/references/browser-rendering.md +0 -305
- package/src/claude/skills/devops/references/cloudflare-d1-kv.md +0 -123
- package/src/claude/skills/devops/references/cloudflare-platform.md +0 -271
- package/src/claude/skills/devops/references/cloudflare-r2-storage.md +0 -280
- package/src/claude/skills/devops/references/cloudflare-workers-advanced.md +0 -312
- package/src/claude/skills/devops/references/cloudflare-workers-apis.md +0 -309
- package/src/claude/skills/devops/references/cloudflare-workers-basics.md +0 -418
- package/src/claude/skills/devops/references/docker-basics.md +0 -297
- package/src/claude/skills/devops/references/docker-compose.md +0 -292
- package/src/claude/skills/devops/references/gcloud-platform.md +0 -297
- package/src/claude/skills/devops/references/gcloud-services.md +0 -304
- package/src/claude/skills/devops/references/kubernetes-basics.md +0 -95
- package/src/claude/skills/devops/references/kubernetes-helm-advanced.md +0 -70
- package/src/claude/skills/devops/references/kubernetes-helm.md +0 -81
- package/src/claude/skills/devops/references/kubernetes-kubectl.md +0 -74
- package/src/claude/skills/devops/references/kubernetes-security-advanced.md +0 -94
- package/src/claude/skills/devops/references/kubernetes-security.md +0 -89
- package/src/claude/skills/devops/references/kubernetes-troubleshooting-advanced.md +0 -74
- package/src/claude/skills/devops/references/kubernetes-troubleshooting.md +0 -49
- package/src/claude/skills/devops/references/kubernetes-workflows-advanced.md +0 -75
- package/src/claude/skills/devops/references/kubernetes-workflows.md +0 -76
- package/src/claude/skills/devops/scripts/cloudflare_deploy.py +0 -269
- package/src/claude/skills/devops/scripts/docker_optimize.py +0 -332
- package/src/claude/skills/devops/scripts/requirements.txt +0 -20
- package/src/claude/skills/devops/scripts/tests/requirements.txt +0 -3
- package/src/claude/skills/devops/scripts/tests/test_cloudflare_deploy.py +0 -285
- package/src/claude/skills/devops/scripts/tests/test_docker_optimize.py +0 -436
- package/src/claude/skills/frontend-design/SKILL.md +0 -135
- package/src/claude/skills/frontend-design/references/ai-multimodal-overview.md +0 -165
- package/src/claude/skills/frontend-design/references/analysis-best-practices.md +0 -80
- package/src/claude/skills/frontend-design/references/analysis-prompts.md +0 -141
- package/src/claude/skills/frontend-design/references/analysis-techniques.md +0 -118
- package/src/claude/skills/frontend-design/references/animejs.md +0 -396
- package/src/claude/skills/frontend-design/references/anti-slop-rules.md +0 -103
- package/src/claude/skills/frontend-design/references/asset-generation.md +0 -337
- package/src/claude/skills/frontend-design/references/bento-motion-engine.md +0 -142
- package/src/claude/skills/frontend-design/references/design-extraction-overview.md +0 -71
- package/src/claude/skills/frontend-design/references/extraction-best-practices.md +0 -141
- package/src/claude/skills/frontend-design/references/extraction-output-templates.md +0 -162
- package/src/claude/skills/frontend-design/references/extraction-prompts.md +0 -127
- package/src/claude/skills/frontend-design/references/magicui-components.md +0 -129
- package/src/claude/skills/frontend-design/references/performance-guardrails.md +0 -169
- package/src/claude/skills/frontend-design/references/premium-design-patterns.md +0 -93
- package/src/claude/skills/frontend-design/references/redesign-audit-checklist.md +0 -114
- package/src/claude/skills/frontend-design/references/technical-accessibility.md +0 -119
- package/src/claude/skills/frontend-design/references/technical-best-practices.md +0 -97
- package/src/claude/skills/frontend-design/references/technical-optimization.md +0 -44
- package/src/claude/skills/frontend-design/references/technical-overview.md +0 -90
- package/src/claude/skills/frontend-design/references/technical-workflows.md +0 -150
- package/src/claude/skills/frontend-design/references/visual-analysis-overview.md +0 -95
- package/src/claude/skills/frontend-design/references/workflow-3d.md +0 -102
- package/src/claude/skills/frontend-design/references/workflow-describe.md +0 -87
- package/src/claude/skills/frontend-design/references/workflow-immersive.md +0 -87
- package/src/claude/skills/frontend-design/references/workflow-quick.md +0 -57
- package/src/claude/skills/frontend-design/references/workflow-screenshot.md +0 -63
- package/src/claude/skills/frontend-design/references/workflow-video.md +0 -74
- package/src/claude/skills/frontend-development/SKILL.md +0 -406
- package/src/claude/skills/frontend-development/resources/common-patterns.md +0 -331
- package/src/claude/skills/frontend-development/resources/complete-examples.md +0 -872
- package/src/claude/skills/frontend-development/resources/component-patterns.md +0 -502
- package/src/claude/skills/frontend-development/resources/data-fetching.md +0 -767
- package/src/claude/skills/frontend-development/resources/file-organization.md +0 -502
- package/src/claude/skills/frontend-development/resources/loading-and-error-states.md +0 -501
- package/src/claude/skills/frontend-development/resources/performance.md +0 -406
- package/src/claude/skills/frontend-development/resources/routing-guide.md +0 -364
- package/src/claude/skills/frontend-development/resources/styling-guide.md +0 -428
- package/src/claude/skills/frontend-development/resources/typescript-standards.md +0 -418
- package/src/claude/skills/mobile-development/SKILL.md +0 -218
- package/src/claude/skills/mobile-development/references/mobile-android.md +0 -604
- package/src/claude/skills/mobile-development/references/mobile-best-practices.md +0 -544
- package/src/claude/skills/mobile-development/references/mobile-debugging.md +0 -1089
- package/src/claude/skills/mobile-development/references/mobile-frameworks.md +0 -465
- package/src/claude/skills/mobile-development/references/mobile-ios.md +0 -496
- package/src/claude/skills/mobile-development/references/mobile-mindset.md +0 -542
- package/src/claude/skills/react-best-practices/AGENTS.md +0 -2249
- package/src/claude/skills/react-best-practices/README.md +0 -123
- package/src/claude/skills/react-best-practices/SKILL.md +0 -128
- package/src/claude/skills/react-best-practices/metadata.json +0 -15
- package/src/claude/skills/react-best-practices/rules/_sections.md +0 -46
- package/src/claude/skills/react-best-practices/rules/_template.md +0 -28
- package/src/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/src/claude/skills/react-best-practices/rules/advanced-use-latest.md +0 -49
- package/src/claude/skills/react-best-practices/rules/async-api-routes.md +0 -38
- package/src/claude/skills/react-best-practices/rules/async-defer-await.md +0 -80
- package/src/claude/skills/react-best-practices/rules/async-dependencies.md +0 -36
- package/src/claude/skills/react-best-practices/rules/async-parallel.md +0 -28
- package/src/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/src/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/src/claude/skills/react-best-practices/rules/bundle-conditional.md +0 -31
- package/src/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/src/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/src/claude/skills/react-best-practices/rules/bundle-preload.md +0 -50
- package/src/claude/skills/react-best-practices/rules/client-event-listeners.md +0 -74
- package/src/claude/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
- package/src/claude/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
- package/src/claude/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
- package/src/claude/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
- package/src/claude/skills/react-best-practices/rules/js-cache-storage.md +0 -70
- package/src/claude/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
- package/src/claude/skills/react-best-practices/rules/js-early-exit.md +0 -50
- package/src/claude/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/src/claude/skills/react-best-practices/rules/js-index-maps.md +0 -37
- package/src/claude/skills/react-best-practices/rules/js-length-check-first.md +0 -49
- package/src/claude/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
- package/src/claude/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/src/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/src/claude/skills/react-best-practices/rules/rendering-activity.md +0 -26
- package/src/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/src/claude/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/src/claude/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/src/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/src/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/src/claude/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/src/claude/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/src/claude/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
- package/src/claude/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
- package/src/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/src/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/src/claude/skills/react-best-practices/rules/rerender-memo.md +0 -44
- package/src/claude/skills/react-best-practices/rules/rerender-transitions.md +0 -40
- package/src/claude/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/src/claude/skills/react-best-practices/rules/server-cache-lru.md +0 -41
- package/src/claude/skills/react-best-practices/rules/server-cache-react.md +0 -26
- package/src/claude/skills/react-best-practices/rules/server-parallel-fetching.md +0 -79
- 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.
|