@dewtech/dare-cli 3.11.0 → 3.13.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 +2 -0
- package/dist/__tests__/cli-only-invariants.test.d.ts +2 -0
- package/dist/__tests__/cli-only-invariants.test.d.ts.map +1 -0
- package/dist/__tests__/cli-only-invariants.test.js +100 -0
- package/dist/__tests__/cli-only-invariants.test.js.map +1 -0
- package/dist/__tests__/cli-only-regression.test.d.ts +2 -0
- package/dist/__tests__/cli-only-regression.test.d.ts.map +1 -0
- package/dist/__tests__/cli-only-regression.test.js +29 -0
- package/dist/__tests__/cli-only-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 +1 -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 +2 -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__/execute-agent.test.js +82 -0
- package/dist/commands/__tests__/execute-agent.test.js.map +1 -1
- 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/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 +111 -4
- package/dist/commands/execute.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.map +1 -1
- package/dist/commands/refine.js +23 -2
- 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 +25 -3
- 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/run_dag.d.ts +1 -1
- package/dist/dag-runner/run_dag.d.ts.map +1 -1
- 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/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/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/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__/safe-spawn.test.js +12 -0
- package/dist/verification/__tests__/safe-spawn.test.js.map +1 -1
- package/package.json +2 -1
- 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/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-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-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-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,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dewtech/dare-ax",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "dare-ax — Agent Experience (AX) skill for DARE Method v3.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"templates",
|
|
17
|
+
"skill.yml"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"lint": "eslint src --ext .ts",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.19.41",
|
|
28
|
+
"typescript": "^5.9.3",
|
|
29
|
+
"vitest": "^1.6.1"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"dare",
|
|
33
|
+
"dare-method",
|
|
34
|
+
"dare-ax",
|
|
35
|
+
"agent-experience",
|
|
36
|
+
"llms-txt",
|
|
37
|
+
"ai-agents",
|
|
38
|
+
"openapi"
|
|
39
|
+
],
|
|
40
|
+
"author": "Dewtech Technologies",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/dewtech-technologies/dare-method.git",
|
|
45
|
+
"directory": "packages/skills/dare-ax"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dare-ax — secret-detector
|
|
3
|
+
* Detects API keys, tokens, passwords, and other secrets in text content.
|
|
4
|
+
* License: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface SecretCheckResult {
|
|
8
|
+
found: boolean;
|
|
9
|
+
pattern?: string;
|
|
10
|
+
line?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Patterns that indicate the presence of a secret. */
|
|
14
|
+
const SECRET_PATTERNS: Array<{ name: string; pattern: RegExp }> = [
|
|
15
|
+
// Generic high-entropy secrets
|
|
16
|
+
{ name: 'Generic API Key assignment', pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*["']?[A-Za-z0-9\-_]{16,}["']?/i },
|
|
17
|
+
{ name: 'Generic Secret assignment', pattern: /(?:secret|access[_-]?secret|client[_-]?secret)\s*[:=]\s*["']?[A-Za-z0-9\-_]{16,}["']?/i },
|
|
18
|
+
{ name: 'Generic Token assignment', pattern: /(?:token|access[_-]?token|auth[_-]?token|bearer)\s*[:=]\s*["']?[A-Za-z0-9\-_.]{20,}["']?/i },
|
|
19
|
+
{ name: 'Password assignment', pattern: /(?:password|passwd|pwd)\s*[:=]\s*["'][^"']{4,}["']/i },
|
|
20
|
+
|
|
21
|
+
// AWS
|
|
22
|
+
{ name: 'AWS Access Key ID', pattern: /AKIA[0-9A-Z]{16}/ },
|
|
23
|
+
{ name: 'AWS Secret Access Key', pattern: /[Aa][Ww][Ss][_\-\s]?[Ss][Ee][Cc][Rr][Ee][Tt]\s*[:=]\s*["']?[A-Za-z0-9+/]{40}["']?/ },
|
|
24
|
+
|
|
25
|
+
// GitHub
|
|
26
|
+
{ name: 'GitHub Token', pattern: /gh[pousr]_[A-Za-z0-9_]{36,}/ },
|
|
27
|
+
{ name: 'GitHub Fine-grained Token', pattern: /github_pat_[A-Za-z0-9_]{82}/ },
|
|
28
|
+
|
|
29
|
+
// Stripe
|
|
30
|
+
{ name: 'Stripe Secret Key', pattern: /sk_(live|test)_[A-Za-z0-9]{24,}/ },
|
|
31
|
+
|
|
32
|
+
// Google
|
|
33
|
+
{ name: 'Google API Key', pattern: /AIza[0-9A-Za-z_\-]{35}/ },
|
|
34
|
+
{ name: 'Google OAuth Token', pattern: /ya29\.[0-9A-Za-z_\-]{68,}/ },
|
|
35
|
+
|
|
36
|
+
// Anthropic
|
|
37
|
+
{ name: 'Anthropic API Key', pattern: /sk-ant-[A-Za-z0-9\-]{40,}/ },
|
|
38
|
+
|
|
39
|
+
// OpenAI
|
|
40
|
+
{ name: 'OpenAI API Key', pattern: /sk-[A-Za-z0-9]{48}/ },
|
|
41
|
+
|
|
42
|
+
// Slack
|
|
43
|
+
{ name: 'Slack Bot Token', pattern: /xoxb-[0-9]{11}-[0-9]{11}-[0-9A-Za-z]{24}/ },
|
|
44
|
+
{ name: 'Slack User Token', pattern: /xoxp-[0-9]{11}-[0-9]{11}-[0-9A-Za-z]{24}/ },
|
|
45
|
+
|
|
46
|
+
// Generic PEM private key header
|
|
47
|
+
{ name: 'Private Key', pattern: /-----BEGIN\s+(RSA|EC|OPENSSH|DSA)?\s*PRIVATE KEY-----/ },
|
|
48
|
+
|
|
49
|
+
// Database connection strings with credentials
|
|
50
|
+
{
|
|
51
|
+
name: 'Database URL with credentials',
|
|
52
|
+
pattern: /(?:postgres|postgresql|mysql|mongodb|redis):\/\/[^:]+:[^@]+@/i,
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Checks a text string for secrets.
|
|
58
|
+
* Returns found=true and the pattern name if any secret is detected.
|
|
59
|
+
*/
|
|
60
|
+
export function containsSecrets(content: string): SecretCheckResult {
|
|
61
|
+
const lines = content.split('\n');
|
|
62
|
+
|
|
63
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
64
|
+
const line = lines[lineIndex];
|
|
65
|
+
|
|
66
|
+
// Skip comments and template placeholders
|
|
67
|
+
if (line.trim().startsWith('#') && !line.includes('=') && !line.includes(':')) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Skip Jinja2 template placeholders like {{ variable }}
|
|
72
|
+
if (/\{\{.*?\}\}/.test(line)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for (const { name, pattern } of SECRET_PATTERNS) {
|
|
77
|
+
if (pattern.test(line)) {
|
|
78
|
+
return {
|
|
79
|
+
found: true,
|
|
80
|
+
pattern: name,
|
|
81
|
+
line: lineIndex + 1,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { found: false };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Returns all secret matches found in content, not just the first one.
|
|
92
|
+
* Useful for detailed reporting.
|
|
93
|
+
*/
|
|
94
|
+
export function findAllSecrets(
|
|
95
|
+
content: string
|
|
96
|
+
): Array<{ pattern: string; line: number; lineContent: string }> {
|
|
97
|
+
const results: Array<{ pattern: string; line: number; lineContent: string }> = [];
|
|
98
|
+
const lines = content.split('\n');
|
|
99
|
+
|
|
100
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
101
|
+
const line = lines[lineIndex];
|
|
102
|
+
|
|
103
|
+
if (line.trim().startsWith('#') && !line.includes('=') && !line.includes(':')) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (/\{\{.*?\}\}/.test(line)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (const { name, pattern } of SECRET_PATTERNS) {
|
|
112
|
+
if (pattern.test(line)) {
|
|
113
|
+
results.push({
|
|
114
|
+
pattern: name,
|
|
115
|
+
line: lineIndex + 1,
|
|
116
|
+
lineContent: line.trim(),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return results;
|
|
123
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: dare-ax
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
description: >
|
|
4
|
+
Agent Experience (AX) skill — codifies best practices for AI-assisted development
|
|
5
|
+
in three planes: Discovery, Usage, and Defense. Ensures projects expose structured
|
|
6
|
+
signals (llms.txt, OpenAPI, --json CLI, rate limits) that code agents need to work
|
|
7
|
+
correctly without unnecessary refactoring.
|
|
8
|
+
author: Dewtech Technologies
|
|
9
|
+
license: MIT
|
|
10
|
+
dependencies: {}
|
|
11
|
+
metrics:
|
|
12
|
+
- id: M-01
|
|
13
|
+
description: llms.txt exists and is valid (no secrets, required sections present)
|
|
14
|
+
- id: M-02
|
|
15
|
+
description: public/openapi.json or openapi.json exists
|
|
16
|
+
- id: M-03
|
|
17
|
+
description: CLI supports --json flag
|
|
18
|
+
- id: M-04
|
|
19
|
+
description: Rate limit configuration is present (rack-attack, express-rate-limit, tower-governor, etc.)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# llms.txt — Project Context for AI Agents
|
|
2
|
+
# Generated by dare-ax v1.0.0 — DO NOT add secrets to this file
|
|
3
|
+
|
|
4
|
+
## Project Overview
|
|
5
|
+
{{ project_overview }}
|
|
6
|
+
|
|
7
|
+
## Tech Stack
|
|
8
|
+
- Language: {{ language }}
|
|
9
|
+
- Framework: {{ framework }}
|
|
10
|
+
- Database: {{ database }}
|
|
11
|
+
- Key Dependencies:
|
|
12
|
+
{% for dep in key_dependencies %}
|
|
13
|
+
- {{ dep }}
|
|
14
|
+
{% endfor %}
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
{{ architecture_description }}
|
|
18
|
+
|
|
19
|
+
## Directory Structure
|
|
20
|
+
```
|
|
21
|
+
{{ directory_structure }}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Key Endpoints
|
|
25
|
+
{% if endpoints %}
|
|
26
|
+
{% for endpoint in endpoints %}
|
|
27
|
+
- {{ endpoint.method }} {{ endpoint.path }}{% if endpoint.description %} — {{ endpoint.description }}{% endif %}
|
|
28
|
+
|
|
29
|
+
{% endfor %}
|
|
30
|
+
{% else %}
|
|
31
|
+
- See OpenAPI spec: GET /openapi.json
|
|
32
|
+
{% endif %}
|
|
33
|
+
|
|
34
|
+
## Important Files
|
|
35
|
+
- `{{ config_file }}` — application configuration
|
|
36
|
+
{% if has_docker %}
|
|
37
|
+
- `docker-compose.yml` — local dev environment
|
|
38
|
+
{% endif %}
|
|
39
|
+
{% if has_makefile %}
|
|
40
|
+
- `Makefile` — common commands (make dev, make test, make build)
|
|
41
|
+
{% endif %}
|
|
42
|
+
{% if has_taskfile %}
|
|
43
|
+
- `tasks.json` or `Taskfile.yml` — common commands
|
|
44
|
+
{% endif %}
|
|
45
|
+
|
|
46
|
+
## Getting Started
|
|
47
|
+
```bash
|
|
48
|
+
{{ getting_started_command }}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Rate Limits
|
|
52
|
+
{% if rate_limits %}
|
|
53
|
+
{% for limit in rate_limits %}
|
|
54
|
+
- {{ limit.scope }}: {{ limit.limit }} req/min per IP
|
|
55
|
+
{% endfor %}
|
|
56
|
+
{% else %}
|
|
57
|
+
- Public endpoints: 100 req/min per IP
|
|
58
|
+
- Auth endpoints: 10 req/min per IP
|
|
59
|
+
{% endif %}
|
|
60
|
+
|
|
61
|
+
## Security Notes
|
|
62
|
+
- All user input validated in handlers
|
|
63
|
+
- SQL queries use parameterized queries
|
|
64
|
+
- Environment variables: see `.env.example`
|
|
65
|
+
{% if extra_security_notes %}
|
|
66
|
+
{% for note in extra_security_notes %}
|
|
67
|
+
- {{ note }}
|
|
68
|
+
{% endfor %}
|
|
69
|
+
{% endif %}
|
|
70
|
+
|
|
71
|
+
## For AI Agents
|
|
72
|
+
- OpenAPI: `GET /openapi.json`
|
|
73
|
+
- CLI: `{{ cli_binary }} --help`, `{{ cli_binary }} --json`
|
|
74
|
+
- No secrets in this file or in any `llms.txt`
|
|
75
|
+
- Architecture: Handler → Service → Repository → Model (no direct Handler→Repository calls)
|
|
76
|
+
{% if agent_notes %}
|
|
77
|
+
{% for note in agent_notes %}
|
|
78
|
+
- {{ note }}
|
|
79
|
+
{% endfor %}
|
|
80
|
+
{% endif %}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dare-ax — generator tests
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { DareAxGenerator } from '../generator.js';
|
|
10
|
+
import { ProjectConfig } from '../types.js';
|
|
11
|
+
|
|
12
|
+
const MINIMAL_CONFIG: ProjectConfig = {
|
|
13
|
+
name: 'test-project',
|
|
14
|
+
projectOverview: 'A test project for dare-ax generator tests.',
|
|
15
|
+
language: 'TypeScript',
|
|
16
|
+
framework: 'NestJS',
|
|
17
|
+
database: 'Postgres',
|
|
18
|
+
keyDependencies: ['nestjs', 'typeorm', 'pg', 'class-validator', 'rxjs'],
|
|
19
|
+
architectureDescription:
|
|
20
|
+
'Layered architecture: Handlers → Services → Repositories → Models. ' +
|
|
21
|
+
'HTTP handlers in controllers, business logic in services, DB access in repositories.',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe('DareAxGenerator', () => {
|
|
25
|
+
let tmpDir: string;
|
|
26
|
+
let generator: DareAxGenerator;
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dare-ax-test-'));
|
|
30
|
+
generator = new DareAxGenerator();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('generateLlmsTxt', () => {
|
|
38
|
+
it('creates llms.txt at project root', () => {
|
|
39
|
+
const outputPath = generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
40
|
+
|
|
41
|
+
expect(fs.existsSync(outputPath)).toBe(true);
|
|
42
|
+
expect(outputPath).toBe(path.join(tmpDir, 'llms.txt'));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('generated file contains required sections', () => {
|
|
46
|
+
generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
47
|
+
|
|
48
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
49
|
+
|
|
50
|
+
expect(content).toContain('## Project Overview');
|
|
51
|
+
expect(content).toContain('## Tech Stack');
|
|
52
|
+
expect(content).toContain('## Architecture');
|
|
53
|
+
expect(content).toContain('## Key Endpoints');
|
|
54
|
+
expect(content).toContain('## For AI Agents');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('inserts project overview text', () => {
|
|
58
|
+
generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
59
|
+
|
|
60
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
61
|
+
expect(content).toContain('A test project for dare-ax generator tests.');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('inserts tech stack fields', () => {
|
|
65
|
+
generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
66
|
+
|
|
67
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
68
|
+
expect(content).toContain('Language: TypeScript');
|
|
69
|
+
expect(content).toContain('Framework: NestJS');
|
|
70
|
+
expect(content).toContain('Database: Postgres');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('lists key dependencies', () => {
|
|
74
|
+
generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
75
|
+
|
|
76
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
77
|
+
expect(content).toContain('nestjs');
|
|
78
|
+
expect(content).toContain('typeorm');
|
|
79
|
+
expect(content).toContain('pg');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('uses custom cli binary name', () => {
|
|
83
|
+
const config: ProjectConfig = { ...MINIMAL_CONFIG, cliBinary: 'my-cli' };
|
|
84
|
+
generator.generateLlmsTxt(tmpDir, config);
|
|
85
|
+
|
|
86
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
87
|
+
expect(content).toContain('my-cli --help');
|
|
88
|
+
expect(content).toContain('my-cli --json');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('uses project name as cli binary by default', () => {
|
|
92
|
+
generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
93
|
+
|
|
94
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
95
|
+
expect(content).toContain('test-project --help');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('includes custom rate limits when specified', () => {
|
|
99
|
+
const config: ProjectConfig = {
|
|
100
|
+
...MINIMAL_CONFIG,
|
|
101
|
+
rateLimits: [
|
|
102
|
+
{ scope: 'Public API', limit: 60 },
|
|
103
|
+
{ scope: 'Admin API', limit: 20 },
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
generator.generateLlmsTxt(tmpDir, config);
|
|
107
|
+
|
|
108
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
109
|
+
expect(content).toContain('Public API');
|
|
110
|
+
expect(content).toContain('60 req/min');
|
|
111
|
+
expect(content).toContain('Admin API');
|
|
112
|
+
expect(content).toContain('20 req/min');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('includes default rate limits when none specified', () => {
|
|
116
|
+
generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
117
|
+
|
|
118
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
119
|
+
expect(content).toContain('100 req/min');
|
|
120
|
+
expect(content).toContain('10 req/min');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('renders endpoints section when endpoints provided', () => {
|
|
124
|
+
const config: ProjectConfig = {
|
|
125
|
+
...MINIMAL_CONFIG,
|
|
126
|
+
endpoints: [
|
|
127
|
+
{ method: 'GET', path: '/api/v1/users', description: 'List users' },
|
|
128
|
+
{ method: 'POST', path: '/api/v1/users', description: 'Create user' },
|
|
129
|
+
],
|
|
130
|
+
};
|
|
131
|
+
generator.generateLlmsTxt(tmpDir, config);
|
|
132
|
+
|
|
133
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
134
|
+
expect(content).toContain('GET /api/v1/users');
|
|
135
|
+
expect(content).toContain('POST /api/v1/users');
|
|
136
|
+
expect(content).toContain('List users');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('throws when secret detected in generated content', () => {
|
|
140
|
+
// Inject a fake AWS key into the project overview
|
|
141
|
+
const evilConfig: ProjectConfig = {
|
|
142
|
+
...MINIMAL_CONFIG,
|
|
143
|
+
projectOverview: 'Project with key ' + 'AKIA' + 'IOSFODNN7EXAMPLE embedded.',
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
expect(() => generator.generateLlmsTxt(tmpDir, evilConfig)).toThrow(
|
|
147
|
+
/Secret detected/
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// File should NOT have been written
|
|
151
|
+
expect(fs.existsSync(path.join(tmpDir, 'llms.txt'))).toBe(false);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('throws when axNotApplicable is true', () => {
|
|
155
|
+
const config: ProjectConfig = { ...MINIMAL_CONFIG, axNotApplicable: true };
|
|
156
|
+
|
|
157
|
+
expect(() => generator.generateLlmsTxt(tmpDir, config)).toThrow(
|
|
158
|
+
/ax: not-applicable/
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('overwrites existing llms.txt on re-run', () => {
|
|
163
|
+
generator.generateLlmsTxt(tmpDir, MINIMAL_CONFIG);
|
|
164
|
+
|
|
165
|
+
const updated: ProjectConfig = {
|
|
166
|
+
...MINIMAL_CONFIG,
|
|
167
|
+
projectOverview: 'Updated description after second run.',
|
|
168
|
+
};
|
|
169
|
+
generator.generateLlmsTxt(tmpDir, updated);
|
|
170
|
+
|
|
171
|
+
const content = fs.readFileSync(path.join(tmpDir, 'llms.txt'), 'utf-8');
|
|
172
|
+
expect(content).toContain('Updated description after second run.');
|
|
173
|
+
expect(content).not.toContain('A test project for dare-ax generator tests.');
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe('renderLlmsTxt', () => {
|
|
178
|
+
it('returns rendered content without writing to disk', () => {
|
|
179
|
+
const content = generator.renderLlmsTxt(MINIMAL_CONFIG);
|
|
180
|
+
|
|
181
|
+
expect(typeof content).toBe('string');
|
|
182
|
+
expect(content).toContain('## Project Overview');
|
|
183
|
+
expect(content).toContain('## For AI Agents');
|
|
184
|
+
expect(fs.readdirSync(tmpDir)).toHaveLength(0);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('throws when axNotApplicable is true', () => {
|
|
188
|
+
const config: ProjectConfig = { ...MINIMAL_CONFIG, axNotApplicable: true };
|
|
189
|
+
|
|
190
|
+
expect(() => generator.renderLlmsTxt(config)).toThrow(/ax: not-applicable/);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|