@jaimevalasek/aioson 1.7.2 → 1.8.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/CHANGELOG.md +35 -0
- package/README.md +153 -10
- package/docs/en/cli-reference.md +56 -1
- package/docs/en/i18n.md +18 -18
- package/docs/en/schemas/index.json +10 -0
- package/docs/en/schemas/parallel-assign.schema.json +9 -0
- package/docs/en/schemas/parallel-doctor.schema.json +36 -0
- package/docs/en/schemas/parallel-guard.schema.json +63 -0
- package/docs/en/schemas/parallel-merge.schema.json +84 -0
- package/docs/en/schemas/parallel-status.schema.json +91 -1
- package/docs/integrations/apps-publish-marketplace.md +94 -0
- package/docs/pt/README.md +9 -0
- package/docs/pt/agentes.md +324 -3
- package/docs/pt/clientes-ai.md +7 -3
- package/docs/pt/comandos-cli.md +160 -13
- package/docs/pt/compress-agents.md +304 -0
- package/docs/pt/design-docs-governance.md +59 -0
- package/docs/pt/feature-archive.md +191 -0
- package/docs/pt/genome-3.0-spec.md +115 -4
- package/docs/pt/genome-distribution.md +232 -0
- package/docs/pt/inicio-rapido.md +1 -0
- package/docs/pt/motor-hardening.md +492 -0
- package/docs/pt/runner-system.md +113 -0
- package/package.json +2 -1
- package/src/agent-manifests.js +66 -0
- package/src/agents.js +27 -7
- package/src/autonomy-policy.js +139 -0
- package/src/brain-query.js +161 -0
- package/src/cli.js +1377 -1099
- package/src/commands/agents.js +102 -7
- package/src/commands/artifact-validate.js +33 -4
- package/src/commands/auth.js +272 -0
- package/src/commands/brain-query.js +44 -0
- package/src/commands/briefing.js +344 -0
- package/src/commands/commit-prepare.js +547 -0
- package/src/commands/compress-agents.js +416 -0
- package/src/commands/context-health.js +4 -2
- package/src/commands/context-trim.js +17 -11
- package/src/commands/design-hybrid-options.js +3 -3
- package/src/commands/devlog-process.js +6 -4
- package/src/commands/dossier.js +423 -0
- package/src/commands/feature-archive.js +513 -0
- package/src/commands/feature-close.js +123 -18
- package/src/commands/gate-approve.js +198 -0
- package/src/commands/gate-check.js +24 -5
- package/src/commands/genome-doctor.js +166 -9
- package/src/commands/git-guard.js +170 -0
- package/src/commands/harness.js +121 -0
- package/src/commands/implementation-plan.js +47 -20
- package/src/commands/init.js +6 -2
- package/src/commands/install.js +6 -2
- package/src/commands/live.js +497 -56
- package/src/commands/locale-apply.js +9 -6
- package/src/commands/locale-diff.js +11 -112
- package/src/commands/mcp-doctor.js +2 -1
- package/src/commands/mcp-init.js +4 -10
- package/src/commands/memory.js +234 -0
- package/src/commands/parallel-assign.js +107 -27
- package/src/commands/parallel-doctor.js +416 -3
- package/src/commands/parallel-guard.js +241 -0
- package/src/commands/parallel-init.js +66 -4
- package/src/commands/parallel-merge.js +299 -0
- package/src/commands/parallel-status.js +147 -3
- package/src/commands/preflight.js +63 -4
- package/src/commands/qa-init.js +10 -5
- package/src/commands/revision.js +235 -0
- package/src/commands/scaffold-complete.js +188 -0
- package/src/commands/security-audit.js +275 -0
- package/src/commands/security-scan.js +376 -0
- package/src/commands/self-implement-loop.js +46 -2
- package/src/commands/setup-context.js +11 -10
- package/src/commands/squad-agent-create.js +51 -9
- package/src/commands/squad-investigate.js +53 -0
- package/src/commands/squad-plan.js +33 -1
- package/src/commands/squad-scaffold.js +4 -3
- package/src/commands/squad-score.js +71 -14
- package/src/commands/squad-status.js +22 -1
- package/src/commands/squad-validate.js +93 -2
- package/src/commands/store-genome.js +304 -0
- package/src/commands/store-skill.js +247 -0
- package/src/commands/store-squad.js +431 -0
- package/src/commands/store-system.js +392 -0
- package/src/commands/tool-capabilities.js +63 -0
- package/src/commands/update.js +3 -3
- package/src/commands/verify-gate.js +40 -0
- package/src/commands/workflow-execute.js +644 -155
- package/src/commands/workflow-harden.js +231 -0
- package/src/commands/workflow-heal.js +136 -0
- package/src/commands/workflow-next.js +460 -22
- package/src/commands/workflow-status.js +328 -138
- package/src/commands/workspace.js +144 -0
- package/src/constants.js +42 -75
- package/src/context-memory.js +133 -4
- package/src/context-writer.js +2 -1
- package/src/context.js +32 -2
- package/src/doctor.js +46 -6
- package/src/dossier/codemap-store.js +267 -0
- package/src/dossier/dossier-bootstrap.js +222 -0
- package/src/dossier/dossier-compact.js +159 -0
- package/src/dossier/lock.js +128 -0
- package/src/dossier/revision-store.js +313 -0
- package/src/dossier/schema.js +155 -0
- package/src/dossier/store.js +400 -0
- package/src/execution-gateway.js +3 -0
- package/src/friction-scanner.js +202 -0
- package/src/genome-schema.js +24 -1
- package/src/genomes.js +33 -0
- package/src/handoff-contract.js +363 -0
- package/src/handoff-validator.js +45 -0
- package/src/harness/circuit-breaker.js +135 -0
- package/src/i18n/messages/en.js +317 -22
- package/src/i18n/messages/es.js +259 -18
- package/src/i18n/messages/fr.js +260 -18
- package/src/i18n/messages/pt-BR.js +313 -22
- package/src/install-profile.js +0 -16
- package/src/installer.js +70 -6
- package/src/lib/git-commit-guard.js +691 -0
- package/src/lib/security/artifact-reader.js +167 -0
- package/src/lib/security/exit-codes.js +51 -0
- package/src/lib/security/findings-writer.js +176 -0
- package/src/lib/security/runtime-events.js +77 -0
- package/src/lib/security/secrets-regex.js +115 -0
- package/src/lib/store/security-scan.js +173 -0
- package/src/lib/terminal-checkbox.js +130 -0
- package/src/lib/tmux-launcher.js +163 -0
- package/src/lib/tool-capabilities.js +102 -0
- package/src/locales.js +12 -8
- package/src/parallel-workspace.js +756 -0
- package/src/parser.js +8 -1
- package/src/path-guard.js +47 -0
- package/src/preflight-engine.js +237 -26
- package/src/self-healing.js +142 -0
- package/src/session-handoff.js +111 -1
- package/src/squad/squad-scaffold.js +183 -19
- package/src/test-briefing.js +226 -0
- package/src/updater.js +1 -1
- package/src/utils.js +3 -0
- package/src/workflow-gates.js +185 -0
- package/template/.aioson/agents/analyst.md +76 -130
- package/template/.aioson/agents/architect.md +53 -86
- package/template/.aioson/agents/committer.md +161 -0
- package/template/.aioson/agents/cypher.md +252 -0
- package/template/.aioson/agents/dev.md +112 -628
- package/template/.aioson/agents/deyvin.md +33 -236
- package/template/.aioson/agents/discover.md +235 -0
- package/template/.aioson/agents/discovery-design-doc.md +17 -252
- package/template/.aioson/agents/genome.md +76 -26
- package/template/.aioson/agents/manifests/analyst.manifest.json +26 -0
- package/template/.aioson/agents/manifests/architect.manifest.json +23 -0
- package/template/.aioson/agents/manifests/committer.manifest.json +23 -0
- package/template/.aioson/agents/manifests/dev.manifest.json +37 -0
- package/template/.aioson/agents/manifests/orchestrator.manifest.json +30 -0
- package/template/.aioson/agents/manifests/pentester.manifest.json +39 -0
- package/template/.aioson/agents/manifests/pm.manifest.json +26 -0
- package/template/.aioson/agents/manifests/product.manifest.json +23 -0
- package/template/.aioson/agents/manifests/qa.manifest.json +25 -0
- package/template/.aioson/agents/manifests/setup.manifest.json +20 -0
- package/template/.aioson/agents/manifests/ux-ui.manifest.json +24 -0
- package/template/.aioson/agents/neo.md +5 -7
- package/template/.aioson/agents/orache.md +2 -6
- package/template/.aioson/agents/orchestrator.md +81 -182
- package/template/.aioson/agents/pentester.md +235 -0
- package/template/.aioson/agents/pm.md +40 -104
- package/template/.aioson/agents/product.md +99 -344
- package/template/.aioson/agents/profiler-enricher.md +57 -6
- package/template/.aioson/agents/profiler-forge.md +17 -7
- package/template/.aioson/agents/profiler-researcher.md +29 -6
- package/template/.aioson/agents/qa.md +168 -514
- package/template/.aioson/agents/setup.md +52 -278
- package/template/.aioson/agents/sheldon.md +122 -754
- package/template/.aioson/agents/site-forge.md +111 -1583
- package/template/.aioson/agents/squad.md +139 -2010
- package/template/.aioson/agents/tester.md +10 -0
- package/template/.aioson/agents/ux-ui.md +104 -812
- package/template/.aioson/agents/validator.md +69 -0
- package/template/.aioson/brains/scripts/query.js +5 -1
- package/template/.aioson/config/autonomy-protocol.json +43 -0
- package/template/.aioson/config.md +43 -15
- package/template/.aioson/constitution.md +36 -33
- package/template/.aioson/context/design-doc.md +136 -0
- package/template/.aioson/context/project-map.md +57 -0
- package/template/.aioson/design-docs/code-reuse.md +48 -0
- package/template/.aioson/design-docs/componentization.md +47 -0
- package/template/.aioson/design-docs/file-size.md +52 -0
- package/template/.aioson/design-docs/folder-structure.md +51 -0
- package/template/.aioson/design-docs/naming.md +54 -0
- package/template/.aioson/docs/LAYERS.md +12 -2
- package/template/.aioson/docs/dev/execution-discipline.md +106 -0
- package/template/.aioson/docs/dev/stack-conventions.md +83 -0
- package/template/.aioson/docs/deyvin/continuity-recovery.md +57 -0
- package/template/.aioson/docs/deyvin/debugging-escalation.md +30 -0
- package/template/.aioson/docs/deyvin/pair-execution.md +44 -0
- package/template/.aioson/docs/deyvin/runtime-handoffs.md +36 -0
- package/template/.aioson/docs/product/conversation-playbook.md +116 -0
- package/template/.aioson/docs/product/prd-contract.md +107 -0
- package/template/.aioson/docs/product/quality-lens.md +57 -0
- package/template/.aioson/docs/product/research-loop.md +65 -0
- package/template/.aioson/docs/sheldon/enrichment-paths.md +134 -0
- package/template/.aioson/docs/sheldon/quality-lens.md +57 -0
- package/template/.aioson/docs/sheldon/research-loop.md +56 -0
- package/template/.aioson/docs/sheldon/web-intelligence.md +75 -0
- package/template/.aioson/docs/site-forge-build.md +195 -0
- package/template/.aioson/docs/site-forge-extraction.md +135 -0
- package/template/.aioson/docs/site-forge-qa.md +155 -0
- package/template/.aioson/docs/site-forge-recon.md +434 -0
- package/template/.aioson/docs/site-forge-transform.md +249 -0
- package/template/.aioson/docs/squad/content-output.md +91 -0
- package/template/.aioson/docs/squad/creation-flow.md +135 -0
- package/template/.aioson/docs/squad/domain-classification.md +117 -0
- package/template/.aioson/docs/squad/genome-bindings.md +47 -0
- package/template/.aioson/docs/squad/package-contract.md +234 -0
- package/template/.aioson/docs/squad/quality-lens.md +56 -0
- package/template/.aioson/docs/squad/research-loop.md +59 -0
- package/template/.aioson/docs/squad/session-operations.md +117 -0
- package/template/.aioson/docs/squad/workflow-quality.md +165 -0
- package/template/.aioson/docs/ux-ui/accessibility-audit.md +55 -0
- package/template/.aioson/docs/ux-ui/audit-mode.md +86 -0
- package/template/.aioson/docs/ux-ui/component-map.md +35 -0
- package/template/.aioson/docs/ux-ui/design-execution.md +111 -0
- package/template/.aioson/docs/ux-ui/design-gate.md +27 -0
- package/template/.aioson/docs/ux-ui/research-mode.md +39 -0
- package/template/.aioson/docs/ux-ui/site-delivery.md +156 -0
- package/template/.aioson/docs/ux-ui/token-contract.md +57 -0
- package/template/.aioson/genomes/copywriting.meta.json +48 -0
- package/template/.aioson/git-guard.json +11 -0
- package/template/.aioson/mcp/servers.md +0 -1
- package/template/.aioson/rules/agent-language-policy.md +93 -0
- package/template/.aioson/rules/aioson-context-boundary.md +63 -0
- package/template/.aioson/rules/canonical-path-contract.md +47 -0
- package/template/.aioson/rules/data-format-convention.md +24 -86
- package/template/.aioson/rules/disk-first-artifacts.md +44 -0
- package/template/.aioson/rules/output-brevity.md +44 -0
- package/template/.aioson/rules/prd-section-ownership.md +49 -0
- package/template/.aioson/rules/security-baseline.md +139 -0
- package/template/.aioson/rules/spec-level-ownership.md +61 -0
- package/template/.aioson/rules/squad-driver-pattern.md +81 -0
- package/template/.aioson/schemas/squad-blueprint.schema.json +24 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +44 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/pm.md +30 -0
- package/template/.aioson/skills/process/secure-tdd/SKILL.md +97 -0
- package/template/.aioson/skills/process/secure-tdd/references/nextjs.md +81 -0
- package/template/.aioson/skills/process/secure-tdd/references/node-express.md +91 -0
- package/template/.aioson/skills/process/secure-tdd/references/planned-stacks.md +33 -0
- package/template/.aioson/skills/static/harness-validate/SKILL.md +46 -0
- package/template/.aioson/skills/static/web-research-cache.md +3 -0
- package/template/.aioson/tasks/squad-create.md +35 -8
- package/template/.aioson/tasks/squad-design.md +50 -2
- package/template/.aioson/tasks/squad-investigate.md +14 -1
- package/template/.claude/commands/aioson/agent/committer.md +5 -0
- package/template/.claude/commands/aioson/agent/copywriter.md +5 -0
- package/template/.claude/commands/aioson/agent/cypher.md +5 -0
- package/template/.claude/commands/aioson/agent/pair.md +5 -0
- package/template/.claude/commands/aioson/agent/validator.md +5 -0
- package/template/.gemini/commands/aios-analyst.toml +6 -3
- package/template/.gemini/commands/aios-architect.toml +7 -6
- package/template/.gemini/commands/aios-committer.toml +7 -0
- package/template/.gemini/commands/aios-copywriter.toml +7 -0
- package/template/.gemini/commands/aios-cypher.toml +7 -0
- package/template/.gemini/commands/aios-dev.toml +8 -7
- package/template/.gemini/commands/aios-deyvin.toml +6 -5
- package/template/.gemini/commands/aios-discovery-design-doc.toml +6 -3
- package/template/.gemini/commands/aios-genome.toml +7 -0
- package/template/.gemini/commands/aios-neo.toml +5 -3
- package/template/.gemini/commands/aios-orache.toml +7 -0
- package/template/.gemini/commands/aios-orchestrator.toml +8 -7
- package/template/.gemini/commands/aios-pair.toml +6 -5
- package/template/.gemini/commands/aios-pm.toml +8 -7
- package/template/.gemini/commands/aios-product.toml +5 -3
- package/template/.gemini/commands/aios-qa.toml +6 -5
- package/template/.gemini/commands/aios-setup.toml +5 -2
- package/template/.gemini/commands/aios-sheldon.toml +7 -0
- package/template/.gemini/commands/aios-site-forge.toml +7 -0
- package/template/.gemini/commands/aios-squad.toml +7 -0
- package/template/.gemini/commands/aios-tester.toml +6 -5
- package/template/.gemini/commands/aios-ux-ui.toml +8 -7
- package/template/.gemini/commands/aios-validator.toml +7 -0
- package/template/AGENTS.md +12 -1
- package/template/CLAUDE.md +5 -1
- package/template/.aioson/locales/en/agents/analyst.md +0 -244
- package/template/.aioson/locales/en/agents/architect.md +0 -245
- package/template/.aioson/locales/en/agents/dev.md +0 -397
- package/template/.aioson/locales/en/agents/deyvin.md +0 -137
- package/template/.aioson/locales/en/agents/discovery-design-doc.md +0 -27
- package/template/.aioson/locales/en/agents/genome.md +0 -212
- package/template/.aioson/locales/en/agents/neo.md +0 -8
- package/template/.aioson/locales/en/agents/orache.md +0 -6
- package/template/.aioson/locales/en/agents/orchestrator.md +0 -189
- package/template/.aioson/locales/en/agents/pair.md +0 -5
- package/template/.aioson/locales/en/agents/pm.md +0 -84
- package/template/.aioson/locales/en/agents/product.md +0 -378
- package/template/.aioson/locales/en/agents/profiler-enricher.md +0 -5
- package/template/.aioson/locales/en/agents/profiler-forge.md +0 -5
- package/template/.aioson/locales/en/agents/profiler-researcher.md +0 -5
- package/template/.aioson/locales/en/agents/qa.md +0 -270
- package/template/.aioson/locales/en/agents/setup.md +0 -421
- package/template/.aioson/locales/en/agents/sheldon.md +0 -455
- package/template/.aioson/locales/en/agents/squad.md +0 -449
- package/template/.aioson/locales/en/agents/tester.md +0 -6
- package/template/.aioson/locales/en/agents/ux-ui.md +0 -668
- package/template/.aioson/locales/es/agents/analyst.md +0 -225
- package/template/.aioson/locales/es/agents/architect.md +0 -245
- package/template/.aioson/locales/es/agents/dev.md +0 -370
- package/template/.aioson/locales/es/agents/deyvin.md +0 -99
- package/template/.aioson/locales/es/agents/discovery-design-doc.md +0 -21
- package/template/.aioson/locales/es/agents/genome.md +0 -104
- package/template/.aioson/locales/es/agents/neo.md +0 -50
- package/template/.aioson/locales/es/agents/orache.md +0 -105
- package/template/.aioson/locales/es/agents/orchestrator.md +0 -194
- package/template/.aioson/locales/es/agents/pair.md +0 -7
- package/template/.aioson/locales/es/agents/pm.md +0 -90
- package/template/.aioson/locales/es/agents/product.md +0 -372
- package/template/.aioson/locales/es/agents/profiler-enricher.md +0 -7
- package/template/.aioson/locales/es/agents/profiler-forge.md +0 -7
- package/template/.aioson/locales/es/agents/profiler-researcher.md +0 -7
- package/template/.aioson/locales/es/agents/qa.md +0 -198
- package/template/.aioson/locales/es/agents/setup.md +0 -405
- package/template/.aioson/locales/es/agents/sheldon.md +0 -309
- package/template/.aioson/locales/es/agents/squad.md +0 -532
- package/template/.aioson/locales/es/agents/tester.md +0 -9
- package/template/.aioson/locales/es/agents/ux-ui.md +0 -212
- package/template/.aioson/locales/fr/agents/analyst.md +0 -225
- package/template/.aioson/locales/fr/agents/architect.md +0 -245
- package/template/.aioson/locales/fr/agents/dev.md +0 -370
- package/template/.aioson/locales/fr/agents/deyvin.md +0 -99
- package/template/.aioson/locales/fr/agents/discovery-design-doc.md +0 -21
- package/template/.aioson/locales/fr/agents/genome.md +0 -104
- package/template/.aioson/locales/fr/agents/neo.md +0 -50
- package/template/.aioson/locales/fr/agents/orache.md +0 -106
- package/template/.aioson/locales/fr/agents/orchestrator.md +0 -194
- package/template/.aioson/locales/fr/agents/pair.md +0 -7
- package/template/.aioson/locales/fr/agents/pm.md +0 -90
- package/template/.aioson/locales/fr/agents/product.md +0 -372
- package/template/.aioson/locales/fr/agents/profiler-enricher.md +0 -7
- package/template/.aioson/locales/fr/agents/profiler-forge.md +0 -7
- package/template/.aioson/locales/fr/agents/profiler-researcher.md +0 -7
- package/template/.aioson/locales/fr/agents/qa.md +0 -198
- package/template/.aioson/locales/fr/agents/setup.md +0 -405
- package/template/.aioson/locales/fr/agents/sheldon.md +0 -309
- package/template/.aioson/locales/fr/agents/squad.md +0 -532
- package/template/.aioson/locales/fr/agents/tester.md +0 -9
- package/template/.aioson/locales/fr/agents/ux-ui.md +0 -212
- package/template/.aioson/locales/pt-BR/agents/analyst.md +0 -319
- package/template/.aioson/locales/pt-BR/agents/architect.md +0 -284
- package/template/.aioson/locales/pt-BR/agents/dev.md +0 -483
- package/template/.aioson/locales/pt-BR/agents/deyvin.md +0 -184
- package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +0 -198
- package/template/.aioson/locales/pt-BR/agents/genome.md +0 -297
- package/template/.aioson/locales/pt-BR/agents/neo.md +0 -208
- package/template/.aioson/locales/pt-BR/agents/orache.md +0 -137
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +0 -324
- package/template/.aioson/locales/pt-BR/agents/pair.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/pm.md +0 -182
- package/template/.aioson/locales/pt-BR/agents/product.md +0 -466
- package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/qa.md +0 -300
- package/template/.aioson/locales/pt-BR/agents/setup.md +0 -533
- package/template/.aioson/locales/pt-BR/agents/sheldon.md +0 -323
- package/template/.aioson/locales/pt-BR/agents/squad.md +0 -1330
- package/template/.aioson/locales/pt-BR/agents/tester.md +0 -449
- package/template/.aioson/locales/pt-BR/agents/ux-ui.md +0 -669
|
@@ -23,10 +23,9 @@ Clone the structure, content, and/or visual design of a real website. Build a Ne
|
|
|
23
23
|
Load `.aioson/brains/_index.json` on activation — it's ~2KB.
|
|
24
24
|
|
|
25
25
|
When task involves visual cloning, CSS animation, hover effects, scroll, video, or font extraction:
|
|
26
|
-
|
|
27
26
|
1. Find matching brain files from index (tag match against task context)
|
|
28
27
|
2. Load those brain files — not all, only relevant
|
|
29
|
-
3. For nodes with `q >= 4`: apply as the default approach
|
|
28
|
+
3. For nodes with `q >= 4`: apply as the default approach
|
|
30
29
|
4. For nodes with `v === "AVOID"`: never implement what's in their `not` field
|
|
31
30
|
5. Traverse `see[]` links to explore connected knowledge
|
|
32
31
|
|
|
@@ -35,40 +34,32 @@ Cross-reference command (run before Phase 2 if task involves animation/interacti
|
|
|
35
34
|
node .aioson/brains/scripts/query.js --agent site-forge --min-quality 4 --format compact
|
|
36
35
|
```
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
- Add nodes to `.aioson/brains/site-forge/visual-patterns.brain.json`
|
|
40
|
-
- Rate quality 1–5 (be honest — 3 = theoretical, 5 = verified in production)
|
|
41
|
-
- Add `see[]` links to related nodes (Zettelkasten web)
|
|
42
|
-
- Update `_index.json` nodes count and `updated` date
|
|
37
|
+
After forging a skill, record new learnings back into `.aioson/brains/site-forge/visual-patterns.brain.json`. Rate quality 1–5. Add `see[]` links. Update `_index.json`.
|
|
43
38
|
|
|
44
39
|
---
|
|
45
40
|
|
|
46
41
|
## Project rules, docs & design docs
|
|
47
42
|
|
|
48
|
-
|
|
43
|
+
Check silently — if absent or empty, move on without mentioning it.
|
|
49
44
|
|
|
50
|
-
1. **`.aioson/rules/`** —
|
|
45
|
+
1. **`.aioson/rules/`** — Load if `agents:` is absent or includes `site-forge`. Loaded rules override defaults here.
|
|
51
46
|
2. **`.aioson/docs/`** — Load only files whose `description` frontmatter is relevant to the current task.
|
|
52
|
-
3. **`.aioson/context/design-doc*.md`** —
|
|
47
|
+
3. **`.aioson/context/design-doc*.md`** — Load when `agents:` is absent and `scope` matches, or when `agents:` includes `site-forge`.
|
|
53
48
|
|
|
54
49
|
---
|
|
55
50
|
|
|
56
|
-
##
|
|
51
|
+
## Smart Onboarding
|
|
57
52
|
|
|
58
53
|
**Parse the input first:**
|
|
59
54
|
|
|
60
55
|
- URL + skill name (explicit) → **Mode A**. Go to Step 0.
|
|
61
56
|
- URL + `--skill-only` or `--no-build` flag → **Mode D**. Go to Step 0.
|
|
62
57
|
- URL + skill name + `--blend` flag → **Mode E**. Ask for blend ratio (default 50%). Go to Step 0.
|
|
63
|
-
- URL only (no skill, no flags) → Run
|
|
64
|
-
- No URL, any input → Run
|
|
65
|
-
|
|
66
|
-
---
|
|
58
|
+
- URL only (no skill, no flags) → Run questionnaire below.
|
|
59
|
+
- No URL, any input → Run questionnaire below.
|
|
67
60
|
|
|
68
61
|
### Onboarding questionnaire
|
|
69
62
|
|
|
70
|
-
Present this when the mode is not unambiguous from the input:
|
|
71
|
-
|
|
72
63
|
```
|
|
73
64
|
Olá! Vou te guiar para o modo certo de clonagem.
|
|
74
65
|
|
|
@@ -90,30 +81,23 @@ O que você quer fazer com este site?
|
|
|
90
81
|
Responda A, B, C ou D.
|
|
91
82
|
```
|
|
92
83
|
|
|
93
|
-
**After
|
|
94
|
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
- **D selected:** Ask for URL (if not yet provided). List available skills — ask which to use. Ask for blend ratio (default 50%). → Route to **Mode E**.
|
|
99
|
-
|
|
100
|
-
Map user choices to internal modes:
|
|
101
|
-
- User choice A → **Mode C** (emphasizes deep content extraction, applies skill to build)
|
|
102
|
-
- User choice B → **Mode B** (existing faithful clone + skill forge)
|
|
103
|
-
- User choice C → **Mode D** (skill forge only)
|
|
104
|
-
- User choice D → **Mode E** (clone + blend)
|
|
84
|
+
**After user answers:**
|
|
85
|
+
- A selected → collect URL + skill from `.aioson/installed-skills/` or `.aioson/skills/design/` → route to **Mode C**
|
|
86
|
+
- B selected → collect URL → route to **Mode B**
|
|
87
|
+
- C selected → collect URL → route to **Mode D** (skill only)
|
|
88
|
+
- D selected → collect URL + skill + blend ratio (default 50%) → route to **Mode E**
|
|
105
89
|
|
|
106
|
-
Once all inputs
|
|
90
|
+
Once all inputs confirmed, proceed to Step 0.
|
|
107
91
|
|
|
108
92
|
---
|
|
109
93
|
|
|
110
94
|
## Step 0 — Preflight
|
|
111
95
|
|
|
112
|
-
Run all checks BEFORE
|
|
96
|
+
Run all checks BEFORE Phase 1. Block on critical failures.
|
|
113
97
|
|
|
114
98
|
### 0.1 Browser MCP check (CRITICAL)
|
|
115
99
|
|
|
116
|
-
Attempt
|
|
100
|
+
Attempt minimal navigation to detect available browser MCP. Preference order:
|
|
117
101
|
1. Playwright MCP (`@playwright/mcp`) — preferred
|
|
118
102
|
2. Puppeteer MCP (`@modelcontextprotocol/server-puppeteer`) — fallback
|
|
119
103
|
3. Browserbase MCP — cloud option
|
|
@@ -135,10 +119,9 @@ Add it to your Claude Code MCP settings and re-activate /site-forge.
|
|
|
135
119
|
```
|
|
136
120
|
Do not proceed past Step 0 if no browser MCP is available.
|
|
137
121
|
|
|
138
|
-
### 0.2 Mode
|
|
139
|
-
|
|
140
|
-
After onboarding, confirm the active mode to the user:
|
|
122
|
+
### 0.2 Mode confirmation
|
|
141
123
|
|
|
124
|
+
Confirm to the user:
|
|
142
125
|
```
|
|
143
126
|
Modo ativo: [A | B | C | D | E]
|
|
144
127
|
URL: <url>
|
|
@@ -146,1608 +129,153 @@ Skill: <skill-name> (if applicable)
|
|
|
146
129
|
Blend: <ratio>% (Mode E only)
|
|
147
130
|
```
|
|
148
131
|
|
|
149
|
-
**Mode A / C / E — Skill resolution:**
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
1. `.aioson/installed-skills/<skill-name>/SKILL.md` — skills from @design-hybrid-forge
|
|
153
|
-
2. `.aioson/skills/design/<skill-name>/SKILL.md` — core AIOSON design skills
|
|
132
|
+
**Mode A / C / E — Skill resolution:** Look in order:
|
|
133
|
+
1. `.aioson/installed-skills/<skill-name>/SKILL.md`
|
|
134
|
+
2. `.aioson/skills/design/<skill-name>/SKILL.md`
|
|
154
135
|
|
|
155
|
-
|
|
136
|
+
If not found:
|
|
156
137
|
```
|
|
157
138
|
⛔ Skill "<skill-name>" not found.
|
|
158
|
-
|
|
159
|
-
Skills disponíveis:
|
|
160
|
-
[list from both paths]
|
|
161
|
-
|
|
139
|
+
Skills disponíveis: [list from both paths]
|
|
162
140
|
Para criar uma nova hybrid skill: /design-hybrid-forge
|
|
163
141
|
```
|
|
164
142
|
|
|
165
|
-
**Mode B / D
|
|
166
|
-
|
|
167
|
-
### 0.3 Output directory detection
|
|
143
|
+
**Mode B / D:** Skill forged during Phase 3B — none needed now.
|
|
168
144
|
|
|
169
|
-
|
|
145
|
+
### 0.3 Output directory detection (Modes A, B, C, E)
|
|
170
146
|
|
|
171
|
-
Check
|
|
172
|
-
- `package.json` with `"next"` in dependencies, or
|
|
173
|
-
- `next.config.*` file present
|
|
147
|
+
Check for existing Next.js project: `package.json` with `"next"` in dependencies, or `next.config.*` present.
|
|
174
148
|
|
|
175
|
-
|
|
149
|
+
- Found → use it. Warn if uncommitted changes exist.
|
|
150
|
+
- Not found → ask: "No Next.js project found. Should I scaffold one with `create-next-app` (TypeScript + Tailwind + App Router)?"
|
|
151
|
+
If yes: `npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --no-git`
|
|
176
152
|
|
|
177
|
-
**
|
|
178
|
-
> "No Next.js project found. Should I scaffold one with `create-next-app` (TypeScript + Tailwind + App Router)?"
|
|
179
|
-
>
|
|
180
|
-
> If yes:
|
|
181
|
-
> ```bash
|
|
182
|
-
> npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --no-git
|
|
183
|
-
> ```
|
|
184
|
-
|
|
185
|
-
**Mode D (skill only):** Skip this check. No Next.js project needed.
|
|
153
|
+
**Mode D:** Skip — no Next.js project needed.
|
|
186
154
|
|
|
187
155
|
### 0.4 Research directories
|
|
188
156
|
|
|
189
|
-
Create before
|
|
157
|
+
Create before Phase 1:
|
|
190
158
|
- `docs/research/<hostname>/`
|
|
191
159
|
- `docs/research/components/`
|
|
192
160
|
- `public/images/<hostname>/` (Modes A, B, C, E only)
|
|
193
161
|
|
|
194
162
|
---
|
|
195
163
|
|
|
196
|
-
## Phase
|
|
197
|
-
|
|
198
|
-
**Goal:** Capture raw information about the site. All modes run this phase.
|
|
199
|
-
|
|
200
|
-
### 1.1 Multi-viewport screenshots
|
|
201
|
-
|
|
202
|
-
Navigate to the URL and capture at three widths:
|
|
203
|
-
- Desktop: 1440px
|
|
204
|
-
- Tablet: 768px
|
|
205
|
-
- Mobile: 390px
|
|
206
|
-
|
|
207
|
-
Save to `docs/research/<hostname>/screenshots/desktop.png`, `tablet.png`, `mobile.png`.
|
|
208
|
-
|
|
209
|
-
**Bot protection:** If the page renders blank, shows a CAPTCHA, or redirects to a challenge page, tell the user:
|
|
210
|
-
> "This site has bot protection. Please provide session cookies or a local HAR capture to continue."
|
|
211
|
-
|
|
212
|
-
### 1.2 Deep asset inventory (CRITICAL — do not skip steps)
|
|
213
|
-
|
|
214
|
-
**Step A — Trigger lazy loads before extraction:**
|
|
215
|
-
|
|
216
|
-
```javascript
|
|
217
|
-
// Scroll to trigger lazy-loaded images before extracting
|
|
218
|
-
await page.evaluate(() => {
|
|
219
|
-
return new Promise(resolve => {
|
|
220
|
-
let totalHeight = 0;
|
|
221
|
-
const distance = 300;
|
|
222
|
-
const timer = setInterval(() => {
|
|
223
|
-
window.scrollBy(0, distance);
|
|
224
|
-
totalHeight += distance;
|
|
225
|
-
if (totalHeight >= document.body.scrollHeight) {
|
|
226
|
-
clearInterval(timer);
|
|
227
|
-
window.scrollTo(0, 0);
|
|
228
|
-
resolve();
|
|
229
|
-
}
|
|
230
|
-
}, 100);
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
Wait 1 second after scroll for lazy-loaded content to appear.
|
|
236
|
-
|
|
237
|
-
**Step B — Collect all image URLs:**
|
|
238
|
-
|
|
239
|
-
```javascript
|
|
240
|
-
// Run via browser MCP evaluate()
|
|
241
|
-
const allAssets = new Set();
|
|
242
|
-
|
|
243
|
-
// 1. img tags — including srcset variants
|
|
244
|
-
document.querySelectorAll('img').forEach(img => {
|
|
245
|
-
if (img.src) allAssets.add(img.src);
|
|
246
|
-
if (img.srcset) {
|
|
247
|
-
img.srcset.split(',').forEach(s => {
|
|
248
|
-
const url = s.trim().split(' ')[0];
|
|
249
|
-
if (url) allAssets.add(new URL(url, window.location.href).href);
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
if (img.dataset.src) allAssets.add(new URL(img.dataset.src, window.location.href).href);
|
|
253
|
-
if (img.dataset.srcset) {
|
|
254
|
-
img.dataset.srcset.split(',').forEach(s => {
|
|
255
|
-
const url = s.trim().split(' ')[0];
|
|
256
|
-
if (url) allAssets.add(new URL(url, window.location.href).href);
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
// 2. picture source elements
|
|
262
|
-
document.querySelectorAll('picture source').forEach(s => {
|
|
263
|
-
if (s.srcset) {
|
|
264
|
-
s.srcset.split(',').forEach(src => {
|
|
265
|
-
const url = src.trim().split(' ')[0];
|
|
266
|
-
if (url) allAssets.add(new URL(url, window.location.href).href);
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
// 3. CSS background-image on ALL elements
|
|
272
|
-
document.querySelectorAll('*').forEach(el => {
|
|
273
|
-
const bg = window.getComputedStyle(el).backgroundImage;
|
|
274
|
-
if (bg && bg !== 'none') {
|
|
275
|
-
const matches = bg.match(/url\(["']?([^"')]+)["']?\)/g) || [];
|
|
276
|
-
matches.forEach(m => {
|
|
277
|
-
const url = m.replace(/url\(["']?|["']?\)/g, '').trim();
|
|
278
|
-
if (url && !url.startsWith('data:')) allAssets.add(new URL(url, window.location.href).href);
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
// 4. video elements (poster + source)
|
|
284
|
-
document.querySelectorAll('video').forEach(v => {
|
|
285
|
-
if (v.poster) allAssets.add(v.poster);
|
|
286
|
-
if (v.src && v.src !== window.location.href) allAssets.add(v.src);
|
|
287
|
-
v.querySelectorAll('source').forEach(s => {
|
|
288
|
-
if (s.src) allAssets.add(s.src);
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
// 5. SVG use references (external sprite files)
|
|
293
|
-
document.querySelectorAll('use').forEach(u => {
|
|
294
|
-
const href = u.getAttribute('href') || u.getAttribute('xlink:href');
|
|
295
|
-
if (href && !href.startsWith('#')) {
|
|
296
|
-
allAssets.add(new URL(href.split('#')[0], window.location.href).href);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
// 6. inline style background-image attributes
|
|
301
|
-
document.querySelectorAll('[style]').forEach(el => {
|
|
302
|
-
const style = el.getAttribute('style') || '';
|
|
303
|
-
const matches = style.match(/url\(["']?([^"')]+)["']?\)/g) || [];
|
|
304
|
-
matches.forEach(m => {
|
|
305
|
-
const url = m.replace(/url\(["']?|["']?\)/g, '').trim();
|
|
306
|
-
if (url && !url.startsWith('data:')) allAssets.add(new URL(url, window.location.href).href);
|
|
307
|
-
});
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
// 7. og:image and twitter:image meta tags
|
|
311
|
-
document.querySelectorAll('meta[property="og:image"], meta[name="twitter:image"]').forEach(m => {
|
|
312
|
-
const content = m.getAttribute('content');
|
|
313
|
-
if (content) allAssets.add(new URL(content, window.location.href).href);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
return {
|
|
317
|
-
images: [...allAssets].filter(url => url.startsWith('http')),
|
|
318
|
-
fonts: [...document.querySelectorAll('link[rel=stylesheet]')]
|
|
319
|
-
.map(l => l.href)
|
|
320
|
-
.filter(h => h.includes('fonts') || h.includes('typekit') || h.includes('adobe'))
|
|
321
|
-
};
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
Download all collected images to `public/images/<hostname>/`. Skip images > 2MB unless they are clearly structural (hero, logo, background). Preserve original filenames when possible; sanitize paths.
|
|
325
|
-
|
|
326
|
-
**Download is mandatory in Modes A, B, C, E.** Do not skip it. The copyright notice below is informational only — it does not prevent the download.
|
|
327
|
-
|
|
328
|
-
Skip download in **Mode D** (skill only) — record URLs but don't download.
|
|
329
|
-
|
|
330
|
-
**Copyright / reference notice:** Tell the user after Phase 1:
|
|
331
|
-
> "As imagens foram baixadas para `public/images/<hostname>/` e serão usadas como referência durante o desenvolvimento.
|
|
332
|
-
> São arquivos temporários — substitua-os pelos seus próprios assets antes de publicar.
|
|
333
|
-
> Você pode deletar a pasta `public/images/<hostname>/` a qualquer momento após substituir as imagens nos componentes."
|
|
334
|
-
|
|
335
|
-
### 1.3 Font discovery
|
|
336
|
-
|
|
337
|
-
Extract from `<link>` tags and `getComputedStyle()` on heading, body, and code elements:
|
|
338
|
-
- Font families in use
|
|
339
|
-
- Weights loaded
|
|
340
|
-
- Where each is applied
|
|
341
|
-
|
|
342
|
-
### 1.4 Internal link crawl (configurable)
|
|
343
|
-
|
|
344
|
-
After the main page is fully captured, collect internal links:
|
|
345
|
-
|
|
346
|
-
```javascript
|
|
347
|
-
const hostname = window.location.hostname;
|
|
348
|
-
const links = [...document.querySelectorAll('a[href]')]
|
|
349
|
-
.map(a => a.href)
|
|
350
|
-
.filter(href => {
|
|
351
|
-
try {
|
|
352
|
-
return new URL(href).hostname === hostname;
|
|
353
|
-
} catch { return false; }
|
|
354
|
-
});
|
|
355
|
-
return [...new Set(links)];
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
**Default crawl behavior:**
|
|
359
|
-
- **Mode B, D (faithful clone / skill forge):** Follow up to **5 internal links** to capture sub-pages, blog posts, or feature pages that may have additional design patterns.
|
|
360
|
-
- **Mode A, C (content harvest):** Follow up to **10 internal links** — content and assets across the site are the primary goal.
|
|
361
|
-
- **Mode E (blend):** Follow up to **5 internal links**.
|
|
362
|
-
|
|
363
|
-
For each crawled sub-page: capture screenshots, run asset inventory (Step B above), note layout differences vs. main page.
|
|
364
|
-
|
|
365
|
-
Save crawl manifest to `docs/research/<hostname>/crawl-manifest.json`:
|
|
366
|
-
```json
|
|
367
|
-
{
|
|
368
|
-
"mainUrl": "<url>",
|
|
369
|
-
"crawledUrls": ["<url1>", "<url2>"],
|
|
370
|
-
"assetsPerPage": { "<url>": ["<asset-path>", ...] }
|
|
371
|
-
}
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
**If the user wants to skip sub-page crawl:** `--no-crawl` flag.
|
|
375
|
-
|
|
376
|
-
### 1.5 Interaction sweep (CRITICAL — complete before Phase 2)
|
|
377
|
-
|
|
378
|
-
Perform in this order:
|
|
379
|
-
1. Slow scroll top→bottom: observe sticky headers, scroll-driven animations, parallax, lazy loads
|
|
380
|
-
2. Click all interactive elements: tabs, dropdowns, modals, accordions, carousels
|
|
381
|
-
3. Hover suspect elements: nav items, cards, buttons, tooltips
|
|
382
|
-
4. Resize to 768px then 390px: observe nav collapses, layout reflows, hidden elements
|
|
383
|
-
|
|
384
|
-
Document per section:
|
|
385
|
-
- What triggers what (scroll position, click target, hover element)
|
|
386
|
-
- What animates (which elements, which CSS properties change — type only, not values)
|
|
387
|
-
- Which elements are sticky and at what scroll position they activate
|
|
388
|
-
- Where layout changes at each viewport
|
|
389
|
-
|
|
390
|
-
### 1.6 Page topology
|
|
391
|
-
|
|
392
|
-
Map all sections top→bottom with a one-line description:
|
|
393
|
-
```
|
|
394
|
-
1. Header — sticky nav, logo left, links right, CTA button
|
|
395
|
-
2. Hero — full-viewport, headline + subtitle + 2 CTAs, background gradient
|
|
396
|
-
3. Features — 3-column card grid, icon + title + body each
|
|
397
|
-
4. Pricing — 2-column comparison, monthly/annual toggle
|
|
398
|
-
5. Footer — 4-column links, legal row
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**Output:** `docs/research/<hostname>/reconnaissance.json`
|
|
402
|
-
|
|
403
|
-
```json
|
|
404
|
-
{
|
|
405
|
-
"url": "https://example.com",
|
|
406
|
-
"hostname": "example.com",
|
|
407
|
-
"screenshotsTaken": ["desktop", "tablet", "mobile"],
|
|
408
|
-
"fonts": [{ "family": "Inter", "weights": [400, 500, 600], "usedFor": "body" }],
|
|
409
|
-
"assetsDownloaded": ["hero.webp", "logo.svg"],
|
|
410
|
-
"crawledPages": ["<url>", "..."],
|
|
411
|
-
"interactionModel": {
|
|
412
|
-
"header": "scroll-driven shrink at 50px",
|
|
413
|
-
"featureTabs": "click-switch content",
|
|
414
|
-
"pricingToggle": "click-switch monthly/annual"
|
|
415
|
-
},
|
|
416
|
-
"pageTopology": ["Header", "Hero", "Features", "Pricing", "Footer"],
|
|
417
|
-
"breakpoints": { "tablet": 768, "mobile": 390 }
|
|
418
|
-
}
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
**Exit criterion:** Screenshots captured at all viewports. Assets inventoried (all sources: img, background-image, srcset, video, SVG). Lazy loads triggered before extraction. Interaction model documented for every section. Page topology complete.
|
|
422
|
-
|
|
423
|
-
---
|
|
424
|
-
|
|
425
|
-
## Phase 1.5 — Deep Animation & Video Extraction
|
|
426
|
-
|
|
427
|
-
**Goal:** Extract the real animation machinery — CSS keyframes, JS animation libraries, video assets, and scroll-triggered DOM mutations. This phase transforms a visual clone into a behavioral clone.
|
|
428
|
-
|
|
429
|
-
**All modes run this phase.** Skip only if `--no-deep` flag is set.
|
|
430
|
-
|
|
431
|
-
### 1.5.1 Animation library detection
|
|
432
|
-
|
|
433
|
-
Run immediately after Phase 1.1. The result determines which implementation strategy Phase 4.4 will use.
|
|
434
|
-
|
|
435
|
-
```javascript
|
|
436
|
-
return {
|
|
437
|
-
gsap: typeof window.gsap !== 'undefined',
|
|
438
|
-
scrollTrigger: typeof window.ScrollTrigger !== 'undefined',
|
|
439
|
-
framerMotion: !!document.querySelector('[data-framer-component-type]'),
|
|
440
|
-
aos: typeof window.AOS !== 'undefined',
|
|
441
|
-
lottie: typeof window.lottie !== 'undefined',
|
|
442
|
-
threejs: typeof window.THREE !== 'undefined',
|
|
443
|
-
swiper: typeof window.Swiper !== 'undefined',
|
|
444
|
-
motionOne: typeof window.animate !== 'undefined' && !!window.animate?.toString?.().includes('motion'),
|
|
445
|
-
};
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
Save result to `docs/research/<hostname>/animations-raw.json` under key `jsLibraries`.
|
|
449
|
-
|
|
450
|
-
### 1.5.2 CSS animation rules extraction
|
|
451
|
-
|
|
452
|
-
Extract all animatable CSS rules directly from loaded stylesheets — not computed values. This captures `@keyframes`, `animation-*`, `transition`, `transform`, `scroll-timeline`, and `will-change` rules that `getComputedStyle` never exposes.
|
|
453
|
-
|
|
454
|
-
```javascript
|
|
455
|
-
const animationRules = [];
|
|
456
|
-
const keyframes = [];
|
|
457
|
-
const scrollLinked = [];
|
|
458
|
-
|
|
459
|
-
for (const sheet of document.styleSheets) {
|
|
460
|
-
try {
|
|
461
|
-
for (const rule of sheet.cssRules) {
|
|
462
|
-
const text = rule.cssText;
|
|
463
|
-
|
|
464
|
-
// @keyframes blocks
|
|
465
|
-
if (rule instanceof CSSKeyframesRule) {
|
|
466
|
-
keyframes.push({
|
|
467
|
-
name: rule.name,
|
|
468
|
-
cssText: text,
|
|
469
|
-
keyCount: rule.cssRules.length,
|
|
470
|
-
});
|
|
471
|
-
continue;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// Rules with animation or transition properties
|
|
475
|
-
if (
|
|
476
|
-
text.includes('animation') ||
|
|
477
|
-
text.includes('transition') ||
|
|
478
|
-
text.includes('transform') ||
|
|
479
|
-
text.includes('will-change') ||
|
|
480
|
-
text.includes('scroll-timeline') ||
|
|
481
|
-
text.includes('animation-timeline') ||
|
|
482
|
-
text.includes('view-timeline')
|
|
483
|
-
) {
|
|
484
|
-
animationRules.push({
|
|
485
|
-
selector: rule.selectorText || rule.cssText.split('{')[0].trim(),
|
|
486
|
-
cssText: text,
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Scroll-linked animations (@scroll-timeline, animation-timeline: scroll())
|
|
491
|
-
if (
|
|
492
|
-
text.includes('scroll-timeline') ||
|
|
493
|
-
text.includes('animation-timeline') ||
|
|
494
|
-
text.includes('view-timeline') ||
|
|
495
|
-
text.includes('scroll()')
|
|
496
|
-
) {
|
|
497
|
-
scrollLinked.push({
|
|
498
|
-
selector: rule.selectorText || rule.cssText.split('{')[0].trim(),
|
|
499
|
-
cssText: text,
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
} catch {
|
|
504
|
-
// Cross-origin stylesheets — skip silently
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
return { animationRules, keyframes, scrollLinked };
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
Save to `docs/research/<hostname>/animations-raw.json` under keys `animationRules`, `keyframes`, `scrollLinked`.
|
|
512
|
-
|
|
513
|
-
**Also extract** computed animation properties on elements that are currently visible:
|
|
514
|
-
|
|
515
|
-
```javascript
|
|
516
|
-
const animated = [];
|
|
517
|
-
document.querySelectorAll('*').forEach(el => {
|
|
518
|
-
const s = window.getComputedStyle(el);
|
|
519
|
-
if (
|
|
520
|
-
s.animationName !== 'none' ||
|
|
521
|
-
s.transition !== 'all 0s ease 0s' ||
|
|
522
|
-
s.transform !== 'none' ||
|
|
523
|
-
s.willChange !== 'auto'
|
|
524
|
-
) {
|
|
525
|
-
animated.push({
|
|
526
|
-
selector: el.tagName + (el.id ? '#' + el.id : '') + (el.className ? '.' + [...el.classList].join('.') : ''),
|
|
527
|
-
animationName: s.animationName,
|
|
528
|
-
animationDuration: s.animationDuration,
|
|
529
|
-
animationTimingFunction: s.animationTimingFunction,
|
|
530
|
-
transition: s.transition,
|
|
531
|
-
transform: s.transform,
|
|
532
|
-
willChange: s.willChange,
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
});
|
|
536
|
-
return animated;
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
Save to `animations-raw.json` under key `activeAnimations`.
|
|
540
|
-
|
|
541
|
-
### 1.5.3 Video extraction and download
|
|
542
|
-
|
|
543
|
-
```javascript
|
|
544
|
-
return [...document.querySelectorAll('video')].map(v => ({
|
|
545
|
-
sources: [...v.querySelectorAll('source')].map(s => ({
|
|
546
|
-
src: s.src,
|
|
547
|
-
type: s.type,
|
|
548
|
-
})),
|
|
549
|
-
src: v.src || null,
|
|
550
|
-
poster: v.poster || null,
|
|
551
|
-
autoplay: v.autoplay,
|
|
552
|
-
muted: v.muted,
|
|
553
|
-
loop: v.loop,
|
|
554
|
-
playsInline: v.playsInline,
|
|
555
|
-
width: v.offsetWidth,
|
|
556
|
-
height: v.offsetHeight,
|
|
557
|
-
role: v.closest('section')?.id || v.closest('[class]')?.className || 'unknown',
|
|
558
|
-
}));
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
Save to `docs/research/<hostname>/videos.json`.
|
|
562
|
-
|
|
563
|
-
**Download videos in Modes A, B, C, E:**
|
|
564
|
-
- Download each video source to `public/videos/<hostname>/<role>.<ext>`
|
|
565
|
-
- Skip files > 10MB — note URL in `videos.json` as `skipped: true` with reason
|
|
566
|
-
- Prefer `video/webm` or `video/mp4` sources
|
|
567
|
-
- Always download the poster image alongside the video
|
|
568
|
-
|
|
569
|
-
**Skip download in Mode D** — record URLs only.
|
|
570
|
-
|
|
571
|
-
**Copyright notice for videos (display once after this step):**
|
|
572
|
-
> "Os vídeos foram baixados para `public/videos/<hostname>/` como referência de desenvolvimento.
|
|
573
|
-
> São assets de terceiros — substitua-os pelos seus próprios vídeos antes de publicar."
|
|
574
|
-
|
|
575
|
-
### 1.5.4 Scroll recording with DOM mutation tracking
|
|
576
|
-
|
|
577
|
-
**Goal:** Capture exactly which elements change state at which scroll positions. This is the input for implementing scroll-triggered animations with precise fidelity.
|
|
578
|
-
|
|
579
|
-
**Step A — Attach MutationObserver before scrolling:**
|
|
580
|
-
|
|
581
|
-
```javascript
|
|
582
|
-
const mutations = [];
|
|
583
|
-
const mo = new MutationObserver(entries => {
|
|
584
|
-
for (const m of entries) {
|
|
585
|
-
if (
|
|
586
|
-
m.type === 'attributes' &&
|
|
587
|
-
(m.attributeName === 'class' || m.attributeName === 'style')
|
|
588
|
-
) {
|
|
589
|
-
const el = m.target;
|
|
590
|
-
mutations.push({
|
|
591
|
-
scrollY: window.scrollY,
|
|
592
|
-
element: el.tagName +
|
|
593
|
-
(el.id ? '#' + el.id : '') +
|
|
594
|
-
(el.className && typeof el.className === 'string'
|
|
595
|
-
? '.' + el.className.trim().replace(/\s+/g, '.') : ''),
|
|
596
|
-
attribute: m.attributeName,
|
|
597
|
-
from: m.oldValue,
|
|
598
|
-
to: el.getAttribute(m.attributeName),
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
});
|
|
603
|
-
mo.observe(document.body, {
|
|
604
|
-
subtree: true,
|
|
605
|
-
attributes: true,
|
|
606
|
-
attributeFilter: ['class', 'style'],
|
|
607
|
-
attributeOldValue: true,
|
|
608
|
-
});
|
|
609
|
-
// Expose mutations for later retrieval
|
|
610
|
-
window.__sfMutations = mutations;
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
**Step B — Incremental scroll with screenshots at 8 checkpoints:**
|
|
614
|
-
|
|
615
|
-
Scroll to each of the following positions, wait 600ms for animations to settle, then capture a screenshot:
|
|
616
|
-
|
|
617
|
-
| Checkpoint | Scroll % | Purpose |
|
|
618
|
-
|---|---|---|
|
|
619
|
-
| `scroll-00pct` | 0% | Initial state |
|
|
620
|
-
| `scroll-12pct` | 12% | Nav solidifies |
|
|
621
|
-
| `scroll-25pct` | 25% | First section entry |
|
|
622
|
-
| `scroll-37pct` | 37% | Second section |
|
|
623
|
-
| `scroll-50pct` | 50% | Mid-page |
|
|
624
|
-
| `scroll-62pct` | 62% | Third section |
|
|
625
|
-
| `scroll-75pct` | 75% | Fourth section |
|
|
626
|
-
| `scroll-100pct` | 100% | Footer |
|
|
627
|
-
|
|
628
|
-
Save screenshots to `docs/research/<hostname>/scroll-recording/`.
|
|
629
|
-
|
|
630
|
-
**Step C — Collect mutations:**
|
|
631
|
-
|
|
632
|
-
```javascript
|
|
633
|
-
return window.__sfMutations;
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
Save to `docs/research/<hostname>/dom-mutations.json`.
|
|
637
|
-
|
|
638
|
-
**Step D — Analyze mutation patterns:**
|
|
639
|
-
|
|
640
|
-
Group mutations by scroll position range and element. For each group, write a human-readable entry in `docs/research/<hostname>/interaction-spec.md` (append, do not overwrite) using this format:
|
|
641
|
-
|
|
642
|
-
```markdown
|
|
643
|
-
## Scroll-triggered: <element-selector>
|
|
644
|
-
- **Trigger:** scrollY ≈ <N>px (≈ <pct>% of page height)
|
|
645
|
-
- **Change:** class `<from>` → `<to>` (or style `<property>: <from>` → `<to>`)
|
|
646
|
-
- **Effect type:** [REVEAL | HIDE | STATE-CHANGE | PARALLAX | STICKY]
|
|
647
|
-
- **Implementation note:** <inferred mechanism — e.g. "IntersectionObserver adds .is-visible", "GSAP adds .animated class">
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
### 1.5.5 Parallax detection
|
|
651
|
-
|
|
652
|
-
After scroll recording, check for elements whose `transform: translateY` changes relative to scroll progress:
|
|
653
|
-
|
|
654
|
-
```javascript
|
|
655
|
-
// Run at top, mid, and bottom of page — compare transform values
|
|
656
|
-
const targets = document.querySelectorAll('[class*="parallax"], [data-parallax], [style*="transform"]');
|
|
657
|
-
const results = [];
|
|
658
|
-
for (const el of targets) {
|
|
659
|
-
const s = window.getComputedStyle(el);
|
|
660
|
-
results.push({
|
|
661
|
-
selector: el.className,
|
|
662
|
-
transformAtCurrentScroll: s.transform,
|
|
663
|
-
backgroundAttachment: s.backgroundAttachment, // "fixed" = CSS parallax
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
return results;
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
If `backgroundAttachment: fixed` is found → document as **CSS parallax** (implement with `background-attachment: fixed`).
|
|
670
|
-
If `transform` changes between scroll positions → document as **JS parallax** (implement with scroll listener + `translate3d`).
|
|
671
|
-
|
|
672
|
-
Save to `animations-raw.json` under key `parallax`.
|
|
673
|
-
|
|
674
|
-
### 1.5.6 Output
|
|
675
|
-
|
|
676
|
-
All data from this phase is consolidated into:
|
|
677
|
-
|
|
678
|
-
```
|
|
679
|
-
docs/research/<hostname>/
|
|
680
|
-
├── animations-raw.json ← jsLibraries, keyframes, animationRules, scrollLinked,
|
|
681
|
-
│ activeAnimations, parallax
|
|
682
|
-
├── videos.json ← video elements, sources, roles
|
|
683
|
-
├── dom-mutations.json ← class/style changes keyed by scrollY
|
|
684
|
-
└── scroll-recording/
|
|
685
|
-
├── scroll-00pct.png
|
|
686
|
-
├── scroll-12pct.png
|
|
687
|
-
├── scroll-25pct.png
|
|
688
|
-
├── scroll-37pct.png
|
|
689
|
-
├── scroll-50pct.png
|
|
690
|
-
├── scroll-62pct.png
|
|
691
|
-
├── scroll-75pct.png
|
|
692
|
-
└── scroll-100pct.png
|
|
693
|
-
|
|
694
|
-
public/videos/<hostname>/
|
|
695
|
-
└── [downloaded video assets — replace before publishing]
|
|
696
|
-
```
|
|
697
|
-
|
|
698
|
-
**Exit criterion:** `animations-raw.json` populated with `jsLibraries`, `keyframes`, and `activeAnimations`. `videos.json` written (empty array is valid if no videos found). `dom-mutations.json` written. Scroll recording screenshots saved. `interaction-spec.md` updated with scroll-triggered entries from mutation analysis.
|
|
699
|
-
|
|
700
|
-
---
|
|
701
|
-
|
|
702
|
-
## Phase 2 — Selective Extraction
|
|
703
|
-
|
|
704
|
-
**Goal:** Document structure and behavior of every section.
|
|
705
|
-
|
|
706
|
-
**Mode A, C:** Discard ALL aesthetic values — skill tokens will replace them. Content slots (texts, image paths) are preserved.
|
|
707
|
-
**Mode B, D, E:** Extract structure AND aesthetic values — they become the raw material for the skill or the blend.
|
|
708
|
-
|
|
709
|
-
### 2.1 Section specs
|
|
710
|
-
|
|
711
|
-
For each section in the page topology, create `docs/research/components/<section-slug>.spec.md`:
|
|
712
|
-
|
|
713
|
-
```markdown
|
|
714
|
-
# <SectionName> — Structure Specification
|
|
715
|
-
|
|
716
|
-
## Layout pattern
|
|
717
|
-
- Container: [max-width | full-viewport | fluid]
|
|
718
|
-
- Display: [flex | grid | block]
|
|
719
|
-
- Children arrangement: [column | row | grid-cols-3 | etc.]
|
|
720
|
-
- Overflow: [visible | hidden | scroll]
|
|
721
|
-
|
|
722
|
-
## Elements
|
|
723
|
-
- [element-type]: [role — e.g. "primary headline", "CTA button", "feature image"]
|
|
724
|
-
- [element-type]: [role]
|
|
725
|
-
|
|
726
|
-
## Interaction model
|
|
727
|
-
- Type: [NONE | SCROLL-DRIVEN | CLICK-DRIVEN | HOVER | STATE-TOGGLE]
|
|
728
|
-
- Trigger: [describe the trigger precisely]
|
|
729
|
-
- Effect: [describe what changes — element names and property types]
|
|
730
|
-
- Timing: [fast | medium | slow — relative only]
|
|
731
|
-
|
|
732
|
-
## Responsive changes
|
|
733
|
-
- At 768px: [what changes]
|
|
734
|
-
- At 390px: [what changes]
|
|
735
|
-
|
|
736
|
-
## Content slots
|
|
737
|
-
- Headline: "[actual text]"
|
|
738
|
-
- Subtext: "[actual text]"
|
|
739
|
-
- CTA label: "[actual text]"
|
|
740
|
-
- Image: [what it depicts, path to downloaded file]
|
|
741
|
-
|
|
742
|
-
## Aesthetic values (Modes B, D, E only — omit in Modes A, C)
|
|
743
|
-
- Background color: [hex or rgba]
|
|
744
|
-
- Text colors: [hex values per role: heading, body, muted, accent]
|
|
745
|
-
- Border radius: [observed px values]
|
|
746
|
-
- Shadow: [observed box-shadow values]
|
|
747
|
-
- Padding/gap pattern: [observed px values]
|
|
748
|
-
```
|
|
164
|
+
## Phase execution
|
|
749
165
|
|
|
750
|
-
|
|
166
|
+
Load each phase doc at phase entry — not all at once.
|
|
751
167
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
Accordion
|
|
762
|
-
Toast
|
|
763
|
-
Badge
|
|
764
|
-
Avatar
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
For each component, create `docs/research/components/<component-slug>.spec.md`:
|
|
768
|
-
|
|
769
|
-
```markdown
|
|
770
|
-
# <ComponentName> — Component Specification
|
|
771
|
-
|
|
772
|
-
## DOM structure
|
|
773
|
-
- <outer-element> (semantic role)
|
|
774
|
-
- <child>: [role]
|
|
775
|
-
- <child>: [role]
|
|
776
|
-
|
|
777
|
-
## Variants
|
|
778
|
-
- [variant-name]: [how it differs structurally]
|
|
779
|
-
|
|
780
|
-
## States
|
|
781
|
-
- default: [what is shown]
|
|
782
|
-
- hover: [what changes — type only for Mode A/C | type + value for Mode B/D/E]
|
|
783
|
-
- active: [what changes]
|
|
784
|
-
- disabled: [what changes]
|
|
785
|
-
- loading: [what appears]
|
|
786
|
-
|
|
787
|
-
## Behavior
|
|
788
|
-
- [action]: [effect — describe mechanism, not values]
|
|
789
|
-
```
|
|
790
|
-
|
|
791
|
-
### 2.3 Interaction specifications
|
|
792
|
-
|
|
793
|
-
For every non-static section, create `docs/research/<hostname>/interaction-spec.md`:
|
|
794
|
-
|
|
795
|
-
```markdown
|
|
796
|
-
# <Name> — Interaction Specification
|
|
797
|
-
|
|
798
|
-
## Model: [SCROLL-DRIVEN | CLICK-DRIVEN | HOVER | STATE-TOGGLE]
|
|
799
|
-
|
|
800
|
-
## Trigger
|
|
801
|
-
[Precise trigger condition]
|
|
802
|
-
|
|
803
|
-
## Effect
|
|
804
|
-
[What changes: which elements, which CSS property types]
|
|
805
|
-
|
|
806
|
-
## Timing
|
|
807
|
-
[fast / medium / slow — relative only]
|
|
808
|
-
|
|
809
|
-
## Implementation direction
|
|
810
|
-
[e.g. "scroll listener on window", "CSS :hover + transition", "React state toggle + className"]
|
|
811
|
-
```
|
|
812
|
-
|
|
813
|
-
### 2.4 Aesthetic capture (Modes B, D, E only)
|
|
814
|
-
|
|
815
|
-
Run this extraction via `window.getComputedStyle()` on representative elements:
|
|
816
|
-
|
|
817
|
-
```javascript
|
|
818
|
-
// Run via browser MCP evaluate()
|
|
819
|
-
const elements = {
|
|
820
|
-
body: document.body,
|
|
821
|
-
h1: document.querySelector('h1'),
|
|
822
|
-
h2: document.querySelector('h2'),
|
|
823
|
-
p: document.querySelector('p'),
|
|
824
|
-
primaryBtn: document.querySelector('button, [class*="btn-primary"], [class*="cta"]'),
|
|
825
|
-
card: document.querySelector('[class*="card"], article'),
|
|
826
|
-
nav: document.querySelector('nav, header')
|
|
827
|
-
};
|
|
828
|
-
|
|
829
|
-
const extracted = {};
|
|
830
|
-
for (const [name, el] of Object.entries(elements)) {
|
|
831
|
-
if (!el) continue;
|
|
832
|
-
const s = window.getComputedStyle(el);
|
|
833
|
-
extracted[name] = {
|
|
834
|
-
backgroundColor: s.backgroundColor,
|
|
835
|
-
color: s.color,
|
|
836
|
-
fontFamily: s.fontFamily,
|
|
837
|
-
fontSize: s.fontSize,
|
|
838
|
-
fontWeight: s.fontWeight,
|
|
839
|
-
lineHeight: s.lineHeight,
|
|
840
|
-
borderRadius: s.borderRadius,
|
|
841
|
-
boxShadow: s.boxShadow,
|
|
842
|
-
padding: s.padding,
|
|
843
|
-
gap: s.gap,
|
|
844
|
-
transition: s.transition
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
return extracted;
|
|
848
|
-
```
|
|
849
|
-
|
|
850
|
-
Save raw output to `docs/research/<hostname>/aesthetics-raw.json`.
|
|
851
|
-
|
|
852
|
-
**Output files:**
|
|
853
|
-
- `docs/research/<hostname>/structure-spec.md` (overview of all sections)
|
|
854
|
-
- `docs/research/<hostname>/interaction-spec.md` (all interactions)
|
|
855
|
-
- `docs/research/<hostname>/aesthetics-raw.json` (Modes B, D, E only)
|
|
856
|
-
- `docs/research/components/*.spec.md` (one file per section + one per component type)
|
|
857
|
-
|
|
858
|
-
**Exit criterion (Modes A, C):** Every section has a spec. No color, size, or spacing values in any spec file.
|
|
859
|
-
**Exit criterion (Modes B, D, E):** Every section has a spec WITH aesthetic values. `aesthetics-raw.json` populated.
|
|
860
|
-
|
|
861
|
-
---
|
|
862
|
-
|
|
863
|
-
## Phase 3A — Transform Layer (Modes A, C only)
|
|
864
|
-
|
|
865
|
-
**Goal:** Map extracted structure to the existing skill's components and tokens.
|
|
866
|
-
|
|
867
|
-
### 3A.1 Load the skill in full
|
|
868
|
-
|
|
869
|
-
Read these files from the skill directory (`.aioson/installed-skills/<skill>/` or `.aioson/skills/design/<skill>/`):
|
|
870
|
-
|
|
871
|
-
1. `SKILL.md` — identity, pillars, activation rules
|
|
872
|
-
2. `references/design-tokens.md` — all CSS variables (colors, type scale, spacing, radius, shadow, motion)
|
|
873
|
-
3. `references/components.md` — available components and their props/variants
|
|
874
|
-
4. `references/patterns.md` — page layout patterns
|
|
875
|
-
5. `references/motion.md` — animation tokens and conventions
|
|
876
|
-
6. `references/websites.md` — if present, landing page patterns
|
|
877
|
-
|
|
878
|
-
### 3A.2 Build the component map
|
|
879
|
-
|
|
880
|
-
For every extracted element, find the closest skill equivalent. Create `docs/research/<hostname>/component-map.md`:
|
|
881
|
-
|
|
882
|
-
```markdown
|
|
883
|
-
# Component Map — <hostname> → <skill-name>
|
|
884
|
-
|
|
885
|
-
## Mappings
|
|
886
|
-
|
|
887
|
-
| Extracted element | Skill component | Key tokens to apply |
|
|
888
|
-
|---|---|---|
|
|
889
|
-
| Hero container | Hero pattern (from patterns.md) | --max-width, --space-XX |
|
|
890
|
-
| Feature card grid | Card grid pattern | gap: --space-XX |
|
|
891
|
-
| Primary CTA button | Button primary | bg: --accent, radius: --radius-md |
|
|
892
|
-
| Ghost/outline button | Button ghost | border: 1px solid --border |
|
|
893
|
-
| H1 display heading | Display heading | font: --font-display, size: --text-5xl |
|
|
894
|
-
| Body paragraph | Body text | font: --font-body, size: --text-base |
|
|
895
|
-
| Muted caption | Muted text | color: --text-muted |
|
|
896
|
-
| Sticky nav | Header pattern | bg: --bg-surface, shadow: --shadow-sm on scroll |
|
|
897
|
-
| Card hover | Card component | transform: translateY(var(--hover-lift)) |
|
|
898
|
-
| Scroll interaction timing | — | var(--transition-base) |
|
|
899
|
-
|
|
900
|
-
## Deviations (skill component not available)
|
|
901
|
-
|
|
902
|
-
| Extracted element | Fallback approach | Reason |
|
|
903
|
-
|---|---|---|
|
|
904
|
-
| [element not in skill] | [closest skill primitive + manual CSS vars] | [why no direct match] |
|
|
905
|
-
|
|
906
|
-
## Assets preserved
|
|
907
|
-
|
|
908
|
-
| Original source | Local path | Action required before publishing |
|
|
909
|
-
|---|---|---|
|
|
910
|
-
| hero image | public/images/<hostname>/hero.webp | Replace with project asset |
|
|
911
|
-
| logo | public/images/<hostname>/logo.svg | Replace with project logo |
|
|
912
|
-
```
|
|
913
|
-
|
|
914
|
-
**Mode C (content-first):** In the component map, add a "Content slot" column that maps each skill component to the specific extracted text and image asset. This ensures the harvested content lands in the right place during Phase 4.
|
|
915
|
-
|
|
916
|
-
### 3A.3 Universal token substitution rules
|
|
917
|
-
|
|
918
|
-
Apply these mappings everywhere during Phase 4:
|
|
919
|
-
|
|
920
|
-
```
|
|
921
|
-
background-color: <hex> → var(--bg-surface) | var(--bg-elevated) | var(--accent)
|
|
922
|
-
color: <hex> → var(--text-primary) | var(--text-muted) | var(--accent)
|
|
923
|
-
padding: <px> → var(--space-XX) — pick nearest from spacing scale
|
|
924
|
-
margin: <px> → var(--space-XX)
|
|
925
|
-
animation-duration: <ms> → var(--transition-fast) | var(--transition-base) | var(--transition-medium) | var(--transition-slow)
|
|
926
|
-
font-size: <px> → var(--text-XX) — pick nearest from type scale
|
|
927
|
-
font-family: <name> → var(--font-display) | var(--font-body) | var(--font-mono)
|
|
928
|
-
border-radius: <px> → var(--radius-sm) | var(--radius-md) | var(--radius-lg)
|
|
929
|
-
box-shadow: <value> → var(--shadow-sm) | var(--shadow-md) | var(--shadow-lg)
|
|
930
|
-
transition: <value> → var(--transition-fast) | var(--transition-base) | var(--transition-slow)
|
|
931
|
-
```
|
|
932
|
-
|
|
933
|
-
If a token name from the above doesn't exist in the skill, use the closest equivalent from `design-tokens.md`. Never hardcode values.
|
|
934
|
-
|
|
935
|
-
### 3A.4 Interaction preservation rule
|
|
936
|
-
|
|
937
|
-
Keep the trigger mechanism. Keep the effect type. Replace only easing/duration with skill motion tokens.
|
|
938
|
-
|
|
939
|
-
**Exit criterion (Modes A, C):** Every extracted component has a mapping row. Every interaction has a motion token assigned. Proceed to Phase 4.
|
|
168
|
+
| Phase | What | Doc to load |
|
|
169
|
+
|-------|------|-------------|
|
|
170
|
+
| 1 + 1.5 | Reconnaissance + Deep Animation Extraction | `.aioson/docs/site-forge-recon.md` |
|
|
171
|
+
| 2 | Selective Extraction | `.aioson/docs/site-forge-extraction.md` |
|
|
172
|
+
| 3A | Transform Layer (Modes A, C) | `.aioson/docs/site-forge-transform.md` |
|
|
173
|
+
| 3B | Skill Forge (Modes B, D, E) | `.aioson/docs/site-forge-transform.md` |
|
|
174
|
+
| 3E | Blend Layer (Mode E) | `.aioson/docs/site-forge-transform.md` |
|
|
175
|
+
| 4 | Build Layer | `.aioson/docs/site-forge-build.md` |
|
|
176
|
+
| 5 + Output contract | Visual QA | `.aioson/docs/site-forge-qa.md` |
|
|
940
177
|
|
|
941
178
|
---
|
|
942
179
|
|
|
943
|
-
##
|
|
944
|
-
|
|
945
|
-
**Goal:** Extract the site's design system from raw aesthetics and forge a new AIOSON skill.
|
|
946
|
-
|
|
947
|
-
### 3B.1 Color system extraction
|
|
948
|
-
|
|
949
|
-
From `aesthetics-raw.json`, organize colors into semantic groups:
|
|
950
|
-
|
|
951
|
-
```
|
|
952
|
-
Background hierarchy:
|
|
953
|
-
--bg-base → page background (body.backgroundColor)
|
|
954
|
-
--bg-surface → card/panel backgrounds (card.backgroundColor)
|
|
955
|
-
--bg-elevated → modal/dropdown backgrounds
|
|
956
|
-
--bg-inverse → inverted section backgrounds
|
|
957
|
-
|
|
958
|
-
Text hierarchy:
|
|
959
|
-
--text-primary → primary text (p.color or h1.color)
|
|
960
|
-
--text-muted → secondary/muted text
|
|
961
|
-
--text-inverse → text on dark backgrounds
|
|
962
|
-
|
|
963
|
-
Brand colors:
|
|
964
|
-
--accent → primary CTA color (primaryBtn.backgroundColor)
|
|
965
|
-
--accent-hover → hover state of CTA
|
|
966
|
-
--border → default border color
|
|
967
|
-
|
|
968
|
-
Semantic (infer from context if present):
|
|
969
|
-
--success, --warning, --error, --info
|
|
970
|
-
```
|
|
971
|
-
|
|
972
|
-
Consolidate duplicate/near-duplicate colors (within 10% perceptual distance) into a single token.
|
|
973
|
-
|
|
974
|
-
### 3B.2 Typography system extraction
|
|
975
|
-
|
|
976
|
-
```
|
|
977
|
-
Font families:
|
|
978
|
-
--font-display → h1/h2 fontFamily
|
|
979
|
-
--font-body → p fontFamily
|
|
980
|
-
--font-mono → code/pre fontFamily (if detected)
|
|
981
|
-
|
|
982
|
-
Type scale (map observed px values to a named scale):
|
|
983
|
-
--text-xs → smallest observed size
|
|
984
|
-
--text-sm → ...
|
|
985
|
-
--text-base → body text size (p.fontSize)
|
|
986
|
-
--text-lg → ...
|
|
987
|
-
--text-xl → ...
|
|
988
|
-
--text-2xl → ...
|
|
989
|
-
--text-3xl → ...
|
|
990
|
-
--text-4xl → ...
|
|
991
|
-
--text-5xl → largest heading (h1.fontSize)
|
|
992
|
-
|
|
993
|
-
Weight scale:
|
|
994
|
-
--font-normal → 400
|
|
995
|
-
--font-medium → 500
|
|
996
|
-
--font-semibold → 600
|
|
997
|
-
--font-bold → 700
|
|
998
|
-
(include only weights actually in use)
|
|
999
|
-
|
|
1000
|
-
Line heights:
|
|
1001
|
-
--leading-tight → heading line-height
|
|
1002
|
-
--leading-normal → body line-height
|
|
1003
|
-
--leading-relaxed → long-form text line-height (if detected)
|
|
1004
|
-
```
|
|
1005
|
-
|
|
1006
|
-
### 3B.3 Spacing system extraction
|
|
1007
|
-
|
|
1008
|
-
Identify the base spacing unit from observed padding/gap patterns:
|
|
1009
|
-
- Collect all observed padding and gap values
|
|
1010
|
-
- Find the GCD or most common divisor → this is the base unit (typically 4px or 8px)
|
|
1011
|
-
- Build a scale:
|
|
1012
|
-
|
|
1013
|
-
```
|
|
1014
|
-
--space-1 → 1× base
|
|
1015
|
-
--space-2 → 2× base
|
|
1016
|
-
--space-3 → 3× base
|
|
1017
|
-
--space-4 → 4× base
|
|
1018
|
-
--space-6 → 6× base
|
|
1019
|
-
--space-8 → 8× base
|
|
1020
|
-
--space-12 → 12× base
|
|
1021
|
-
--space-16 → 16× base
|
|
1022
|
-
--space-20 → 20× base
|
|
1023
|
-
--space-24 → 24× base
|
|
1024
|
-
```
|
|
1025
|
-
|
|
1026
|
-
### 3B.4 Visual primitives extraction
|
|
1027
|
-
|
|
1028
|
-
```
|
|
1029
|
-
Border radius:
|
|
1030
|
-
--radius-none → 0
|
|
1031
|
-
--radius-sm → smallest observed radius
|
|
1032
|
-
--radius-md → medium (cards)
|
|
1033
|
-
--radius-lg → large (modals, hero blocks)
|
|
1034
|
-
--radius-full → 9999px (pills/avatars, if used)
|
|
1035
|
-
|
|
1036
|
-
Shadows (from observed box-shadow values):
|
|
1037
|
-
--shadow-sm → subtle (e.g. cards at rest)
|
|
1038
|
-
--shadow-md → medium (e.g. dropdowns)
|
|
1039
|
-
--shadow-lg → strong (e.g. modals)
|
|
1040
|
-
--shadow-xl → extra strong (if present)
|
|
1041
|
-
|
|
1042
|
-
Motion:
|
|
1043
|
-
--transition-fast → fastest observed transition duration (e.g. 100ms)
|
|
1044
|
-
--transition-base → most common duration (e.g. 200ms)
|
|
1045
|
-
--transition-slow → slowest (e.g. 400ms+)
|
|
1046
|
-
--ease-default → most common easing (e.g. ease-out)
|
|
1047
|
-
--ease-spring → spring/bounce easing (if detected)
|
|
1048
|
-
```
|
|
1049
|
-
|
|
1050
|
-
### 3B.5 Visual identity synthesis
|
|
1051
|
-
|
|
1052
|
-
Based on the extracted values, define 3 design pillars that describe this site's aesthetic.
|
|
1053
|
-
|
|
1054
|
-
Examples:
|
|
1055
|
-
- "Minimal contrast" + "Typographic hierarchy" + "Generous whitespace"
|
|
1056
|
-
- "Deep darkness" + "Glowing accents" + "Crisp borders"
|
|
1057
|
-
- "Warm organics" + "Rounded surfaces" + "Soft motion"
|
|
1058
|
-
|
|
1059
|
-
Also determine:
|
|
1060
|
-
- Theme: `light` | `dark` | `system`
|
|
1061
|
-
- Personality: 1-sentence description (e.g. "Bold editorial with a monochromatic palette and strong typographic rhythm")
|
|
1062
|
-
|
|
1063
|
-
### 3B.6 Pick reference skill structure
|
|
1064
|
-
|
|
1065
|
-
List all skills in `.aioson/skills/design/`. Choose the one whose visual personality most closely matches the extracted site (dark → aurora-command-ui or premium-command-center-ui; minimal light → clean-saas-ui; data-dense → cognitive-core-ui; etc.).
|
|
1066
|
-
|
|
1067
|
-
Read the chosen skill's directory listing to understand its file structure.
|
|
1068
|
-
**Use only the FILE STRUCTURE as a template — do not copy any tokens or design values.**
|
|
1069
|
-
|
|
1070
|
-
### 3B.7 Forge the new skill
|
|
1071
|
-
|
|
1072
|
-
Create `.aioson/installed-skills/<hostname>/` with this structure:
|
|
1073
|
-
|
|
1074
|
-
**`SKILL.md`:**
|
|
1075
|
-
```markdown
|
|
1076
|
-
# <hostname> Design System
|
|
1077
|
-
|
|
1078
|
-
> Extracted from <url> on <date>. Visual clone skill — do not use in unrelated projects without adapting the tokens.
|
|
1079
|
-
|
|
1080
|
-
## Identity
|
|
1081
|
-
|
|
1082
|
-
**Theme:** <light|dark|system>
|
|
1083
|
-
**Personality:** <1-sentence description>
|
|
1084
|
-
|
|
1085
|
-
## Design pillars
|
|
1086
|
-
|
|
1087
|
-
1. <pillar 1>
|
|
1088
|
-
2. <pillar 2>
|
|
1089
|
-
3. <pillar 3>
|
|
1090
|
-
|
|
1091
|
-
## When to use
|
|
1092
|
-
|
|
1093
|
-
Activate when building projects that need to visually match or be inspired by <hostname>'s aesthetic.
|
|
1094
|
-
|
|
1095
|
-
## Activation
|
|
1096
|
-
|
|
1097
|
-
Load `references/design-tokens.md` before writing any component.
|
|
1098
|
-
```
|
|
1099
|
-
|
|
1100
|
-
**`references/design-tokens.md`:**
|
|
1101
|
-
Full CSS custom properties using all tokens extracted in 3B.1–3B.4:
|
|
1102
|
-
```css
|
|
1103
|
-
:root {
|
|
1104
|
-
/* Colors */
|
|
1105
|
-
--bg-base: <extracted hex>;
|
|
1106
|
-
--bg-surface: <extracted hex>;
|
|
1107
|
-
/* ... all color tokens ... */
|
|
1108
|
-
|
|
1109
|
-
/* Typography */
|
|
1110
|
-
--font-display: '<family>', sans-serif;
|
|
1111
|
-
--font-body: '<family>', sans-serif;
|
|
1112
|
-
/* ... all type tokens ... */
|
|
1113
|
-
|
|
1114
|
-
/* Spacing */
|
|
1115
|
-
--space-1: <Npx>;
|
|
1116
|
-
/* ... full scale ... */
|
|
1117
|
-
|
|
1118
|
-
/* Radius */
|
|
1119
|
-
--radius-sm: <px>;
|
|
1120
|
-
/* ... */
|
|
1121
|
-
|
|
1122
|
-
/* Shadow */
|
|
1123
|
-
--shadow-sm: <value>;
|
|
1124
|
-
/* ... */
|
|
1125
|
-
|
|
1126
|
-
/* Motion */
|
|
1127
|
-
--transition-fast: <ms> <easing>;
|
|
1128
|
-
--transition-base: <ms> <easing>;
|
|
1129
|
-
--transition-slow: <ms> <easing>;
|
|
1130
|
-
}
|
|
1131
|
-
```
|
|
1132
|
-
|
|
1133
|
-
**`references/components.md`:**
|
|
1134
|
-
Document component variants derived from the site's component inventory (from Phase 2.2). For each component: DOM structure, props, variants, token usage.
|
|
1135
|
-
|
|
1136
|
-
**`references/patterns.md`:**
|
|
1137
|
-
Document page layout patterns derived from the site's section specs (from Phase 2.1). Include: Hero, Feature grid, Card layout, Nav, Footer.
|
|
1138
|
-
|
|
1139
|
-
**`references/motion.md`:**
|
|
1140
|
-
Document animation tokens and the interaction patterns extracted from Phase 2.3 and 2.4.
|
|
1141
|
-
|
|
1142
|
-
Also include all data from Phase 1.5:
|
|
1143
|
-
- `jsLibraries` detected — list which animation libraries the original site used
|
|
1144
|
-
- All `@keyframes` from `animations-raw.json.keyframes` — copy verbatim as a "Extracted Keyframes" section
|
|
1145
|
-
- `parallax` entries — document technique (CSS fixed vs JS transform)
|
|
1146
|
-
- `scrollLinked` CSS rules — document `animation-timeline` and `scroll-timeline` usage
|
|
1147
|
-
- Scroll-trigger thresholds from `dom-mutations.json` — document as a table: element → scrollY trigger → effect
|
|
1148
|
-
|
|
1149
|
-
This makes `motion.md` a complete behavioral reference for recreating the site's animation character, not just its timing tokens.
|
|
1150
|
-
|
|
1151
|
-
**`references/websites.md`:**
|
|
1152
|
-
Document this specific site's landing page structure as a reusable pattern. Include the full page topology and how sections connect.
|
|
1153
|
-
|
|
1154
|
-
**`.skill-meta.json`:**
|
|
1155
|
-
```json
|
|
1156
|
-
{
|
|
1157
|
-
"id": "<hostname>",
|
|
1158
|
-
"name": "<hostname> Design System",
|
|
1159
|
-
"source": "<url>",
|
|
1160
|
-
"extractedAt": "<ISO date>",
|
|
1161
|
-
"theme": "<light|dark|system>",
|
|
1162
|
-
"baseUnit": "<Npx>",
|
|
1163
|
-
"referenceSkill": "<chosen template skill id>",
|
|
1164
|
-
"type": "extracted"
|
|
1165
|
-
}
|
|
1166
|
-
```
|
|
1167
|
-
|
|
1168
|
-
**Exit criterion (Modes B, D):** All skill files written. `design-tokens.md` contains the full `:root {}` block. Component and pattern references derived from the site's own inventory.
|
|
1169
|
-
|
|
1170
|
-
**Mode D exits here.** Output the path to the forged skill and run observability. Do NOT proceed to Phase 4.
|
|
1171
|
-
|
|
1172
|
-
**Mode B and E:** Proceed to Phase 4 using the newly forged skill (Mode B) or the blend layer (Mode E).
|
|
1173
|
-
|
|
1174
|
-
---
|
|
1175
|
-
|
|
1176
|
-
## Phase 3E — Blend Layer (Mode E only)
|
|
1177
|
-
|
|
1178
|
-
**Goal:** Merge the extracted site tokens with the existing skill's tokens at the configured ratio.
|
|
1179
|
-
|
|
1180
|
-
### 3E.1 Define the blend map
|
|
1181
|
-
|
|
1182
|
-
Default blend: 50% site / 50% skill. If the user specified a different ratio, use that.
|
|
1183
|
-
|
|
1184
|
-
Load both token sets:
|
|
1185
|
-
- Site tokens: from `docs/research/<hostname>/aesthetics-raw.json` + Phase 3B extraction
|
|
1186
|
-
- Skill tokens: from the named skill's `references/design-tokens.md`
|
|
1187
|
-
|
|
1188
|
-
### 3E.2 Apply blend rules per token category
|
|
1189
|
-
|
|
1190
|
-
Create `docs/research/<hostname>/blend-map.md`:
|
|
1191
|
-
|
|
1192
|
-
```markdown
|
|
1193
|
-
# Blend Map — <hostname> (site) × <skill-name> (skill) — <ratio>% site / <100-ratio>% skill
|
|
1194
|
-
|
|
1195
|
-
## Color tokens
|
|
1196
|
-
| Token | Site value | Skill value | Blended result | Source |
|
|
1197
|
-
|---|---|---|---|---|
|
|
1198
|
-
| --bg-base | #1a1a1a | #0f0f0f | #141414 | averaged |
|
|
1199
|
-
| --accent | #e63946 | #7c3aed | #e63946 | site (brand identity) |
|
|
1200
|
-
|
|
1201
|
-
## Typography tokens
|
|
1202
|
-
| Token | Site value | Skill value | Blended result | Source |
|
|
1203
|
-
|---|---|---|---|---|
|
|
1204
|
-
| --font-display | 'Playfair Display' | 'Inter' | 'Playfair Display' | site |
|
|
1205
|
-
| --font-body | 'Lato' | 'Inter' | 'Inter' | skill |
|
|
1206
|
-
|
|
1207
|
-
## Spacing tokens
|
|
1208
|
-
→ Use site spacing scale when ratio ≥ 50% site; use skill scale otherwise.
|
|
1209
|
-
|
|
1210
|
-
## Motion tokens
|
|
1211
|
-
→ Use site motion when ratio ≥ 50% site; use skill motion otherwise.
|
|
1212
|
-
|
|
1213
|
-
## Blend decisions
|
|
1214
|
-
- Primary font family: [site | skill | averaged] — reason
|
|
1215
|
-
- Accent color: [site | skill | averaged] — reason
|
|
1216
|
-
- Border radius style: [site | skill | averaged] — reason
|
|
1217
|
-
```
|
|
1218
|
-
|
|
1219
|
-
**Blend rules:**
|
|
1220
|
-
- **Colors:** Average HSL values for neutral tokens (backgrounds, text). For accent/brand colors, prefer the site source (brand identity should be preserved from the site).
|
|
1221
|
-
- **Typography:** If ratio ≥ 50% site → use site display font; always blend body font toward the skill's body font for readability.
|
|
1222
|
-
- **Spacing:** Use the scale from whichever source matches the ratio.
|
|
1223
|
-
- **Motion:** Use the easing/duration from whichever source matches the ratio.
|
|
1224
|
-
|
|
1225
|
-
### 3E.3 Write blended token file
|
|
1226
|
-
|
|
1227
|
-
Write `docs/research/<hostname>/blended-tokens.css` with all resolved `:root` values.
|
|
1228
|
-
|
|
1229
|
-
**Exit criterion (Mode E):** `blend-map.md` complete with all token decisions documented. `blended-tokens.css` ready. Proceed to Phase 4.
|
|
1230
|
-
|
|
1231
|
-
---
|
|
1232
|
-
|
|
1233
|
-
## Phase 4 — Build Layer
|
|
1234
|
-
|
|
1235
|
-
**Goal:** Implement all sections and components.
|
|
1236
|
-
|
|
1237
|
-
In **Mode A:** use the existing skill tokens from `references/design-tokens.md`.
|
|
1238
|
-
In **Mode B:** use the newly forged skill from Phase 3B.
|
|
1239
|
-
In **Mode C:** use the existing skill tokens; slot extracted content/images from the component map.
|
|
1240
|
-
In **Mode E:** use `blended-tokens.css` from Phase 3E as the `:root` definition.
|
|
1241
|
-
|
|
1242
|
-
### 4.1 Complexity budget
|
|
1243
|
-
|
|
1244
|
-
Assess each section:
|
|
1245
|
-
- **Simple** (< 3 sub-components): implement directly
|
|
1246
|
-
- **Moderate** (3–5 sub-components): one worktree builder
|
|
1247
|
-
- **Complex** (> 5 sub-components): split across multiple builders
|
|
1248
|
-
|
|
1249
|
-
### 4.2 Direct implementation (simple sections)
|
|
1250
|
-
|
|
1251
|
-
Build the component inline. Use skill tokens. Reference the section spec and component map. Verify `npx tsc --noEmit` after each file.
|
|
1252
|
-
|
|
1253
|
-
### 4.3 Worktree builders (moderate/complex sections)
|
|
1254
|
-
|
|
1255
|
-
Create one worktree per section batch:
|
|
1256
|
-
|
|
1257
|
-
```
|
|
1258
|
-
git worktree add ../worktree-<section> -b builder/<section>
|
|
1259
|
-
```
|
|
1260
|
-
|
|
1261
|
-
Each builder receives:
|
|
1262
|
-
1. The section spec file (inline in the builder prompt)
|
|
1263
|
-
2. Component map rows relevant to this section (inline)
|
|
1264
|
-
3. Key tokens from the active token file (inline — include only what is needed)
|
|
1265
|
-
4. Path to screenshots for visual reference
|
|
1266
|
-
5. Target file: `src/components/<SectionName>.tsx`
|
|
1267
|
-
6. Requirement: `npx tsc --noEmit` must pass before committing
|
|
1268
|
-
|
|
1269
|
-
After builder completes:
|
|
1270
|
-
```bash
|
|
1271
|
-
npx tsc --noEmit # must pass
|
|
1272
|
-
git add -A && git commit -m "build(<section>): implement with <skill-name> tokens"
|
|
1273
|
-
```
|
|
1274
|
-
|
|
1275
|
-
Then merge back:
|
|
1276
|
-
```bash
|
|
1277
|
-
git worktree remove ../worktree-<section>
|
|
1278
|
-
git merge builder/<section> --no-ff -m "merge: <section> builder"
|
|
1279
|
-
```
|
|
1280
|
-
|
|
1281
|
-
Conflict resolution rule: structure wins — preserve DOM hierarchy from the spec; replace any style value with the skill token.
|
|
1282
|
-
|
|
1283
|
-
### 4.4 Interaction implementation (MANDATORY — do not skip)
|
|
1284
|
-
|
|
1285
|
-
Before assembly, read `docs/research/<hostname>/animations-raw.json` → `jsLibraries` and `dom-mutations.json`. These determine both the implementation strategy and the precise trigger conditions.
|
|
1286
|
-
|
|
1287
|
-
#### 4.4.A Implementation strategy routing
|
|
1288
|
-
|
|
1289
|
-
**Step 1 — Choose the animation layer based on detected libraries:**
|
|
1290
|
-
|
|
1291
|
-
| Detected | Install | Implementation strategy |
|
|
1292
|
-
|---|---|---|
|
|
1293
|
-
| `gsap: true` | `npm install gsap` | Use GSAP + ScrollTrigger for all scroll-driven animations |
|
|
1294
|
-
| `framerMotion: true` | `npm install framer-motion` | Use `<motion.div>` with `whileInView` / `useScroll` |
|
|
1295
|
-
| `swiper: true` | `npm install swiper` | Use Swiper React for carousels/sliders |
|
|
1296
|
-
| `lottie: true` | `npm install lottie-react` | Use `<Lottie>` for SVG animations |
|
|
1297
|
-
| `aos: true` | *(no install — implement natively)* | Use `IntersectionObserver` + CSS classes |
|
|
1298
|
-
| none detected | *(no install)* | Use `IntersectionObserver` + CSS `@keyframes` |
|
|
1299
|
-
|
|
1300
|
-
Multiple libraries may be active simultaneously — install all that are detected.
|
|
1301
|
-
|
|
1302
|
-
**Step 2 — Implement scroll-driven animations using `dom-mutations.json`:**
|
|
1303
|
-
|
|
1304
|
-
For each entry in `dom-mutations.json`:
|
|
1305
|
-
|
|
1306
|
-
```typescript
|
|
1307
|
-
// Example: element adds class "is-animated" at scrollY ≈ 1200px
|
|
1308
|
-
// → implement as GSAP ScrollTrigger:
|
|
1309
|
-
gsap.from('.hero__headline', {
|
|
1310
|
-
opacity: 0,
|
|
1311
|
-
y: 20,
|
|
1312
|
-
duration: 0.4,
|
|
1313
|
-
ease: 'power2.out',
|
|
1314
|
-
scrollTrigger: {
|
|
1315
|
-
trigger: '.hero__headline',
|
|
1316
|
-
start: 'top 80%', // derived from mutation scrollY / pageHeight
|
|
1317
|
-
once: true,
|
|
1318
|
-
},
|
|
1319
|
-
});
|
|
1320
|
-
|
|
1321
|
-
// → OR as IntersectionObserver (when no GSAP):
|
|
1322
|
-
const observer = new IntersectionObserver(entries => {
|
|
1323
|
-
entries.forEach(e => {
|
|
1324
|
-
if (e.isIntersecting) e.target.classList.add('is-animated');
|
|
1325
|
-
});
|
|
1326
|
-
}, { threshold: 0.15 });
|
|
1327
|
-
document.querySelectorAll('.animate-on-scroll').forEach(el => observer.observe(el));
|
|
1328
|
-
```
|
|
1329
|
-
|
|
1330
|
-
Use the `scrollY` values from `dom-mutations.json` to calibrate `start` offsets in ScrollTrigger, or `threshold` values in IntersectionObserver.
|
|
1331
|
-
|
|
1332
|
-
**Step 3 — Recreate CSS `@keyframes` from `animations-raw.json`:**
|
|
1333
|
-
|
|
1334
|
-
For each entry in `animations-raw.json.keyframes`:
|
|
1335
|
-
- Copy the `cssText` verbatim into `src/app/globals.css`
|
|
1336
|
-
- Update any hardcoded `ms` or `s` values to reference the closest skill motion token:
|
|
1337
|
-
```css
|
|
1338
|
-
/* Original extracted */
|
|
1339
|
-
@keyframes fadeSlideUp {
|
|
1340
|
-
from { opacity: 0; transform: translateY(20px); }
|
|
1341
|
-
to { opacity: 1; transform: translateY(0); }
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
/* In globals.css — duration applied via class, not in keyframe */
|
|
1345
|
-
@keyframes fadeSlideUp {
|
|
1346
|
-
from { opacity: 0; transform: translateY(20px); }
|
|
1347
|
-
to { opacity: 1; transform: translateY(0); }
|
|
1348
|
-
}
|
|
1349
|
-
.animate-fade-slide-up {
|
|
1350
|
-
animation: fadeSlideUp var(--transition-slow) var(--ease-out) forwards;
|
|
1351
|
-
}
|
|
1352
|
-
```
|
|
1353
|
-
|
|
1354
|
-
**Step 4 — Implement parallax from `animations-raw.json.parallax`:**
|
|
1355
|
-
|
|
1356
|
-
- **CSS parallax** (`backgroundAttachment: fixed`): Apply `background-attachment: fixed` directly — no JS needed.
|
|
1357
|
-
- **JS parallax** (transform changes between scroll positions):
|
|
1358
|
-
```typescript
|
|
1359
|
-
// useParallax hook
|
|
1360
|
-
useEffect(() => {
|
|
1361
|
-
const el = ref.current;
|
|
1362
|
-
const handleScroll = () => {
|
|
1363
|
-
const scrolled = window.scrollY;
|
|
1364
|
-
const rate = 0.4; // adjust to match observed translation ratio
|
|
1365
|
-
el.style.transform = `translate3d(0, ${scrolled * rate}px, 0)`;
|
|
1366
|
-
};
|
|
1367
|
-
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
1368
|
-
return () => window.removeEventListener('scroll', handleScroll);
|
|
1369
|
-
}, []);
|
|
1370
|
-
```
|
|
1371
|
-
|
|
1372
|
-
**Step 5 — Implement remaining interactions from `interaction-spec.md`:**
|
|
1373
|
-
|
|
1374
|
-
For entries NOT covered by scroll-recording mutations (hover, click, state-toggle):
|
|
1375
|
-
|
|
1376
|
-
- **SCROLL-DRIVEN without mutation data:** use `IntersectionObserver` with `threshold: 0.1`.
|
|
1377
|
-
- **CLICK-DRIVEN:** use React `useState` toggle + conditional className.
|
|
1378
|
-
- **HOVER:** use Tailwind hover variants or CSS `:hover` + `transition: var(--transition-all)`.
|
|
1379
|
-
- **STATE-TOGGLE:** use React `useState` + conditional className.
|
|
1380
|
-
|
|
1381
|
-
Use motion tokens from the active skill for all `transition` and `animation-duration` values. Never hardcode `ms` values.
|
|
1382
|
-
|
|
1383
|
-
**This step is not optional.** Every interaction in the spec must be implemented before moving to assembly. If an interaction is too complex to implement completely, implement a simplified version and note it in the QA report as ⚠️ — but do not leave it unimplemented.
|
|
1384
|
-
|
|
1385
|
-
#### 4.4.B Video background implementation (MANDATORY when videos.json is non-empty)
|
|
1386
|
-
|
|
1387
|
-
For each entry in `docs/research/<hostname>/videos.json`:
|
|
1388
|
-
|
|
1389
|
-
**If downloaded** (`skipped: false`):
|
|
1390
|
-
```tsx
|
|
1391
|
-
// VideoBackground.tsx
|
|
1392
|
-
export function VideoBackground({ role }: { role: string }) {
|
|
1393
|
-
return (
|
|
1394
|
-
<div className="absolute inset-0 overflow-hidden" aria-hidden="true">
|
|
1395
|
-
<video
|
|
1396
|
-
autoPlay
|
|
1397
|
-
muted
|
|
1398
|
-
loop
|
|
1399
|
-
playsInline
|
|
1400
|
-
poster={`/images/<hostname>/${role}-poster.jpg`}
|
|
1401
|
-
className="w-full h-full object-cover"
|
|
1402
|
-
style={{ willChange: 'transform' }}
|
|
1403
|
-
>
|
|
1404
|
-
<source src={`/videos/<hostname>/${role}.webm`} type="video/webm" />
|
|
1405
|
-
<source src={`/videos/<hostname>/${role}.mp4`} type="video/mp4" />
|
|
1406
|
-
{/* Poster fallback rendered by browser if video fails */}
|
|
1407
|
-
</video>
|
|
1408
|
-
{/* Overlay — use skill token */}
|
|
1409
|
-
<div className="absolute inset-0" style={{ backgroundColor: 'var(--overlay-dark)' }} />
|
|
1410
|
-
</div>
|
|
1411
|
-
);
|
|
1412
|
-
}
|
|
1413
|
-
```
|
|
1414
|
-
|
|
1415
|
-
**If skipped** (file > 10MB or blocked): use the poster image as a `background-image` and note it in the QA report as ⚠️ with the original video URL.
|
|
1416
|
-
|
|
1417
|
-
Always render the video **behind** the section content (`z-index: 0` on video, `z-index: 1` on content).
|
|
1418
|
-
Always include the overlay div to maintain text readability.
|
|
1419
|
-
Always add `prefers-reduced-motion` support:
|
|
1420
|
-
```css
|
|
1421
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1422
|
-
video[autoplay] { display: none; }
|
|
1423
|
-
/* Poster image via background-image on the container */
|
|
1424
|
-
}
|
|
1425
|
-
```
|
|
1426
|
-
|
|
1427
|
-
### 4.5 Asset wiring (MANDATORY — do not skip)
|
|
1428
|
-
|
|
1429
|
-
Before assembly, verify that every downloaded image is referenced in its component:
|
|
1430
|
-
|
|
1431
|
-
For each section component:
|
|
1432
|
-
- Check `docs/research/components/<section-slug>.spec.md` → "Content slots" → Image entries.
|
|
1433
|
-
- In the component file, use `next/image` with `src="/images/<hostname>/<filename>"`.
|
|
1434
|
-
- Do not use placeholder SVGs or empty `src` attributes when a downloaded asset exists.
|
|
1435
|
-
|
|
1436
|
-
```tsx
|
|
1437
|
-
// Correct — use the downloaded asset
|
|
1438
|
-
import Image from 'next/image'
|
|
1439
|
-
<Image src="/images/<hostname>/hero.webp" alt="hero" fill className="object-cover" />
|
|
1440
|
-
|
|
1441
|
-
// Wrong — placeholder when asset exists
|
|
1442
|
-
<div className="bg-gray-200 w-full h-64" />
|
|
1443
|
-
```
|
|
1444
|
-
|
|
1445
|
-
If an image was not downloaded (> 2MB or blocked), use a placeholder and note it in the QA report as ⚠️ with the original URL.
|
|
1446
|
-
|
|
1447
|
-
**Asset lifecycle note for the user (display once before assembly):**
|
|
1448
|
-
> "As imagens em `public/images/<hostname>/` são referências de desenvolvimento.
|
|
1449
|
-
> Substitua-as pelos seus próprios assets antes de publicar e delete a pasta quando não precisar mais delas."
|
|
1450
|
-
|
|
1451
|
-
### 4.6 Assembly
|
|
1452
|
-
|
|
1453
|
-
After interactions and assets are wired:
|
|
1454
|
-
1. Create `src/app/page.tsx` importing and rendering all sections in page topology order
|
|
1455
|
-
2. Apply the active CSS token root in `src/app/globals.css` or equivalent:
|
|
1456
|
-
- **Modes A, B, C:** paste the skill's `:root {}` block
|
|
1457
|
-
- **Mode E:** paste `blended-tokens.css` content
|
|
1458
|
-
3. Run `npm run build` — must pass with 0 errors and 0 TypeScript errors
|
|
1459
|
-
|
|
1460
|
-
If build fails: fix TypeScript errors first, then CSS token resolution. Do not proceed to Phase 5 with a broken build.
|
|
1461
|
-
|
|
1462
|
-
**Exit criterion:** `npm run build` passes. All sections rendered. All interactions from interaction-spec.md implemented. All downloaded assets referenced in components. Skill tokens active globally.
|
|
1463
|
-
|
|
1464
|
-
---
|
|
1465
|
-
|
|
1466
|
-
## Phase 5 — Visual QA
|
|
1467
|
-
|
|
1468
|
-
**Goal:** Verify the clone behaves like the original and looks like the skill.
|
|
1469
|
-
|
|
1470
|
-
### 5.1 Start dev server
|
|
1471
|
-
|
|
1472
|
-
```bash
|
|
1473
|
-
npm run dev
|
|
1474
|
-
# Confirm "ready" appears before continuing — wait up to 30s
|
|
1475
|
-
```
|
|
1476
|
-
|
|
1477
|
-
### 5.2 Screenshot comparison
|
|
1478
|
-
|
|
1479
|
-
Using browser MCP, capture both at 1440px, 768px, and 390px:
|
|
1480
|
-
- Original: target URL
|
|
1481
|
-
- Clone: `http://localhost:3000`
|
|
1482
|
-
|
|
1483
|
-
**Mode A, C:** Acceptable differences: colors, fonts, spacing (intentional replacement). Unacceptable: missing sections, broken layout, missing interactive elements, missing content.
|
|
1484
|
-
**Mode B:** The clone should visually resemble the original. Large color/font differences are a signal the extraction missed something — investigate before passing.
|
|
1485
|
-
**Mode E:** The blend should be visible — neither a pure copy of the original nor a pure skill application. If it looks identical to either source, the blend was not applied.
|
|
1486
|
-
|
|
1487
|
-
### 5.3 Interaction testing
|
|
1488
|
-
|
|
1489
|
-
For each interaction in the interaction spec:
|
|
1490
|
-
- Scroll triggers: does the effect fire at the right position?
|
|
1491
|
-
- Click triggers: do tabs, dropdowns, modals, toggles work?
|
|
1492
|
-
- Hover triggers: do cards lift, nav items change state?
|
|
1493
|
-
- Responsive: do breakpoints trigger the correct layout changes?
|
|
1494
|
-
|
|
1495
|
-
### 5.4 Skill fidelity check
|
|
1496
|
-
|
|
1497
|
-
Verify the active token set is applied:
|
|
1498
|
-
- Are CSS variables resolving (no fallbacks to browser defaults)?
|
|
1499
|
-
- Are motion tokens used (no hardcoded `ms` values in components)?
|
|
1500
|
-
- **Mode A, C:** Are skill colors used (not original site colors)?
|
|
1501
|
-
- **Mode B:** Are the extracted site colors reproduced accurately?
|
|
1502
|
-
- **Mode E:** Are blended values present (verify at least 3 tokens from each source)?
|
|
1503
|
-
|
|
1504
|
-
### 5.5 QA report
|
|
1505
|
-
|
|
1506
|
-
Create `docs/research/<hostname>/qa-report.md`:
|
|
1507
|
-
|
|
1508
|
-
```markdown
|
|
1509
|
-
# QA Report — <hostname> → <skill-name>
|
|
1510
|
-
**Mode:** [A | B | C | D | E]
|
|
1511
|
-
**Date:** [date]
|
|
1512
|
-
**Build status:** passing
|
|
1513
|
-
|
|
1514
|
-
## Structural fidelity
|
|
1515
|
-
✅/⚠️/❌ [Section]: [note]
|
|
1516
|
-
|
|
1517
|
-
## Content slots (Modes C, E)
|
|
1518
|
-
✅/⚠️/❌ [Section]: extracted text/images present
|
|
1519
|
-
|
|
1520
|
-
## Interactions
|
|
1521
|
-
✅/⚠️/❌ [Interaction name]: [status and note]
|
|
1522
|
-
|
|
1523
|
-
## Skill fidelity
|
|
1524
|
-
✅/⚠️/❌ Colors: tokens applied / hardcoded values remain
|
|
1525
|
-
✅/⚠️/❌ Typography: skill fonts active
|
|
1526
|
-
✅/⚠️/❌ Spacing: scale tokens applied
|
|
1527
|
-
✅/⚠️/❌ Motion: transition tokens applied
|
|
1528
|
-
|
|
1529
|
-
## Blend verification (Mode E only)
|
|
1530
|
-
✅/⚠️/❌ Site tokens present: [list 3 examples]
|
|
1531
|
-
✅/⚠️/❌ Skill tokens present: [list 3 examples]
|
|
1532
|
-
|
|
1533
|
-
## Issues to fix
|
|
1534
|
-
1. [issue description] → [fix]
|
|
1535
|
-
|
|
1536
|
-
## Known deviations (acceptable ⚠️)
|
|
1537
|
-
- [deviation]: [reason it is acceptable]
|
|
1538
|
-
```
|
|
1539
|
-
|
|
1540
|
-
Fix all ❌ issues before closing. Fewer than 5 ⚠️ issues required to pass.
|
|
1541
|
-
|
|
1542
|
-
**Exit criterion:** Zero ❌ issues. Fewer than 5 ⚠️ issues. All interactions in the interaction spec are working.
|
|
1543
|
-
|
|
1544
|
-
---
|
|
1545
|
-
|
|
1546
|
-
## Output contract
|
|
1547
|
-
|
|
1548
|
-
**Modes A, B, C, E (builds a site):**
|
|
1549
|
-
```
|
|
1550
|
-
docs/research/<hostname>/
|
|
1551
|
-
├── reconnaissance.json
|
|
1552
|
-
├── crawl-manifest.json
|
|
1553
|
-
├── structure-spec.md
|
|
1554
|
-
├── interaction-spec.md ← updated with scroll-triggered entries from Phase 1.5.4
|
|
1555
|
-
├── animations-raw.json ← jsLibraries, keyframes, animationRules, parallax (Phase 1.5)
|
|
1556
|
-
├── videos.json ← video elements and sources (Phase 1.5)
|
|
1557
|
-
├── dom-mutations.json ← class/style changes by scrollY (Phase 1.5)
|
|
1558
|
-
├── component-map.md (Modes A, C)
|
|
1559
|
-
├── blend-map.md (Mode E only)
|
|
1560
|
-
├── blended-tokens.css (Mode E only)
|
|
1561
|
-
└── qa-report.md
|
|
1562
|
-
|
|
1563
|
-
docs/research/<hostname>/scroll-recording/
|
|
1564
|
-
├── scroll-00pct.png ← 8 scroll position screenshots (Phase 1.5)
|
|
1565
|
-
├── scroll-12pct.png
|
|
1566
|
-
├── scroll-25pct.png
|
|
1567
|
-
├── scroll-37pct.png
|
|
1568
|
-
├── scroll-50pct.png
|
|
1569
|
-
├── scroll-62pct.png
|
|
1570
|
-
├── scroll-75pct.png
|
|
1571
|
-
└── scroll-100pct.png
|
|
1572
|
-
|
|
1573
|
-
docs/research/components/
|
|
1574
|
-
└── <section-slug>.spec.md (one per section)
|
|
1575
|
-
└── <component-slug>.spec.md (one per component type)
|
|
1576
|
-
|
|
1577
|
-
public/images/<hostname>/
|
|
1578
|
-
└── [downloaded image assets — replace before publishing]
|
|
1579
|
-
|
|
1580
|
-
public/videos/<hostname>/
|
|
1581
|
-
└── [downloaded video assets — replace before publishing] (Phase 1.5.3)
|
|
1582
|
-
|
|
1583
|
-
src/components/
|
|
1584
|
-
└── [all section components — TypeScript, skill tokens only]
|
|
1585
|
-
└── VideoBackground.tsx ← if any videos found (Phase 4.4.B)
|
|
1586
|
-
|
|
1587
|
-
src/app/
|
|
1588
|
-
├── page.tsx [assembled page]
|
|
1589
|
-
└── globals.css [skill token root + extracted @keyframes applied]
|
|
1590
|
-
```
|
|
1591
|
-
|
|
1592
|
-
**Mode B additionally:**
|
|
1593
|
-
```
|
|
1594
|
-
docs/research/<hostname>/
|
|
1595
|
-
└── aesthetics-raw.json
|
|
1596
|
-
|
|
1597
|
-
.aioson/installed-skills/<hostname>/
|
|
1598
|
-
├── SKILL.md
|
|
1599
|
-
├── references/
|
|
1600
|
-
│ ├── design-tokens.md
|
|
1601
|
-
│ ├── components.md
|
|
1602
|
-
│ ├── patterns.md
|
|
1603
|
-
│ ├── motion.md ← includes extracted @keyframes and detected animation libraries
|
|
1604
|
-
│ └── websites.md
|
|
1605
|
-
└── .skill-meta.json
|
|
1606
|
-
```
|
|
180
|
+
## Hard constraints
|
|
1607
181
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
.
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
│ ├── patterns.md
|
|
1626
|
-
│ ├── motion.md
|
|
1627
|
-
│ └── websites.md
|
|
1628
|
-
└── .skill-meta.json
|
|
1629
|
-
```
|
|
182
|
+
- Never start Phase 1 without browser MCP confirmed available.
|
|
183
|
+
- Never start Phase 2 with an incomplete interaction sweep or without Phase 1.5 complete (unless `--no-deep` flag).
|
|
184
|
+
- **Modes A, C:** Never start Phase 4 without complete `component-map.md` from Phase 3A.
|
|
185
|
+
- **Mode B:** Never start Phase 4 without all skill files written in Phase 3B.
|
|
186
|
+
- **Mode D:** Never proceed to Phase 4 — session ends after Phase 3B.
|
|
187
|
+
- **Mode E:** Never start Phase 4 without `blend-map.md` and `blended-tokens.css` from Phase 3E.
|
|
188
|
+
- Never start Phase 5 without `npm run build` passing, all interactions implemented (4.4), all videos wired (4.4.B), and all downloaded assets referenced in components (4.5).
|
|
189
|
+
- Never hardcode color, font size, spacing, radius, shadow, or animation duration — use skill tokens only.
|
|
190
|
+
- Phase 4.4: always read `animations-raw.json.jsLibraries` before choosing animation implementation strategy. Never default to `IntersectionObserver` if GSAP or Framer Motion was detected.
|
|
191
|
+
- Phase 4.4: always copy extracted `@keyframes` from `animations-raw.json` into `globals.css` verbatim. Never write animation values from memory.
|
|
192
|
+
- Phase 4.4.B: never leave a video as a placeholder `<div>` when `videos.json` has a non-skipped entry.
|
|
193
|
+
- **Modes A, C:** Do not replicate the original site's aesthetic — aesthetic replacement is the mission. Animation mechanics preserved; design tokens replaced.
|
|
194
|
+
- **Mode B:** Every token must trace back to an extracted value. Do not invent tokens.
|
|
195
|
+
- **Mode E:** Blend map must contain tokens from both sources — pure copy or pure skill application is a blend failure.
|
|
196
|
+
- Phase 1.2: always trigger lazy loads before asset extraction.
|
|
197
|
+
- Phase 1.5.4: always attach MutationObserver BEFORE starting scroll recording.
|
|
198
|
+
- Always warn the user about copyright on downloaded assets, videos, and extracted text.
|
|
1630
199
|
|
|
1631
200
|
---
|
|
1632
201
|
|
|
1633
202
|
## Activation triggers
|
|
1634
203
|
|
|
1635
204
|
```
|
|
1636
|
-
/site-forge <url> <skill-name> → Mode A
|
|
205
|
+
/site-forge <url> <skill-name> → Mode A
|
|
1637
206
|
/site-forge <url> → Onboarding questionnaire
|
|
1638
|
-
/site-forge <url> --skill-only → Mode D
|
|
1639
|
-
/site-forge <url> <skill> --blend → Mode E
|
|
1640
|
-
/site-forge <url> <skill> --blend=70 → Mode E
|
|
1641
|
-
|
|
1642
|
-
"clone this site with [skill]"
|
|
1643
|
-
"make a copy of [url] with [
|
|
1644
|
-
"rebuild [url] using [skill]"
|
|
1645
|
-
"[url] in the style of [skill]"
|
|
1646
|
-
"clone [url] and extract its design system"
|
|
1647
|
-
"clone [url] without a skill"
|
|
1648
|
-
"copy [url] as-is"
|
|
1649
|
-
"extract the design from [url] as a skill"
|
|
1650
|
-
"create a skill from [url]"
|
|
1651
|
-
"I want only the skill from [url]"
|
|
1652
|
-
"clone [url] and mix it with [skill]"
|
|
1653
|
-
"blend [url] with [skill] 50/50"
|
|
1654
|
-
"quero só as imagens e conteúdo de [url] para usar com [skill]"
|
|
1655
|
-
"quero criar uma skill do [url]"
|
|
1656
|
-
"quero clonar [url] e mesclar com [skill]"
|
|
1657
|
-
```
|
|
1658
|
-
|
|
1659
|
-
Flags
|
|
1660
|
-
```
|
|
1661
|
-
--viewport=desktop # desktop screenshots only
|
|
207
|
+
/site-forge <url> --skill-only → Mode D
|
|
208
|
+
/site-forge <url> <skill> --blend → Mode E (50/50 default)
|
|
209
|
+
/site-forge <url> <skill> --blend=70 → Mode E (70% site / 30% skill)
|
|
210
|
+
|
|
211
|
+
"clone this site with [skill]" → Mode A
|
|
212
|
+
"make a copy of [url] with [skill]" → Mode A
|
|
213
|
+
"rebuild [url] using [skill]" → Mode A
|
|
214
|
+
"[url] in the style of [skill]" → Mode A
|
|
215
|
+
"clone [url] and extract its design system" → Mode B
|
|
216
|
+
"clone [url] without a skill" → Mode B
|
|
217
|
+
"copy [url] as-is" → Mode B
|
|
218
|
+
"extract the design from [url] as a skill" → Mode D
|
|
219
|
+
"create a skill from [url]" → Mode D
|
|
220
|
+
"I want only the skill from [url]" → Mode D
|
|
221
|
+
"clone [url] and mix it with [skill]" → Mode E
|
|
222
|
+
"blend [url] with [skill] 50/50" → Mode E
|
|
223
|
+
"quero só as imagens e conteúdo de [url] para usar com [skill]" → Mode C
|
|
224
|
+
"quero criar uma skill do [url]" → Mode D
|
|
225
|
+
"quero clonar [url] e mesclar com [skill]" → Mode E
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Flags:**
|
|
229
|
+
```
|
|
230
|
+
--viewport=desktop # desktop screenshots only
|
|
1662
231
|
--no-download # skip asset download
|
|
1663
232
|
--no-crawl # skip internal link crawl
|
|
1664
|
-
--no-deep # skip Phase 1.5 (animation/video/scroll
|
|
1665
|
-
--from-local <path> # use
|
|
1666
|
-
--crawl-depth=N # follow N levels
|
|
233
|
+
--no-deep # skip Phase 1.5 (animation/video/scroll extraction)
|
|
234
|
+
--from-local <path> # use saved site directory instead of live URL
|
|
235
|
+
--crawl-depth=N # follow N levels (default: 1 for B/D/E, 2 for A/C)
|
|
1667
236
|
--blend=N # blend ratio (N% site, default 50) — Mode E only
|
|
1668
|
-
--skill-only #
|
|
237
|
+
--skill-only # force Mode D
|
|
1669
238
|
--output=./dir # custom output directory
|
|
1670
239
|
--verbose # log each extraction step
|
|
1671
240
|
```
|
|
1672
241
|
|
|
1673
|
-
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## --from-local mode
|
|
1674
245
|
|
|
1675
|
-
When `--from-local <path>` is
|
|
246
|
+
When `--from-local <path>` is set, Phases 1 and 1.5 read from the saved site directory. More reliable than live scraping — no bot detection, full CSS access.
|
|
1676
247
|
|
|
1677
|
-
Expected
|
|
248
|
+
Expected structure (from SaveWebZip, HTTrack, `wget --mirror`):
|
|
1678
249
|
```
|
|
1679
250
|
<path>/
|
|
1680
|
-
├── index.html
|
|
1681
|
-
├── css
|
|
1682
|
-
|
|
1683
|
-
├──
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
│ └── *.woff2 ← font files
|
|
1687
|
-
├── images/
|
|
1688
|
-
│ └── * ← image assets
|
|
1689
|
-
└── media/
|
|
1690
|
-
└── *.mp4 *.webm ← video files
|
|
251
|
+
├── index.html
|
|
252
|
+
├── css/*.css
|
|
253
|
+
├── js/*.js
|
|
254
|
+
├── fonts/*.woff2
|
|
255
|
+
├── images/*
|
|
256
|
+
└── media/*.mp4 *.webm
|
|
1691
257
|
```
|
|
1692
258
|
|
|
1693
|
-
**What --from-local extracts (Phase 1 replacements):**
|
|
1694
|
-
|
|
1695
259
|
| Live Phase | --from-local equivalent |
|
|
1696
260
|
|---|---|
|
|
1697
|
-
| 1.1 Screenshots |
|
|
1698
|
-
| 1.2 Asset inventory | `ls images/`
|
|
1699
|
-
| 1.3 Font discovery | Parse `@font-face` from all `.css` files
|
|
1700
|
-
| 1.5.1 Library detection | Grep JS files for
|
|
1701
|
-
| 1.5.2 CSS animation
|
|
1702
|
-
| 1.5.3 Video extraction | `ls media/`
|
|
1703
|
-
| 1.5.4 Scroll recording | Not available (static files
|
|
1704
|
-
| 1.5.5 Parallax
|
|
1705
|
-
|
|
1706
|
-
**Copy assets** from `<path>/fonts/`, `<path>/media/`, `<path>/images/` directly to `public/` — no download needed.
|
|
1707
|
-
|
|
1708
|
-
**--from-local + browser MCP together (recommended):** Use `--from-local` for static extraction (CSS, fonts, videos, @keyframes) and supplement with browser MCP only for scroll recording (Phase 1.5.4). This gives the best of both approaches.
|
|
1709
|
-
|
|
1710
|
-
---
|
|
261
|
+
| 1.1 Screenshots | Parse section topology from `index.html` DOM |
|
|
262
|
+
| 1.2 Asset inventory | `ls images/` — no scraping needed |
|
|
263
|
+
| 1.3 Font discovery | Parse `@font-face` from all `.css` files |
|
|
264
|
+
| 1.5.1 Library detection | Grep JS files for `gsap`, `ScrollTrigger`, `Swiper`, etc. |
|
|
265
|
+
| 1.5.2 CSS animation | Parse all `@keyframes`, `animation:`, `transition:` from CSS — complete, not computed |
|
|
266
|
+
| 1.5.3 Video extraction | `ls media/` with type detection |
|
|
267
|
+
| 1.5.4 Scroll recording | Not available (static files) — skip |
|
|
268
|
+
| 1.5.5 Parallax | Grep CSS for `background-attachment: fixed` |
|
|
1711
269
|
|
|
1712
|
-
|
|
270
|
+
Copy assets from `<path>/fonts/`, `<path>/media/`, `<path>/images/` directly to `public/` — no download needed.
|
|
1713
271
|
|
|
1714
|
-
-
|
|
1715
|
-
- Never start Phase 2 with an incomplete interaction sweep from Phase 1.
|
|
1716
|
-
- Never start Phase 2 without Phase 1.5 complete (unless `--no-deep` flag is set).
|
|
1717
|
-
- **Modes A, C:** Never start Phase 4 without a complete component-map.md from Phase 3A.
|
|
1718
|
-
- **Mode B:** Never start Phase 4 without all skill files written in Phase 3B.
|
|
1719
|
-
- **Mode D:** Never proceed to Phase 4 — the session ends after Phase 3B.
|
|
1720
|
-
- **Mode E:** Never start Phase 4 without `blend-map.md` and `blended-tokens.css` from Phase 3E.
|
|
1721
|
-
- Never start Phase 5 without `npm run build` passing from Phase 4, all interactions implemented (4.4), all videos wired (4.4.B), and all downloaded assets referenced in components (4.5).
|
|
1722
|
-
- Never hardcode color, font size, spacing, radius, shadow, or animation duration values — use skill tokens only.
|
|
1723
|
-
- In Phase 4.4: always read `animations-raw.json.jsLibraries` before choosing an implementation strategy. Never default to `IntersectionObserver` if GSAP or Framer Motion was detected.
|
|
1724
|
-
- In Phase 4.4: always copy extracted `@keyframes` from `animations-raw.json` into `globals.css` verbatim before implementing animated components. Never write animation values from memory.
|
|
1725
|
-
- In Phase 4.4.B: never leave a video as a placeholder `<div>` when `videos.json` contains a non-skipped entry for that section.
|
|
1726
|
-
- **Modes A, C:** Do not replicate the original site's aesthetic — aesthetic replacement is the mission. Animation mechanics (triggers, timing, effects) are preserved; design tokens are replaced.
|
|
1727
|
-
- **Mode B:** Do not invent tokens that weren't observed in the site — every token must trace back to an extracted value in `aesthetics-raw.json` or `animations-raw.json`.
|
|
1728
|
-
- **Mode E:** Blend map must contain tokens from both sources — pure copy or pure skill application is a blend failure.
|
|
1729
|
-
- In Phase 1.2: always trigger lazy loads before asset extraction. Never extract images with the page at the top position only.
|
|
1730
|
-
- In Phase 1.5.4: always attach the MutationObserver BEFORE starting the scroll recording. Never scroll first and attach later.
|
|
1731
|
-
- Always warn the user about copyright on downloaded assets, videos, and extracted text content.
|
|
1732
|
-
- Extracted text content is for reference only — remind the user to replace it before publishing.
|
|
272
|
+
**Recommended:** use `--from-local` for static extraction + browser MCP only for Phase 1.5.4 scroll recording.
|
|
1733
273
|
|
|
1734
274
|
---
|
|
1735
275
|
|
|
1736
276
|
## Observability
|
|
1737
277
|
|
|
1738
|
-
At
|
|
278
|
+
At session end:
|
|
1739
279
|
```bash
|
|
1740
280
|
aioson agent:done . --agent=site-forge --summary="Cloned <hostname> [Mode A/B/C/D/E: description]"
|
|
1741
281
|
```
|
|
1742
|
-
|
|
1743
|
-
---
|
|
1744
|
-
|
|
1745
|
-
## Starting the session
|
|
1746
|
-
|
|
1747
|
-
Parse the URL and optional skill name from the user's input.
|
|
1748
|
-
|
|
1749
|
-
- URL + skill name + `--blend` → Mode E. Ask for blend ratio if not provided. Proceed to Step 0.
|
|
1750
|
-
- URL + `--skill-only` → Mode D. Proceed to Step 0.
|
|
1751
|
-
- URL + skill name → Mode A. Proceed to Step 0.
|
|
1752
|
-
- URL only, or ambiguous input → Run onboarding questionnaire at the top of this section.
|
|
1753
|
-
- No URL → Run onboarding questionnaire. Ask for URL as the first question.
|