specweave 1.0.362 → 1.0.367
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/bin/specweave.js +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +33 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/sync-progress.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-progress.js +1 -0
- package/dist/src/cli/commands/sync-progress.js.map +1 -1
- package/dist/src/core/config/config-manager.d.ts.map +1 -1
- package/dist/src/core/config/config-manager.js +6 -0
- package/dist/src/core/config/config-manager.js.map +1 -1
- package/dist/src/core/config/types.d.ts +2 -2
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.js +69 -0
- package/dist/src/core/lazy-loading/llm-plugin-detector.js.map +1 -1
- package/dist/src/core/migration/umbrella-migrator.d.ts.map +1 -1
- package/dist/src/core/migration/umbrella-migrator.js +17 -1
- package/dist/src/core/migration/umbrella-migrator.js.map +1 -1
- package/dist/src/sync/external-issue-auto-creator.d.ts.map +1 -1
- package/dist/src/sync/external-issue-auto-creator.js +13 -1
- package/dist/src/sync/external-issue-auto-creator.js.map +1 -1
- package/dist/src/sync/sync-target-resolver.d.ts +2 -2
- package/dist/src/sync/sync-target-resolver.d.ts.map +1 -1
- package/dist/src/sync/sync-target-resolver.js +17 -4
- package/dist/src/sync/sync-target-resolver.js.map +1 -1
- package/package.json +1 -1
- package/plugins/SKILLS-VS-AGENTS.md +212 -119
- package/plugins/specweave/agents/sw-architect.md +8 -67
- package/plugins/specweave/agents/sw-planner.md +10 -82
- package/plugins/specweave/agents/sw-pm.md +9 -103
- package/plugins/specweave/hooks/.specweave/logs/auto-iterations.log +1 -0
- package/plugins/specweave/hooks/.specweave/logs/auto-stop-reasons.log +1 -0
- package/plugins/specweave/skills/.specweave/logs/reflect/auto-reflect.log +15 -0
- package/plugins/specweave/skills/.specweave/logs/reflect/reflect.log +3 -0
- package/plugins/specweave/skills/.specweave/logs/stop-auto.log +1 -0
- package/plugins/specweave/skills/brainstorm/SKILL.md +128 -26
- package/plugins/specweave/skills/increment/SKILL.md +50 -32
- package/plugins/specweave/skills/pm/SKILL.md +28 -1
- package/plugins/specweave/skills/pm/phases/02-spec-creation.md +17 -0
- package/plugins/specweave/skills/team-lead/agents/database.md +12 -12
- package/plugins/specweave/skills/team-lead/agents/security.md +12 -12
- package/plugins/specweave/skills/team-lead/agents/testing.md +12 -12
- package/plugins/specweave/skills/team-merge/SKILL.md +11 -0
- package/plugins/specweave/skills/test-aware-planner/SKILL.md +1 -1
- package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +180 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1266 -0
- package/plugins/specweave-github/lib/enhanced-github-sync.js +249 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +150 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1260 -0
|
@@ -26,21 +26,21 @@ WORKFLOW:
|
|
|
26
26
|
3. Create YOUR increment in YOUR repo: .specweave/increments/[ID]/
|
|
27
27
|
4. Activate the increment: Edit metadata.json to set "status": "active" and update "lastActivity" timestamp
|
|
28
28
|
5. Read the MASTER SPEC at [MASTER_INCREMENT_PATH]/spec.md for scope and ACs
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
6. Audit code produced by other agents for security issues
|
|
30
|
+
7. Create plan files (plan.md, tasks.md) for your increment
|
|
31
|
+
8. Send plan to team-lead and WAIT for approval:
|
|
32
32
|
SendMessage({ type: "message", recipient: "team-lead",
|
|
33
33
|
content: "PLAN_READY: [increment path]. [summary of security findings, hardening plan].",
|
|
34
34
|
summary: "Security plan ready for review" })
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
9. WAIT for "PLAN_APPROVED" message. If "PLAN_REJECTED", revise and re-submit.
|
|
36
|
+
10. Implement auth/authz middleware if needed
|
|
37
|
+
11. Add input validation and sanitization
|
|
38
|
+
12. Execute tasks autonomously: /sw:auto --simple (minimal context mode to prevent context overflow)
|
|
39
|
+
13. Run all tests for owned code (security tests): npm test
|
|
40
|
+
14. Run security audit tools (npm audit, dependency check)
|
|
41
|
+
15. Do NOT signal completion until all tests pass
|
|
42
|
+
16. Signal COMPLETION via SendMessage to team-lead with summary of tasks done, test results, and security findings
|
|
43
|
+
17. Do NOT run /sw:done or /sw:grill yourself — team-lead handles closure centrally
|
|
44
44
|
|
|
45
45
|
RULES:
|
|
46
46
|
- WRITE only to files you own (listed above)
|
|
@@ -31,21 +31,21 @@ WORKFLOW:
|
|
|
31
31
|
3. Create YOUR increment in YOUR repo: .specweave/increments/[ID]/
|
|
32
32
|
4. Activate the increment: Edit metadata.json to set "status": "active" and update "lastActivity" timestamp
|
|
33
33
|
5. Read the MASTER SPEC at [MASTER_INCREMENT_PATH]/spec.md for scope and ACs
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
6. Wait for ALL other agents to produce initial code
|
|
35
|
+
7. Create plan files (plan.md, tasks.md) for your increment
|
|
36
|
+
8. Send plan to team-lead and WAIT for approval:
|
|
37
37
|
SendMessage({ type: "message", recipient: "team-lead",
|
|
38
38
|
content: "PLAN_READY: [increment path]. [summary of test strategy, coverage plan].",
|
|
39
39
|
summary: "Testing plan ready for review" })
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
9. WAIT for "PLAN_APPROVED" message. If "PLAN_REJECTED", revise and re-submit.
|
|
41
|
+
10. Write unit tests for new services/components
|
|
42
|
+
11. Write integration tests for API endpoints
|
|
43
|
+
12. Write E2E tests for user journeys
|
|
44
|
+
13. Execute tasks autonomously: /sw:auto --simple (minimal context mode to prevent context overflow)
|
|
45
|
+
14. Run all tests (unit + integration + E2E): npm test && npx playwright test
|
|
46
|
+
15. Do NOT signal completion until all tests pass -- if tests fail, fix and repeat
|
|
47
|
+
16. Signal COMPLETION via SendMessage to team-lead with summary of tasks done and test results
|
|
48
|
+
17. Do NOT run /sw:done or /sw:grill yourself — team-lead handles closure centrally
|
|
49
49
|
|
|
50
50
|
RULES:
|
|
51
51
|
- WRITE only to test files (listed above)
|
|
@@ -71,15 +71,26 @@ Closure order respects contract chain:
|
|
|
71
71
|
For each teammate's increment, in dependency order:
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
|
+
# PRE-CLOSURE: Ensure increment is in "active" status (agents may not have activated it)
|
|
75
|
+
STATUS=$(jq -r '.status' .specweave/increments/<id>/metadata.json)
|
|
76
|
+
if [ "$STATUS" = "planned" ] || [ "$STATUS" = "backlog" ]; then
|
|
77
|
+
# Edit metadata.json to set "status": "active"
|
|
78
|
+
fi
|
|
79
|
+
|
|
74
80
|
# Run /sw:done --auto per increment -- triggers quality gates, skips user confirmation
|
|
75
81
|
/sw:done <increment-id> --auto
|
|
82
|
+
|
|
83
|
+
# If /sw:done fails, fix root cause and retry (max 2 retries)
|
|
84
|
+
# Common fixes: sync ACs, update task counts, write missing reports
|
|
76
85
|
```
|
|
77
86
|
|
|
78
87
|
This ensures:
|
|
88
|
+
- Increment is in correct lifecycle status before closure attempt
|
|
79
89
|
- `/sw:grill` runs for each increment
|
|
80
90
|
- `tasks.md` and `spec.md` ACs are validated
|
|
81
91
|
- `metadata.json` is updated to `completed`
|
|
82
92
|
- Living docs are generated
|
|
93
|
+
- Failures are retried rather than silently skipped
|
|
83
94
|
|
|
84
95
|
### Step 5: Trigger Sync
|
|
85
96
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Generate tasks.md with embedded test plans in BDD format, one user story at a time to prevent crashes. Use for test-first task planning where each task includes Given/When/Then scenarios. Produces implementation tasks with inline test specifications.
|
|
3
3
|
context: fork
|
|
4
|
-
model:
|
|
4
|
+
model: sonnet
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Test-Aware Planner Skill
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { AdoClientV2 } from "./ado-client-v2.js";
|
|
2
|
+
import { EnhancedContentBuilder } from "../../../src/core/sync/enhanced-content-builder.js";
|
|
3
|
+
import { SpecIncrementMapper } from "../../../src/core/sync/spec-increment-mapper.js";
|
|
4
|
+
import { parseSpecContent } from "../../../src/core/spec-content-sync.js";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import fs from "fs/promises";
|
|
7
|
+
async function syncSpecToAdoWithEnhancedContent(options) {
|
|
8
|
+
const { specPath, organization, project, dryRun = false, verbose = false } = options;
|
|
9
|
+
try {
|
|
10
|
+
const baseSpec = await parseSpecContent(specPath);
|
|
11
|
+
if (!baseSpec) {
|
|
12
|
+
return {
|
|
13
|
+
success: false,
|
|
14
|
+
action: "error",
|
|
15
|
+
error: "Failed to parse spec content"
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (verbose) {
|
|
19
|
+
console.log(`\u{1F4C4} Parsed spec: ${baseSpec.identifier.compact}`);
|
|
20
|
+
}
|
|
21
|
+
const specId = baseSpec.identifier.full || baseSpec.identifier.compact;
|
|
22
|
+
const rootDir = await findSpecWeaveRoot(specPath);
|
|
23
|
+
const mapper = new SpecIncrementMapper(rootDir);
|
|
24
|
+
const mapping = await mapper.mapSpecToIncrements(specId);
|
|
25
|
+
if (verbose) {
|
|
26
|
+
console.log(`\u{1F517} Found ${mapping.increments.length} related increments`);
|
|
27
|
+
}
|
|
28
|
+
const taskMapping = buildTaskMapping(mapping.increments, organization, project);
|
|
29
|
+
const architectureDocs = await findArchitectureDocs(rootDir, specId);
|
|
30
|
+
const enhancedSpec = {
|
|
31
|
+
...baseSpec,
|
|
32
|
+
summary: baseSpec.description,
|
|
33
|
+
taskMapping,
|
|
34
|
+
architectureDocs
|
|
35
|
+
};
|
|
36
|
+
const builder = new EnhancedContentBuilder();
|
|
37
|
+
const description = builder.buildExternalDescription(enhancedSpec);
|
|
38
|
+
if (verbose) {
|
|
39
|
+
console.log(`\u{1F4DD} Generated description: ${description.length} characters`);
|
|
40
|
+
}
|
|
41
|
+
if (dryRun) {
|
|
42
|
+
console.log("\u{1F50D} DRY RUN - Would create/update feature with:");
|
|
43
|
+
console.log(` Title: ${baseSpec.title}`);
|
|
44
|
+
console.log(` Description length: ${description.length}`);
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
action: "no-change",
|
|
48
|
+
tasksLinked: taskMapping?.tasks.length || 0
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (!organization || !project) {
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
action: "error",
|
|
55
|
+
error: "Azure DevOps organization/project not specified"
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const profile = {
|
|
59
|
+
provider: "ado",
|
|
60
|
+
displayName: `${organization}/${project}`,
|
|
61
|
+
config: {
|
|
62
|
+
organization,
|
|
63
|
+
project
|
|
64
|
+
},
|
|
65
|
+
timeRange: { default: "1M", max: "6M" }
|
|
66
|
+
};
|
|
67
|
+
const pat = process.env.AZURE_DEVOPS_PAT || "";
|
|
68
|
+
const client = new AdoClientV2(profile, pat);
|
|
69
|
+
const existingFeature = await findExistingFeature(client, baseSpec.identifier.compact);
|
|
70
|
+
let result;
|
|
71
|
+
if (existingFeature) {
|
|
72
|
+
await client.updateWorkItem(existingFeature.id, {
|
|
73
|
+
title: `[${baseSpec.identifier.compact}] ${baseSpec.title}`,
|
|
74
|
+
description
|
|
75
|
+
});
|
|
76
|
+
result = {
|
|
77
|
+
success: true,
|
|
78
|
+
action: "updated",
|
|
79
|
+
featureId: existingFeature.id,
|
|
80
|
+
featureUrl: `https://dev.azure.com/${organization}/${project}/_workitems/edit/${existingFeature.id}`,
|
|
81
|
+
tasksLinked: taskMapping?.tasks.length || 0
|
|
82
|
+
};
|
|
83
|
+
} else {
|
|
84
|
+
const feature = await client.createEpic({
|
|
85
|
+
title: `[${baseSpec.identifier.compact}] ${baseSpec.title}`,
|
|
86
|
+
description,
|
|
87
|
+
tags: ["spec", "external-tool-sync"]
|
|
88
|
+
});
|
|
89
|
+
result = {
|
|
90
|
+
success: true,
|
|
91
|
+
action: "created",
|
|
92
|
+
featureId: feature.id,
|
|
93
|
+
featureUrl: `https://dev.azure.com/${organization}/${project}/_workitems/edit/${feature.id}`,
|
|
94
|
+
tasksLinked: taskMapping?.tasks.length || 0
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (verbose) {
|
|
98
|
+
console.log(`\u2705 ${result.action === "created" ? "Created" : "Updated"} feature #${result.featureId}`);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
action: "error",
|
|
105
|
+
error: error.message
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function findSpecWeaveRoot(specPath) {
|
|
110
|
+
let currentDir = path.dirname(specPath);
|
|
111
|
+
while (true) {
|
|
112
|
+
const specweaveDir = path.join(currentDir, ".specweave");
|
|
113
|
+
try {
|
|
114
|
+
await fs.access(specweaveDir);
|
|
115
|
+
return currentDir;
|
|
116
|
+
} catch {
|
|
117
|
+
const parentDir = path.dirname(currentDir);
|
|
118
|
+
if (parentDir === currentDir) {
|
|
119
|
+
throw new Error(".specweave directory not found");
|
|
120
|
+
}
|
|
121
|
+
currentDir = parentDir;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function buildTaskMapping(increments, organization, project) {
|
|
126
|
+
if (increments.length === 0) return void 0;
|
|
127
|
+
const firstIncrement = increments[0];
|
|
128
|
+
const tasks = firstIncrement.tasks.map((task) => ({
|
|
129
|
+
id: task.id,
|
|
130
|
+
title: task.title,
|
|
131
|
+
userStories: task.userStories
|
|
132
|
+
}));
|
|
133
|
+
// Derive repository name from git remote or fall back to project name
|
|
134
|
+
let repoName = project;
|
|
135
|
+
try {
|
|
136
|
+
const { execSync } = require("child_process");
|
|
137
|
+
const remoteUrl = execSync("git remote get-url origin", { encoding: "utf-8" }).trim();
|
|
138
|
+
const match = remoteUrl.match(/\/([^/]+?)(?:\.git)?$/);
|
|
139
|
+
if (match) repoName = match[1];
|
|
140
|
+
} catch {
|
|
141
|
+
// Fallback to project name if git is unavailable
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
incrementId: firstIncrement.id,
|
|
145
|
+
tasks,
|
|
146
|
+
tasksUrl: `https://dev.azure.com/${organization}/${project}/_git/${repoName}?path=/.specweave/increments/${firstIncrement.id}/tasks.md`
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async function findArchitectureDocs(rootDir, specId) {
|
|
150
|
+
const docs = [];
|
|
151
|
+
const archDir = path.join(rootDir, ".specweave/docs/internal/architecture");
|
|
152
|
+
try {
|
|
153
|
+
const adrDir = path.join(archDir, "adr");
|
|
154
|
+
try {
|
|
155
|
+
const adrs = await fs.readdir(adrDir);
|
|
156
|
+
const relatedAdrs = adrs.filter((file) => file.includes(specId.replace("spec-", "")));
|
|
157
|
+
for (const adr of relatedAdrs) {
|
|
158
|
+
docs.push({
|
|
159
|
+
type: "adr",
|
|
160
|
+
path: path.join(adrDir, adr),
|
|
161
|
+
title: adr.replace(".md", "").replace(/-/g, " ")
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
} catch {
|
|
165
|
+
}
|
|
166
|
+
} catch {
|
|
167
|
+
}
|
|
168
|
+
return docs;
|
|
169
|
+
}
|
|
170
|
+
async function findExistingFeature(client, specId) {
|
|
171
|
+
try {
|
|
172
|
+
const features = await client.queryWorkItems(`[System.Title] Contains '[${specId}]' AND [System.WorkItemType] = 'Feature'`);
|
|
173
|
+
return features[0] || null;
|
|
174
|
+
} catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export {
|
|
179
|
+
syncSpecToAdoWithEnhancedContent
|
|
180
|
+
};
|