@dewtech/dare-cli 2.16.0 → 3.0.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 +196 -3
- package/dist/__tests__/confidence.test.d.ts +2 -0
- package/dist/__tests__/confidence.test.d.ts.map +1 -0
- package/dist/__tests__/confidence.test.js +73 -0
- package/dist/__tests__/confidence.test.js.map +1 -0
- package/dist/__tests__/datamodel.test.d.ts +2 -0
- package/dist/__tests__/datamodel.test.d.ts.map +1 -0
- package/dist/__tests__/datamodel.test.js +131 -0
- package/dist/__tests__/datamodel.test.js.map +1 -0
- package/dist/__tests__/dna-detector.test.d.ts +2 -0
- package/dist/__tests__/dna-detector.test.d.ts.map +1 -0
- package/dist/__tests__/dna-detector.test.js +97 -0
- package/dist/__tests__/dna-detector.test.js.map +1 -0
- package/dist/__tests__/dna-facts.test.d.ts +2 -0
- package/dist/__tests__/dna-facts.test.d.ts.map +1 -0
- package/dist/__tests__/dna-facts.test.js +44 -0
- package/dist/__tests__/dna-facts.test.js.map +1 -0
- package/dist/__tests__/graph-renderer.test.d.ts +2 -0
- package/dist/__tests__/graph-renderer.test.d.ts.map +1 -0
- package/dist/__tests__/graph-renderer.test.js +85 -0
- package/dist/__tests__/graph-renderer.test.js.map +1 -0
- package/dist/__tests__/migration.test.d.ts +2 -0
- package/dist/__tests__/migration.test.d.ts.map +1 -0
- package/dist/__tests__/migration.test.js +77 -0
- package/dist/__tests__/migration.test.js.map +1 -0
- package/dist/__tests__/module-detector.test.d.ts +2 -0
- package/dist/__tests__/module-detector.test.d.ts.map +1 -0
- package/dist/__tests__/module-detector.test.js +83 -0
- package/dist/__tests__/module-detector.test.js.map +1 -0
- package/dist/__tests__/refine.test.d.ts +2 -0
- package/dist/__tests__/refine.test.d.ts.map +1 -0
- package/dist/__tests__/refine.test.js +186 -0
- package/dist/__tests__/refine.test.js.map +1 -0
- package/dist/__tests__/reverse-facts.test.d.ts +2 -0
- package/dist/__tests__/reverse-facts.test.d.ts.map +1 -0
- package/dist/__tests__/reverse-facts.test.js +78 -0
- package/dist/__tests__/reverse-facts.test.js.map +1 -0
- package/dist/__tests__/review.test.d.ts +2 -0
- package/dist/__tests__/review.test.d.ts.map +1 -0
- package/dist/__tests__/review.test.js +242 -0
- package/dist/__tests__/review.test.js.map +1 -0
- package/dist/__tests__/update.test.d.ts +2 -0
- package/dist/__tests__/update.test.d.ts.map +1 -0
- package/dist/__tests__/update.test.js +150 -0
- package/dist/__tests__/update.test.js.map +1 -0
- package/dist/__tests__/validate.test.js +65 -65
- package/dist/bin/dare.js +38 -3
- package/dist/bin/dare.js.map +1 -1
- package/dist/commands/blueprint.js +122 -122
- package/dist/commands/dag.d.ts.map +1 -1
- package/dist/commands/dag.js +43 -79
- package/dist/commands/dag.js.map +1 -1
- package/dist/commands/dna.d.ts +3 -0
- package/dist/commands/dna.d.ts.map +1 -0
- package/dist/commands/dna.js +69 -0
- package/dist/commands/dna.js.map +1 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +76 -0
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +101 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/new.d.ts +16 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +103 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/refine.d.ts +16 -0
- package/dist/commands/refine.d.ts.map +1 -0
- package/dist/commands/refine.js +167 -0
- package/dist/commands/refine.js.map +1 -0
- package/dist/commands/reverse.d.ts +3 -0
- package/dist/commands/reverse.d.ts.map +1 -0
- package/dist/commands/reverse.js +201 -0
- package/dist/commands/reverse.js.map +1 -0
- package/dist/commands/review.d.ts +16 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +106 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/update.d.ts +13 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +149 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/welcome.d.ts +14 -0
- package/dist/commands/welcome.d.ts.map +1 -0
- package/dist/commands/welcome.js +29 -0
- package/dist/commands/welcome.js.map +1 -0
- package/dist/skills/commands/add.d.ts +23 -0
- package/dist/skills/commands/add.d.ts.map +1 -0
- package/dist/skills/commands/add.js +206 -0
- package/dist/skills/commands/add.js.map +1 -0
- package/dist/skills/commands/info.d.ts +14 -0
- package/dist/skills/commands/info.d.ts.map +1 -0
- package/dist/skills/commands/info.js +99 -0
- package/dist/skills/commands/info.js.map +1 -0
- package/dist/skills/commands/list.d.ts +19 -0
- package/dist/skills/commands/list.d.ts.map +1 -0
- package/dist/skills/commands/list.js +163 -0
- package/dist/skills/commands/list.js.map +1 -0
- package/dist/skills/commands/publish.d.ts +56 -0
- package/dist/skills/commands/publish.d.ts.map +1 -0
- package/dist/skills/commands/publish.js +272 -0
- package/dist/skills/commands/publish.js.map +1 -0
- package/dist/skills/commands/remove.d.ts +19 -0
- package/dist/skills/commands/remove.d.ts.map +1 -0
- package/dist/skills/commands/remove.js +96 -0
- package/dist/skills/commands/remove.js.map +1 -0
- package/dist/skills/commands/update.d.ts +31 -0
- package/dist/skills/commands/update.d.ts.map +1 -0
- package/dist/skills/commands/update.js +132 -0
- package/dist/skills/commands/update.js.map +1 -0
- package/dist/skills/index.d.ts +22 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +33 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/manifest.d.ts +54 -0
- package/dist/skills/manifest.d.ts.map +1 -0
- package/dist/skills/manifest.js +162 -0
- package/dist/skills/manifest.js.map +1 -0
- package/dist/skills/registry-local.d.ts +67 -0
- package/dist/skills/registry-local.d.ts.map +1 -0
- package/dist/skills/registry-local.js +130 -0
- package/dist/skills/registry-local.js.map +1 -0
- package/dist/skills/registry-mock.json +109 -0
- package/dist/skills/registry-remote.d.ts +110 -0
- package/dist/skills/registry-remote.d.ts.map +1 -0
- package/dist/skills/registry-remote.js +246 -0
- package/dist/skills/registry-remote.js.map +1 -0
- package/dist/skills/registry.d.ts +49 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +94 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/tests/manifest.spec.d.ts +8 -0
- package/dist/skills/tests/manifest.spec.d.ts.map +1 -0
- package/dist/skills/tests/manifest.spec.js +176 -0
- package/dist/skills/tests/manifest.spec.js.map +1 -0
- package/dist/skills/tests/publish.spec.d.ts +12 -0
- package/dist/skills/tests/publish.spec.d.ts.map +1 -0
- package/dist/skills/tests/publish.spec.js +276 -0
- package/dist/skills/tests/publish.spec.js.map +1 -0
- package/dist/skills/tests/registry-local.spec.d.ts +8 -0
- package/dist/skills/tests/registry-local.spec.d.ts.map +1 -0
- package/dist/skills/tests/registry-local.spec.js +231 -0
- package/dist/skills/tests/registry-local.spec.js.map +1 -0
- package/dist/skills/tests/registry.spec.d.ts +7 -0
- package/dist/skills/tests/registry.spec.d.ts.map +1 -0
- package/dist/skills/tests/registry.spec.js +58 -0
- package/dist/skills/tests/registry.spec.js.map +1 -0
- package/dist/skills/tests/remote-registry.spec.d.ts +9 -0
- package/dist/skills/tests/remote-registry.spec.d.ts.map +1 -0
- package/dist/skills/tests/remote-registry.spec.js +357 -0
- package/dist/skills/tests/remote-registry.spec.js.map +1 -0
- package/dist/skills/tests/update.spec.d.ts +9 -0
- package/dist/skills/tests/update.spec.d.ts.map +1 -0
- package/dist/skills/tests/update.spec.js +166 -0
- package/dist/skills/tests/update.spec.js.map +1 -0
- package/dist/types/Refine.types.d.ts +96 -0
- package/dist/types/Refine.types.d.ts.map +1 -0
- package/dist/types/Refine.types.js +19 -0
- package/dist/types/Refine.types.js.map +1 -0
- package/dist/types/Review.types.d.ts +86 -0
- package/dist/types/Review.types.d.ts.map +1 -0
- package/dist/types/Review.types.js +15 -0
- package/dist/types/Review.types.js.map +1 -0
- package/dist/types/UpdateManifest.types.d.ts +91 -0
- package/dist/types/UpdateManifest.types.d.ts.map +1 -0
- package/dist/types/UpdateManifest.types.js +13 -0
- package/dist/types/UpdateManifest.types.js.map +1 -0
- package/dist/utils/ReviewRunner.d.ts +42 -0
- package/dist/utils/ReviewRunner.d.ts.map +1 -0
- package/dist/utils/ReviewRunner.js +175 -0
- package/dist/utils/ReviewRunner.js.map +1 -0
- package/dist/utils/UpdateApplier.d.ts +42 -0
- package/dist/utils/UpdateApplier.d.ts.map +1 -0
- package/dist/utils/UpdateApplier.js +207 -0
- package/dist/utils/UpdateApplier.js.map +1 -0
- package/dist/utils/UpdateDetector.d.ts +56 -0
- package/dist/utils/UpdateDetector.d.ts.map +1 -0
- package/dist/utils/UpdateDetector.js +164 -0
- package/dist/utils/UpdateDetector.js.map +1 -0
- package/dist/utils/banner.d.ts +28 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +77 -0
- package/dist/utils/banner.js.map +1 -0
- package/dist/utils/banner.spec.d.ts +5 -0
- package/dist/utils/banner.spec.d.ts.map +1 -0
- package/dist/utils/banner.spec.js +253 -0
- package/dist/utils/banner.spec.js.map +1 -0
- package/dist/utils/complexity-analyzer.d.ts +60 -0
- package/dist/utils/complexity-analyzer.d.ts.map +1 -0
- package/dist/utils/complexity-analyzer.js +292 -0
- package/dist/utils/complexity-analyzer.js.map +1 -0
- package/dist/utils/confidence.d.ts +41 -0
- package/dist/utils/confidence.d.ts.map +1 -0
- package/dist/utils/confidence.js +101 -0
- package/dist/utils/confidence.js.map +1 -0
- package/dist/utils/datamodel.d.ts +41 -0
- package/dist/utils/datamodel.d.ts.map +1 -0
- package/dist/utils/datamodel.js +535 -0
- package/dist/utils/datamodel.js.map +1 -0
- package/dist/utils/dna-detector.d.ts +61 -0
- package/dist/utils/dna-detector.d.ts.map +1 -0
- package/dist/utils/dna-detector.js +354 -0
- package/dist/utils/dna-detector.js.map +1 -0
- package/dist/utils/dna-facts.d.ts +13 -0
- package/dist/utils/dna-facts.d.ts.map +1 -0
- package/dist/utils/dna-facts.js +109 -0
- package/dist/utils/dna-facts.js.map +1 -0
- package/dist/utils/excalidraw-renderer.d.ts +11 -71
- package/dist/utils/excalidraw-renderer.d.ts.map +1 -1
- package/dist/utils/excalidraw-renderer.js +29 -162
- package/dist/utils/excalidraw-renderer.js.map +1 -1
- package/dist/utils/graph-renderer.d.ts +115 -0
- package/dist/utils/graph-renderer.d.ts.map +1 -0
- package/dist/utils/graph-renderer.js +216 -0
- package/dist/utils/graph-renderer.js.map +1 -0
- package/dist/utils/migration.d.ts +64 -0
- package/dist/utils/migration.d.ts.map +1 -0
- package/dist/utils/migration.js +183 -0
- package/dist/utils/migration.js.map +1 -0
- package/dist/utils/module-detector.d.ts +46 -0
- package/dist/utils/module-detector.d.ts.map +1 -0
- package/dist/utils/module-detector.js +348 -0
- package/dist/utils/module-detector.js.map +1 -0
- package/dist/utils/project-generator.d.ts.map +1 -1
- package/dist/utils/project-generator.js +273 -254
- package/dist/utils/project-generator.js.map +1 -1
- package/dist/utils/reverse-facts.d.ts +50 -0
- package/dist/utils/reverse-facts.d.ts.map +1 -0
- package/dist/utils/reverse-facts.js +291 -0
- package/dist/utils/reverse-facts.js.map +1 -0
- package/dist/utils/stack-bootstrap.js +371 -371
- package/dist/utils/static-analyzer.d.ts +29 -0
- package/dist/utils/static-analyzer.d.ts.map +1 -0
- package/dist/utils/static-analyzer.js +390 -0
- package/dist/utils/static-analyzer.js.map +1 -0
- package/dist/utils/version-compare.d.ts +27 -0
- package/dist/utils/version-compare.d.ts.map +1 -0
- package/dist/utils/version-compare.js +47 -0
- package/dist/utils/version-compare.js.map +1 -0
- package/package.json +8 -3
- package/templates/DARE-dag-example.yaml +280 -280
- package/templates/UPDATE-MANIFEST.json +48 -0
- package/templates/backend/node-nestjs/.env.example +9 -9
- package/templates/backend/node-nestjs/nest-cli.json +8 -8
- package/templates/backend/node-nestjs/package.json +50 -50
- package/templates/backend/node-nestjs/src/app.controller.ts +12 -12
- package/templates/backend/node-nestjs/src/app.module.ts +15 -15
- package/templates/backend/node-nestjs/src/app.service.ts +8 -8
- package/templates/backend/node-nestjs/src/main.ts +24 -24
- package/templates/backend/node-nestjs/tsconfig.json +21 -21
- package/templates/backend/php-laravel/.env.example +22 -22
- package/templates/backend/php-laravel/app/Http/Controllers/HealthController.php +15 -15
- package/templates/backend/php-laravel/composer.json +40 -40
- package/templates/backend/python-fastapi/.env.example +4 -4
- package/templates/backend/python-fastapi/app/api/router.py +8 -8
- package/templates/backend/python-fastapi/app/core/config.py +20 -20
- package/templates/backend/python-fastapi/main.py +35 -35
- package/templates/backend/python-fastapi/requirements.txt +13 -13
- package/templates/backend/rust-axum/.env.example +3 -3
- package/templates/backend/rust-axum/Cargo.toml +23 -23
- package/templates/backend/rust-axum/src/errors.rs +30 -30
- package/templates/backend/rust-axum/src/main.rs +32 -32
- package/templates/backend/rust-axum/src/routes.rs +6 -6
- package/templates/frontend/leptos-csr/.cargo/config.toml +2 -2
- package/templates/frontend/leptos-csr/Cargo.toml +16 -16
- package/templates/frontend/leptos-csr/Trunk.toml +10 -10
- package/templates/frontend/leptos-csr/index.html +11 -11
- package/templates/frontend/leptos-csr/src/lib.rs +20 -20
- package/templates/frontend/leptos-csr/style/main.scss +19 -19
- package/templates/frontend/leptos-fullstack/.cargo/config.toml +4 -4
- package/templates/frontend/leptos-fullstack/Cargo.toml +56 -56
- package/templates/frontend/leptos-fullstack/src/app.rs +49 -49
- package/templates/frontend/leptos-fullstack/src/lib.rs +9 -9
- package/templates/frontend/leptos-fullstack/src/main.rs +29 -29
- package/templates/frontend/leptos-fullstack/style/main.scss +19 -19
- package/templates/frontend/react/index.html +12 -12
- package/templates/frontend/react/package.json +35 -35
- package/templates/frontend/react/src/App.tsx +25 -25
- package/templates/frontend/react/src/main.tsx +9 -9
- package/templates/frontend/vue/package.json +32 -32
- package/templates/frontend/vue/src/App.vue +7 -7
- package/templates/frontend/vue/src/main.ts +10 -10
- package/templates/frontend/vue/src/router/index.ts +14 -14
- package/templates/frontend/vue/src/views/HomeView.vue +6 -6
- package/templates/hooks/pre-commit-dare-validate +24 -24
- package/templates/ide/antigravity/.agents/skills/dare-ax/SKILL.md +152 -0
- package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +180 -36
- package/templates/ide/antigravity/.agents/skills/dare-dag-build/SKILL.md +154 -0
- package/templates/ide/antigravity/.agents/skills/dare-dag-run/SKILL.md +130 -0
- package/templates/ide/antigravity/.agents/skills/dare-dag-runner/SKILL.md +203 -203
- package/templates/ide/antigravity/.agents/skills/dare-dna/SKILL.md +63 -0
- package/templates/ide/antigravity/.agents/skills/dare-docker/SKILL.md +315 -0
- package/templates/ide/antigravity/.agents/skills/dare-frontend-design/SKILL.md +192 -0
- package/templates/ide/antigravity/.agents/skills/dare-laravel-api/SKILL.md +337 -0
- package/templates/ide/antigravity/.agents/skills/dare-layered-design/SKILL.md +166 -0
- package/templates/ide/antigravity/.agents/skills/dare-llm-integration/SKILL.md +217 -0
- package/templates/ide/antigravity/.agents/skills/dare-migrate/SKILL.md +61 -0
- package/templates/ide/antigravity/.agents/skills/dare-quality-telemetry/SKILL.md +187 -0
- package/templates/ide/antigravity/.agents/skills/dare-realtime/SKILL.md +217 -0
- package/templates/ide/antigravity/.agents/skills/dare-refine/SKILL.md +114 -0
- package/templates/ide/antigravity/.agents/skills/dare-reverse/SKILL.md +108 -0
- package/templates/ide/antigravity/.agents/skills/dare-review/SKILL.md +111 -0
- package/templates/ide/antigravity/.agents/skills/dare-rust-leptos/SKILL.md +263 -0
- package/templates/ide/antigravity/.agents/skills/dare-rust-workspace/SKILL.md +275 -275
- package/templates/ide/antigravity/.agents/skills/dare-security/SKILL.md +274 -0
- package/templates/ide/antigravity/.agents/skills/dare-tasks/SKILL.md +265 -224
- package/templates/ide/antigravity/.agents/skills/dare-telemetry/SKILL.md +188 -0
- package/templates/ide/antigravity/.agents/skills/skill-fastapi-api/SKILL.md +343 -0
- package/templates/ide/antigravity/.agents/skills/skill-go-gin-api/SKILL.md +377 -0
- package/templates/ide/antigravity/.agents/skills/skill-mcp-server/SKILL.md +382 -0
- package/templates/ide/antigravity/.agents/skills/skill-nestjs-api/SKILL.md +326 -0
- package/templates/ide/antigravity/.agents/skills/skill-rails-api/SKILL.md +393 -0
- package/templates/ide/antigravity/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/antigravity/templates/DESIGN-template.md +129 -129
- package/templates/ide/antigravity/templates/TASK-SPEC-template.md +141 -100
- package/templates/ide/claude/.claude/commands/dare-ax.md +131 -0
- package/templates/ide/claude/.claude/commands/dare-blueprint.md +134 -78
- package/templates/ide/claude/.claude/commands/dare-bugfix-design.md +119 -0
- package/templates/ide/claude/.claude/commands/dare-dag-build.md +151 -110
- package/templates/ide/claude/.claude/commands/dare-dag-run.md +109 -109
- package/templates/ide/claude/.claude/commands/dare-dag-runner.md +117 -0
- package/templates/ide/claude/.claude/commands/dare-dag-viz.md +197 -197
- package/templates/ide/claude/.claude/commands/dare-design.md +69 -69
- package/templates/ide/claude/.claude/commands/dare-dna.md +75 -0
- package/templates/ide/claude/.claude/commands/dare-docker.md +207 -0
- package/templates/ide/claude/.claude/commands/dare-execute.md +152 -152
- package/templates/ide/claude/.claude/commands/dare-feature-design.md +147 -0
- package/templates/ide/claude/.claude/commands/dare-frontend-design.md +149 -0
- package/templates/ide/claude/.claude/commands/dare-laravel-api.md +211 -0
- package/templates/ide/claude/.claude/commands/dare-layered-design.md +124 -0
- package/templates/ide/claude/.claude/commands/dare-llm-integration.md +148 -0
- package/templates/ide/claude/.claude/commands/dare-migrate.md +72 -0
- package/templates/ide/claude/.claude/commands/dare-quality-telemetry.md +166 -0
- package/templates/ide/claude/.claude/commands/dare-realtime.md +159 -0
- package/templates/ide/claude/.claude/commands/dare-refine.md +145 -0
- package/templates/ide/claude/.claude/commands/dare-reverse.md +139 -0
- package/templates/ide/claude/.claude/commands/dare-review.md +113 -0
- package/templates/ide/claude/.claude/commands/dare-rust-leptos.md +269 -269
- package/templates/ide/claude/.claude/commands/dare-rust-workspace.md +209 -209
- package/templates/ide/claude/.claude/commands/dare-security.md +232 -232
- package/templates/ide/claude/.claude/commands/dare-tasks.md +70 -70
- package/templates/ide/claude/.claude/commands/dare-telemetry.md +132 -0
- package/templates/ide/claude/.claude/commands/skill-fastapi-api.md +205 -0
- package/templates/ide/claude/.claude/commands/skill-go-gin-api.md +232 -0
- package/templates/ide/claude/.claude/commands/skill-mcp-server.md +228 -0
- package/templates/ide/claude/.claude/commands/skill-nestjs-api.md +210 -0
- package/templates/ide/claude/.claude/commands/skill-rails-api.md +236 -0
- package/templates/ide/claude/.claude/settings.example.json +35 -35
- package/templates/ide/claude/CLAUDE.md +146 -146
- package/templates/ide/claude/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/claude/templates/DESIGN-template.md +129 -129
- package/templates/ide/claude/templates/TASK-SPEC-template.md +141 -100
- package/templates/ide/cursor/.cursor/commands/dag-viz.md +139 -0
- package/templates/ide/cursor/.cursor/commands/generate-blueprint.md +86 -41
- package/templates/ide/cursor/.cursor/commands/generate-design.md +35 -35
- package/templates/ide/cursor/.cursor/commands/generate-tasks.md +184 -142
- package/templates/ide/cursor/.cursor/commands/refine-task.md +107 -0
- package/templates/ide/cursor/.cursor/commands/review-task.md +91 -0
- package/templates/ide/cursor/.cursor/commands/run-dag.md +110 -110
- package/templates/ide/cursor/.cursor/rules/skill-ax.mdc +263 -0
- package/templates/ide/cursor/.cursor/rules/skill-dag-build.mdc +173 -0
- package/templates/ide/cursor/.cursor/rules/skill-dag-run.mdc +134 -0
- package/templates/ide/cursor/.cursor/rules/skill-dag-runner.mdc +221 -221
- package/templates/ide/cursor/.cursor/rules/skill-dna.mdc +63 -0
- package/templates/ide/cursor/.cursor/rules/skill-fastapi-api.mdc +352 -0
- package/templates/ide/cursor/.cursor/rules/skill-frontend-design.mdc +244 -0
- package/templates/ide/cursor/.cursor/rules/skill-go-gin-api.mdc +371 -0
- package/templates/ide/cursor/.cursor/rules/skill-layered-design.mdc +266 -0
- package/templates/ide/cursor/.cursor/rules/skill-llm-integration.mdc +295 -0
- package/templates/ide/cursor/.cursor/rules/skill-mcp-server.mdc +367 -0
- package/templates/ide/cursor/.cursor/rules/skill-migrate.mdc +58 -0
- package/templates/ide/cursor/.cursor/rules/skill-nestjs-api.mdc +346 -0
- package/templates/ide/cursor/.cursor/rules/skill-quality-telemetry.mdc +248 -0
- package/templates/ide/cursor/.cursor/rules/skill-rails-api.mdc +400 -0
- package/templates/ide/cursor/.cursor/rules/skill-realtime.mdc +262 -0
- package/templates/ide/cursor/.cursor/rules/skill-reverse.mdc +107 -0
- package/templates/ide/cursor/.cursor/rules/skill-rust-leptos.mdc +281 -0
- package/templates/ide/cursor/.cursor/rules/skill-rust-workspace.mdc +312 -312
- package/templates/ide/cursor/.cursor/rules/skill-security.mdc +245 -245
- package/templates/ide/cursor/templates/BLUEPRINT-template.md +193 -193
- package/templates/ide/cursor/templates/DESIGN-template.md +129 -129
- package/templates/ide/cursor/templates/TASK-SPEC-template.md +141 -100
- package/templates/shared/docker-compose.yml +41 -41
- package/dist/__tests__/dag-runner/adapters.test.d.ts +0 -2
- package/dist/__tests__/dag-runner/adapters.test.d.ts.map +0 -1
- package/dist/__tests__/dag-runner/adapters.test.js +0 -134
- package/dist/__tests__/dag-runner/adapters.test.js.map +0 -1
- package/dist/dag-runner/adapters/antigravity.d.ts +0 -6
- package/dist/dag-runner/adapters/antigravity.d.ts.map +0 -1
- package/dist/dag-runner/adapters/antigravity.js +0 -54
- package/dist/dag-runner/adapters/antigravity.js.map +0 -1
- package/dist/dag-runner/adapters/claude.d.ts +0 -6
- package/dist/dag-runner/adapters/claude.d.ts.map +0 -1
- package/dist/dag-runner/adapters/claude.js +0 -48
- package/dist/dag-runner/adapters/claude.js.map +0 -1
- package/dist/dag-runner/adapters/cursor.d.ts +0 -6
- package/dist/dag-runner/adapters/cursor.d.ts.map +0 -1
- package/dist/dag-runner/adapters/cursor.js +0 -58
- package/dist/dag-runner/adapters/cursor.js.map +0 -1
- package/dist/dag-runner/adapters/index.d.ts +0 -46
- package/dist/dag-runner/adapters/index.d.ts.map +0 -1
- package/dist/dag-runner/adapters/index.js +0 -55
- package/dist/dag-runner/adapters/index.js.map +0 -1
- package/dist/dag-runner/utils/timeout.d.ts +0 -27
- package/dist/dag-runner/utils/timeout.d.ts.map +0 -1
- package/dist/dag-runner/utils/timeout.js +0 -55
- package/dist/dag-runner/utils/timeout.js.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static analyzer for `dare review` — scans source files for "fake
|
|
3
|
+
* completeness" patterns: TODO markers, empty function bodies, explicit
|
|
4
|
+
* stubs, mocks leaked into production code, etc.
|
|
5
|
+
*
|
|
6
|
+
* Detectors are deliberately line-based with regexes. We don't pull in a
|
|
7
|
+
* full multi-language AST stack: the CLI ships across Rust/Go/Python/PHP/
|
|
8
|
+
* Node/TS projects and a precise AST per language explodes the dependency
|
|
9
|
+
* tree. The cost is a small false-positive rate on string-literal hits like
|
|
10
|
+
* `const msg = "TODO: ..."`, which we mitigate by ignoring matches inside
|
|
11
|
+
* string literals at line-scope (single-line heuristic, see `inString`).
|
|
12
|
+
*
|
|
13
|
+
* Each detector is pure: `(line, idx, ctx) -> Violation | null`. Callers
|
|
14
|
+
* (`runStaticAnalysis`) iterate files, classify them as test/production, and
|
|
15
|
+
* skip rules that don't apply to tests.
|
|
16
|
+
*/
|
|
17
|
+
import type { FileReport } from '../types/Review.types.js';
|
|
18
|
+
export declare function isTestFile(filePath: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Analyze a single file. Returns the per-file report. Files that can't be
|
|
21
|
+
* read or are unsupported produce a clean report (no violations).
|
|
22
|
+
*/
|
|
23
|
+
export declare function analyzeFile(absolutePath: string, projectRelativePath: string): Promise<FileReport>;
|
|
24
|
+
/**
|
|
25
|
+
* Run static analysis on a list of files. Files are scanned in parallel —
|
|
26
|
+
* I/O is the bottleneck, CPU work per file is negligible.
|
|
27
|
+
*/
|
|
28
|
+
export declare function runStaticAnalysis(projectRoot: string, projectRelativeFiles: string[]): Promise<FileReport[]>;
|
|
29
|
+
//# sourceMappingURL=static-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-analyzer.d.ts","sourceRoot":"","sources":["../../src/utils/static-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,0BAA0B,CAAC;AA4ClC,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAgBpD;AAmXD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,YAAY,EAAE,MAAM,EACpB,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,oBAAoB,EAAE,MAAM,EAAE,GAC7B,OAAO,CAAC,UAAU,EAAE,CAAC,CAIvB"}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static analyzer for `dare review` — scans source files for "fake
|
|
3
|
+
* completeness" patterns: TODO markers, empty function bodies, explicit
|
|
4
|
+
* stubs, mocks leaked into production code, etc.
|
|
5
|
+
*
|
|
6
|
+
* Detectors are deliberately line-based with regexes. We don't pull in a
|
|
7
|
+
* full multi-language AST stack: the CLI ships across Rust/Go/Python/PHP/
|
|
8
|
+
* Node/TS projects and a precise AST per language explodes the dependency
|
|
9
|
+
* tree. The cost is a small false-positive rate on string-literal hits like
|
|
10
|
+
* `const msg = "TODO: ..."`, which we mitigate by ignoring matches inside
|
|
11
|
+
* string literals at line-scope (single-line heuristic, see `inString`).
|
|
12
|
+
*
|
|
13
|
+
* Each detector is pure: `(line, idx, ctx) -> Violation | null`. Callers
|
|
14
|
+
* (`runStaticAnalysis`) iterate files, classify them as test/production, and
|
|
15
|
+
* skip rules that don't apply to tests.
|
|
16
|
+
*/
|
|
17
|
+
import fs from 'fs-extra';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
// ── File classification ──────────────────────────────────────────────────────
|
|
20
|
+
/** Substrings that mark a path as test/spec/fixture code (mocks allowed there). */
|
|
21
|
+
const TEST_PATH_MARKERS = [
|
|
22
|
+
'/__tests__/',
|
|
23
|
+
'\\__tests__\\',
|
|
24
|
+
'/tests/',
|
|
25
|
+
'\\tests\\',
|
|
26
|
+
'/test/',
|
|
27
|
+
'\\test\\',
|
|
28
|
+
'/spec/',
|
|
29
|
+
'\\spec\\',
|
|
30
|
+
'/__mocks__/',
|
|
31
|
+
'\\__mocks__\\',
|
|
32
|
+
'/fixtures/',
|
|
33
|
+
'\\fixtures\\',
|
|
34
|
+
'/seeders/',
|
|
35
|
+
'\\seeders\\',
|
|
36
|
+
'/factories/',
|
|
37
|
+
'\\factories\\',
|
|
38
|
+
];
|
|
39
|
+
/** Filename suffixes that mark a file as test/spec code. */
|
|
40
|
+
const TEST_FILE_SUFFIXES = [
|
|
41
|
+
'.test.ts',
|
|
42
|
+
'.test.tsx',
|
|
43
|
+
'.test.js',
|
|
44
|
+
'.test.jsx',
|
|
45
|
+
'.spec.ts',
|
|
46
|
+
'.spec.tsx',
|
|
47
|
+
'.spec.js',
|
|
48
|
+
'.spec.jsx',
|
|
49
|
+
'_test.go',
|
|
50
|
+
'_test.py',
|
|
51
|
+
'Test.php',
|
|
52
|
+
'Spec.php',
|
|
53
|
+
'.test.rs',
|
|
54
|
+
];
|
|
55
|
+
/** Python uses a `test_` *prefix* convention. Match basename, not suffix. */
|
|
56
|
+
const TEST_FILE_BASENAME_PREFIXES = ['test_'];
|
|
57
|
+
export function isTestFile(filePath) {
|
|
58
|
+
const normalized = filePath.replace(/\\/g, '/').toLowerCase();
|
|
59
|
+
const basename = normalized.slice(normalized.lastIndexOf('/') + 1);
|
|
60
|
+
if (TEST_PATH_MARKERS.some((marker) => {
|
|
61
|
+
const lower = marker.toLowerCase().replace(/\\/g, '/');
|
|
62
|
+
// Match both `/tests/foo.py` and `tests/foo.py` at path start.
|
|
63
|
+
return normalized.includes(lower) || normalized.startsWith(lower.replace(/^\//, ''));
|
|
64
|
+
})) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (TEST_FILE_SUFFIXES.some((suffix) => filePath.endsWith(suffix)))
|
|
68
|
+
return true;
|
|
69
|
+
if (TEST_FILE_BASENAME_PREFIXES.some((prefix) => basename.startsWith(prefix)))
|
|
70
|
+
return true;
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
/** File extensions we analyze. Anything else is silently skipped. */
|
|
74
|
+
const SUPPORTED_EXTENSIONS = new Set([
|
|
75
|
+
'.ts',
|
|
76
|
+
'.tsx',
|
|
77
|
+
'.js',
|
|
78
|
+
'.jsx',
|
|
79
|
+
'.mjs',
|
|
80
|
+
'.cjs',
|
|
81
|
+
'.py',
|
|
82
|
+
'.rs',
|
|
83
|
+
'.go',
|
|
84
|
+
'.php',
|
|
85
|
+
'.rb',
|
|
86
|
+
'.java',
|
|
87
|
+
'.kt',
|
|
88
|
+
'.cs',
|
|
89
|
+
]);
|
|
90
|
+
function isSupported(filePath) {
|
|
91
|
+
return SUPPORTED_EXTENSIONS.has(path.extname(filePath));
|
|
92
|
+
}
|
|
93
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Crude check for "is this column inside a string literal?". We count
|
|
96
|
+
* unescaped quotes before `col` on the same line; an odd count means we're
|
|
97
|
+
* inside a string. Imperfect across multi-line strings but good enough to
|
|
98
|
+
* suppress comments-in-strings noise without an AST.
|
|
99
|
+
*/
|
|
100
|
+
function inString(line, col) {
|
|
101
|
+
let inSingle = false;
|
|
102
|
+
let inDouble = false;
|
|
103
|
+
let inBacktick = false;
|
|
104
|
+
for (let i = 0; i < col && i < line.length; i++) {
|
|
105
|
+
const ch = line[i];
|
|
106
|
+
const prev = i > 0 ? line[i - 1] : '';
|
|
107
|
+
if (prev === '\\')
|
|
108
|
+
continue;
|
|
109
|
+
if (ch === "'" && !inDouble && !inBacktick)
|
|
110
|
+
inSingle = !inSingle;
|
|
111
|
+
else if (ch === '"' && !inSingle && !inBacktick)
|
|
112
|
+
inDouble = !inDouble;
|
|
113
|
+
else if (ch === '`' && !inSingle && !inDouble)
|
|
114
|
+
inBacktick = !inBacktick;
|
|
115
|
+
}
|
|
116
|
+
return inSingle || inDouble || inBacktick;
|
|
117
|
+
}
|
|
118
|
+
function snippet(line) {
|
|
119
|
+
return line.trim().slice(0, 200);
|
|
120
|
+
}
|
|
121
|
+
function pushViolation(out, kind, severity, file, lineIdx, line, message) {
|
|
122
|
+
out.push({
|
|
123
|
+
kind,
|
|
124
|
+
severity,
|
|
125
|
+
file,
|
|
126
|
+
line: lineIdx + 1,
|
|
127
|
+
snippet: snippet(line),
|
|
128
|
+
message,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// ── Detectors ────────────────────────────────────────────────────────────────
|
|
132
|
+
/**
|
|
133
|
+
* Match `TODO`/`FIXME`/`XXX`/`HACK` markers that look like comments. We
|
|
134
|
+
* require them to follow `//`, `#`, `--`, `/*` or `*` to avoid hitting
|
|
135
|
+
* variable names like `todoList`. Identifiers with these substrings inside
|
|
136
|
+
* a longer word (e.g. `pseudohack`) are skipped via word-boundary anchors.
|
|
137
|
+
*/
|
|
138
|
+
const TODO_MARKER_RE = /(\/\/|#|--|\/\*|\*)\s*(TODO|FIXME|XXX|HACK)\b/i;
|
|
139
|
+
function detectTodoMarkers(line, lineIdx, file, out) {
|
|
140
|
+
const match = TODO_MARKER_RE.exec(line);
|
|
141
|
+
if (!match)
|
|
142
|
+
return;
|
|
143
|
+
if (inString(line, match.index))
|
|
144
|
+
return;
|
|
145
|
+
const marker = match[2].toUpperCase();
|
|
146
|
+
pushViolation(out, 'todo-marker', 'error', file, lineIdx, line, `${marker} marker found — resolve or remove before marking task as DONE.`);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Stub patterns the agent leans on when it doesn't know what to write.
|
|
150
|
+
* Matched across languages — each entry is a regex + a human-readable name.
|
|
151
|
+
*/
|
|
152
|
+
const STUB_PATTERNS = [
|
|
153
|
+
{ re: /throw\s+new\s+Error\(\s*['"`]not[\s-]?implemented['"`]/i, label: "throw new Error('not implemented')" },
|
|
154
|
+
{ re: /throw\s+new\s+Error\(\s*['"`]todo['"`]/i, label: "throw new Error('todo')" },
|
|
155
|
+
{ re: /\bunimplemented!\s*\(/, label: 'unimplemented!()' },
|
|
156
|
+
{ re: /\btodo!\s*\(/, label: 'todo!()' },
|
|
157
|
+
{ re: /\braise\s+NotImplementedError\b/, label: 'raise NotImplementedError' },
|
|
158
|
+
{ re: /\bpanic!\s*\(\s*['"]not[\s-]?implemented['"]/i, label: "panic!('not implemented')" },
|
|
159
|
+
];
|
|
160
|
+
function detectStubs(line, lineIdx, file, out) {
|
|
161
|
+
for (const { re, label } of STUB_PATTERNS) {
|
|
162
|
+
const m = re.exec(line);
|
|
163
|
+
if (!m)
|
|
164
|
+
continue;
|
|
165
|
+
if (inString(line, m.index))
|
|
166
|
+
continue;
|
|
167
|
+
pushViolation(out, 'not-implemented-stub', 'error', file, lineIdx, line, `${label} — replace with real implementation.`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Empty function detector. Matches common single-line empty bodies across
|
|
173
|
+
* languages. Multi-line empty bodies are handled by `detectEmptyBlocks`.
|
|
174
|
+
*/
|
|
175
|
+
/**
|
|
176
|
+
* Optional trailing block matched at end-of-line — tolerates `// comment`,
|
|
177
|
+
* `# comment` or just whitespace. Without this, a perfectly valid stub like
|
|
178
|
+
* `function x() {} // empty` would slip past the detector.
|
|
179
|
+
*/
|
|
180
|
+
const TRAIL = String.raw `\s*;?\s*(?:\/\/.*|#.*|\/\*.*?\*\/)?\s*$`;
|
|
181
|
+
const EMPTY_FN_SINGLE_LINE_PATTERNS = [
|
|
182
|
+
// TS/JS: function foo() {} | () => {} | foo() {} | async foo() {}
|
|
183
|
+
{ re: new RegExp(String.raw `\b(function\s+\w+|=>|\b\w+\s*\([^)]*\))\s*\{\s*\}` + TRAIL), label: 'empty function body' },
|
|
184
|
+
// Python: def foo(...): pass
|
|
185
|
+
{ re: new RegExp(String.raw `\bdef\s+\w+\s*\([^)]*\)\s*(->[^:]+)?:\s*pass` + TRAIL), label: 'def foo(...): pass' },
|
|
186
|
+
// Python: def foo(...): ...
|
|
187
|
+
{ re: new RegExp(String.raw `\bdef\s+\w+\s*\([^)]*\)\s*(->[^:]+)?:\s*\.\.\.` + TRAIL), label: 'def foo(...): ...' },
|
|
188
|
+
// Rust: fn foo() {}
|
|
189
|
+
{ re: new RegExp(String.raw `\bfn\s+\w+\s*\([^)]*\)\s*(->[^{]+)?\{\s*\}` + TRAIL), label: 'fn foo() {}' },
|
|
190
|
+
// Go: func foo() {}
|
|
191
|
+
{ re: new RegExp(String.raw `\bfunc\s+\w+\s*\([^)]*\)\s*[^{]*\{\s*\}` + TRAIL), label: 'func foo() {}' },
|
|
192
|
+
];
|
|
193
|
+
function detectEmptyFunctionsSingleLine(line, lineIdx, file, out) {
|
|
194
|
+
for (const { re, label } of EMPTY_FN_SINGLE_LINE_PATTERNS) {
|
|
195
|
+
if (re.test(line)) {
|
|
196
|
+
pushViolation(out, 'empty-function', 'error', file, lineIdx, line, `${label} — function must do real work.`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/** Placeholder comments — explicit "I'll write this later" intent. */
|
|
202
|
+
const PLACEHOLDER_COMMENT_RE = /(\/\/|#)\s*(implement\s+later|placeholder|stub|fixme\s+implement|to\s+be\s+implemented|tbd)\b/i;
|
|
203
|
+
function detectPlaceholderComments(line, lineIdx, file, out) {
|
|
204
|
+
const m = PLACEHOLDER_COMMENT_RE.exec(line);
|
|
205
|
+
if (!m)
|
|
206
|
+
return;
|
|
207
|
+
if (inString(line, m.index))
|
|
208
|
+
return;
|
|
209
|
+
pushViolation(out, 'placeholder-comment', 'error', file, lineIdx, line, 'Placeholder comment — implement the real behavior.');
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Mock library / spy calls that should never appear in production code.
|
|
213
|
+
* Test files are filtered out by the caller before this runs.
|
|
214
|
+
*/
|
|
215
|
+
const PRODUCTION_MOCK_PATTERNS = [
|
|
216
|
+
{ re: /\bjest\.(fn|mock|spyOn)\s*\(/, label: 'jest.fn / jest.mock / jest.spyOn' },
|
|
217
|
+
{ re: /\bvi\.(fn|mock|spyOn)\s*\(/, label: 'vi.fn / vi.mock / vi.spyOn (vitest)' },
|
|
218
|
+
{ re: /\bsinon\.(stub|spy|mock|fake)\s*\(/, label: 'sinon.stub / sinon.spy' },
|
|
219
|
+
{ re: /\bmockReturnValue(Once)?\s*\(/, label: 'mockReturnValue' },
|
|
220
|
+
{ re: /\bmockResolvedValue(Once)?\s*\(/, label: 'mockResolvedValue' },
|
|
221
|
+
{ re: /\bMock\s*<[^>]+>\s*\(/, label: 'Mock<T>() (Moq/.NET)' },
|
|
222
|
+
{ re: /\bMockito\.(mock|when|verify)\s*\(/, label: 'Mockito (Java)' },
|
|
223
|
+
{ re: /\bunittest\.mock\.|@patch\b|MagicMock\s*\(/, label: 'unittest.mock / @patch' },
|
|
224
|
+
];
|
|
225
|
+
function detectProductionMocks(line, lineIdx, file, out) {
|
|
226
|
+
for (const { re, label } of PRODUCTION_MOCK_PATTERNS) {
|
|
227
|
+
const m = re.exec(line);
|
|
228
|
+
if (!m)
|
|
229
|
+
continue;
|
|
230
|
+
if (inString(line, m.index))
|
|
231
|
+
continue;
|
|
232
|
+
pushViolation(out, 'production-mock', 'error', file, lineIdx, line, `${label} — mocks belong in test files, not production code.`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// ── Multi-line detectors ─────────────────────────────────────────────────────
|
|
237
|
+
/**
|
|
238
|
+
* Multi-line empty block detector — catches:
|
|
239
|
+
* function foo() {
|
|
240
|
+
* }
|
|
241
|
+
*
|
|
242
|
+
* def foo():
|
|
243
|
+
* pass
|
|
244
|
+
*
|
|
245
|
+
* fn foo() -> X {
|
|
246
|
+
* todo!()
|
|
247
|
+
* }
|
|
248
|
+
*
|
|
249
|
+
* Walks the file looking for a function/method declaration followed only by
|
|
250
|
+
* whitespace and an opening brace/colon, then checks if the body is empty
|
|
251
|
+
* or contains only a single stub statement.
|
|
252
|
+
*/
|
|
253
|
+
function detectEmptyBlocks(lines, file, out) {
|
|
254
|
+
const fnDeclRe = /\b(function|fn|func|def|method)\s+(\w+)\s*\([^)]*\)\s*(->[^{:]+)?\s*([{:])\s*$/;
|
|
255
|
+
for (let i = 0; i < lines.length; i++) {
|
|
256
|
+
const decl = fnDeclRe.exec(lines[i]);
|
|
257
|
+
if (!decl)
|
|
258
|
+
continue;
|
|
259
|
+
const opener = decl[4];
|
|
260
|
+
const fnName = decl[2];
|
|
261
|
+
if (opener === '{') {
|
|
262
|
+
// C-style: scan for the matching close brace and check body is empty/trivial.
|
|
263
|
+
let depth = 1;
|
|
264
|
+
let bodyLines = [];
|
|
265
|
+
for (let j = i + 1; j < lines.length && depth > 0; j++) {
|
|
266
|
+
const ln = lines[j];
|
|
267
|
+
for (const ch of ln) {
|
|
268
|
+
if (ch === '{')
|
|
269
|
+
depth++;
|
|
270
|
+
else if (ch === '}')
|
|
271
|
+
depth--;
|
|
272
|
+
if (depth === 0)
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
if (depth > 0)
|
|
276
|
+
bodyLines.push(ln);
|
|
277
|
+
}
|
|
278
|
+
const nonBlank = bodyLines.filter((l) => l.trim() && !l.trim().startsWith('//'));
|
|
279
|
+
if (nonBlank.length === 0) {
|
|
280
|
+
pushViolation(out, 'empty-function', 'error', file, i, lines[i], `Function ${fnName}() has an empty body — function must do real work.`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else if (opener === ':') {
|
|
284
|
+
// Python-style: next non-blank line is the body.
|
|
285
|
+
let j = i + 1;
|
|
286
|
+
while (j < lines.length && !lines[j].trim())
|
|
287
|
+
j++;
|
|
288
|
+
if (j < lines.length) {
|
|
289
|
+
const body = lines[j].trim();
|
|
290
|
+
if (body === 'pass' || body === '...') {
|
|
291
|
+
pushViolation(out, 'empty-function', 'error', file, i, lines[i], `Function ${fnName}() body is just \`${body}\` — implement real behavior.`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Phantom-return detector. Catches functions whose body is just
|
|
299
|
+
* `return null|undefined|{}|[]`. We require a multi-line scan because the
|
|
300
|
+
* function signature is on one line and the return on another.
|
|
301
|
+
*/
|
|
302
|
+
function detectPhantomReturns(lines, file, out) {
|
|
303
|
+
const fnOpenRe = /\b(function|fn|func|def)\s+(\w+)\s*\([^)]*\)\s*(->[^{:]+)?\s*([{:])\s*$/;
|
|
304
|
+
const phantomRe = /^\s*return\s+(null|undefined|\{\s*\}|\[\s*\])\s*;?\s*$/;
|
|
305
|
+
for (let i = 0; i < lines.length; i++) {
|
|
306
|
+
const decl = fnOpenRe.exec(lines[i]);
|
|
307
|
+
if (!decl)
|
|
308
|
+
continue;
|
|
309
|
+
if (decl[4] !== '{')
|
|
310
|
+
continue; // python phantoms are rarer; skip for now
|
|
311
|
+
let depth = 1;
|
|
312
|
+
let statements = 0;
|
|
313
|
+
let phantomFound = false;
|
|
314
|
+
let phantomLine = -1;
|
|
315
|
+
for (let j = i + 1; j < lines.length && depth > 0; j++) {
|
|
316
|
+
const ln = lines[j];
|
|
317
|
+
const depthBefore = depth;
|
|
318
|
+
for (const ch of ln) {
|
|
319
|
+
if (ch === '{')
|
|
320
|
+
depth++;
|
|
321
|
+
else if (ch === '}')
|
|
322
|
+
depth--;
|
|
323
|
+
if (depth === 0)
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
// Skip the closing-brace line itself — it would otherwise count as a
|
|
327
|
+
// statement and defeat the "only one statement" check below.
|
|
328
|
+
if (depthBefore > 0 && depth === 0) {
|
|
329
|
+
const trimmed = ln.trim();
|
|
330
|
+
// A line that's just `}` is the closer; ignore it. But a line like
|
|
331
|
+
// `return x; }` (closer combined with code) still counts.
|
|
332
|
+
if (trimmed === '}' || trimmed === '};')
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
const trimmed = ln.trim();
|
|
336
|
+
if (!trimmed || trimmed.startsWith('//'))
|
|
337
|
+
continue;
|
|
338
|
+
statements++;
|
|
339
|
+
if (phantomRe.test(ln)) {
|
|
340
|
+
phantomFound = true;
|
|
341
|
+
phantomLine = j;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (phantomFound && statements === 1) {
|
|
345
|
+
pushViolation(out, 'phantom-return', 'error', file, phantomLine, lines[phantomLine], `Function ${decl[2]}() only returns a phantom value — no real logic.`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// ── Orchestration ────────────────────────────────────────────────────────────
|
|
350
|
+
/**
|
|
351
|
+
* Analyze a single file. Returns the per-file report. Files that can't be
|
|
352
|
+
* read or are unsupported produce a clean report (no violations).
|
|
353
|
+
*/
|
|
354
|
+
export async function analyzeFile(absolutePath, projectRelativePath) {
|
|
355
|
+
const report = {
|
|
356
|
+
file: projectRelativePath,
|
|
357
|
+
isTestFile: isTestFile(projectRelativePath),
|
|
358
|
+
violations: [],
|
|
359
|
+
};
|
|
360
|
+
if (!isSupported(absolutePath))
|
|
361
|
+
return report;
|
|
362
|
+
if (!(await fs.pathExists(absolutePath)))
|
|
363
|
+
return report;
|
|
364
|
+
const content = await fs.readFile(absolutePath, 'utf-8');
|
|
365
|
+
const lines = content.split(/\r?\n/);
|
|
366
|
+
for (let i = 0; i < lines.length; i++) {
|
|
367
|
+
const line = lines[i];
|
|
368
|
+
// Detectors that fire on every file:
|
|
369
|
+
detectTodoMarkers(line, i, projectRelativePath, report.violations);
|
|
370
|
+
detectStubs(line, i, projectRelativePath, report.violations);
|
|
371
|
+
detectEmptyFunctionsSingleLine(line, i, projectRelativePath, report.violations);
|
|
372
|
+
detectPlaceholderComments(line, i, projectRelativePath, report.violations);
|
|
373
|
+
// Production-only detectors:
|
|
374
|
+
if (!report.isTestFile) {
|
|
375
|
+
detectProductionMocks(line, i, projectRelativePath, report.violations);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
// Multi-line detectors run once over the full buffer.
|
|
379
|
+
detectEmptyBlocks(lines, projectRelativePath, report.violations);
|
|
380
|
+
detectPhantomReturns(lines, projectRelativePath, report.violations);
|
|
381
|
+
return report;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Run static analysis on a list of files. Files are scanned in parallel —
|
|
385
|
+
* I/O is the bottleneck, CPU work per file is negligible.
|
|
386
|
+
*/
|
|
387
|
+
export async function runStaticAnalysis(projectRoot, projectRelativeFiles) {
|
|
388
|
+
return Promise.all(projectRelativeFiles.map((rel) => analyzeFile(path.join(projectRoot, rel), rel)));
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=static-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-analyzer.js","sourceRoot":"","sources":["../../src/utils/static-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAQxB,gFAAgF;AAEhF,mFAAmF;AACnF,MAAM,iBAAiB,GAAG;IACxB,aAAa;IACb,eAAe;IACf,SAAS;IACT,WAAW;IACX,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,UAAU;IACV,aAAa;IACb,eAAe;IACf,YAAY;IACZ,cAAc;IACd,WAAW;IACX,aAAa;IACb,aAAa;IACb,eAAe;CAChB,CAAC;AAEF,4DAA4D;AAC5D,MAAM,kBAAkB,GAAG;IACzB,UAAU;IACV,WAAW;IACX,UAAU;IACV,WAAW;IACX,UAAU;IACV,WAAW;IACX,UAAU;IACV,WAAW;IACX,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;CACX,CAAC;AAEF,6EAA6E;AAC7E,MAAM,2BAA2B,GAAG,CAAC,OAAO,CAAC,CAAC;AAE9C,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9D,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAEnE,IACE,iBAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACvD,+DAA+D;QAC/D,OAAO,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC,CAAC,EACF,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChF,IAAI,2BAA2B,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3F,OAAO,KAAK,CAAC;AACf,CAAC;AAED,qEAAqE;AACrE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,KAAK;IACL,KAAK;CACN,CAAC,CAAC;AAEH,SAAS,WAAW,CAAC,QAAgB;IACnC,OAAO,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,gFAAgF;AAEhF;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAW;IACzC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QAC5B,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU;YAAE,QAAQ,GAAG,CAAC,QAAQ,CAAC;aAC5D,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU;YAAE,QAAQ,GAAG,CAAC,QAAQ,CAAC;aACjE,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ;YAAE,UAAU,GAAG,CAAC,UAAU,CAAC;IAC1E,CAAC;IACD,OAAO,QAAQ,IAAI,QAAQ,IAAI,UAAU,CAAC;AAC5C,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,aAAa,CACpB,GAAgB,EAChB,IAAmB,EACnB,QAA2B,EAC3B,IAAY,EACZ,OAAe,EACf,IAAY,EACZ,OAAe;IAEf,GAAG,CAAC,IAAI,CAAC;QACP,IAAI;QACJ,QAAQ;QACR,IAAI;QACJ,IAAI,EAAE,OAAO,GAAG,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;QACtB,OAAO;KACR,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,cAAc,GAAG,gDAAgD,CAAC;AAExE,SAAS,iBAAiB,CAAC,IAAY,EAAE,OAAe,EAAE,IAAY,EAAE,GAAgB;IACtF,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO;IACxC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,aAAa,CACX,GAAG,EACH,aAAa,EACb,OAAO,EACP,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,GAAG,MAAM,gEAAgE,CAC1E,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,aAAa,GAAyC;IAC1D,EAAE,EAAE,EAAE,yDAAyD,EAAE,KAAK,EAAE,oCAAoC,EAAE;IAC9G,EAAE,EAAE,EAAE,yCAAyC,EAAE,KAAK,EAAE,yBAAyB,EAAE;IACnF,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC1D,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE;IACxC,EAAE,EAAE,EAAE,iCAAiC,EAAE,KAAK,EAAE,2BAA2B,EAAE;IAC7E,EAAE,EAAE,EAAE,+CAA+C,EAAE,KAAK,EAAE,2BAA2B,EAAE;CAC5F,CAAC;AAEF,SAAS,WAAW,CAAC,IAAY,EAAE,OAAe,EAAE,IAAY,EAAE,GAAgB;IAChF,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,aAAa,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC;YAAE,SAAS;QACtC,aAAa,CACX,GAAG,EACH,sBAAsB,EACtB,OAAO,EACP,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,GAAG,KAAK,sCAAsC,CAC/C,CAAC;QACF,OAAO;IACT,CAAC;AACH,CAAC;AAED;;;GAGG;AACH;;;;GAIG;AACH,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAA,yCAAyC,CAAC;AAElE,MAAM,6BAA6B,GAAyC;IAC1E,kEAAkE;IAClE,EAAE,EAAE,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,mDAAmD,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE;IACvH,6BAA6B;IAC7B,EAAE,EAAE,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,8CAA8C,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE;IACjH,4BAA4B;IAC5B,EAAE,EAAE,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,gDAAgD,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE;IAClH,oBAAoB;IACpB,EAAE,EAAE,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,4CAA4C,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE;IACxG,oBAAoB;IACpB,EAAE,EAAE,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,yCAAyC,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE;CACxG,CAAC;AAEF,SAAS,8BAA8B,CACrC,IAAY,EACZ,OAAe,EACf,IAAY,EACZ,GAAgB;IAEhB,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,6BAA6B,EAAE,CAAC;QAC1D,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClB,aAAa,CACX,GAAG,EACH,gBAAgB,EAChB,OAAO,EACP,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,GAAG,KAAK,gCAAgC,CACzC,CAAC;YACF,OAAO;QACT,CAAC;IACH,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,MAAM,sBAAsB,GAC1B,gGAAgG,CAAC;AAEnG,SAAS,yBAAyB,CAChC,IAAY,EACZ,OAAe,EACf,IAAY,EACZ,GAAgB;IAEhB,MAAM,CAAC,GAAG,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC;QAAE,OAAO;IACf,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC;QAAE,OAAO;IACpC,aAAa,CACX,GAAG,EACH,qBAAqB,EACrB,OAAO,EACP,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,oDAAoD,CACrD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,wBAAwB,GAAyC;IACrE,EAAE,EAAE,EAAE,8BAA8B,EAAE,KAAK,EAAE,kCAAkC,EAAE;IACjF,EAAE,EAAE,EAAE,4BAA4B,EAAE,KAAK,EAAE,qCAAqC,EAAE;IAClF,EAAE,EAAE,EAAE,oCAAoC,EAAE,KAAK,EAAE,wBAAwB,EAAE;IAC7E,EAAE,EAAE,EAAE,+BAA+B,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACjE,EAAE,EAAE,EAAE,iCAAiC,EAAE,KAAK,EAAE,mBAAmB,EAAE;IACrE,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,sBAAsB,EAAE;IAC9D,EAAE,EAAE,EAAE,oCAAoC,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACrE,EAAE,EAAE,EAAE,4CAA4C,EAAE,KAAK,EAAE,wBAAwB,EAAE;CACtF,CAAC;AAEF,SAAS,qBAAqB,CAC5B,IAAY,EACZ,OAAe,EACf,IAAY,EACZ,GAAgB;IAEhB,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,wBAAwB,EAAE,CAAC;QACrD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC;YAAE,SAAS;QACtC,aAAa,CACX,GAAG,EACH,iBAAiB,EACjB,OAAO,EACP,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,GAAG,KAAK,qDAAqD,CAC9D,CAAC;QACF,OAAO;IACT,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;;;;;GAeG;AACH,SAAS,iBAAiB,CAAC,KAAe,EAAE,IAAY,EAAE,GAAgB;IACxE,MAAM,QAAQ,GACZ,gFAAgF,CAAC;IAEnF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEvB,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,8EAA8E;YAC9E,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,SAAS,GAAa,EAAE,CAAC;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACpB,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;oBACpB,IAAI,EAAE,KAAK,GAAG;wBAAE,KAAK,EAAE,CAAC;yBACnB,IAAI,EAAE,KAAK,GAAG;wBAAE,KAAK,EAAE,CAAC;oBAC7B,IAAI,KAAK,KAAK,CAAC;wBAAE,MAAM;gBACzB,CAAC;gBACD,IAAI,KAAK,GAAG,CAAC;oBAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACjF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,aAAa,CACX,GAAG,EACH,gBAAgB,EAChB,OAAO,EACP,IAAI,EACJ,CAAC,EACD,KAAK,CAAC,CAAC,CAAC,EACR,YAAY,MAAM,oDAAoD,CACvE,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,iDAAiD;YACjD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAAE,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC7B,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;oBACtC,aAAa,CACX,GAAG,EACH,gBAAgB,EAChB,OAAO,EACP,IAAI,EACJ,CAAC,EACD,KAAK,CAAC,CAAC,CAAC,EACR,YAAY,MAAM,qBAAqB,IAAI,+BAA+B,CAC3E,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAAe,EAAE,IAAY,EAAE,GAAgB;IAC3E,MAAM,QAAQ,GACZ,yEAAyE,CAAC;IAC5E,MAAM,SAAS,GAAG,wDAAwD,CAAC;IAE3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,SAAS,CAAC,0CAA0C;QAEzE,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACvD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACpB,MAAM,WAAW,GAAG,KAAK,CAAC;YAC1B,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;gBACpB,IAAI,EAAE,KAAK,GAAG;oBAAE,KAAK,EAAE,CAAC;qBACnB,IAAI,EAAE,KAAK,GAAG;oBAAE,KAAK,EAAE,CAAC;gBAC7B,IAAI,KAAK,KAAK,CAAC;oBAAE,MAAM;YACzB,CAAC;YACD,qEAAqE;YACrE,6DAA6D;YAC7D,IAAI,WAAW,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBACnC,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;gBAC1B,mEAAmE;gBACnE,0DAA0D;gBAC1D,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI;oBAAE,SAAS;YACpD,CAAC;YACD,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,SAAS;YACnD,UAAU,EAAE,CAAC;YACb,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBACvB,YAAY,GAAG,IAAI,CAAC;gBACpB,WAAW,GAAG,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,IAAI,YAAY,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrC,aAAa,CACX,GAAG,EACH,gBAAgB,EAChB,OAAO,EACP,IAAI,EACJ,WAAW,EACX,KAAK,CAAC,WAAW,CAAC,EAClB,YAAY,IAAI,CAAC,CAAC,CAAC,kDAAkD,CACtE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,YAAoB,EACpB,mBAA2B;IAE3B,MAAM,MAAM,GAAe;QACzB,IAAI,EAAE,mBAAmB;QACzB,UAAU,EAAE,UAAU,CAAC,mBAAmB,CAAC;QAC3C,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAExD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAErC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,qCAAqC;QACrC,iBAAiB,CAAC,IAAI,EAAE,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACnE,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7D,8BAA8B,CAAC,IAAI,EAAE,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAChF,yBAAyB,CAAC,IAAI,EAAE,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAE3E,6BAA6B;QAC7B,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACvB,qBAAqB,CAAC,IAAI,EAAE,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACjE,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAEpE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,oBAA8B;IAE9B,OAAO,OAAO,CAAC,GAAG,CAChB,oBAAoB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CACjF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal semver comparison utilities for `dare update`.
|
|
3
|
+
*
|
|
4
|
+
* We don't pull in `semver` from npm because the comparisons we need are
|
|
5
|
+
* trivial (compare `MAJOR.MINOR.PATCH` triples, no ranges, no pre-releases)
|
|
6
|
+
* and the CLI already ships a slim dependency tree.
|
|
7
|
+
*/
|
|
8
|
+
export interface ParsedVersion {
|
|
9
|
+
major: number;
|
|
10
|
+
minor: number;
|
|
11
|
+
patch: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parse a semver-like string. Throws on invalid input so callers don't end up
|
|
15
|
+
* silently comparing `NaN`s.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseVersion(input: string): ParsedVersion;
|
|
18
|
+
/** Return `-1` if `a < b`, `0` if equal, `1` if `a > b`. */
|
|
19
|
+
export declare function compareVersions(a: string, b: string): -1 | 0 | 1;
|
|
20
|
+
/** True when `version` is strictly greater than `baseline`. */
|
|
21
|
+
export declare function isNewerThan(version: string, baseline: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Sort version strings ascending (oldest first). Caller-owned array stays
|
|
24
|
+
* untouched.
|
|
25
|
+
*/
|
|
26
|
+
export declare function sortVersionsAscending(versions: string[]): string[];
|
|
27
|
+
//# sourceMappingURL=version-compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-compare.d.ts","sourceRoot":"","sources":["../../src/utils/version-compare.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAUzD;AAED,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAOhE;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAElE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal semver comparison utilities for `dare update`.
|
|
3
|
+
*
|
|
4
|
+
* We don't pull in `semver` from npm because the comparisons we need are
|
|
5
|
+
* trivial (compare `MAJOR.MINOR.PATCH` triples, no ranges, no pre-releases)
|
|
6
|
+
* and the CLI already ships a slim dependency tree.
|
|
7
|
+
*/
|
|
8
|
+
const SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;
|
|
9
|
+
/**
|
|
10
|
+
* Parse a semver-like string. Throws on invalid input so callers don't end up
|
|
11
|
+
* silently comparing `NaN`s.
|
|
12
|
+
*/
|
|
13
|
+
export function parseVersion(input) {
|
|
14
|
+
const match = SEMVER_RE.exec(input.trim());
|
|
15
|
+
if (!match) {
|
|
16
|
+
throw new Error(`Invalid version string: "${input}"`);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
major: Number(match[1]),
|
|
20
|
+
minor: Number(match[2]),
|
|
21
|
+
patch: Number(match[3]),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Return `-1` if `a < b`, `0` if equal, `1` if `a > b`. */
|
|
25
|
+
export function compareVersions(a, b) {
|
|
26
|
+
const va = parseVersion(a);
|
|
27
|
+
const vb = parseVersion(b);
|
|
28
|
+
if (va.major !== vb.major)
|
|
29
|
+
return va.major < vb.major ? -1 : 1;
|
|
30
|
+
if (va.minor !== vb.minor)
|
|
31
|
+
return va.minor < vb.minor ? -1 : 1;
|
|
32
|
+
if (va.patch !== vb.patch)
|
|
33
|
+
return va.patch < vb.patch ? -1 : 1;
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
/** True when `version` is strictly greater than `baseline`. */
|
|
37
|
+
export function isNewerThan(version, baseline) {
|
|
38
|
+
return compareVersions(version, baseline) === 1;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Sort version strings ascending (oldest first). Caller-owned array stays
|
|
42
|
+
* untouched.
|
|
43
|
+
*/
|
|
44
|
+
export function sortVersionsAscending(versions) {
|
|
45
|
+
return [...versions].sort(compareVersions);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=version-compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-compare.js","sourceRoot":"","sources":["../../src/utils/version-compare.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,MAAM,SAAS,GAAG,kCAAkC,CAAC;AAErD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,GAAG,CAAC,CAAC;IACxD,CAAC;IACD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACxB,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,CAAC;AACX,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,QAAgB;IAC3D,OAAO,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAkB;IACtD,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAC7C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dewtech/dare-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "DARE Framework - CLI, GraphRAG engine, MCP server and shared types in a single package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"chalk": "^5.3.0",
|
|
24
24
|
"commander": "^11.0.0",
|
|
25
|
+
"figlet": "^1.7.0",
|
|
26
|
+
"gradient-string": "^2.0.2",
|
|
25
27
|
"cors": "^2.8.5",
|
|
26
28
|
"express": "^4.18.0",
|
|
27
29
|
"fs-extra": "^11.1.1",
|
|
@@ -31,10 +33,13 @@
|
|
|
31
33
|
"pino": "^8.16.0",
|
|
32
34
|
"pino-pretty": "^10.2.0",
|
|
33
35
|
"sql.js": "^1.11.0",
|
|
34
|
-
"yaml": "^2.3.1"
|
|
36
|
+
"yaml": "^2.3.1",
|
|
37
|
+
"@dewtech/dare-stack-ruby-rails-8": "1.0.0"
|
|
35
38
|
},
|
|
36
39
|
"devDependencies": {
|
|
37
40
|
"@types/cors": "^2.8.13",
|
|
41
|
+
"@types/figlet": "^1.5.8",
|
|
42
|
+
"@types/gradient-string": "^1.1.6",
|
|
38
43
|
"@types/express": "^4.17.0",
|
|
39
44
|
"@types/fs-extra": "^11.0.1",
|
|
40
45
|
"@types/inquirer": "^9.0.3",
|
|
@@ -73,7 +78,7 @@
|
|
|
73
78
|
},
|
|
74
79
|
"scripts": {
|
|
75
80
|
"sync": "tsx scripts/sync-implementations.ts",
|
|
76
|
-
"build": "tsx scripts/sync-implementations.ts && tsc",
|
|
81
|
+
"build": "tsx scripts/sync-implementations.ts && tsc && node -e \"require('fs-extra').copySync('src/skills/registry-mock.json','dist/skills/registry-mock.json')\"",
|
|
77
82
|
"dev": "tsx watch src/bin/dare.ts",
|
|
78
83
|
"test": "vitest run",
|
|
79
84
|
"lint": "eslint src --ext .ts",
|