@dewtech/dare-cli 3.10.0 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/__tests__/ci-pr-regression.test.d.ts +2 -0
- package/dist/__tests__/ci-pr-regression.test.d.ts.map +1 -0
- package/dist/__tests__/ci-pr-regression.test.js +76 -0
- package/dist/__tests__/ci-pr-regression.test.js.map +1 -0
- package/dist/__tests__/dashboard-front.test.d.ts +2 -0
- package/dist/__tests__/dashboard-front.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard-front.test.js +37 -0
- package/dist/__tests__/dashboard-front.test.js.map +1 -0
- package/dist/__tests__/dashboard-regression.test.d.ts +2 -0
- package/dist/__tests__/dashboard-regression.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard-regression.test.js +68 -0
- package/dist/__tests__/dashboard-regression.test.js.map +1 -0
- package/dist/__tests__/dynamic-dag-regression.test.d.ts +2 -0
- package/dist/__tests__/dynamic-dag-regression.test.d.ts.map +1 -0
- package/dist/__tests__/dynamic-dag-regression.test.js +464 -0
- package/dist/__tests__/dynamic-dag-regression.test.js.map +1 -0
- package/dist/__tests__/ensure-skills.test.js +5 -0
- package/dist/__tests__/ensure-skills.test.js.map +1 -1
- package/dist/__tests__/ide-command-parity.test.js +2 -0
- package/dist/__tests__/ide-command-parity.test.js.map +1 -1
- package/dist/__tests__/project-generator.test.js +17 -0
- package/dist/__tests__/project-generator.test.js.map +1 -1
- package/dist/__tests__/reverse-facts.test.js +1 -0
- package/dist/__tests__/reverse-facts.test.js.map +1 -1
- package/dist/__tests__/terminal-parity-regression.test.d.ts +2 -0
- package/dist/__tests__/terminal-parity-regression.test.d.ts.map +1 -0
- package/dist/__tests__/terminal-parity-regression.test.js +116 -0
- package/dist/__tests__/terminal-parity-regression.test.js.map +1 -0
- package/dist/__tests__/terminal-parity.test.d.ts +2 -0
- package/dist/__tests__/terminal-parity.test.d.ts.map +1 -0
- package/dist/__tests__/terminal-parity.test.js +81 -0
- package/dist/__tests__/terminal-parity.test.js.map +1 -0
- package/dist/agent/__tests__/antigravity-driver.test.d.ts +2 -0
- package/dist/agent/__tests__/antigravity-driver.test.d.ts.map +1 -0
- package/dist/agent/__tests__/antigravity-driver.test.js +52 -0
- package/dist/agent/__tests__/antigravity-driver.test.js.map +1 -0
- package/dist/agent/__tests__/codex-driver.test.d.ts +2 -0
- package/dist/agent/__tests__/codex-driver.test.d.ts.map +1 -0
- package/dist/agent/__tests__/codex-driver.test.js +68 -0
- package/dist/agent/__tests__/codex-driver.test.js.map +1 -0
- package/dist/agent/__tests__/cursor-driver.test.d.ts +2 -0
- package/dist/agent/__tests__/cursor-driver.test.d.ts.map +1 -0
- package/dist/agent/__tests__/cursor-driver.test.js +52 -0
- package/dist/agent/__tests__/cursor-driver.test.js.map +1 -0
- package/dist/agent/driver.d.ts +1 -1
- package/dist/agent/driver.d.ts.map +1 -1
- package/dist/agent/drivers/antigravity.d.ts +8 -0
- package/dist/agent/drivers/antigravity.d.ts.map +1 -0
- package/dist/agent/drivers/antigravity.js +99 -0
- package/dist/agent/drivers/antigravity.js.map +1 -0
- package/dist/agent/drivers/codex.d.ts +12 -0
- package/dist/agent/drivers/codex.d.ts.map +1 -0
- package/dist/agent/drivers/codex.js +137 -0
- package/dist/agent/drivers/codex.js.map +1 -0
- package/dist/agent/drivers/cursor.d.ts +8 -0
- package/dist/agent/drivers/cursor.d.ts.map +1 -0
- package/dist/agent/drivers/cursor.js +99 -0
- package/dist/agent/drivers/cursor.js.map +1 -0
- package/dist/ai/__tests__/ai-core.test.d.ts +2 -0
- package/dist/ai/__tests__/ai-core.test.d.ts.map +1 -0
- package/dist/ai/__tests__/ai-core.test.js +41 -0
- package/dist/ai/__tests__/ai-core.test.js.map +1 -0
- package/dist/ai/__tests__/parity.test.d.ts +2 -0
- package/dist/ai/__tests__/parity.test.d.ts.map +1 -0
- package/dist/ai/__tests__/parity.test.js +36 -0
- package/dist/ai/__tests__/parity.test.js.map +1 -0
- package/dist/ai/__tests__/pipeline.test.d.ts +2 -0
- package/dist/ai/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/ai/__tests__/pipeline.test.js +147 -0
- package/dist/ai/__tests__/pipeline.test.js.map +1 -0
- package/dist/ai/__tests__/refine-bridge.test.d.ts +2 -0
- package/dist/ai/__tests__/refine-bridge.test.d.ts.map +1 -0
- package/dist/ai/__tests__/refine-bridge.test.js +17 -0
- package/dist/ai/__tests__/refine-bridge.test.js.map +1 -0
- package/dist/ai/__tests__/resolve.test.d.ts +2 -0
- package/dist/ai/__tests__/resolve.test.d.ts.map +1 -0
- package/dist/ai/__tests__/resolve.test.js +42 -0
- package/dist/ai/__tests__/resolve.test.js.map +1 -0
- package/dist/ai/capabilities.d.ts +3 -0
- package/dist/ai/capabilities.d.ts.map +1 -0
- package/dist/ai/capabilities.js +11 -0
- package/dist/ai/capabilities.js.map +1 -0
- package/dist/ai/command-options.d.ts +10 -0
- package/dist/ai/command-options.d.ts.map +1 -0
- package/dist/ai/command-options.js +15 -0
- package/dist/ai/command-options.js.map +1 -0
- package/dist/ai/config.d.ts +27 -0
- package/dist/ai/config.d.ts.map +1 -0
- package/dist/ai/config.js +89 -0
- package/dist/ai/config.js.map +1 -0
- package/dist/ai/parity.d.ts +13 -0
- package/dist/ai/parity.d.ts.map +1 -0
- package/dist/ai/parity.js +87 -0
- package/dist/ai/parity.js.map +1 -0
- package/dist/ai/parse-json-output.d.ts +5 -0
- package/dist/ai/parse-json-output.d.ts.map +1 -0
- package/dist/ai/parse-json-output.js +25 -0
- package/dist/ai/parse-json-output.js.map +1 -0
- package/dist/ai/pipeline.d.ts +20 -0
- package/dist/ai/pipeline.d.ts.map +1 -0
- package/dist/ai/pipeline.js +303 -0
- package/dist/ai/pipeline.js.map +1 -0
- package/dist/ai/prompts.d.ts +6 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +49 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/ai/providers.d.ts +63 -0
- package/dist/ai/providers.d.ts.map +1 -0
- package/dist/ai/providers.js +297 -0
- package/dist/ai/providers.js.map +1 -0
- package/dist/ai/refine-bridge.d.ts +5 -0
- package/dist/ai/refine-bridge.d.ts.map +1 -0
- package/dist/ai/refine-bridge.js +14 -0
- package/dist/ai/refine-bridge.js.map +1 -0
- package/dist/ai/registry.d.ts +12 -0
- package/dist/ai/registry.d.ts.map +1 -0
- package/dist/ai/registry.js +43 -0
- package/dist/ai/registry.js.map +1 -0
- package/dist/ai/resolve.d.ts +28 -0
- package/dist/ai/resolve.d.ts.map +1 -0
- package/dist/ai/resolve.js +83 -0
- package/dist/ai/resolve.js.map +1 -0
- package/dist/ai/schemas.d.ts +175 -0
- package/dist/ai/schemas.d.ts.map +1 -0
- package/dist/ai/schemas.js +199 -0
- package/dist/ai/schemas.js.map +1 -0
- package/dist/ai/types.d.ts +52 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +8 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/bin/dare.js +4 -0
- package/dist/bin/dare.js.map +1 -1
- package/dist/commands/__tests__/ai-command.test.d.ts +2 -0
- package/dist/commands/__tests__/ai-command.test.d.ts.map +1 -0
- package/dist/commands/__tests__/ai-command.test.js +68 -0
- package/dist/commands/__tests__/ai-command.test.js.map +1 -0
- package/dist/commands/__tests__/dashboard-command.test.d.ts +2 -0
- package/dist/commands/__tests__/dashboard-command.test.d.ts.map +1 -0
- package/dist/commands/__tests__/dashboard-command.test.js +62 -0
- package/dist/commands/__tests__/dashboard-command.test.js.map +1 -0
- package/dist/commands/__tests__/execute-agent.test.js +82 -0
- package/dist/commands/__tests__/execute-agent.test.js.map +1 -1
- package/dist/commands/__tests__/gate-flags.test.d.ts +2 -0
- package/dist/commands/__tests__/gate-flags.test.d.ts.map +1 -0
- package/dist/commands/__tests__/gate-flags.test.js +58 -0
- package/dist/commands/__tests__/gate-flags.test.js.map +1 -0
- package/dist/commands/__tests__/persist-viz.test.d.ts +2 -0
- package/dist/commands/__tests__/persist-viz.test.d.ts.map +1 -0
- package/dist/commands/__tests__/persist-viz.test.js +178 -0
- package/dist/commands/__tests__/persist-viz.test.js.map +1 -0
- package/dist/commands/__tests__/refine-apply.test.d.ts +2 -0
- package/dist/commands/__tests__/refine-apply.test.d.ts.map +1 -0
- package/dist/commands/__tests__/refine-apply.test.js +118 -0
- package/dist/commands/__tests__/refine-apply.test.js.map +1 -0
- package/dist/commands/__tests__/replan-splice.test.d.ts +2 -0
- package/dist/commands/__tests__/replan-splice.test.d.ts.map +1 -0
- package/dist/commands/__tests__/replan-splice.test.js +295 -0
- package/dist/commands/__tests__/replan-splice.test.js.map +1 -0
- package/dist/commands/ai.d.ts +3 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +141 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/blueprint.d.ts.map +1 -1
- package/dist/commands/blueprint.js +17 -3
- package/dist/commands/blueprint.js.map +1 -1
- package/dist/commands/dag.d.ts.map +1 -1
- package/dist/commands/dag.js +2 -0
- package/dist/commands/dag.js.map +1 -1
- package/dist/commands/dashboard.d.ts +17 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +77 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/design.d.ts.map +1 -1
- package/dist/commands/design.js +21 -2
- package/dist/commands/design.js.map +1 -1
- package/dist/commands/discover.d.ts.map +1 -1
- package/dist/commands/discover.js +9 -1
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/dna.d.ts.map +1 -1
- package/dist/commands/dna.js +23 -3
- package/dist/commands/dna.js.map +1 -1
- package/dist/commands/execute.d.ts +11 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +219 -6
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/graph.d.ts.map +1 -1
- package/dist/commands/graph.js +33 -5
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/guard.d.ts.map +1 -1
- package/dist/commands/guard.js +27 -3
- package/dist/commands/guard.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +1 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +14 -2
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/patterns.d.ts.map +1 -1
- package/dist/commands/patterns.js +14 -2
- package/dist/commands/patterns.js.map +1 -1
- package/dist/commands/refine.d.ts +2 -0
- package/dist/commands/refine.d.ts.map +1 -1
- package/dist/commands/refine.js +94 -22
- package/dist/commands/refine.js.map +1 -1
- package/dist/commands/reverse.d.ts.map +1 -1
- package/dist/commands/reverse.js +28 -3
- package/dist/commands/reverse.js.map +1 -1
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +60 -7
- package/dist/commands/review.js.map +1 -1
- package/dist/core/types/project.d.ts +1 -1
- package/dist/core/types/project.d.ts.map +1 -1
- package/dist/dag-runner/__tests__/maxdepth-config.test.d.ts +2 -0
- package/dist/dag-runner/__tests__/maxdepth-config.test.d.ts.map +1 -0
- package/dist/dag-runner/__tests__/maxdepth-config.test.js +28 -0
- package/dist/dag-runner/__tests__/maxdepth-config.test.js.map +1 -0
- package/dist/dag-runner/__tests__/sub-dag.test.d.ts +2 -0
- package/dist/dag-runner/__tests__/sub-dag.test.d.ts.map +1 -0
- package/dist/dag-runner/__tests__/sub-dag.test.js +127 -0
- package/dist/dag-runner/__tests__/sub-dag.test.js.map +1 -0
- package/dist/dag-runner/run_dag.d.ts +3 -1
- package/dist/dag-runner/run_dag.d.ts.map +1 -1
- package/dist/dag-runner/run_dag.js.map +1 -1
- package/dist/dag-runner/state-store.d.ts +2 -0
- package/dist/dag-runner/state-store.d.ts.map +1 -1
- package/dist/dag-runner/state-store.js +44 -8
- package/dist/dag-runner/state-store.js.map +1 -1
- package/dist/dag-runner/sub-dag.d.ts +23 -0
- package/dist/dag-runner/sub-dag.d.ts.map +1 -0
- package/dist/dag-runner/sub-dag.js +117 -0
- package/dist/dag-runner/sub-dag.js.map +1 -0
- package/dist/dashboard/__tests__/dashboard-routes.test.d.ts +2 -0
- package/dist/dashboard/__tests__/dashboard-routes.test.d.ts.map +1 -0
- package/dist/dashboard/__tests__/dashboard-routes.test.js +102 -0
- package/dist/dashboard/__tests__/dashboard-routes.test.js.map +1 -0
- package/dist/dashboard/routes.d.ts +8 -0
- package/dist/dashboard/routes.d.ts.map +1 -0
- package/dist/dashboard/routes.js +70 -0
- package/dist/dashboard/routes.js.map +1 -0
- package/dist/exec/safe-spawn.d.ts.map +1 -1
- package/dist/exec/safe-spawn.js +6 -1
- package/dist/exec/safe-spawn.js.map +1 -1
- package/dist/graphrag/__tests__/hybrid-integration.test.js +1 -1
- package/dist/graphrag/__tests__/hybrid-integration.test.js.map +1 -1
- package/dist/graphrag/__tests__/no-heavy-dep-in-core.test.js +2 -2
- package/dist/graphrag/__tests__/no-heavy-dep-in-core.test.js.map +1 -1
- package/dist/graphrag/embeddings.js +1 -1
- package/dist/graphrag/embeddings.js.map +1 -1
- package/dist/http/__tests__/shared-app.test.d.ts +2 -0
- package/dist/http/__tests__/shared-app.test.d.ts.map +1 -0
- package/dist/http/__tests__/shared-app.test.js +57 -0
- package/dist/http/__tests__/shared-app.test.js.map +1 -0
- package/dist/http/app.d.ts +15 -0
- package/dist/http/app.d.ts.map +1 -0
- package/dist/http/app.js +32 -0
- package/dist/http/app.js.map +1 -0
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +5 -15
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/reporters/__tests__/github-reporter.test.d.ts +2 -0
- package/dist/reporters/__tests__/github-reporter.test.d.ts.map +1 -0
- package/dist/reporters/__tests__/github-reporter.test.js +93 -0
- package/dist/reporters/__tests__/github-reporter.test.js.map +1 -0
- package/dist/reporters/ci-gate.d.ts +27 -0
- package/dist/reporters/ci-gate.d.ts.map +1 -0
- package/dist/reporters/ci-gate.js +100 -0
- package/dist/reporters/ci-gate.js.map +1 -0
- package/dist/reporters/github.d.ts +36 -0
- package/dist/reporters/github.d.ts.map +1 -0
- package/dist/reporters/github.js +142 -0
- package/dist/reporters/github.js.map +1 -0
- package/dist/skills/bundled.d.ts +5 -0
- package/dist/skills/bundled.d.ts.map +1 -0
- package/dist/skills/bundled.js +34 -0
- package/dist/skills/bundled.js.map +1 -0
- package/dist/skills/commands/add.d.ts +1 -3
- package/dist/skills/commands/add.d.ts.map +1 -1
- package/dist/skills/commands/add.js +20 -3
- package/dist/skills/commands/add.js.map +1 -1
- package/dist/skills/tests/bundled.spec.d.ts +2 -0
- package/dist/skills/tests/bundled.spec.d.ts.map +1 -0
- package/dist/skills/tests/bundled.spec.js +24 -0
- package/dist/skills/tests/bundled.spec.js.map +1 -0
- package/dist/telemetry/__tests__/aggregator.test.d.ts +2 -0
- package/dist/telemetry/__tests__/aggregator.test.d.ts.map +1 -0
- package/dist/telemetry/__tests__/aggregator.test.js +164 -0
- package/dist/telemetry/__tests__/aggregator.test.js.map +1 -0
- package/dist/telemetry/aggregator.d.ts +43 -0
- package/dist/telemetry/aggregator.d.ts.map +1 -0
- package/dist/telemetry/aggregator.js +282 -0
- package/dist/telemetry/aggregator.js.map +1 -0
- package/dist/types/UpdateManifest.types.d.ts +1 -1
- package/dist/types/UpdateManifest.types.d.ts.map +1 -1
- package/dist/utils/dag-converter.js +1 -1
- package/dist/utils/dag-converter.js.map +1 -1
- package/dist/utils/excalidraw-renderer.d.ts.map +1 -1
- package/dist/utils/excalidraw-renderer.js +1 -0
- package/dist/utils/excalidraw-renderer.js.map +1 -1
- package/dist/utils/graph-renderer.d.ts +2 -0
- package/dist/utils/graph-renderer.d.ts.map +1 -1
- package/dist/utils/graph-renderer.js +188 -14
- package/dist/utils/graph-renderer.js.map +1 -1
- package/dist/utils/project-detector.d.ts +1 -0
- package/dist/utils/project-detector.d.ts.map +1 -1
- package/dist/utils/project-detector.js +8 -0
- package/dist/utils/project-detector.js.map +1 -1
- package/dist/utils/project-generator.d.ts +1 -1
- package/dist/utils/project-generator.d.ts.map +1 -1
- package/dist/utils/project-generator.js +23 -2
- package/dist/utils/project-generator.js.map +1 -1
- package/dist/utils/templates.d.ts +2 -0
- package/dist/utils/templates.d.ts.map +1 -1
- package/dist/utils/templates.js +74 -0
- package/dist/utils/templates.js.map +1 -1
- package/dist/verification/__tests__/decay-policy.test.js +1 -0
- package/dist/verification/__tests__/decay-policy.test.js.map +1 -1
- package/dist/verification/__tests__/safe-spawn.test.js +12 -0
- package/dist/verification/__tests__/safe-spawn.test.js.map +1 -1
- package/dist/verification/config.d.ts.map +1 -1
- package/dist/verification/config.js +2 -0
- package/dist/verification/config.js.map +1 -1
- package/dist/verification/types.d.ts +2 -0
- package/dist/verification/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/skills/dare-ax/generator.ts +325 -0
- package/skills/dare-ax/index.ts +19 -0
- package/skills/dare-ax/metrics.ts +352 -0
- package/skills/dare-ax/package-lock.json +1855 -0
- package/skills/dare-ax/package.json +50 -0
- package/skills/dare-ax/secret-detector.ts +123 -0
- package/skills/dare-ax/skill.yml +19 -0
- package/skills/dare-ax/templates/llms.txt.jinja2 +80 -0
- package/skills/dare-ax/tests/generator.spec.ts +193 -0
- package/skills/dare-ax/tests/metrics.spec.ts +394 -0
- package/skills/dare-ax/tests/validator.spec.ts +298 -0
- package/skills/dare-ax/tsconfig.json +18 -0
- package/skills/dare-ax/types.ts +79 -0
- package/skills/dare-ax/validator.ts +238 -0
- package/skills/dare-frontend-design/generator.ts +616 -0
- package/skills/dare-frontend-design/index.ts +25 -0
- package/skills/dare-frontend-design/linter.ts +227 -0
- package/skills/dare-frontend-design/metrics.ts +82 -0
- package/skills/dare-frontend-design/package-lock.json +1855 -0
- package/skills/dare-frontend-design/package.json +43 -0
- package/skills/dare-frontend-design/skill.yml +20 -0
- package/skills/dare-frontend-design/tests/frontend_design.spec.ts +435 -0
- package/skills/dare-frontend-design/tsconfig.json +18 -0
- package/skills/dare-frontend-design/types.ts +62 -0
- package/skills/dare-layered-design/generator.ts +740 -0
- package/skills/dare-layered-design/index.ts +17 -0
- package/skills/dare-layered-design/linter.ts +462 -0
- package/skills/dare-layered-design/metrics.ts +409 -0
- package/skills/dare-layered-design/package-lock.json +1855 -0
- package/skills/dare-layered-design/package.json +50 -0
- package/skills/dare-layered-design/skill.yml +35 -0
- package/skills/dare-layered-design/tests/generator.spec.ts +156 -0
- package/skills/dare-layered-design/tests/linter.spec.ts +255 -0
- package/skills/dare-layered-design/tests/metrics.spec.ts +286 -0
- package/skills/dare-layered-design/tsconfig.json +18 -0
- package/skills/dare-layered-design/types.ts +48 -0
- package/skills/dare-llm-integration/cache/llm_cache.ts +122 -0
- package/skills/dare-llm-integration/index.ts +49 -0
- package/skills/dare-llm-integration/metrics.ts +107 -0
- package/skills/dare-llm-integration/package-lock.json +1855 -0
- package/skills/dare-llm-integration/package.json +49 -0
- package/skills/dare-llm-integration/prompts/prompt_loader.ts +258 -0
- package/skills/dare-llm-integration/providers/anthropic_provider.ts +159 -0
- package/skills/dare-llm-integration/providers/dummy_provider.ts +113 -0
- package/skills/dare-llm-integration/providers/llm_provider.ts +6 -0
- package/skills/dare-llm-integration/providers/openai_provider.ts +215 -0
- package/skills/dare-llm-integration/rate_limit/token_bucket.ts +86 -0
- package/skills/dare-llm-integration/skill.yml +23 -0
- package/skills/dare-llm-integration/tests/fixtures/greet_v1.jinja2 +1 -0
- package/skills/dare-llm-integration/tests/fixtures/summarize_v1.jinja2 +1 -0
- package/skills/dare-llm-integration/tests/fixtures/summarize_v2.jinja2 +3 -0
- package/skills/dare-llm-integration/tests/llm_integration.spec.ts +657 -0
- package/skills/dare-llm-integration/tsconfig.json +23 -0
- package/skills/dare-llm-integration/types.ts +91 -0
- package/skills/dare-llm-integration/validators/output_validator.ts +200 -0
- package/skills/dare-quality-telemetry/collect.ts +134 -0
- package/skills/dare-quality-telemetry/collectors/dare_ax_collector.ts +301 -0
- package/skills/dare-quality-telemetry/collectors/dare_layered_design_collector.ts +406 -0
- package/skills/dare-quality-telemetry/collectors/index.ts +24 -0
- package/skills/dare-quality-telemetry/github_actions_template.ts +25 -0
- package/skills/dare-quality-telemetry/index.ts +18 -0
- package/skills/dare-quality-telemetry/metrics.ts +137 -0
- package/skills/dare-quality-telemetry/package-lock.json +1855 -0
- package/skills/dare-quality-telemetry/package.json +48 -0
- package/skills/dare-quality-telemetry/regression.ts +60 -0
- package/skills/dare-quality-telemetry/reporter.ts +132 -0
- package/skills/dare-quality-telemetry/skill.yml +18 -0
- package/skills/dare-quality-telemetry/tests/quality_telemetry.spec.ts +885 -0
- package/skills/dare-quality-telemetry/tsconfig.json +19 -0
- package/skills/dare-quality-telemetry/types.ts +41 -0
- package/skills/dare-realtime/event_registry.ts +101 -0
- package/skills/dare-realtime/index.ts +30 -0
- package/skills/dare-realtime/metrics.ts +84 -0
- package/skills/dare-realtime/package-lock.json +1855 -0
- package/skills/dare-realtime/package.json +43 -0
- package/skills/dare-realtime/reconnect_strategy.ts +85 -0
- package/skills/dare-realtime/schema_validator.ts +80 -0
- package/skills/dare-realtime/skill.yml +21 -0
- package/skills/dare-realtime/subscription_manager.ts +106 -0
- package/skills/dare-realtime/tests/realtime.spec.ts +482 -0
- package/skills/dare-realtime/tsconfig.json +18 -0
- package/skills/dare-realtime/types.ts +51 -0
- package/templates/.github/workflows/dare-pr.yml +26 -0
- package/templates/dashboard/app.js +184 -0
- package/templates/dashboard/index.html +63 -0
- package/templates/dashboard/style.css +134 -0
- package/templates/ide/antigravity/.agents/skills/dare-ai/SKILL.md +17 -0
- package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +2 -0
- package/templates/ide/antigravity/.agents/skills/dare-dashboard/SKILL.md +18 -0
- package/templates/ide/antigravity/.agents/skills/dare-design/SKILL.md +2 -0
- package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +3 -0
- package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +3 -0
- package/templates/ide/antigravity/.agents/skills/dare-patterns/SKILL.md +3 -0
- package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +3 -0
- package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +3 -0
- package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +3 -0
- package/templates/ide/claude/.claude/commands/dare-ai.md +17 -0
- package/templates/ide/claude/.claude/commands/dare-blueprint.md +2 -0
- package/templates/ide/claude/.claude/commands/dare-dashboard.md +18 -0
- package/templates/ide/claude/.claude/commands/dare-design.md +2 -0
- package/templates/ide/claude/.claude/commands/dare-dna.md +2 -0
- package/templates/ide/claude/.claude/commands/dare-migrate.md +2 -0
- package/templates/ide/claude/.claude/commands/dare-patterns.md +3 -0
- package/templates/ide/claude/.claude/commands/dare-refine.md +3 -0
- package/templates/ide/claude/.claude/commands/dare-reverse.md +2 -0
- package/templates/ide/claude/.claude/commands/dare-review.md +3 -0
- package/templates/ide/cursor/.cursor/commands/dare-ai.md +17 -0
- package/templates/ide/cursor/.cursor/commands/dare-blueprint.md +3 -0
- package/templates/ide/cursor/.cursor/commands/dare-dashboard.md +18 -0
- package/templates/ide/cursor/.cursor/commands/dare-design.md +3 -0
- package/templates/ide/cursor/.cursor/commands/dare-dna.md +2 -0
- package/templates/ide/cursor/.cursor/commands/dare-migrate.md +2 -0
- package/templates/ide/cursor/.cursor/commands/dare-patterns.md +3 -0
- package/templates/ide/cursor/.cursor/commands/dare-refine.md +3 -0
- package/templates/ide/cursor/.cursor/commands/dare-reverse.md +2 -0
- package/templates/ide/cursor/.cursor/commands/dare-review.md +3 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dare-frontend-design — FrontendGenerator
|
|
3
|
+
* Scaffolds DARE-compliant frontend structure for React or Vue projects.
|
|
4
|
+
* License: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import type { ScaffoldOptions, ScaffoldResult, Framework } from './types.js';
|
|
10
|
+
|
|
11
|
+
export class FrontendGenerator {
|
|
12
|
+
/**
|
|
13
|
+
* Generate a DARE-compliant frontend project structure.
|
|
14
|
+
*/
|
|
15
|
+
scaffold(options: ScaffoldOptions): ScaffoldResult {
|
|
16
|
+
const { framework, outputDir, projectName = 'my-app' } = options;
|
|
17
|
+
|
|
18
|
+
const dirsCreated: string[] = [];
|
|
19
|
+
const filesCreated: string[] = [];
|
|
20
|
+
|
|
21
|
+
if (framework === 'react') {
|
|
22
|
+
scaffoldReact(outputDir, projectName, dirsCreated, filesCreated);
|
|
23
|
+
} else if (framework === 'vue') {
|
|
24
|
+
scaffoldVue(outputDir, projectName, dirsCreated, filesCreated);
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error(`FrontendGenerator: unknown framework "${framework as string}"`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
filesCreated,
|
|
31
|
+
dirsCreated,
|
|
32
|
+
framework,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// React scaffold
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
function scaffoldReact(
|
|
42
|
+
outputDir: string,
|
|
43
|
+
projectName: string,
|
|
44
|
+
dirsCreated: string[],
|
|
45
|
+
filesCreated: string[]
|
|
46
|
+
): void {
|
|
47
|
+
const dirs = [
|
|
48
|
+
'src/components',
|
|
49
|
+
'src/hooks',
|
|
50
|
+
'src/pages',
|
|
51
|
+
'src/store',
|
|
52
|
+
'src/api',
|
|
53
|
+
'src/types',
|
|
54
|
+
'src/styles',
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
for (const dir of dirs) {
|
|
58
|
+
const fullDir = path.join(outputDir, dir);
|
|
59
|
+
mkdirSafe(fullDir);
|
|
60
|
+
dirsCreated.push(fullDir);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const files: Record<string, string> = {
|
|
64
|
+
'src/components/ErrorBoundary.tsx': reactErrorBoundaryTemplate(),
|
|
65
|
+
'src/components/LoadingSpinner.tsx': reactLoadingSpinnerTemplate(),
|
|
66
|
+
'src/hooks/useFetch.ts': reactUseFetchTemplate(),
|
|
67
|
+
'src/pages/NotFoundPage.tsx': reactNotFoundPageTemplate(),
|
|
68
|
+
'src/api/client.ts': reactApiClientTemplate(),
|
|
69
|
+
'src/api/endpoints.ts': reactEndpointsTemplate(),
|
|
70
|
+
'src/store/store.ts': reactStoreTemplate(),
|
|
71
|
+
'src/types/index.ts': reactTypesTemplate(),
|
|
72
|
+
'src/App.tsx': reactAppTemplate(projectName),
|
|
73
|
+
'src/styles/globals.css': cssGlobalsTemplate(),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
for (const [relPath, content] of Object.entries(files)) {
|
|
77
|
+
const fullPath = path.join(outputDir, relPath);
|
|
78
|
+
fs.writeFileSync(fullPath, content, 'utf-8');
|
|
79
|
+
filesCreated.push(fullPath);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Vue scaffold
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
function scaffoldVue(
|
|
88
|
+
outputDir: string,
|
|
89
|
+
projectName: string,
|
|
90
|
+
dirsCreated: string[],
|
|
91
|
+
filesCreated: string[]
|
|
92
|
+
): void {
|
|
93
|
+
const dirs = [
|
|
94
|
+
'src/components',
|
|
95
|
+
'src/composables',
|
|
96
|
+
'src/pages',
|
|
97
|
+
'src/stores',
|
|
98
|
+
'src/api',
|
|
99
|
+
'src/types',
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
for (const dir of dirs) {
|
|
103
|
+
const fullDir = path.join(outputDir, dir);
|
|
104
|
+
mkdirSafe(fullDir);
|
|
105
|
+
dirsCreated.push(fullDir);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const files: Record<string, string> = {
|
|
109
|
+
'src/components/ErrorBoundary.vue': vueErrorBoundaryTemplate(),
|
|
110
|
+
'src/components/LoadingSpinner.vue': vueLoadingSpinnerTemplate(),
|
|
111
|
+
'src/composables/useFetch.ts': vueUseFetchTemplate(),
|
|
112
|
+
'src/pages/NotFoundPage.vue': vueNotFoundPageTemplate(),
|
|
113
|
+
'src/api/client.ts': vueApiClientTemplate(),
|
|
114
|
+
'src/api/endpoints.ts': vueEndpointsTemplate(),
|
|
115
|
+
'src/stores/app.ts': vuePiniaStoreTemplate(projectName),
|
|
116
|
+
'src/types/index.ts': vueTypesTemplate(),
|
|
117
|
+
'src/App.vue': vueAppTemplate(projectName),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
for (const [relPath, content] of Object.entries(files)) {
|
|
121
|
+
const fullPath = path.join(outputDir, relPath);
|
|
122
|
+
fs.writeFileSync(fullPath, content, 'utf-8');
|
|
123
|
+
filesCreated.push(fullPath);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function mkdirSafe(dir: string): void {
|
|
128
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// React templates
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
function reactErrorBoundaryTemplate(): string {
|
|
136
|
+
return `/**
|
|
137
|
+
* ErrorBoundary — wraps children and catches render errors.
|
|
138
|
+
* DARE Frontend Design: every page must have an error boundary.
|
|
139
|
+
*/
|
|
140
|
+
import { useState, useEffect, type ReactNode } from 'react';
|
|
141
|
+
|
|
142
|
+
interface ErrorBoundaryProps {
|
|
143
|
+
children: ReactNode;
|
|
144
|
+
fallback?: ReactNode;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function ErrorBoundary({ children, fallback }: ErrorBoundaryProps) {
|
|
148
|
+
const [hasError, setHasError] = useState(false);
|
|
149
|
+
const [error, setError] = useState<Error | null>(null);
|
|
150
|
+
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
const handler = (event: ErrorEvent) => {
|
|
153
|
+
setHasError(true);
|
|
154
|
+
setError(event.error as Error);
|
|
155
|
+
};
|
|
156
|
+
window.addEventListener('error', handler);
|
|
157
|
+
return () => window.removeEventListener('error', handler);
|
|
158
|
+
}, []);
|
|
159
|
+
|
|
160
|
+
if (hasError) {
|
|
161
|
+
return (
|
|
162
|
+
fallback ?? (
|
|
163
|
+
<div role="alert" style={{ padding: '1rem', color: 'red' }}>
|
|
164
|
+
<h2>Something went wrong</h2>
|
|
165
|
+
{error && <pre style={{ fontSize: '0.8rem' }}>{error.message}</pre>}
|
|
166
|
+
</div>
|
|
167
|
+
)
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return <>{children}</>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export default ErrorBoundary;
|
|
175
|
+
`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function reactLoadingSpinnerTemplate(): string {
|
|
179
|
+
return `/**
|
|
180
|
+
* LoadingSpinner — accessible loading indicator.
|
|
181
|
+
*/
|
|
182
|
+
interface LoadingSpinnerProps {
|
|
183
|
+
label?: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function LoadingSpinner({ label = 'Loading...' }: LoadingSpinnerProps) {
|
|
187
|
+
return (
|
|
188
|
+
<div role="status" aria-label={label} style={{ textAlign: 'center', padding: '1rem' }}>
|
|
189
|
+
<span aria-hidden="true">⏳</span>
|
|
190
|
+
<span className="sr-only">{label}</span>
|
|
191
|
+
</div>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export default LoadingSpinner;
|
|
196
|
+
`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function reactUseFetchTemplate(): string {
|
|
200
|
+
return `/**
|
|
201
|
+
* useFetch — generic data fetching hook.
|
|
202
|
+
* DARE Frontend Design: all API calls isolated in custom hooks.
|
|
203
|
+
*/
|
|
204
|
+
import { useState, useEffect } from 'react';
|
|
205
|
+
|
|
206
|
+
type FetchState<T> =
|
|
207
|
+
| { status: 'idle' }
|
|
208
|
+
| { status: 'loading' }
|
|
209
|
+
| { status: 'success'; data: T }
|
|
210
|
+
| { status: 'error'; message: string };
|
|
211
|
+
|
|
212
|
+
export function useFetch<T>(url: string | null): FetchState<T> {
|
|
213
|
+
const [state, setState] = useState<FetchState<T>>({ status: 'idle' });
|
|
214
|
+
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
if (!url) return;
|
|
217
|
+
|
|
218
|
+
let cancelled = false;
|
|
219
|
+
setState({ status: 'loading' });
|
|
220
|
+
|
|
221
|
+
fetch(url)
|
|
222
|
+
.then((res) => {
|
|
223
|
+
if (!res.ok) throw new Error(\`HTTP \${res.status}: \${res.statusText}\`);
|
|
224
|
+
return res.json() as Promise<T>;
|
|
225
|
+
})
|
|
226
|
+
.then((data) => {
|
|
227
|
+
if (!cancelled) setState({ status: 'success', data });
|
|
228
|
+
})
|
|
229
|
+
.catch((err: unknown) => {
|
|
230
|
+
if (!cancelled) {
|
|
231
|
+
setState({ status: 'error', message: err instanceof Error ? err.message : String(err) });
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
return () => {
|
|
236
|
+
cancelled = true;
|
|
237
|
+
};
|
|
238
|
+
}, [url]);
|
|
239
|
+
|
|
240
|
+
return state;
|
|
241
|
+
}
|
|
242
|
+
`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function reactNotFoundPageTemplate(): string {
|
|
246
|
+
return `/**
|
|
247
|
+
* NotFoundPage — 404 page with error boundary.
|
|
248
|
+
* DARE Frontend Design: each page wrapped in ErrorBoundary.
|
|
249
|
+
*/
|
|
250
|
+
import ErrorBoundary from '../components/ErrorBoundary';
|
|
251
|
+
|
|
252
|
+
export function NotFoundPage() {
|
|
253
|
+
return (
|
|
254
|
+
<ErrorBoundary>
|
|
255
|
+
<main role="main" style={{ textAlign: 'center', padding: '2rem' }}>
|
|
256
|
+
<h1>404 — Page Not Found</h1>
|
|
257
|
+
<p>The page you are looking for does not exist.</p>
|
|
258
|
+
<a href="/">Go home</a>
|
|
259
|
+
</main>
|
|
260
|
+
</ErrorBoundary>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export default NotFoundPage;
|
|
265
|
+
`;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function reactApiClientTemplate(): string {
|
|
269
|
+
return `/**
|
|
270
|
+
* API client — wraps fetch with auth headers.
|
|
271
|
+
* DARE Frontend Design: centralized API layer (no direct fetch in components).
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
const BASE_URL = import.meta.env.VITE_API_URL ?? '/api/v1';
|
|
275
|
+
|
|
276
|
+
export async function apiGet<T>(path: string): Promise<T> {
|
|
277
|
+
const res = await fetch(\`\${BASE_URL}\${path}\`, {
|
|
278
|
+
headers: getHeaders(),
|
|
279
|
+
});
|
|
280
|
+
if (!res.ok) throw new Error(\`GET \${path} failed: \${res.status}\`);
|
|
281
|
+
return res.json() as Promise<T>;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export async function apiPost<T>(path: string, body: unknown): Promise<T> {
|
|
285
|
+
const res = await fetch(\`\${BASE_URL}\${path}\`, {
|
|
286
|
+
method: 'POST',
|
|
287
|
+
headers: { ...getHeaders(), 'Content-Type': 'application/json' },
|
|
288
|
+
body: JSON.stringify(body),
|
|
289
|
+
});
|
|
290
|
+
if (!res.ok) throw new Error(\`POST \${path} failed: \${res.status}\`);
|
|
291
|
+
return res.json() as Promise<T>;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function getHeaders(): Record<string, string> {
|
|
295
|
+
const token = sessionStorage.getItem('auth_token');
|
|
296
|
+
return token ? { Authorization: \`Bearer \${token}\` } : {};
|
|
297
|
+
}
|
|
298
|
+
`;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function reactEndpointsTemplate(): string {
|
|
302
|
+
return `/**
|
|
303
|
+
* API endpoints — type-safe endpoint definitions.
|
|
304
|
+
* DARE Frontend Design: endpoints from OpenAPI spec centralized here.
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
export const ENDPOINTS = {
|
|
308
|
+
// Replace with actual endpoints from OpenAPI spec
|
|
309
|
+
users: {
|
|
310
|
+
list: '/users',
|
|
311
|
+
detail: (id: string) => \`/users/\${id}\`,
|
|
312
|
+
create: '/users',
|
|
313
|
+
delete: (id: string) => \`/users/\${id}\`,
|
|
314
|
+
},
|
|
315
|
+
} as const;
|
|
316
|
+
`;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function reactStoreTemplate(): string {
|
|
320
|
+
return `/**
|
|
321
|
+
* Global store configuration.
|
|
322
|
+
* DARE Frontend Design: global state centralized (Redux/Zustand/etc).
|
|
323
|
+
* Replace with your chosen state management library.
|
|
324
|
+
*/
|
|
325
|
+
|
|
326
|
+
// Minimal store using React context (replace with Redux/Zustand if needed)
|
|
327
|
+
import { createContext, useContext, useState, type ReactNode } from 'react';
|
|
328
|
+
|
|
329
|
+
interface AppState {
|
|
330
|
+
user: { id: string; name: string } | null;
|
|
331
|
+
setUser: (user: { id: string; name: string } | null) => void;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const AppContext = createContext<AppState | null>(null);
|
|
335
|
+
|
|
336
|
+
export function AppProvider({ children }: { children: ReactNode }) {
|
|
337
|
+
const [user, setUser] = useState<{ id: string; name: string } | null>(null);
|
|
338
|
+
return <AppContext.Provider value={{ user, setUser }}>{children}</AppContext.Provider>;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export function useAppStore(): AppState {
|
|
342
|
+
const ctx = useContext(AppContext);
|
|
343
|
+
if (!ctx) throw new Error('useAppStore must be used within AppProvider');
|
|
344
|
+
return ctx;
|
|
345
|
+
}
|
|
346
|
+
`;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function reactTypesTemplate(): string {
|
|
350
|
+
return `/**
|
|
351
|
+
* Shared TypeScript types.
|
|
352
|
+
* DARE Frontend Design: all types explicit (strict mode).
|
|
353
|
+
*/
|
|
354
|
+
|
|
355
|
+
export interface ApiError {
|
|
356
|
+
status: number;
|
|
357
|
+
message: string;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export interface PaginatedResponse<T> {
|
|
361
|
+
data: T[];
|
|
362
|
+
total: number;
|
|
363
|
+
page: number;
|
|
364
|
+
perPage: number;
|
|
365
|
+
}
|
|
366
|
+
`;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function reactAppTemplate(projectName: string): string {
|
|
370
|
+
return `/**
|
|
371
|
+
* ${projectName} — App entry point.
|
|
372
|
+
* DARE Frontend Design: router setup with error boundaries.
|
|
373
|
+
*/
|
|
374
|
+
import { ErrorBoundary } from './components/ErrorBoundary';
|
|
375
|
+
import { NotFoundPage } from './pages/NotFoundPage';
|
|
376
|
+
|
|
377
|
+
export function App() {
|
|
378
|
+
return (
|
|
379
|
+
<ErrorBoundary>
|
|
380
|
+
<div id="app">
|
|
381
|
+
{/* Router setup here (React Router, TanStack Router, etc.) */}
|
|
382
|
+
<NotFoundPage />
|
|
383
|
+
</div>
|
|
384
|
+
</ErrorBoundary>
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export default App;
|
|
389
|
+
`;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function cssGlobalsTemplate(): string {
|
|
393
|
+
return `/* Global styles — DARE Frontend Design */
|
|
394
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
395
|
+
body { margin: 0; font-family: system-ui, sans-serif; }
|
|
396
|
+
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
|
|
397
|
+
`;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// ---------------------------------------------------------------------------
|
|
401
|
+
// Vue templates
|
|
402
|
+
// ---------------------------------------------------------------------------
|
|
403
|
+
|
|
404
|
+
function vueErrorBoundaryTemplate(): string {
|
|
405
|
+
return `<script setup lang="ts">
|
|
406
|
+
/**
|
|
407
|
+
* ErrorBoundary.vue — wraps slot content and catches errors.
|
|
408
|
+
* DARE Frontend Design: every page must have an error boundary.
|
|
409
|
+
*/
|
|
410
|
+
import { ref, onErrorCaptured } from 'vue';
|
|
411
|
+
|
|
412
|
+
const hasError = ref(false);
|
|
413
|
+
const errorMessage = ref('');
|
|
414
|
+
|
|
415
|
+
onErrorCaptured((err: Error) => {
|
|
416
|
+
hasError.value = true;
|
|
417
|
+
errorMessage.value = err.message;
|
|
418
|
+
return false; // prevent propagation
|
|
419
|
+
});
|
|
420
|
+
</script>
|
|
421
|
+
|
|
422
|
+
<template>
|
|
423
|
+
<div v-if="hasError" role="alert" class="error-boundary">
|
|
424
|
+
<h2>Something went wrong</h2>
|
|
425
|
+
<pre>{{ errorMessage }}</pre>
|
|
426
|
+
</div>
|
|
427
|
+
<slot v-else />
|
|
428
|
+
</template>
|
|
429
|
+
`;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function vueLoadingSpinnerTemplate(): string {
|
|
433
|
+
return `<script setup lang="ts">
|
|
434
|
+
/**
|
|
435
|
+
* LoadingSpinner.vue — accessible loading indicator.
|
|
436
|
+
*/
|
|
437
|
+
defineProps<{ label?: string }>();
|
|
438
|
+
</script>
|
|
439
|
+
|
|
440
|
+
<template>
|
|
441
|
+
<div role="status" :aria-label="label ?? 'Loading...'" class="loading-spinner">
|
|
442
|
+
<span aria-hidden="true">⏳</span>
|
|
443
|
+
<span class="sr-only">{{ label ?? 'Loading...' }}</span>
|
|
444
|
+
</div>
|
|
445
|
+
</template>
|
|
446
|
+
`;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function vueUseFetchTemplate(): string {
|
|
450
|
+
return `/**
|
|
451
|
+
* useFetch.ts — generic data fetching composable.
|
|
452
|
+
* DARE Frontend Design: all API calls isolated in composables.
|
|
453
|
+
*/
|
|
454
|
+
import { ref, watchEffect, type Ref } from 'vue';
|
|
455
|
+
|
|
456
|
+
type FetchStatus = 'idle' | 'loading' | 'success' | 'error';
|
|
457
|
+
|
|
458
|
+
export function useFetch<T>(url: Ref<string | null>) {
|
|
459
|
+
const status = ref<FetchStatus>('idle');
|
|
460
|
+
const data = ref<T | null>(null);
|
|
461
|
+
const error = ref<string | null>(null);
|
|
462
|
+
|
|
463
|
+
watchEffect((onCleanup) => {
|
|
464
|
+
if (!url.value) return;
|
|
465
|
+
|
|
466
|
+
let cancelled = false;
|
|
467
|
+
status.value = 'loading';
|
|
468
|
+
error.value = null;
|
|
469
|
+
|
|
470
|
+
fetch(url.value)
|
|
471
|
+
.then((res) => {
|
|
472
|
+
if (!res.ok) throw new Error(\`HTTP \${res.status}\`);
|
|
473
|
+
return res.json() as Promise<T>;
|
|
474
|
+
})
|
|
475
|
+
.then((result) => {
|
|
476
|
+
if (!cancelled) {
|
|
477
|
+
data.value = result;
|
|
478
|
+
status.value = 'success';
|
|
479
|
+
}
|
|
480
|
+
})
|
|
481
|
+
.catch((err: unknown) => {
|
|
482
|
+
if (!cancelled) {
|
|
483
|
+
error.value = err instanceof Error ? err.message : String(err);
|
|
484
|
+
status.value = 'error';
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
onCleanup(() => { cancelled = true; });
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
return { status, data, error };
|
|
492
|
+
}
|
|
493
|
+
`;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function vueNotFoundPageTemplate(): string {
|
|
497
|
+
return `<script setup lang="ts">
|
|
498
|
+
/**
|
|
499
|
+
* NotFoundPage.vue — 404 page with error boundary.
|
|
500
|
+
* DARE Frontend Design: each page wrapped in ErrorBoundary.
|
|
501
|
+
*/
|
|
502
|
+
import ErrorBoundary from '../components/ErrorBoundary.vue';
|
|
503
|
+
</script>
|
|
504
|
+
|
|
505
|
+
<template>
|
|
506
|
+
<ErrorBoundary>
|
|
507
|
+
<main role="main" style="text-align: center; padding: 2rem">
|
|
508
|
+
<h1>404 — Page Not Found</h1>
|
|
509
|
+
<p>The page you are looking for does not exist.</p>
|
|
510
|
+
<a href="/">Go home</a>
|
|
511
|
+
</main>
|
|
512
|
+
</ErrorBoundary>
|
|
513
|
+
</template>
|
|
514
|
+
`;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function vueApiClientTemplate(): string {
|
|
518
|
+
return `/**
|
|
519
|
+
* API client — wraps fetch with auth headers.
|
|
520
|
+
* DARE Frontend Design: centralized API layer.
|
|
521
|
+
*/
|
|
522
|
+
|
|
523
|
+
const BASE_URL = import.meta.env.VITE_API_URL ?? '/api/v1';
|
|
524
|
+
|
|
525
|
+
export async function apiGet<T>(path: string): Promise<T> {
|
|
526
|
+
const res = await fetch(\`\${BASE_URL}\${path}\`, { headers: getHeaders() });
|
|
527
|
+
if (!res.ok) throw new Error(\`GET \${path} failed: \${res.status}\`);
|
|
528
|
+
return res.json() as Promise<T>;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
export async function apiPost<T>(path: string, body: unknown): Promise<T> {
|
|
532
|
+
const res = await fetch(\`\${BASE_URL}\${path}\`, {
|
|
533
|
+
method: 'POST',
|
|
534
|
+
headers: { ...getHeaders(), 'Content-Type': 'application/json' },
|
|
535
|
+
body: JSON.stringify(body),
|
|
536
|
+
});
|
|
537
|
+
if (!res.ok) throw new Error(\`POST \${path} failed: \${res.status}\`);
|
|
538
|
+
return res.json() as Promise<T>;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function getHeaders(): Record<string, string> {
|
|
542
|
+
const token = sessionStorage.getItem('auth_token');
|
|
543
|
+
return token ? { Authorization: \`Bearer \${token}\` } : {};
|
|
544
|
+
}
|
|
545
|
+
`;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function vueEndpointsTemplate(): string {
|
|
549
|
+
return `/**
|
|
550
|
+
* API endpoints — type-safe endpoint definitions.
|
|
551
|
+
*/
|
|
552
|
+
export const ENDPOINTS = {
|
|
553
|
+
users: {
|
|
554
|
+
list: '/users',
|
|
555
|
+
detail: (id: string) => \`/users/\${id}\`,
|
|
556
|
+
},
|
|
557
|
+
} as const;
|
|
558
|
+
`;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function vuePiniaStoreTemplate(projectName: string): string {
|
|
562
|
+
return `/**
|
|
563
|
+
* ${projectName} — Pinia store.
|
|
564
|
+
* DARE Frontend Design: global state via stores.
|
|
565
|
+
*/
|
|
566
|
+
import { defineStore } from 'pinia';
|
|
567
|
+
import { ref } from 'vue';
|
|
568
|
+
|
|
569
|
+
export const useAppStore = defineStore('app', () => {
|
|
570
|
+
const user = ref<{ id: string; name: string } | null>(null);
|
|
571
|
+
|
|
572
|
+
function setUser(newUser: { id: string; name: string } | null) {
|
|
573
|
+
user.value = newUser;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return { user, setUser };
|
|
577
|
+
});
|
|
578
|
+
`;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
function vueTypesTemplate(): string {
|
|
582
|
+
return `/**
|
|
583
|
+
* Shared TypeScript types.
|
|
584
|
+
*/
|
|
585
|
+
export interface ApiError {
|
|
586
|
+
status: number;
|
|
587
|
+
message: string;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
export interface PaginatedResponse<T> {
|
|
591
|
+
data: T[];
|
|
592
|
+
total: number;
|
|
593
|
+
page: number;
|
|
594
|
+
perPage: number;
|
|
595
|
+
}
|
|
596
|
+
`;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
function vueAppTemplate(projectName: string): string {
|
|
600
|
+
return `<script setup lang="ts">
|
|
601
|
+
/**
|
|
602
|
+
* ${projectName} — App.vue entry point.
|
|
603
|
+
* DARE Frontend Design: router-view with error boundary.
|
|
604
|
+
*/
|
|
605
|
+
import ErrorBoundary from './components/ErrorBoundary.vue';
|
|
606
|
+
</script>
|
|
607
|
+
|
|
608
|
+
<template>
|
|
609
|
+
<ErrorBoundary>
|
|
610
|
+
<div id="app">
|
|
611
|
+
<!-- RouterView here once Vue Router is set up -->
|
|
612
|
+
</div>
|
|
613
|
+
</ErrorBoundary>
|
|
614
|
+
</template>
|
|
615
|
+
`;
|
|
616
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dare-frontend-design — public API
|
|
3
|
+
* License: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Types
|
|
7
|
+
export type {
|
|
8
|
+
Framework,
|
|
9
|
+
LinterViolation,
|
|
10
|
+
LinterRule,
|
|
11
|
+
LinterResult,
|
|
12
|
+
ScaffoldOptions,
|
|
13
|
+
ScaffoldResult,
|
|
14
|
+
MetricResult,
|
|
15
|
+
FrontendMetricsInput,
|
|
16
|
+
} from './types.js';
|
|
17
|
+
|
|
18
|
+
// Linter
|
|
19
|
+
export { FrontendLinter } from './linter.js';
|
|
20
|
+
|
|
21
|
+
// Generator
|
|
22
|
+
export { FrontendGenerator } from './generator.js';
|
|
23
|
+
|
|
24
|
+
// Metrics
|
|
25
|
+
export { collectFrontendMetrics } from './metrics.js';
|