specweave 1.0.488 → 1.0.489
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 +1 -1
- package/dist/plugins/specweave-ado/lib/ado-ac-checkbox-sync.d.ts +13 -5
- package/dist/plugins/specweave-ado/lib/ado-ac-checkbox-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-ac-checkbox-sync.js +28 -26
- package/dist/plugins/specweave-ado/lib/ado-ac-checkbox-sync.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-client.d.ts +10 -0
- package/dist/plugins/specweave-ado/lib/ado-client.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-client.js +14 -0
- package/dist/plugins/specweave-ado/lib/ado-client.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-pull-sync.d.ts +35 -0
- package/dist/plugins/specweave-ado/lib/ado-pull-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-pull-sync.js +53 -0
- package/dist/plugins/specweave-ado/lib/ado-pull-sync.js.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-rate-limiter.d.ts +46 -0
- package/dist/plugins/specweave-ado/lib/ado-rate-limiter.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-rate-limiter.js +65 -0
- package/dist/plugins/specweave-ado/lib/ado-rate-limiter.js.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.d.ts +7 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.js +25 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts +17 -1
- package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-status-sync.js +51 -9
- package/dist/plugins/specweave-ado/lib/ado-status-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-push-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-push-sync.js +15 -3
- package/dist/plugins/specweave-github/lib/github-push-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.d.ts +31 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.js +170 -97
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts +36 -1
- package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-status-sync.js +185 -82
- package/dist/plugins/specweave-jira/lib/jira-status-sync.js.map +1 -1
- package/dist/src/adapters/adapter-loader.d.ts.map +1 -1
- package/dist/src/adapters/adapter-loader.js +8 -2
- package/dist/src/adapters/adapter-loader.js.map +1 -1
- package/dist/src/adapters/codex/adapter.d.ts.map +1 -1
- package/dist/src/adapters/codex/adapter.js +1 -0
- package/dist/src/adapters/codex/adapter.js.map +1 -1
- package/dist/src/adapters/cursor/adapter.d.ts.map +1 -1
- package/dist/src/adapters/cursor/adapter.js +1 -0
- package/dist/src/adapters/cursor/adapter.js.map +1 -1
- package/dist/src/adapters/generic/adapter.d.ts +6 -3
- package/dist/src/adapters/generic/adapter.d.ts.map +1 -1
- package/dist/src/adapters/generic/adapter.js +53 -47
- package/dist/src/adapters/generic/adapter.js.map +1 -1
- package/dist/src/adapters/kimi/adapter.d.ts +21 -0
- package/dist/src/adapters/kimi/adapter.d.ts.map +1 -0
- package/dist/src/adapters/kimi/adapter.js +57 -0
- package/dist/src/adapters/kimi/adapter.js.map +1 -0
- package/dist/src/adapters/opencode/adapter.d.ts +24 -0
- package/dist/src/adapters/opencode/adapter.d.ts.map +1 -0
- package/dist/src/adapters/opencode/adapter.js +71 -0
- package/dist/src/adapters/opencode/adapter.js.map +1 -0
- package/dist/src/adapters/registry.yaml +59 -0
- package/dist/src/adapters/trae/adapter.d.ts +21 -0
- package/dist/src/adapters/trae/adapter.d.ts.map +1 -0
- package/dist/src/adapters/trae/adapter.js +64 -0
- package/dist/src/adapters/trae/adapter.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +156 -5
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/update-instructions.d.ts.map +1 -1
- package/dist/src/cli/commands/update-instructions.js +10 -0
- package/dist/src/cli/commands/update-instructions.js.map +1 -1
- package/dist/src/cli/helpers/init/index.d.ts +1 -0
- package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/index.js +2 -0
- package/dist/src/cli/helpers/init/index.js.map +1 -1
- package/dist/src/cli/helpers/init/next-steps.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/next-steps.js +52 -0
- package/dist/src/cli/helpers/init/next-steps.js.map +1 -1
- package/dist/src/cli/helpers/init/skill-creator-installer.d.ts +24 -0
- package/dist/src/cli/helpers/init/skill-creator-installer.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/skill-creator-installer.js +54 -0
- package/dist/src/cli/helpers/init/skill-creator-installer.js.map +1 -0
- package/dist/src/core/ado-description-updater.d.ts +22 -0
- package/dist/src/core/ado-description-updater.d.ts.map +1 -0
- package/dist/src/core/ado-description-updater.js +46 -0
- package/dist/src/core/ado-description-updater.js.map +1 -0
- package/dist/src/core/closure-dispatcher.d.ts +96 -0
- package/dist/src/core/closure-dispatcher.d.ts.map +1 -0
- package/dist/src/core/closure-dispatcher.js +116 -0
- package/dist/src/core/closure-dispatcher.js.map +1 -0
- package/dist/src/core/config/types.d.ts +2 -0
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/errors/sync-error.d.ts +12 -0
- package/dist/src/core/errors/sync-error.d.ts.map +1 -0
- package/dist/src/core/errors/sync-error.js +19 -0
- package/dist/src/core/errors/sync-error.js.map +1 -0
- package/dist/src/core/skill-gen/rule-collector.d.ts +28 -0
- package/dist/src/core/skill-gen/rule-collector.d.ts.map +1 -0
- package/dist/src/core/skill-gen/rule-collector.js +112 -0
- package/dist/src/core/skill-gen/rule-collector.js.map +1 -0
- package/dist/src/core/skill-gen/signal-collector.d.ts +2 -1
- package/dist/src/core/skill-gen/signal-collector.d.ts.map +1 -1
- package/dist/src/core/skill-gen/signal-collector.js +21 -5
- package/dist/src/core/skill-gen/signal-collector.js.map +1 -1
- package/dist/src/core/sync/persistent-circuit-breaker.d.ts +22 -0
- package/dist/src/core/sync/persistent-circuit-breaker.d.ts.map +1 -0
- package/dist/src/core/sync/persistent-circuit-breaker.js +65 -0
- package/dist/src/core/sync/persistent-circuit-breaker.js.map +1 -0
- package/dist/src/core/sync/retry-wrapper.d.ts +13 -0
- package/dist/src/core/sync/retry-wrapper.d.ts.map +1 -0
- package/dist/src/core/sync/retry-wrapper.js +37 -0
- package/dist/src/core/sync/retry-wrapper.js.map +1 -0
- package/dist/src/importers/ac-parser.d.ts +27 -0
- package/dist/src/importers/ac-parser.d.ts.map +1 -0
- package/dist/src/importers/ac-parser.js +47 -0
- package/dist/src/importers/ac-parser.js.map +1 -0
- package/dist/src/sync/types.d.ts +8 -0
- package/dist/src/sync/types.d.ts.map +1 -1
- package/dist/src/sync/types.js +12 -0
- package/dist/src/sync/types.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-silent-failures.md +65 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-spec-compliance.md +83 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-types.md +68 -0
- package/plugins/specweave/skills/skill-gen/SKILL.md +20 -3
- package/plugins/specweave/skills/team-lead/agents/architect.md +52 -0
- package/plugins/specweave/skills/team-lead/agents/pm.md +50 -0
- package/plugins/specweave/skills/team-lead/agents/researcher.md +64 -0
- package/plugins/specweave-ado/lib/ado-ac-checkbox-sync.js +23 -21
- package/plugins/specweave-ado/lib/ado-ac-checkbox-sync.ts +37 -29
- package/plugins/specweave-ado/lib/ado-client.js +14 -0
- package/plugins/specweave-ado/lib/ado-client.ts +18 -0
- package/plugins/specweave-ado/lib/ado-pull-sync.js +35 -0
- package/plugins/specweave-ado/lib/ado-pull-sync.ts +74 -0
- package/plugins/specweave-ado/lib/ado-rate-limiter.js +56 -0
- package/plugins/specweave-ado/lib/ado-rate-limiter.ts +86 -0
- package/plugins/specweave-ado/lib/ado-spec-sync.js +25 -1
- package/plugins/specweave-ado/lib/ado-spec-sync.ts +32 -2
- package/plugins/specweave-ado/lib/ado-status-sync.js +52 -14
- package/plugins/specweave-ado/lib/ado-status-sync.ts +64 -16
- package/plugins/specweave-github/lib/github-client-v2.ts +1 -1
- package/plugins/specweave-github/lib/github-push-sync.js +11 -3
- package/plugins/specweave-github/lib/github-push-sync.ts +16 -3
- package/plugins/specweave-jira/lib/jira-spec-sync.js +60 -1
- package/plugins/specweave-jira/lib/jira-spec-sync.ts +93 -1
- package/plugins/specweave-jira/lib/jira-status-sync.js +151 -109
- package/plugins/specweave-jira/lib/jira-status-sync.ts +161 -39
|
@@ -14,6 +14,7 @@ import { join, relative } from 'path';
|
|
|
14
14
|
import { SKILL_GEN_DEFAULTS } from './types.js';
|
|
15
15
|
import { collectMarkdownFiles, loadSignalStore, saveSignalStore, sanitizeString, estimateTokenCount, capEvidence, TOKEN_BUDGET, } from './utils.js';
|
|
16
16
|
import { loadLLMConfig, createProvider, hasLLMConfig } from '../llm/provider-factory.js';
|
|
17
|
+
import { RuleCollector } from './rule-collector.js';
|
|
17
18
|
const LLM_PATTERN_SCHEMA = {
|
|
18
19
|
type: 'object',
|
|
19
20
|
properties: {
|
|
@@ -39,6 +40,7 @@ export class SignalCollector {
|
|
|
39
40
|
this.projectRoot = projectRoot;
|
|
40
41
|
this.maxSignals = options?.maxSignals ?? SKILL_GEN_DEFAULTS.maxSignals;
|
|
41
42
|
this.minSignalCount = options?.minSignalCount ?? SKILL_GEN_DEFAULTS.minSignalCount;
|
|
43
|
+
this.ruleCollector = new RuleCollector(projectRoot);
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* Collect signals from living docs for the given increment.
|
|
@@ -139,10 +141,12 @@ export class SignalCollector {
|
|
|
139
141
|
}
|
|
140
142
|
if (docs.length === 0)
|
|
141
143
|
return [];
|
|
144
|
+
// Collect existing rules for dedup context
|
|
145
|
+
const existingRules = await this.ruleCollector.collectExistingRules();
|
|
142
146
|
const totalTokens = docs.reduce((sum, d) => sum + d.tokens, 0);
|
|
143
147
|
if (totalTokens <= TOKEN_BUDGET) {
|
|
144
148
|
// Single call
|
|
145
|
-
const prompt = this.buildPrompt(docs);
|
|
149
|
+
const prompt = this.buildPrompt(docs, existingRules || undefined);
|
|
146
150
|
const result = await provider.analyzeStructured(prompt, {
|
|
147
151
|
schema: LLM_PATTERN_SCHEMA,
|
|
148
152
|
temperature: 0.1,
|
|
@@ -172,7 +176,7 @@ export class SignalCollector {
|
|
|
172
176
|
const allPatterns = [];
|
|
173
177
|
for (const chunk of chunks) {
|
|
174
178
|
try {
|
|
175
|
-
const prompt = this.buildPrompt(chunk);
|
|
179
|
+
const prompt = this.buildPrompt(chunk, existingRules || undefined);
|
|
176
180
|
const result = await provider.analyzeStructured(prompt, {
|
|
177
181
|
schema: LLM_PATTERN_SCHEMA,
|
|
178
182
|
temperature: 0.1,
|
|
@@ -197,20 +201,32 @@ export class SignalCollector {
|
|
|
197
201
|
return Array.from(seen.values());
|
|
198
202
|
}
|
|
199
203
|
/**
|
|
200
|
-
* Build the user prompt with <documents> block.
|
|
204
|
+
* Build the user prompt with <documents> block and optional <existing-rules> dedup context.
|
|
201
205
|
*/
|
|
202
|
-
buildPrompt(docs) {
|
|
206
|
+
buildPrompt(docs, existingRules) {
|
|
203
207
|
const docBlocks = docs
|
|
204
208
|
.map(d => `--- file: ${d.path} ---\n${d.content}`)
|
|
205
209
|
.join('\n');
|
|
206
|
-
|
|
210
|
+
let prompt = `Analyze these project documents and identify recurring patterns.
|
|
207
211
|
For each pattern provide: category (kebab-case slug), name (short identifier),
|
|
208
212
|
description (1-2 sentences explaining what the pattern is and why it matters),
|
|
209
213
|
and evidence (list of relevant quotes or references from the docs, max 5 per pattern).
|
|
210
214
|
|
|
215
|
+
Do NOT suggest patterns that are already covered by existing project rules
|
|
216
|
+
(shown in the <existing-rules> section if present).
|
|
217
|
+
|
|
211
218
|
<documents>
|
|
212
219
|
${docBlocks}
|
|
213
220
|
</documents>`;
|
|
221
|
+
if (existingRules) {
|
|
222
|
+
prompt += `
|
|
223
|
+
|
|
224
|
+
<existing-rules>
|
|
225
|
+
The following project rules already exist. DO NOT suggest patterns that duplicate or overlap with these existing rules.
|
|
226
|
+
${existingRules}
|
|
227
|
+
</existing-rules>`;
|
|
228
|
+
}
|
|
229
|
+
return prompt;
|
|
214
230
|
}
|
|
215
231
|
/**
|
|
216
232
|
* Create or update a signal entry.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal-collector.js","sourceRoot":"","sources":["../../../../src/core/skill-gen/signal-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"signal-collector.js","sourceRoot":"","sources":["../../../../src/core/skill-gen/signal-collector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent Circuit Breaker
|
|
3
|
+
*
|
|
4
|
+
* Wraps the in-memory SyncCircuitBreaker with file-based persistence
|
|
5
|
+
* so open/closed state survives across process restarts.
|
|
6
|
+
*
|
|
7
|
+
* State file format: { state, failures, lastFailure }
|
|
8
|
+
*/
|
|
9
|
+
import { type CircuitBreakerState } from '../increment/sync-circuit-breaker.js';
|
|
10
|
+
export declare class PersistentCircuitBreaker {
|
|
11
|
+
private breaker;
|
|
12
|
+
private filePath;
|
|
13
|
+
constructor(filePath: string);
|
|
14
|
+
canSync(): boolean;
|
|
15
|
+
recordSuccess(): void;
|
|
16
|
+
recordFailure(): void;
|
|
17
|
+
reset(): void;
|
|
18
|
+
getState(): CircuitBreakerState;
|
|
19
|
+
private loadState;
|
|
20
|
+
private saveState;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=persistent-circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-circuit-breaker.d.ts","sourceRoot":"","sources":["../../../../src/core/sync/persistent-circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAsB,KAAK,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAQpG,qBAAa,wBAAwB;IACnC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAM5B,OAAO,IAAI,OAAO;IAIlB,aAAa,IAAI,IAAI;IAKrB,aAAa,IAAI,IAAI;IAKrB,KAAK,IAAI,IAAI;IAKb,QAAQ,IAAI,mBAAmB;IAI/B,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,SAAS;CAclB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent Circuit Breaker
|
|
3
|
+
*
|
|
4
|
+
* Wraps the in-memory SyncCircuitBreaker with file-based persistence
|
|
5
|
+
* so open/closed state survives across process restarts.
|
|
6
|
+
*
|
|
7
|
+
* State file format: { state, failures, lastFailure }
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
10
|
+
import { dirname } from 'path';
|
|
11
|
+
import { SyncCircuitBreaker } from '../increment/sync-circuit-breaker.js';
|
|
12
|
+
export class PersistentCircuitBreaker {
|
|
13
|
+
constructor(filePath) {
|
|
14
|
+
this.filePath = filePath;
|
|
15
|
+
this.breaker = new SyncCircuitBreaker();
|
|
16
|
+
this.loadState();
|
|
17
|
+
}
|
|
18
|
+
canSync() {
|
|
19
|
+
return this.breaker.canSync();
|
|
20
|
+
}
|
|
21
|
+
recordSuccess() {
|
|
22
|
+
this.breaker.recordSuccess();
|
|
23
|
+
this.saveState();
|
|
24
|
+
}
|
|
25
|
+
recordFailure() {
|
|
26
|
+
this.breaker.recordFailure();
|
|
27
|
+
this.saveState();
|
|
28
|
+
}
|
|
29
|
+
reset() {
|
|
30
|
+
this.breaker.reset();
|
|
31
|
+
this.saveState();
|
|
32
|
+
}
|
|
33
|
+
getState() {
|
|
34
|
+
return this.breaker.getState();
|
|
35
|
+
}
|
|
36
|
+
loadState() {
|
|
37
|
+
try {
|
|
38
|
+
const raw = readFileSync(this.filePath, 'utf-8');
|
|
39
|
+
const data = JSON.parse(raw);
|
|
40
|
+
// Replay persisted state onto the in-memory breaker
|
|
41
|
+
for (let i = 0; i < (data.failures ?? 0); i++) {
|
|
42
|
+
this.breaker.recordFailure();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// No file or corrupted — start fresh (closed)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
saveState() {
|
|
50
|
+
const state = this.breaker.getState();
|
|
51
|
+
const data = {
|
|
52
|
+
state: state.state,
|
|
53
|
+
failures: state.failures,
|
|
54
|
+
lastFailure: state.lastFailure?.toISOString(),
|
|
55
|
+
};
|
|
56
|
+
try {
|
|
57
|
+
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
58
|
+
writeFileSync(this.filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Best-effort persistence — don't crash on write failure
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=persistent-circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-circuit-breaker.js","sourceRoot":"","sources":["../../../../src/core/sync/persistent-circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAA4B,MAAM,sCAAsC,CAAC;AAQpG,MAAM,OAAO,wBAAwB;IAInC,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,aAAa;QACX,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,aAAa;QACX,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC;IAEO,SAAS;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,IAAI,GAAmB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAE7C,oDAAoD;YACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8CAA8C;QAChD,CAAC;IACH,CAAC;IAEO,SAAS;QACf,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,GAAmB;YAC3B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,WAAW,EAAE;SAC9C,CAAC;QACF,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvD,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;QAC3D,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry wrapper with exponential backoff and jitter.
|
|
3
|
+
*
|
|
4
|
+
* Retries on network errors (no status) and 5xx server errors.
|
|
5
|
+
* Does not retry 4xx client errors (non-retryable).
|
|
6
|
+
*/
|
|
7
|
+
export interface RetryOptions {
|
|
8
|
+
maxRetries: number;
|
|
9
|
+
baseMs: number;
|
|
10
|
+
maxMs: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Promise<T>;
|
|
13
|
+
//# sourceMappingURL=retry-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-wrapper.d.ts","sourceRoot":"","sources":["../../../../src/core/sync/retry-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAeD,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,CAAC,CAAC,CAqBZ"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry wrapper with exponential backoff and jitter.
|
|
3
|
+
*
|
|
4
|
+
* Retries on network errors (no status) and 5xx server errors.
|
|
5
|
+
* Does not retry 4xx client errors (non-retryable).
|
|
6
|
+
*/
|
|
7
|
+
function isRetryable(error) {
|
|
8
|
+
if (typeof error === 'object' && error !== null && 'status' in error) {
|
|
9
|
+
const status = error.status;
|
|
10
|
+
return status >= 500;
|
|
11
|
+
}
|
|
12
|
+
// Network errors (no status) are retryable
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
function delay(ms) {
|
|
16
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
|
+
}
|
|
18
|
+
export async function withRetry(fn, opts) {
|
|
19
|
+
let lastError;
|
|
20
|
+
for (let attempt = 0; attempt < opts.maxRetries; attempt++) {
|
|
21
|
+
try {
|
|
22
|
+
return await fn();
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
lastError = error;
|
|
26
|
+
if (!isRetryable(error) || attempt === opts.maxRetries - 1) {
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
const exponential = opts.baseMs * Math.pow(2, attempt);
|
|
30
|
+
const jitter = 0.5 + Math.random(); // 0.5..1.5
|
|
31
|
+
const wait = Math.min(exponential * jitter, opts.maxMs);
|
|
32
|
+
await delay(wait);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw lastError;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=retry-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-wrapper.js","sourceRoot":"","sources":["../../../../src/core/sync/retry-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;QACrE,MAAM,MAAM,GAAI,KAA4B,CAAC,MAAM,CAAC;QACpD,OAAO,MAAM,IAAI,GAAG,CAAC;IACvB,CAAC;IACD,2CAA2C;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,IAAkB;IAElB,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAElB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;gBAC3D,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW;YAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACxD,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AC Parser for External Item Descriptions
|
|
3
|
+
*
|
|
4
|
+
* Extracts acceptance criteria from external item descriptions
|
|
5
|
+
* (GitHub issue body, JIRA description, ADO work item description).
|
|
6
|
+
*
|
|
7
|
+
* Recognizes checkbox-style items:
|
|
8
|
+
* - [ ] unchecked criterion
|
|
9
|
+
* - [x] completed criterion
|
|
10
|
+
* * [ ] asterisk-style checkbox
|
|
11
|
+
*
|
|
12
|
+
* Non-checkbox list items are ignored.
|
|
13
|
+
*
|
|
14
|
+
* @module importers/ac-parser
|
|
15
|
+
*/
|
|
16
|
+
export interface ACEntry {
|
|
17
|
+
text: string;
|
|
18
|
+
completed: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse acceptance criteria from an external item description.
|
|
22
|
+
*
|
|
23
|
+
* @param description - Raw markdown/HTML description from GitHub/JIRA/ADO
|
|
24
|
+
* @returns Array of AC entries with text and completion status
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseExternalACs(description: string): ACEntry[];
|
|
27
|
+
//# sourceMappingURL=ac-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ac-parser.d.ts","sourceRoot":"","sources":["../../../src/importers/ac-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AASD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,EAAE,CAsB/D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AC Parser for External Item Descriptions
|
|
3
|
+
*
|
|
4
|
+
* Extracts acceptance criteria from external item descriptions
|
|
5
|
+
* (GitHub issue body, JIRA description, ADO work item description).
|
|
6
|
+
*
|
|
7
|
+
* Recognizes checkbox-style items:
|
|
8
|
+
* - [ ] unchecked criterion
|
|
9
|
+
* - [x] completed criterion
|
|
10
|
+
* * [ ] asterisk-style checkbox
|
|
11
|
+
*
|
|
12
|
+
* Non-checkbox list items are ignored.
|
|
13
|
+
*
|
|
14
|
+
* @module importers/ac-parser
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Regex for markdown checkbox items:
|
|
18
|
+
* - Matches "- [ ]", "- [x]", "- [X]", "* [ ]", "* [x]", "* [X]"
|
|
19
|
+
* - Captures the check state and the text after
|
|
20
|
+
*/
|
|
21
|
+
const CHECKBOX_REGEX = /^[\s]*[-*]\s+\[([ xX])\]\s+(.+)$/gm;
|
|
22
|
+
/**
|
|
23
|
+
* Parse acceptance criteria from an external item description.
|
|
24
|
+
*
|
|
25
|
+
* @param description - Raw markdown/HTML description from GitHub/JIRA/ADO
|
|
26
|
+
* @returns Array of AC entries with text and completion status
|
|
27
|
+
*/
|
|
28
|
+
export function parseExternalACs(description) {
|
|
29
|
+
if (!description)
|
|
30
|
+
return [];
|
|
31
|
+
const results = [];
|
|
32
|
+
let match;
|
|
33
|
+
// Reset regex state (global flag requires manual reset)
|
|
34
|
+
CHECKBOX_REGEX.lastIndex = 0;
|
|
35
|
+
while ((match = CHECKBOX_REGEX.exec(description)) !== null) {
|
|
36
|
+
const checkState = match[1];
|
|
37
|
+
const text = match[2].trim();
|
|
38
|
+
if (text) {
|
|
39
|
+
results.push({
|
|
40
|
+
text,
|
|
41
|
+
completed: checkState === 'x' || checkState === 'X',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return results;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ac-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ac-parser.js","sourceRoot":"","sources":["../../../src/importers/ac-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH;;;;GAIG;AACH,MAAM,cAAc,GAAG,oCAAoC,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,IAAI,KAA6B,CAAC;IAElC,wDAAwD;IACxD,cAAc,CAAC,SAAS,GAAG,CAAC,CAAC;IAE7B,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE7B,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,SAAS,EAAE,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG;aACpD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/src/sync/types.d.ts
CHANGED
|
@@ -89,6 +89,14 @@ export declare function formatIssueTitle(usId: string, title: string): string;
|
|
|
89
89
|
* "FS-172: True Autonomous Mode"
|
|
90
90
|
*/
|
|
91
91
|
export declare function formatMilestoneTitle(fsId: string, title: string): string;
|
|
92
|
+
/**
|
|
93
|
+
* Append a platform suffix to an existing ID string.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* formatSuffixedId('FS-001', 'github') → 'FS-001G'
|
|
97
|
+
* formatSuffixedId('FS-001', undefined) → 'FS-001'
|
|
98
|
+
*/
|
|
99
|
+
export declare function formatSuffixedId(id: string, platform: Platform | undefined): string;
|
|
92
100
|
/**
|
|
93
101
|
* Parse an issue title in the new "US-XXX: Title" format.
|
|
94
102
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sync/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AACjD,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACnD,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,cAAc,CAI9C,CAAC;AAEX,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAIxC,CAAC;AAMX,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAID;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAWnD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,GAAG,SAAS,CAElF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAG1F;AAMD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;CACrB;AAID;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAWrF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIjE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAGvG;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIrF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIzG"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sync/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AACjD,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACnD,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,cAAc,CAI9C,CAAC;AAEX,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAIxC,CAAC;AAMX,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAID;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAWnD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,GAAG,SAAS,CAElF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAG1F;AAMD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;CACrB;AAID;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAWrF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIjE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAGvG;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAGnF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIrF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIzG"}
|
package/dist/src/sync/types.js
CHANGED
|
@@ -127,6 +127,18 @@ export function formatIssueTitle(usId, title) {
|
|
|
127
127
|
export function formatMilestoneTitle(fsId, title) {
|
|
128
128
|
return `${fsId}: ${title}`;
|
|
129
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Append a platform suffix to an existing ID string.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* formatSuffixedId('FS-001', 'github') → 'FS-001G'
|
|
135
|
+
* formatSuffixedId('FS-001', undefined) → 'FS-001'
|
|
136
|
+
*/
|
|
137
|
+
export function formatSuffixedId(id, platform) {
|
|
138
|
+
if (!platform)
|
|
139
|
+
return id;
|
|
140
|
+
return `${id}${SUFFIX_MAP[platform]}`;
|
|
141
|
+
}
|
|
130
142
|
/**
|
|
131
143
|
* Parse an issue title in the new "US-XXX: Title" format.
|
|
132
144
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/sync/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/sync/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.489",
|
|
4
4
|
"description": "100+ domain-expert AI skills — PM, Architect, Frontend, QA, Security and more. Skills learn your team's patterns permanently. Spec-first planning, autonomous execution, multi-agent teams, synced to GitHub/JIRA. Claude Code, Cursor, Copilot & more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
You are the SILENT FAILURES REVIEWER agent.
|
|
2
|
+
|
|
3
|
+
REVIEW TARGET: [REVIEW_TARGET]
|
|
4
|
+
|
|
5
|
+
MISSION:
|
|
6
|
+
Find code that fails silently — errors that are swallowed, ignored, or hidden behind
|
|
7
|
+
fallback values without logging or notification. Silent failures are among the hardest
|
|
8
|
+
bugs to diagnose because nothing appears broken until data is corrupted or users report
|
|
9
|
+
mysterious behavior. You are a read-only analyst — your job is to FIND issues, not fix them.
|
|
10
|
+
|
|
11
|
+
SCOPE:
|
|
12
|
+
- If reviewing a PR: run `gh pr diff [PR_NUMBER]` to get the diff, then analyze changed files
|
|
13
|
+
- If reviewing a module: read all files in the target path
|
|
14
|
+
- Focus on error handling paths — follow every catch, callback, and conditional
|
|
15
|
+
|
|
16
|
+
CHECKLIST:
|
|
17
|
+
1. Empty catch blocks (catch(e) {} or catch(e) { /* ignore */ })
|
|
18
|
+
2. Catch blocks that log but don't re-throw or return an error state
|
|
19
|
+
3. Error callbacks with unused error parameter (fs.readFile(path, (err, data) => { ... }))
|
|
20
|
+
4. Promise chains without .catch() or missing error boundary
|
|
21
|
+
5. try/catch returning default/fallback values without logging the original error
|
|
22
|
+
6. Event emitter 'error' events not handled (crashes process silently in Node.js)
|
|
23
|
+
7. HTTP handlers that always return 200 regardless of internal failures
|
|
24
|
+
8. Conditional logic with missing else/default that silently falls through
|
|
25
|
+
9. Async functions that don't propagate errors to callers
|
|
26
|
+
10. Optional chaining (?.) used to silence errors instead of handling null states
|
|
27
|
+
|
|
28
|
+
OUTPUT FORMAT:
|
|
29
|
+
Produce a structured findings report using this format for each finding:
|
|
30
|
+
|
|
31
|
+
### [SEVERITY]: [Title]
|
|
32
|
+
- **File**: path/to/file.ts:line
|
|
33
|
+
- **Category**: Silent failure type (e.g., Empty catch, Swallowed error, Missing .catch())
|
|
34
|
+
- **Description**: What fails silently and how
|
|
35
|
+
- **Hidden errors**: What error types are being swallowed (e.g., network errors, validation errors)
|
|
36
|
+
- **User impact**: What the user experiences (wrong data, missing features, no feedback)
|
|
37
|
+
- **Recommendation**: How to properly handle the error
|
|
38
|
+
- **Code snippet**: The problematic code (keep brief)
|
|
39
|
+
|
|
40
|
+
Severity levels: CRITICAL | HIGH | MEDIUM | LOW | INFO
|
|
41
|
+
|
|
42
|
+
COMMUNICATION:
|
|
43
|
+
When done, signal completion:
|
|
44
|
+
SendMessage({
|
|
45
|
+
type: "message",
|
|
46
|
+
recipient: "team-lead",
|
|
47
|
+
content: "REVIEW_COMPLETE: Silent failures review finished. Found [N] issues: [X critical, Y high, Z medium]. Key findings: [brief summary of top 3].",
|
|
48
|
+
summary: "Silent failures review complete"
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
If you need clarification about error handling conventions:
|
|
52
|
+
SendMessage({
|
|
53
|
+
type: "message",
|
|
54
|
+
recipient: "team-lead",
|
|
55
|
+
content: "REVIEW_QUESTION: [your question]",
|
|
56
|
+
summary: "Silent failures reviewer needs clarification"
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
RULES:
|
|
60
|
+
- READ-ONLY: Do not modify any files
|
|
61
|
+
- Be specific: include file paths and line numbers for every finding
|
|
62
|
+
- Prioritize: CRITICAL and HIGH findings first
|
|
63
|
+
- No speculation: only report issues where you can trace the silent failure path
|
|
64
|
+
- Consider project conventions: check for custom error handlers, logging utilities
|
|
65
|
+
- Distinguish intentional vs accidental: some silent handling is by design (e.g., optional features)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
You are the SPEC COMPLIANCE REVIEWER agent.
|
|
2
|
+
|
|
3
|
+
REVIEW TARGET: [REVIEW_TARGET]
|
|
4
|
+
INCREMENT PATH: [INCREMENT_PATH]
|
|
5
|
+
|
|
6
|
+
MISSION:
|
|
7
|
+
Verify that the implementation matches the specification. Cross-reference each acceptance
|
|
8
|
+
criterion in spec.md against the actual codebase to find gaps, misinterpretations, and
|
|
9
|
+
scope creep. You are a read-only analyst — your job is to FIND compliance gaps, not fix them.
|
|
10
|
+
|
|
11
|
+
SCOPE:
|
|
12
|
+
- Read spec.md from [INCREMENT_PATH]/spec.md to extract all acceptance criteria
|
|
13
|
+
- If no INCREMENT_PATH provided, search for active increments in .specweave/increments/
|
|
14
|
+
- Analyze the codebase for implementation evidence of each AC
|
|
15
|
+
- Check test coverage for each AC
|
|
16
|
+
|
|
17
|
+
CHECKLIST:
|
|
18
|
+
1. Extract all AC-US*-* acceptance criteria from spec.md
|
|
19
|
+
2. For each AC, search the codebase for implementation evidence:
|
|
20
|
+
- Code that fulfills the criterion (function, endpoint, component)
|
|
21
|
+
- Test that validates the criterion (unit, integration, E2E)
|
|
22
|
+
3. Verify edge cases mentioned in ACs are handled in code
|
|
23
|
+
4. Check error scenarios from ACs have proper handling
|
|
24
|
+
5. Validate data format requirements from ACs (types, schemas, constraints)
|
|
25
|
+
6. Detect scope creep: features implemented but NOT specified in any AC
|
|
26
|
+
7. Detect misinterpretations: code does something similar but not exactly what AC requires
|
|
27
|
+
8. Check tasks.md completion status matches actual code state
|
|
28
|
+
|
|
29
|
+
OUTPUT FORMAT:
|
|
30
|
+
Produce two sections:
|
|
31
|
+
|
|
32
|
+
## AC Compliance Table
|
|
33
|
+
| AC ID | Expected Behavior | Implementation Status | Evidence | Test Coverage |
|
|
34
|
+
|-------|---------------------|----------------------|----------|---------------|
|
|
35
|
+
| AC-US1-01 | User can log in | PASS | src/api/auth.ts:42 | auth.test.ts:15 |
|
|
36
|
+
| AC-US1-02 | Invalid creds show error | FAIL - missing | N/A | N/A |
|
|
37
|
+
|
|
38
|
+
## Scope Creep Findings
|
|
39
|
+
For each unrequested feature found:
|
|
40
|
+
|
|
41
|
+
### [SEVERITY]: [Title]
|
|
42
|
+
- **File**: path/to/file.ts:line
|
|
43
|
+
- **Category**: Scope creep / Unrequested feature
|
|
44
|
+
- **Description**: What was implemented that no AC requested
|
|
45
|
+
- **Risk**: Why this is problematic (maintenance burden, untested surface, spec divergence)
|
|
46
|
+
- **Recommendation**: Remove, or create a new AC to cover it
|
|
47
|
+
|
|
48
|
+
## Misinterpretation Findings
|
|
49
|
+
For each AC where implementation differs from spec intent:
|
|
50
|
+
|
|
51
|
+
### [SEVERITY]: [Title]
|
|
52
|
+
- **AC**: AC-USNN-NN
|
|
53
|
+
- **Expected**: What the AC specifies
|
|
54
|
+
- **Actual**: What the code does
|
|
55
|
+
- **Gap**: How they differ
|
|
56
|
+
- **Recommendation**: What needs to change
|
|
57
|
+
|
|
58
|
+
Severity levels: CRITICAL | HIGH | MEDIUM | LOW | INFO
|
|
59
|
+
|
|
60
|
+
COMMUNICATION:
|
|
61
|
+
When done, signal completion:
|
|
62
|
+
SendMessage({
|
|
63
|
+
type: "message",
|
|
64
|
+
recipient: "team-lead",
|
|
65
|
+
content: "REVIEW_COMPLETE: Spec compliance review finished. ACs: [X/Y passed]. Scope creep: [N items]. Misinterpretations: [N items]. Key gaps: [brief summary].",
|
|
66
|
+
summary: "Spec compliance review complete"
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
If spec.md is missing or empty:
|
|
70
|
+
SendMessage({
|
|
71
|
+
type: "message",
|
|
72
|
+
recipient: "team-lead",
|
|
73
|
+
content: "REVIEW_QUESTION: No spec.md found at [INCREMENT_PATH]. Cannot perform spec compliance review without a specification. Provide increment path or skip this reviewer.",
|
|
74
|
+
summary: "Spec compliance reviewer: no spec found"
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
RULES:
|
|
78
|
+
- READ-ONLY: Do not modify any files
|
|
79
|
+
- Be specific: include file paths and line numbers for every finding
|
|
80
|
+
- Every AC must have a verdict (PASS, FAIL, PARTIAL, NOT FOUND)
|
|
81
|
+
- Do not rubber-stamp: verify actual implementation, not just task completion checkboxes
|
|
82
|
+
- Consider intent: understand what the AC means, not just literal text matching
|
|
83
|
+
- Flag both missing features AND extra features (scope creep)
|