specweave 0.6.8 → 0.7.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/.claude-plugin/README.md +1 -1
- package/CLAUDE.md +903 -99
- package/README.md +143 -207
- package/bin/specweave.js +67 -0
- package/dist/cli/commands/abandon.d.ts +13 -0
- package/dist/cli/commands/abandon.d.ts.map +1 -0
- package/dist/cli/commands/abandon.js +15 -0
- package/dist/cli/commands/abandon.js.map +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +90 -18
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/pause.d.ts +13 -0
- package/dist/cli/commands/pause.d.ts.map +1 -0
- package/dist/cli/commands/pause.js +15 -0
- package/dist/cli/commands/pause.js.map +1 -0
- package/dist/cli/commands/qa.d.ts +54 -0
- package/dist/cli/commands/qa.d.ts.map +1 -0
- package/dist/cli/commands/qa.js +98 -0
- package/dist/cli/commands/qa.js.map +1 -0
- package/dist/cli/commands/resume.d.ts +12 -0
- package/dist/cli/commands/resume.d.ts.map +1 -0
- package/dist/cli/commands/resume.js +14 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/status.d.ts +12 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +23 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/ado.d.ts +57 -0
- package/dist/cli/helpers/issue-tracker/ado.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/ado.js +223 -0
- package/dist/cli/helpers/issue-tracker/ado.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/github.d.ts +65 -0
- package/dist/cli/helpers/issue-tracker/github.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/github.js +284 -0
- package/dist/cli/helpers/issue-tracker/github.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/index.d.ts +22 -0
- package/dist/cli/helpers/issue-tracker/index.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/index.js +270 -0
- package/dist/cli/helpers/issue-tracker/index.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/jira.d.ts +61 -0
- package/dist/cli/helpers/issue-tracker/jira.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/jira.js +265 -0
- package/dist/cli/helpers/issue-tracker/jira.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/types.d.ts +86 -0
- package/dist/cli/helpers/issue-tracker/types.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/types.js +16 -0
- package/dist/cli/helpers/issue-tracker/types.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/utils.d.ts +103 -0
- package/dist/cli/helpers/issue-tracker/utils.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/utils.js +240 -0
- package/dist/cli/helpers/issue-tracker/utils.js.map +1 -0
- package/dist/core/increment/limits.d.ts +68 -0
- package/dist/core/increment/limits.d.ts.map +1 -0
- package/dist/core/increment/limits.js +224 -0
- package/dist/core/increment/limits.js.map +1 -0
- package/dist/core/increment/metadata-manager.d.ts +114 -0
- package/dist/core/increment/metadata-manager.d.ts.map +1 -0
- package/dist/core/increment/metadata-manager.js +320 -0
- package/dist/core/increment/metadata-manager.js.map +1 -0
- package/dist/core/increment/status-commands.d.ts +43 -0
- package/dist/core/increment/status-commands.d.ts.map +1 -0
- package/dist/core/increment/status-commands.js +277 -0
- package/dist/core/increment/status-commands.js.map +1 -0
- package/dist/core/plugin-detector.d.ts +1 -0
- package/dist/core/plugin-detector.d.ts.map +1 -1
- package/dist/core/plugin-detector.js +25 -0
- package/dist/core/plugin-detector.js.map +1 -1
- package/dist/core/qa/qa-runner.d.ts +16 -0
- package/dist/core/qa/qa-runner.d.ts.map +1 -0
- package/dist/core/qa/qa-runner.js +404 -0
- package/dist/core/qa/qa-runner.js.map +1 -0
- package/dist/core/qa/quality-gate-decider.d.ts +53 -0
- package/dist/core/qa/quality-gate-decider.d.ts.map +1 -0
- package/dist/core/qa/quality-gate-decider.js +268 -0
- package/dist/core/qa/quality-gate-decider.js.map +1 -0
- package/dist/core/qa/risk-calculator.d.ts +126 -0
- package/dist/core/qa/risk-calculator.d.ts.map +1 -0
- package/dist/core/qa/risk-calculator.js +247 -0
- package/dist/core/qa/risk-calculator.js.map +1 -0
- package/dist/core/qa/types.d.ts +315 -0
- package/dist/core/qa/types.d.ts.map +1 -0
- package/dist/core/qa/types.js +8 -0
- package/dist/core/qa/types.js.map +1 -0
- package/dist/core/types/config.d.ts +35 -0
- package/dist/core/types/config.d.ts.map +1 -1
- package/dist/core/types/config.js +16 -0
- package/dist/core/types/config.js.map +1 -1
- package/dist/core/types/increment-metadata.d.ts +120 -0
- package/dist/core/types/increment-metadata.d.ts.map +1 -0
- package/dist/core/types/increment-metadata.js +138 -0
- package/dist/core/types/increment-metadata.js.map +1 -0
- package/dist/hooks/lib/invoke-translator-skill.d.ts +60 -0
- package/dist/hooks/lib/invoke-translator-skill.d.ts.map +1 -0
- package/dist/hooks/lib/invoke-translator-skill.js +201 -0
- package/dist/hooks/lib/invoke-translator-skill.js.map +1 -0
- package/dist/hooks/lib/translate-file.d.ts +59 -0
- package/dist/hooks/lib/translate-file.d.ts.map +1 -0
- package/dist/hooks/lib/translate-file.js +350 -0
- package/dist/hooks/lib/translate-file.js.map +1 -0
- package/dist/locales/en/cli.json +3 -1
- package/dist/metrics/calculators/change-failure-rate.d.ts +22 -0
- package/dist/metrics/calculators/change-failure-rate.d.ts.map +1 -0
- package/dist/metrics/calculators/change-failure-rate.js +70 -0
- package/dist/metrics/calculators/change-failure-rate.js.map +1 -0
- package/dist/metrics/calculators/deployment-frequency.d.ts +20 -0
- package/dist/metrics/calculators/deployment-frequency.d.ts.map +1 -0
- package/dist/metrics/calculators/deployment-frequency.js +61 -0
- package/dist/metrics/calculators/deployment-frequency.js.map +1 -0
- package/dist/metrics/calculators/lead-time.d.ts +22 -0
- package/dist/metrics/calculators/lead-time.d.ts.map +1 -0
- package/dist/metrics/calculators/lead-time.js +82 -0
- package/dist/metrics/calculators/lead-time.js.map +1 -0
- package/dist/metrics/calculators/mttr.d.ts +21 -0
- package/dist/metrics/calculators/mttr.d.ts.map +1 -0
- package/dist/metrics/calculators/mttr.js +60 -0
- package/dist/metrics/calculators/mttr.js.map +1 -0
- package/dist/metrics/dora-calculator.d.ts +24 -0
- package/dist/metrics/dora-calculator.d.ts.map +1 -0
- package/dist/metrics/dora-calculator.js +104 -0
- package/dist/metrics/dora-calculator.js.map +1 -0
- package/dist/metrics/github-client.d.ts +51 -0
- package/dist/metrics/github-client.d.ts.map +1 -0
- package/dist/metrics/github-client.js +133 -0
- package/dist/metrics/github-client.js.map +1 -0
- package/dist/metrics/types.d.ts +112 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +10 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/metrics/utils/percentile.d.ts +25 -0
- package/dist/metrics/utils/percentile.d.ts.map +1 -0
- package/dist/metrics/utils/percentile.js +46 -0
- package/dist/metrics/utils/percentile.js.map +1 -0
- package/dist/metrics/utils/tier-classifier.d.ts +61 -0
- package/dist/metrics/utils/tier-classifier.d.ts.map +1 -0
- package/dist/metrics/utils/tier-classifier.js +100 -0
- package/dist/metrics/utils/tier-classifier.js.map +1 -0
- package/dist/utils/auth-helpers.d.ts +58 -0
- package/dist/utils/auth-helpers.d.ts.map +1 -0
- package/dist/utils/auth-helpers.js +108 -0
- package/dist/utils/auth-helpers.js.map +1 -0
- package/dist/utils/env-file.d.ts +88 -0
- package/dist/utils/env-file.d.ts.map +1 -0
- package/dist/utils/env-file.js +180 -0
- package/dist/utils/env-file.js.map +1 -0
- package/dist/utils/plugin-detection.d.ts +50 -0
- package/dist/utils/plugin-detection.d.ts.map +1 -0
- package/dist/utils/plugin-detection.js +229 -0
- package/dist/utils/plugin-detection.js.map +1 -0
- package/dist/utils/secrets-loader.d.ts +88 -0
- package/dist/utils/secrets-loader.d.ts.map +1 -0
- package/dist/utils/secrets-loader.js +271 -0
- package/dist/utils/secrets-loader.js.map +1 -0
- package/dist/utils/translation.d.ts +187 -0
- package/dist/utils/translation.d.ts.map +1 -0
- package/dist/utils/translation.js +414 -0
- package/dist/utils/translation.js.map +1 -0
- package/package.json +28 -44
- package/plugins/specweave/.claude-plugin/plugin.json +3 -3
- package/plugins/specweave/agents/pm/AGENT.md +330 -54
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +1035 -0
- package/plugins/specweave/agents/test-aware-planner/templates/README.md +118 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-non-testable.md.template +24 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-testable.md.template +53 -0
- package/plugins/specweave/agents/test-aware-planner/templates/tasks-frontmatter.md.template +11 -0
- package/plugins/specweave/commands/README.md +88 -163
- package/plugins/specweave/commands/specweave-abandon.md +314 -0
- package/plugins/specweave/commands/specweave-check-tests.md +546 -0
- package/plugins/specweave/commands/{do.md → specweave-do.md} +5 -7
- package/plugins/specweave/commands/{increment.md → specweave-increment.md} +231 -4
- package/plugins/specweave/commands/specweave-pause.md +189 -0
- package/plugins/specweave/commands/specweave-qa.md +245 -0
- package/plugins/specweave/commands/specweave-resume.md +216 -0
- package/plugins/specweave/commands/specweave-status.md +397 -0
- package/plugins/specweave/commands/specweave-sync-tasks.md +256 -0
- package/plugins/specweave/commands/{translate.md → specweave-translate.md} +3 -3
- package/plugins/specweave/commands/specweave-update-scope.md +351 -0
- package/plugins/specweave/commands/specweave.md +21 -21
- package/plugins/specweave/hooks/post-increment-planning.sh +335 -0
- package/plugins/specweave/hooks/post-task-completion.sh +141 -0
- package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
- package/plugins/specweave/skills/brownfield-analyzer/SKILL.md +9 -9
- package/plugins/specweave/skills/increment-planner/SKILL.md +400 -212
- package/plugins/specweave/skills/increment-quality-judge-v2/SKILL.md +499 -0
- package/plugins/specweave/skills/plugin-detector/SKILL.md +114 -1
- package/plugins/specweave/skills/project-kickstarter/SKILL.md +74 -1
- package/plugins/specweave/skills/{rfc-generator → spec-generator}/SKILL.md +22 -29
- package/plugins/specweave/skills/specweave-detector/SKILL.md +3 -3
- package/plugins/specweave/skills/specweave-framework/SKILL.md +2 -2
- package/plugins/specweave-ado/.claude-plugin/plugin.json +18 -4
- package/plugins/specweave-ado/agents/ado-manager/AGENT.md +426 -0
- package/plugins/specweave-ado/commands/close-workitem.md +52 -0
- package/plugins/specweave-ado/commands/create-workitem.md +53 -0
- package/plugins/specweave-ado/commands/status.md +53 -0
- package/plugins/specweave-ado/commands/sync.md +55 -0
- package/plugins/specweave-ado/lib/ado-client.ts +361 -0
- package/plugins/specweave-ado/reference/ado-specweave-mapping.md +552 -0
- package/plugins/specweave-ado/skills/ado-sync/SKILL.md +344 -193
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +73 -0
- package/plugins/specweave-github/agents/github-manager/AGENT.md +49 -0
- package/plugins/specweave-github/commands/{github-close-issue.md → close-issue.md} +1 -1
- package/plugins/specweave-github/commands/{github-create-issue.md → create-issue.md} +1 -1
- package/plugins/specweave-github/commands/{github-status.md → status.md} +1 -1
- package/plugins/specweave-github/commands/{github-sync-tasks.md → sync-tasks.md} +1 -1
- package/plugins/specweave-github/commands/{github-sync.md → sync.md} +1 -1
- package/plugins/specweave-github/reference/github-specweave-mapping.md +377 -0
- package/plugins/specweave-github/skills/github-sync/SKILL.md +11 -3
- package/plugins/specweave-infrastructure/commands/{specweave.monitor-setup.md → monitor-setup.md} +5 -0
- package/plugins/specweave-infrastructure/commands/{specweave.slo-implement.md → slo-implement.md} +5 -0
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +380 -0
- package/plugins/specweave-jira/commands/{specweave.sync-jira.md → sync.md} +1 -1
- package/plugins/specweave-jira/reference/jira-specweave-mapping.md +508 -0
- package/plugins/specweave-ml/commands/ml-deploy.md +1 -1
- package/plugins/specweave-ml/commands/ml-evaluate.md +1 -1
- package/plugins/specweave-ml/commands/ml-explain.md +1 -1
- package/plugins/specweave-ml/commands/{specweave.ml-pipeline.md → ml-pipeline.md} +5 -0
- package/src/templates/AGENTS.md.template +331 -31
- package/src/templates/CLAUDE.md.template +36 -21
- package/src/templates/COMPLETION-REPORT.template.md +128 -0
- package/src/templates/README.md.template +17 -16
- package/src/templates/docs/README.md +11 -9
- package/src/templates/docs/spec-template.md +229 -0
- package/plugins/specweave/commands/inc.md +0 -85
- package/plugins/specweave/commands/list-increments.md +0 -180
- package/src/adapters/README.md +0 -275
- package/src/adapters/adapter-base.ts +0 -182
- package/src/adapters/adapter-interface.ts +0 -166
- package/src/adapters/adapter-loader.ts +0 -256
- package/src/adapters/agents-md-generator.ts +0 -228
- package/src/adapters/claude/README.md +0 -233
- package/src/adapters/claude/adapter.ts +0 -468
- package/src/adapters/claude-md-generator.ts +0 -377
- package/src/adapters/codex/README.md +0 -105
- package/src/adapters/codex/adapter.ts +0 -333
- package/src/adapters/cursor/.cursor/context/docs-context.md +0 -62
- package/src/adapters/cursor/.cursor/context/increments-context.md +0 -71
- package/src/adapters/cursor/.cursor/context/strategy-context.md +0 -73
- package/src/adapters/cursor/.cursor/context/tests-context.md +0 -89
- package/src/adapters/cursor/README.md +0 -283
- package/src/adapters/cursor/adapter.ts +0 -451
- package/src/adapters/doc-generator.ts +0 -331
- package/src/adapters/gemini/README.md +0 -97
- package/src/adapters/gemini/adapter.ts +0 -298
- package/src/adapters/generic/README.md +0 -277
- package/src/adapters/generic/adapter.ts +0 -378
- package/src/adapters/registry.yaml +0 -187
- /package/plugins/specweave/commands/{costs.md → specweave-costs.md} +0 -0
- /package/plugins/specweave/commands/{done.md → specweave-done.md} +0 -0
- /package/plugins/specweave/commands/{next.md → specweave-next.md} +0 -0
- /package/plugins/specweave/commands/{progress.md → specweave-progress.md} +0 -0
- /package/plugins/specweave/commands/{sync-docs.md → specweave-sync-docs.md} +0 -0
- /package/plugins/specweave/commands/{tdd-cycle.md → specweave-tdd-cycle.md} +0 -0
- /package/plugins/specweave/commands/{tdd-green.md → specweave-tdd-green.md} +0 -0
- /package/plugins/specweave/commands/{tdd-red.md → specweave-tdd-red.md} +0 -0
- /package/plugins/specweave/commands/{tdd-refactor.md → specweave-tdd-refactor.md} +0 -0
- /package/plugins/specweave/commands/{validate.md → specweave-validate.md} +0 -0
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adapter Loader
|
|
3
|
-
*
|
|
4
|
-
* Loads adapters from registry, detects tools, and provides API for init command.
|
|
5
|
-
* Enables SpecWeave to work with ANY AI coding tool.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import fs from 'fs-extra';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
import * as YAML from 'yaml';
|
|
11
|
-
import { execSync } from 'child_process';
|
|
12
|
-
import { IAdapter } from './adapter-interface.js';
|
|
13
|
-
import { CursorAdapter } from './cursor/adapter.js';
|
|
14
|
-
import { GeminiAdapter } from './gemini/adapter.js';
|
|
15
|
-
import { CodexAdapter } from './codex/adapter.js';
|
|
16
|
-
import { GenericAdapter } from './generic/adapter.js';
|
|
17
|
-
import { getDirname } from '../utils/esm-helpers.js';
|
|
18
|
-
|
|
19
|
-
const __dirname = getDirname(import.meta.url);
|
|
20
|
-
|
|
21
|
-
export interface AdapterRegistry {
|
|
22
|
-
version: number;
|
|
23
|
-
last_updated: string;
|
|
24
|
-
adapters: Array<{
|
|
25
|
-
name: string;
|
|
26
|
-
description: string;
|
|
27
|
-
automation_level: string;
|
|
28
|
-
status: string;
|
|
29
|
-
directory: string;
|
|
30
|
-
market_share: string;
|
|
31
|
-
priority: string;
|
|
32
|
-
}>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Adapter Loader - Main API for working with adapters
|
|
37
|
-
*/
|
|
38
|
-
export class AdapterLoader {
|
|
39
|
-
private adapters: Map<string, IAdapter> = new Map();
|
|
40
|
-
private registry: AdapterRegistry | null = null;
|
|
41
|
-
|
|
42
|
-
constructor() {
|
|
43
|
-
this.initializeAdapters();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Initialize all adapters
|
|
48
|
-
*
|
|
49
|
-
* NOTE: Claude Code is NOT an adapter - it's the native/default experience!
|
|
50
|
-
* Adapters only exist for tools that need to APPROXIMATE Claude's native capabilities.
|
|
51
|
-
*/
|
|
52
|
-
private initializeAdapters(): void {
|
|
53
|
-
// Note: No ClaudeAdapter - Claude is the baseline, not an adaptation!
|
|
54
|
-
this.adapters.set('cursor', new CursorAdapter());
|
|
55
|
-
this.adapters.set('gemini', new GeminiAdapter());
|
|
56
|
-
this.adapters.set('codex', new CodexAdapter());
|
|
57
|
-
this.adapters.set('generic', new GenericAdapter());
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Load registry.yaml
|
|
62
|
-
*/
|
|
63
|
-
async loadRegistry(): Promise<AdapterRegistry> {
|
|
64
|
-
if (this.registry) {
|
|
65
|
-
return this.registry;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Try dist first, then fall back to src (for development)
|
|
69
|
-
let registryPath = path.join(__dirname, 'registry.yaml');
|
|
70
|
-
if (!await fs.pathExists(registryPath)) {
|
|
71
|
-
registryPath = path.join(__dirname, '../../src/adapters/registry.yaml');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const content = await fs.readFile(registryPath, 'utf-8');
|
|
75
|
-
this.registry = YAML.parse(content) as AdapterRegistry;
|
|
76
|
-
|
|
77
|
-
return this.registry;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Get all available adapters
|
|
82
|
-
*/
|
|
83
|
-
getAllAdapters(): IAdapter[] {
|
|
84
|
-
return Array.from(this.adapters.values());
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Get adapter by name
|
|
89
|
-
*/
|
|
90
|
-
getAdapter(name: string): IAdapter | undefined {
|
|
91
|
-
return this.adapters.get(name);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Auto-detect which tool is being used
|
|
96
|
-
*
|
|
97
|
-
* Detection priority (based on market share and probability):
|
|
98
|
-
* 1. Claude Code (DEFAULT - best experience, native support)
|
|
99
|
-
* 2. Cursor (if cursor CLI or .cursor/ or .cursorrules exists)
|
|
100
|
-
* 3. Gemini CLI (if gemini CLI found)
|
|
101
|
-
* 4. Codex (if codex CLI found)
|
|
102
|
-
* 5. Generic (only if explicitly requested via --adapter generic)
|
|
103
|
-
*
|
|
104
|
-
* @returns Promise<string> Detected tool name (not adapter - Claude has no adapter!)
|
|
105
|
-
*/
|
|
106
|
-
async detectTool(): Promise<string> {
|
|
107
|
-
console.log('🔍 Detecting AI coding tool...\n');
|
|
108
|
-
|
|
109
|
-
// Check other tools first (if they have specific indicators)
|
|
110
|
-
const detectionOrder = ['cursor', 'gemini', 'codex'];
|
|
111
|
-
|
|
112
|
-
for (const adapterName of detectionOrder) {
|
|
113
|
-
const adapter = this.adapters.get(adapterName);
|
|
114
|
-
if (!adapter) continue;
|
|
115
|
-
|
|
116
|
-
const detected = await adapter.detect();
|
|
117
|
-
if (detected) {
|
|
118
|
-
console.log(`✅ Detected: ${adapter.name} (${adapter.automationLevel} automation)`);
|
|
119
|
-
return adapterName;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Default to Claude Code (best experience, native support)
|
|
124
|
-
// Users can override with --adapter flag if they want a different tool
|
|
125
|
-
console.log(`✅ Detected: claude (native - full automation)`);
|
|
126
|
-
return 'claude';
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Helper: Check if a command exists in PATH
|
|
131
|
-
* Cross-platform: uses 'where' on Windows, 'which' on Unix
|
|
132
|
-
*/
|
|
133
|
-
private async commandExists(command: string): Promise<boolean> {
|
|
134
|
-
try {
|
|
135
|
-
const isWindows = process.platform === 'win32';
|
|
136
|
-
const checkCommand = isWindows ? 'where' : 'which';
|
|
137
|
-
execSync(`${checkCommand} ${command}`, { stdio: 'ignore' });
|
|
138
|
-
return true;
|
|
139
|
-
} catch (error) {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Helper: Check if a file exists
|
|
146
|
-
*/
|
|
147
|
-
private async fileExists(filePath: string): Promise<boolean> {
|
|
148
|
-
try {
|
|
149
|
-
await fs.access(filePath);
|
|
150
|
-
return true;
|
|
151
|
-
} catch (error) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Check requirements for a specific adapter
|
|
158
|
-
*/
|
|
159
|
-
async checkRequirements(adapterName: string): Promise<void> {
|
|
160
|
-
const adapter = this.adapters.get(adapterName);
|
|
161
|
-
if (!adapter) {
|
|
162
|
-
throw new Error(`Adapter not found: ${adapterName}`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const result = await adapter.checkRequirements();
|
|
166
|
-
|
|
167
|
-
if (!result.met) {
|
|
168
|
-
console.error('\n❌ Requirements not met:\n');
|
|
169
|
-
result.missing.forEach(req => console.error(` - ${req}`));
|
|
170
|
-
throw new Error('System requirements not met');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (result.warnings.length > 0) {
|
|
174
|
-
console.warn('\n⚠️ Warnings:\n');
|
|
175
|
-
result.warnings.forEach(warning => console.warn(` - ${warning}`));
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* List all available adapters with details
|
|
181
|
-
*/
|
|
182
|
-
async listAdapters(): Promise<void> {
|
|
183
|
-
const registry = await this.loadRegistry();
|
|
184
|
-
|
|
185
|
-
console.log('\n📋 SpecWeave Tool Support:\n');
|
|
186
|
-
console.log('━'.repeat(70));
|
|
187
|
-
console.log('');
|
|
188
|
-
|
|
189
|
-
// Show Claude first (baseline, not an adapter)
|
|
190
|
-
const claudeInfo = registry.adapters.find(a => a.name === 'claude');
|
|
191
|
-
if (claudeInfo) {
|
|
192
|
-
console.log(`🚀 CLAUDE CODE (Baseline - No Adapter Needed)`);
|
|
193
|
-
console.log(` ${claudeInfo.description}`);
|
|
194
|
-
console.log(` Native: skills, agents, hooks, slash commands | Market: ${claudeInfo.market_share}`);
|
|
195
|
-
console.log('');
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
console.log('📦 Adapters (For Other Tools):\n');
|
|
199
|
-
|
|
200
|
-
// Show other adapters
|
|
201
|
-
for (const adapterInfo of registry.adapters) {
|
|
202
|
-
if (adapterInfo.name === 'claude') continue; // Skip Claude, already shown
|
|
203
|
-
|
|
204
|
-
const adapter = this.adapters.get(adapterInfo.name);
|
|
205
|
-
if (!adapter) continue;
|
|
206
|
-
|
|
207
|
-
console.log(`${this.getAutomationIcon(adapter.automationLevel)} ${adapter.name.toUpperCase()}`);
|
|
208
|
-
console.log(` ${adapter.description}`);
|
|
209
|
-
console.log(` Automation: ${adapter.automationLevel} | Market: ${adapterInfo.market_share}`);
|
|
210
|
-
console.log('');
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
console.log('━'.repeat(70));
|
|
214
|
-
console.log('\nTotal Market Coverage: 100%');
|
|
215
|
-
console.log('SpecWeave works with ANY AI coding tool!');
|
|
216
|
-
console.log('\n💡 Claude Code = Native experience (no adapter)');
|
|
217
|
-
console.log(' Other tools = Adapters approximate Claude\'s capabilities\n');
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Get icon for automation level
|
|
222
|
-
*/
|
|
223
|
-
private getAutomationIcon(level: string): string {
|
|
224
|
-
switch (level) {
|
|
225
|
-
case 'full': return '🚀';
|
|
226
|
-
case 'semi': return '⚡';
|
|
227
|
-
case 'basic': return '📝';
|
|
228
|
-
case 'manual': return '📖';
|
|
229
|
-
default: return '❓';
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Get recommended adapter based on detection and user preference
|
|
235
|
-
*/
|
|
236
|
-
async getRecommendedAdapter(explicitChoice?: string): Promise<IAdapter> {
|
|
237
|
-
// If user explicitly chose an adapter, use it
|
|
238
|
-
if (explicitChoice) {
|
|
239
|
-
const adapter = this.adapters.get(explicitChoice);
|
|
240
|
-
if (!adapter) {
|
|
241
|
-
throw new Error(`Invalid adapter: ${explicitChoice}. Use 'claude', 'cursor', or 'generic'`);
|
|
242
|
-
}
|
|
243
|
-
return adapter;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Otherwise, auto-detect
|
|
247
|
-
const detectedName = await this.detectTool();
|
|
248
|
-
const adapter = this.adapters.get(detectedName);
|
|
249
|
-
|
|
250
|
-
if (!adapter) {
|
|
251
|
-
throw new Error(`Detected adapter not found: ${detectedName}`);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return adapter;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AGENTS.md Generator
|
|
3
|
-
*
|
|
4
|
-
* Generates a universal AGENTS.md file for ALL AI coding tools EXCEPT Claude Code.
|
|
5
|
-
* Follows the agents.md standard: https://agents.md/
|
|
6
|
-
*
|
|
7
|
-
* IMPORTANT:
|
|
8
|
-
* - Claude Code does NOT read this file - it only reads CLAUDE.md
|
|
9
|
-
* - This file is for: Cursor, GitHub Copilot, ChatGPT, Gemini, and ANY other AI tool
|
|
10
|
-
*
|
|
11
|
-
* This ONE file replaces:
|
|
12
|
-
* - .cursorrules (Cursor - legacy)
|
|
13
|
-
* - .github/copilot/instructions.md (Copilot - no longer needed, Copilot reads AGENTS.md)
|
|
14
|
-
* - Any other tool-specific configuration files
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { DocGenerator } from './doc-generator.js';
|
|
18
|
-
import * as path from 'path';
|
|
19
|
-
import fs from 'fs-extra';
|
|
20
|
-
import { getDirname } from '../utils/esm-helpers.js';
|
|
21
|
-
|
|
22
|
-
const __dirname = getDirname(import.meta.url);
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Find the package root by walking up the directory tree looking for package.json
|
|
26
|
-
* This works reliably on all platforms including Windows with UNC paths
|
|
27
|
-
*/
|
|
28
|
-
function findPackageRoot(startDir: string): string | null {
|
|
29
|
-
let currentDir = startDir;
|
|
30
|
-
const root = path.parse(currentDir).root;
|
|
31
|
-
|
|
32
|
-
while (currentDir !== root) {
|
|
33
|
-
const packageJsonPath = path.join(currentDir, 'package.json');
|
|
34
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
35
|
-
try {
|
|
36
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
37
|
-
// Verify this is the specweave package
|
|
38
|
-
if (packageJson.name === 'specweave') {
|
|
39
|
-
return currentDir;
|
|
40
|
-
}
|
|
41
|
-
} catch (error) {
|
|
42
|
-
// Not a valid package.json, continue searching
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
const parentDir = path.dirname(currentDir);
|
|
46
|
-
if (parentDir === currentDir) break; // Reached root
|
|
47
|
-
currentDir = parentDir;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Find template file using package root detection
|
|
55
|
-
*/
|
|
56
|
-
function findTemplateFile(filename: string): string | null {
|
|
57
|
-
const packageRoot = findPackageRoot(__dirname);
|
|
58
|
-
|
|
59
|
-
if (packageRoot) {
|
|
60
|
-
// Try src/templates/ first (for npm installs)
|
|
61
|
-
const srcPath = path.normalize(path.join(packageRoot, 'src', 'templates', filename));
|
|
62
|
-
if (fs.existsSync(srcPath)) {
|
|
63
|
-
return srcPath;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Try dist/templates/ (shouldn't exist but try anyway)
|
|
67
|
-
const distPath = path.normalize(path.join(packageRoot, 'dist', 'templates', filename));
|
|
68
|
-
if (fs.existsSync(distPath)) {
|
|
69
|
-
return distPath;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Try templates/ directly in package root
|
|
73
|
-
const rootPath = path.normalize(path.join(packageRoot, 'templates', filename));
|
|
74
|
-
if (fs.existsSync(rootPath)) {
|
|
75
|
-
return rootPath;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface AgentsMdOptions {
|
|
83
|
-
projectName: string;
|
|
84
|
-
projectPath: string;
|
|
85
|
-
templatePath?: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Generate universal AGENTS.md file
|
|
90
|
-
*/
|
|
91
|
-
export class AgentsMdGenerator {
|
|
92
|
-
private docGen: DocGenerator;
|
|
93
|
-
|
|
94
|
-
constructor(
|
|
95
|
-
skillsDir?: string,
|
|
96
|
-
agentsDir?: string,
|
|
97
|
-
commandsDir?: string
|
|
98
|
-
) {
|
|
99
|
-
this.docGen = new DocGenerator(skillsDir, agentsDir, commandsDir);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Generate complete AGENTS.md content
|
|
104
|
-
*/
|
|
105
|
-
async generate(options: AgentsMdOptions): Promise<string> {
|
|
106
|
-
// Read template - use provided path or find it via package root
|
|
107
|
-
let templatePath = options.templatePath;
|
|
108
|
-
|
|
109
|
-
if (!templatePath || !await fs.pathExists(templatePath)) {
|
|
110
|
-
// Fallback: try to find template using package root detection
|
|
111
|
-
const foundPath = findTemplateFile('AGENTS.md.template');
|
|
112
|
-
if (foundPath) {
|
|
113
|
-
templatePath = foundPath;
|
|
114
|
-
} else {
|
|
115
|
-
const errorMsg = options.templatePath
|
|
116
|
-
? `AGENTS.md template not found at: ${options.templatePath}\nAlso tried package root detection but failed.`
|
|
117
|
-
: `AGENTS.md template not found. Tried:\n - Package root detection\n - __dirname: ${__dirname}\n - Default: ${path.join(__dirname, '../templates/AGENTS.md.template')}`;
|
|
118
|
-
throw new Error(errorMsg);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
let content = await fs.readFile(templatePath, 'utf-8');
|
|
123
|
-
|
|
124
|
-
// Extract agents and skills
|
|
125
|
-
const skills = await this.docGen.extractSkills();
|
|
126
|
-
const agents = await this.docGen.extractAgents();
|
|
127
|
-
|
|
128
|
-
// Replace placeholders
|
|
129
|
-
content = content.replace(/\{PROJECT_NAME\}/g, options.projectName);
|
|
130
|
-
content = content.replace('{AGENTS_SECTION}', this.generateAgentsSection(agents));
|
|
131
|
-
content = content.replace('{SKILLS_SECTION}', this.generateSkillsSection(skills));
|
|
132
|
-
content = content.replace('{TIMESTAMP}', new Date().toISOString().split('T')[0]);
|
|
133
|
-
|
|
134
|
-
return content;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Generate agents section as simple Markdown
|
|
139
|
-
*/
|
|
140
|
-
private generateAgentsSection(agents: any[]): string {
|
|
141
|
-
let section = '';
|
|
142
|
-
|
|
143
|
-
for (const agent of agents) {
|
|
144
|
-
section += `### ${agent.role}\n`;
|
|
145
|
-
section += `**Purpose**: ${agent.description}\n`;
|
|
146
|
-
section += `**When to use**: ${this.getAgentActivation(agent.name)}\n`;
|
|
147
|
-
section += `**Location**: \`.claude/agents/${agent.name}/AGENT.md\`\n\n`;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return section;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Get agent activation guidance
|
|
155
|
-
*/
|
|
156
|
-
private getAgentActivation(agentName: string): string {
|
|
157
|
-
const activations: Record<string, string> = {
|
|
158
|
-
'pm': 'Creating requirements, user stories, product specs (WHAT/WHY)',
|
|
159
|
-
'architect': 'System design, architecture decisions, technical plans (HOW)',
|
|
160
|
-
'devops': 'Infrastructure, deployment, CI/CD pipelines',
|
|
161
|
-
'qa-lead': 'Test strategy, test cases, quality assurance',
|
|
162
|
-
'security': 'Threat modeling, security review, vulnerability assessment',
|
|
163
|
-
'tech-lead': 'Code review, best practices, refactoring',
|
|
164
|
-
'frontend': 'UI components, React/Vue/Angular implementation',
|
|
165
|
-
'nodejs-backend': 'Node.js/Express/NestJS backend APIs',
|
|
166
|
-
'python-backend': 'FastAPI/Django backend APIs',
|
|
167
|
-
'nextjs': 'Next.js App Router applications',
|
|
168
|
-
'dotnet-backend': 'ASP.NET Core backend APIs',
|
|
169
|
-
'sre': 'Incident response, troubleshooting, runbooks',
|
|
170
|
-
'docs-writer': 'Technical documentation, API docs, guides',
|
|
171
|
-
'performance': 'Performance optimization, profiling, benchmarking'
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
return activations[agentName] || 'Specialized tasks requiring this expertise';
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Generate skills section as simple Markdown
|
|
179
|
-
*/
|
|
180
|
-
private generateSkillsSection(skills: any[]): string {
|
|
181
|
-
let section = '';
|
|
182
|
-
|
|
183
|
-
for (const skill of skills) {
|
|
184
|
-
section += `### ${skill.name}\n`;
|
|
185
|
-
section += `**Purpose**: ${skill.description}\n`;
|
|
186
|
-
section += `**When to use**: ${this.getSkillActivation(skill.name)}\n`;
|
|
187
|
-
section += `**Location**: \`.claude/skills/${skill.name}/SKILL.md\`\n\n`;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return section;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Get skill activation guidance
|
|
195
|
-
*/
|
|
196
|
-
private getSkillActivation(skillName: string): string {
|
|
197
|
-
const activations: Record<string, string> = {
|
|
198
|
-
'specweave-detector': 'User asks about SpecWeave commands or workflows',
|
|
199
|
-
'increment-planner': 'Creating new feature increments (/inc command)',
|
|
200
|
-
'context-loader': 'Working on increments, need to load relevant context',
|
|
201
|
-
'skill-router': 'Ambiguous requests that need routing to specific skills',
|
|
202
|
-
'spec-driven-debugging': 'Bug investigation, test failures, unexpected behavior',
|
|
203
|
-
'spec-driven-brainstorming': 'Brainstorming ideas, refining concepts, design thinking',
|
|
204
|
-
'brownfield-analyzer': 'Analyzing existing projects for SpecWeave migration',
|
|
205
|
-
'brownfield-onboarder': 'Onboarding existing projects to SpecWeave',
|
|
206
|
-
'nodejs-backend': 'Node.js/Express/NestJS backend development',
|
|
207
|
-
'python-backend': 'Python/FastAPI/Django backend development',
|
|
208
|
-
'nextjs': 'Next.js App Router application development',
|
|
209
|
-
'frontend': 'React/Vue/Angular frontend development',
|
|
210
|
-
'dotnet-backend': 'ASP.NET Core backend development',
|
|
211
|
-
'e2e-playwright': 'End-to-end testing with Playwright',
|
|
212
|
-
'jira-sync': 'JIRA integration and synchronization',
|
|
213
|
-
'github-sync': 'GitHub issues/milestones synchronization',
|
|
214
|
-
'ado-sync': 'Azure DevOps synchronization',
|
|
215
|
-
'hetzner-provisioner': 'Hetzner Cloud infrastructure provisioning',
|
|
216
|
-
'cost-optimizer': 'Cloud cost optimization and platform comparison',
|
|
217
|
-
'figma-mcp-connector': 'Figma design integration via MCP',
|
|
218
|
-
'design-system-architect': 'Design system and Atomic Design methodology',
|
|
219
|
-
'figma-designer': 'Figma design creation and design tokens',
|
|
220
|
-
'figma-implementer': 'Converting Figma designs to code',
|
|
221
|
-
'figma-to-code': 'Figma to React/Angular code generation',
|
|
222
|
-
'role-orchestrator': 'Multi-agent orchestration for complex tasks',
|
|
223
|
-
'increment-quality-judge': 'AI-powered quality assessment of specs and plans'
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
return activations[skillName] || 'Specialized tasks';
|
|
227
|
-
}
|
|
228
|
-
}
|