specweave 0.32.2 → 0.32.3
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.md +39 -0
- package/bin/specweave.js +34 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts +100 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +291 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts +103 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +310 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts +126 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +207 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -0
- package/dist/src/adapters/codex/README.md +1 -1
- package/dist/src/adapters/codex/adapter.js +1 -1
- package/dist/src/cli/commands/archive.d.ts +2 -0
- package/dist/src/cli/commands/archive.d.ts.map +1 -1
- package/dist/src/cli/commands/archive.js +33 -0
- package/dist/src/cli/commands/archive.js.map +1 -1
- package/dist/src/cli/commands/context.d.ts +92 -0
- package/dist/src/cli/commands/context.d.ts.map +1 -0
- package/dist/src/cli/commands/context.js +205 -0
- package/dist/src/cli/commands/context.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +111 -69
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/init/external-import.d.ts +3 -0
- package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/external-import.js +17 -4
- package/dist/src/cli/helpers/init/external-import.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/jira-ado-auto-detect.d.ts +70 -0
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.js +214 -4
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.js.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +4 -0
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.js +34 -3
- package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
- package/dist/src/cli/helpers/init/testing-config.d.ts +3 -0
- package/dist/src/cli/helpers/init/testing-config.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/testing-config.js +9 -2
- package/dist/src/cli/helpers/init/testing-config.js.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.d.ts +3 -0
- package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.js +21 -4
- package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
- package/dist/src/cli/helpers/init/wizard-navigation.d.ts +45 -0
- package/dist/src/cli/helpers/init/wizard-navigation.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/wizard-navigation.js +97 -0
- package/dist/src/cli/helpers/init/wizard-navigation.js.map +1 -0
- package/dist/src/core/increment/increment-archiver.d.ts +25 -4
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +64 -20
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +65 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +114 -0
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.d.ts +4 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +32 -10
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +7 -3
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts +38 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.js +325 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.js.map +1 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts +74 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.js +366 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.d.ts +64 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.js +229 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/index.d.ts +50 -0
- package/dist/src/core/living-docs/governance/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/index.js +56 -0
- package/dist/src/core/living-docs/governance/index.js.map +1 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.d.ts +89 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.js +356 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.d.ts +83 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.js +347 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/standards-generator.d.ts +38 -0
- package/dist/src/core/living-docs/governance/standards-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/standards-generator.js +476 -0
- package/dist/src/core/living-docs/governance/standards-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +54 -2
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +5 -1
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +358 -30
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +44 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +6 -3
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +17 -8
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.d.ts +22 -0
- package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.js +123 -19
- package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
- package/dist/src/core/llm/provider-factory.js +2 -2
- package/dist/src/core/llm/provider-factory.js.map +1 -1
- package/dist/src/core/llm/providers/anthropic-provider.js +1 -1
- package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
- package/dist/src/core/llm/providers/bedrock-provider.js +8 -4
- package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
- package/dist/src/importers/jira-importer.d.ts +14 -0
- package/dist/src/importers/jira-importer.d.ts.map +1 -1
- package/dist/src/importers/jira-importer.js +75 -0
- package/dist/src/importers/jira-importer.js.map +1 -1
- package/dist/src/integrations/jira/jira-token-provider.d.ts +93 -0
- package/dist/src/integrations/jira/jira-token-provider.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-token-provider.js +160 -0
- package/dist/src/integrations/jira/jira-token-provider.js.map +1 -0
- package/dist/src/sync/ado-reconciler.d.ts +92 -0
- package/dist/src/sync/ado-reconciler.d.ts.map +1 -0
- package/dist/src/sync/ado-reconciler.js +335 -0
- package/dist/src/sync/ado-reconciler.js.map +1 -0
- package/dist/src/sync/jira-reconciler.d.ts +106 -0
- package/dist/src/sync/jira-reconciler.d.ts.map +1 -0
- package/dist/src/sync/jira-reconciler.js +405 -0
- package/dist/src/sync/jira-reconciler.js.map +1 -0
- package/dist/src/types/model-selection.d.ts +6 -4
- package/dist/src/types/model-selection.d.ts.map +1 -1
- package/dist/src/types/model-selection.js +3 -1
- package/dist/src/types/model-selection.js.map +1 -1
- package/dist/src/utils/external-tool-drift-detector.d.ts +1 -1
- package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -1
- package/dist/src/utils/external-tool-drift-detector.js +5 -4
- package/dist/src/utils/external-tool-drift-detector.js.map +1 -1
- package/dist/src/utils/feature-id-derivation.d.ts +8 -3
- package/dist/src/utils/feature-id-derivation.d.ts.map +1 -1
- package/dist/src/utils/feature-id-derivation.js +14 -6
- package/dist/src/utils/feature-id-derivation.js.map +1 -1
- package/dist/src/utils/model-selection.d.ts +3 -4
- package/dist/src/utils/model-selection.d.ts.map +1 -1
- package/dist/src/utils/model-selection.js +3 -4
- package/dist/src/utils/model-selection.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/code-standards-detective/AGENT.md +48 -0
- package/plugins/specweave/commands/specweave-costs.md +4 -4
- package/plugins/specweave/commands/specweave-do.md +9 -9
- package/plugins/specweave/commands/specweave-done.md +13 -0
- package/plugins/specweave/commands/specweave-validate.md +27 -1
- package/plugins/specweave/hooks/hooks.json +10 -0
- package/plugins/specweave/hooks/spec-project-validator.sh +80 -25
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +135 -0
- package/plugins/specweave/scripts/read-costs.sh +3 -3
- package/plugins/specweave/skills/code-standards-analyzer/SKILL.md +58 -6
- package/plugins/specweave/skills/increment-planner/SKILL.md +56 -25
- package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +4 -2
- package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +2 -1
- package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +1 -1
- package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +1 -1
- package/plugins/specweave-ado/commands/cleanup-duplicates.md +212 -0
- package/plugins/specweave-ado/commands/reconcile.md +120 -0
- package/plugins/specweave-ado/lib/ado-duplicate-detector.js +279 -0
- package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +407 -0
- package/plugins/specweave-github/agents/github-manager/AGENT.md +2 -2
- package/plugins/specweave-infrastructure/skills/hetzner-provisioner/README.md +1 -1
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +1 -1
- package/plugins/specweave-jira/agents/jira-multi-project-mapper/AGENT.md +530 -0
- package/plugins/specweave-jira/agents/jira-sync-judge/AGENT.md +438 -0
- package/plugins/specweave-jira/commands/cleanup-duplicates.md +219 -0
- package/plugins/specweave-jira/commands/close.md +297 -0
- package/plugins/specweave-jira/commands/create.md +198 -0
- package/plugins/specweave-jira/commands/reconcile.md +123 -0
- package/plugins/specweave-jira/commands/status.md +215 -0
- package/plugins/specweave-jira/lib/jira-duplicate-detector.js +296 -0
- package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +434 -0
- package/plugins/specweave-jira/lib/jira-permission-gate.js +160 -0
- package/plugins/specweave-jira/lib/jira-permission-gate.ts +276 -0
- package/plugins/specweave-jira/lib/jira-profile-resolver.js +222 -0
- package/plugins/specweave-jira/lib/jira-profile-resolver.ts +427 -0
- package/plugins/specweave-jira/reference/jira-specweave-mapping.md +16 -11
- package/plugins/specweave-release/commands/specweave-release-npm.md +140 -14
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JIRA Reconciler (NEW in v0.33.0)
|
|
3
|
+
*
|
|
4
|
+
* Reconciles JIRA issue states with increment metadata.json statuses.
|
|
5
|
+
* Fixes drift between local SpecWeave state and JIRA:
|
|
6
|
+
* - Closes issues for completed increments that are still open
|
|
7
|
+
* - Reopens issues for in-progress increments that are closed
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the GitHub reconciler pattern for consistency.
|
|
10
|
+
*
|
|
11
|
+
* Triggered by:
|
|
12
|
+
* - /specweave-jira:reconcile command (manual)
|
|
13
|
+
* - SessionStart hook (automatic, if configured)
|
|
14
|
+
* - post-increment-status-change.sh (on resume/abandon)
|
|
15
|
+
*/
|
|
16
|
+
import { promises as fs, existsSync } from 'fs';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { consoleLogger } from '../utils/logger.js';
|
|
19
|
+
/**
|
|
20
|
+
* JIRA Status Mapping
|
|
21
|
+
*/
|
|
22
|
+
const JIRA_STATUSES = {
|
|
23
|
+
CLOSED: ['Done', 'Closed', 'Resolved', "Won't Do"],
|
|
24
|
+
OPEN: ['To Do', 'In Progress', 'In Review', 'Open', 'Reopened'],
|
|
25
|
+
};
|
|
26
|
+
export class JiraReconciler {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.domain = '';
|
|
29
|
+
this.auth = '';
|
|
30
|
+
this.projectRoot = options.projectRoot;
|
|
31
|
+
this.dryRun = options.dryRun ?? false;
|
|
32
|
+
this.logger = options.logger ?? consoleLogger;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Main reconciliation entry point
|
|
36
|
+
*/
|
|
37
|
+
async reconcile() {
|
|
38
|
+
const result = {
|
|
39
|
+
scanned: 0,
|
|
40
|
+
mismatches: 0,
|
|
41
|
+
closed: 0,
|
|
42
|
+
reopened: 0,
|
|
43
|
+
errors: [],
|
|
44
|
+
details: [],
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
// 1. Check if JIRA sync is enabled
|
|
48
|
+
const config = await this.loadConfig();
|
|
49
|
+
const canUpdate = config.sync?.settings?.canUpdateExternalItems ?? false;
|
|
50
|
+
const canUpdateStatus = config.sync?.settings?.canUpdateStatus ?? false;
|
|
51
|
+
const jiraEnabled = config.sync?.jira?.enabled ?? false;
|
|
52
|
+
if (!canUpdate || !jiraEnabled) {
|
|
53
|
+
this.logger.log('ℹ️ JIRA sync is disabled - skipping reconciliation');
|
|
54
|
+
this.logger.log(' Enable with: canUpdateExternalItems=true AND sync.jira.enabled=true');
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
if (!canUpdateStatus) {
|
|
58
|
+
this.logger.log('ℹ️ JIRA status updates are disabled - skipping reconciliation');
|
|
59
|
+
this.logger.log(' Enable with: canUpdateStatus=true');
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
// 2. Verify JIRA credentials
|
|
63
|
+
if (!this.initCredentials()) {
|
|
64
|
+
result.errors.push('JIRA credentials not configured');
|
|
65
|
+
this.logger.error('❌ JIRA credentials not found. Set JIRA_API_TOKEN and JIRA_EMAIL environment variables.');
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
// 3. Scan all non-archived increments
|
|
69
|
+
const increments = await this.scanIncrements();
|
|
70
|
+
result.scanned = increments.length;
|
|
71
|
+
this.logger.log(`\n📊 Scanning ${increments.length} increment(s) for JIRA state drift...\n`);
|
|
72
|
+
// 4. Check and fix each increment
|
|
73
|
+
for (const inc of increments) {
|
|
74
|
+
await this.reconcileIncrement(inc, result);
|
|
75
|
+
}
|
|
76
|
+
// 5. Report summary
|
|
77
|
+
this.logger.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
78
|
+
this.logger.log('📊 JIRA RECONCILIATION SUMMARY');
|
|
79
|
+
this.logger.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
80
|
+
this.logger.log(` Increments scanned: ${result.scanned}`);
|
|
81
|
+
this.logger.log(` Mismatches found: ${result.mismatches}`);
|
|
82
|
+
this.logger.log(` Issues closed: ${result.closed}`);
|
|
83
|
+
this.logger.log(` Issues reopened: ${result.reopened}`);
|
|
84
|
+
this.logger.log(` Errors: ${result.errors.length}`);
|
|
85
|
+
if (this.dryRun) {
|
|
86
|
+
this.logger.log('\n ⚠️ DRY RUN - No changes were made');
|
|
87
|
+
}
|
|
88
|
+
this.logger.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
result.errors.push(`Reconciliation error: ${error.message}`);
|
|
93
|
+
this.logger.error('❌ Reconciliation failed:', error.message);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Reconcile a single increment
|
|
99
|
+
*/
|
|
100
|
+
async reconcileIncrement(inc, result) {
|
|
101
|
+
const status = inc.metadataStatus;
|
|
102
|
+
// Determine expected JIRA state
|
|
103
|
+
const shouldBeClosed = status === 'completed' || status === 'abandoned';
|
|
104
|
+
const shouldBeOpen = status === 'in-progress' || status === 'active' || status === 'planning';
|
|
105
|
+
// Check main issue
|
|
106
|
+
if (inc.issue) {
|
|
107
|
+
await this.reconcileIssue(inc.incrementId, inc.issue.key, shouldBeClosed, shouldBeOpen, status, result);
|
|
108
|
+
}
|
|
109
|
+
// Check User Story issues
|
|
110
|
+
for (const us of inc.userStoryIssues) {
|
|
111
|
+
await this.reconcileIssue(`${inc.incrementId}/${us.userStoryId}`, us.issueKey, shouldBeClosed, shouldBeOpen, status, result);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Reconcile a single issue
|
|
116
|
+
*/
|
|
117
|
+
async reconcileIssue(context, issueKey, shouldBeClosed, shouldBeOpen, metadataStatus, result) {
|
|
118
|
+
try {
|
|
119
|
+
// Get current JIRA state
|
|
120
|
+
const issue = await this.getIssue(issueKey);
|
|
121
|
+
const currentStatus = issue?.fields?.status?.name ?? 'Unknown';
|
|
122
|
+
const isCurrentlyClosed = JIRA_STATUSES.CLOSED.includes(currentStatus);
|
|
123
|
+
// Check for mismatch
|
|
124
|
+
if (shouldBeClosed && !isCurrentlyClosed) {
|
|
125
|
+
// Should be closed but is open
|
|
126
|
+
result.mismatches++;
|
|
127
|
+
this.logger.log(` ❌ Issue ${issueKey} (${context}): ${currentStatus} but should be CLOSED (status=${metadataStatus})`);
|
|
128
|
+
if (!this.dryRun) {
|
|
129
|
+
const comment = `h2. 🔄 Auto-Reconciled by SpecWeave
|
|
130
|
+
|
|
131
|
+
This issue was closed by SpecWeave reconciliation.
|
|
132
|
+
|
|
133
|
+
*Reason*: Increment status is \`${metadataStatus}\` but JIRA issue was still open.
|
|
134
|
+
|
|
135
|
+
----
|
|
136
|
+
🤖 Auto-reconciled by SpecWeave`;
|
|
137
|
+
await this.transitionIssue(issueKey, 'Done', comment);
|
|
138
|
+
result.closed++;
|
|
139
|
+
this.logger.log(` ✅ Closed issue ${issueKey}`);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.logger.log(` [DRY RUN] Would close issue ${issueKey}`);
|
|
143
|
+
}
|
|
144
|
+
result.details.push({
|
|
145
|
+
incrementId: context,
|
|
146
|
+
action: this.dryRun ? 'skip' : 'close',
|
|
147
|
+
issueKey,
|
|
148
|
+
reason: `Status=${metadataStatus}, JIRA=${currentStatus}`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
else if (shouldBeOpen && isCurrentlyClosed) {
|
|
152
|
+
// Should be open but is closed
|
|
153
|
+
result.mismatches++;
|
|
154
|
+
this.logger.log(` ❌ Issue ${issueKey} (${context}): CLOSED but should be OPEN (status=${metadataStatus})`);
|
|
155
|
+
if (!this.dryRun) {
|
|
156
|
+
const comment = `h2. 🔄 Auto-Reconciled by SpecWeave
|
|
157
|
+
|
|
158
|
+
This issue was reopened by SpecWeave reconciliation.
|
|
159
|
+
|
|
160
|
+
*Reason*: Increment status is \`${metadataStatus}\` but JIRA issue was closed.
|
|
161
|
+
This typically happens when an increment was resumed after being paused/completed.
|
|
162
|
+
|
|
163
|
+
----
|
|
164
|
+
🤖 Auto-reconciled by SpecWeave`;
|
|
165
|
+
await this.transitionIssue(issueKey, 'To Do', comment);
|
|
166
|
+
result.reopened++;
|
|
167
|
+
this.logger.log(` ✅ Reopened issue ${issueKey}`);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
this.logger.log(` [DRY RUN] Would reopen issue ${issueKey}`);
|
|
171
|
+
}
|
|
172
|
+
result.details.push({
|
|
173
|
+
incrementId: context,
|
|
174
|
+
action: this.dryRun ? 'skip' : 'reopen',
|
|
175
|
+
issueKey,
|
|
176
|
+
reason: `Status=${metadataStatus}, JIRA=${currentStatus}`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
// State matches
|
|
181
|
+
this.logger.log(` ✅ Issue ${issueKey} (${context}): State matches (${currentStatus})`);
|
|
182
|
+
result.details.push({
|
|
183
|
+
incrementId: context,
|
|
184
|
+
action: 'skip',
|
|
185
|
+
issueKey,
|
|
186
|
+
reason: 'State matches',
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
result.errors.push(`Issue ${issueKey}: ${error.message}`);
|
|
192
|
+
result.details.push({
|
|
193
|
+
incrementId: context,
|
|
194
|
+
action: 'error',
|
|
195
|
+
issueKey,
|
|
196
|
+
reason: error.message,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Scan increments directory for non-archived increments
|
|
202
|
+
*/
|
|
203
|
+
async scanIncrements() {
|
|
204
|
+
const incrementsPath = path.join(this.projectRoot, '.specweave', 'increments');
|
|
205
|
+
const results = [];
|
|
206
|
+
if (!existsSync(incrementsPath)) {
|
|
207
|
+
return results;
|
|
208
|
+
}
|
|
209
|
+
const entries = await fs.readdir(incrementsPath, { withFileTypes: true });
|
|
210
|
+
for (const entry of entries) {
|
|
211
|
+
if (!entry.isDirectory())
|
|
212
|
+
continue;
|
|
213
|
+
if (entry.name === '_archive' || entry.name.startsWith('.'))
|
|
214
|
+
continue;
|
|
215
|
+
const incrementPath = path.join(incrementsPath, entry.name);
|
|
216
|
+
const metadataPath = path.join(incrementPath, 'metadata.json');
|
|
217
|
+
if (!existsSync(metadataPath))
|
|
218
|
+
continue;
|
|
219
|
+
try {
|
|
220
|
+
const metadataContent = await fs.readFile(metadataPath, 'utf-8');
|
|
221
|
+
const metadata = JSON.parse(metadataContent);
|
|
222
|
+
// Check for JIRA issue link (support both new and legacy naming)
|
|
223
|
+
const jiraSync = metadata.external_sync?.jira || metadata.external_ids?.jira;
|
|
224
|
+
if (!jiraSync?.issueKey && !jiraSync?.epic)
|
|
225
|
+
continue;
|
|
226
|
+
const state = {
|
|
227
|
+
incrementId: entry.name,
|
|
228
|
+
incrementPath,
|
|
229
|
+
metadataStatus: metadata.status || 'unknown',
|
|
230
|
+
featureId: metadata.featureId,
|
|
231
|
+
issue: {
|
|
232
|
+
key: jiraSync.issueKey || jiraSync.epic,
|
|
233
|
+
url: jiraSync.issueUrl,
|
|
234
|
+
},
|
|
235
|
+
userStoryIssues: [],
|
|
236
|
+
};
|
|
237
|
+
// Extract user story issues if present
|
|
238
|
+
if (jiraSync.stories && Array.isArray(jiraSync.stories)) {
|
|
239
|
+
for (const story of jiraSync.stories) {
|
|
240
|
+
if (story.issueKey || story.key) {
|
|
241
|
+
state.userStoryIssues.push({
|
|
242
|
+
userStoryId: story.id || story.userStoryId,
|
|
243
|
+
issueKey: story.issueKey || story.key,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
results.push(state);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
// Skip invalid metadata
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return results;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Load config.json
|
|
258
|
+
*/
|
|
259
|
+
async loadConfig() {
|
|
260
|
+
const configPath = path.join(this.projectRoot, '.specweave', 'config.json');
|
|
261
|
+
try {
|
|
262
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
263
|
+
return JSON.parse(content);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
return {};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Initialize JIRA credentials
|
|
271
|
+
*/
|
|
272
|
+
initCredentials() {
|
|
273
|
+
const token = process.env.JIRA_API_TOKEN;
|
|
274
|
+
const email = process.env.JIRA_EMAIL;
|
|
275
|
+
this.domain = process.env.JIRA_DOMAIN || '';
|
|
276
|
+
if (!token || !email || !this.domain) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
this.auth = Buffer.from(`${email}:${token}`).toString('base64');
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Get issue from JIRA API
|
|
284
|
+
*/
|
|
285
|
+
async getIssue(issueKey) {
|
|
286
|
+
const url = `https://${this.domain}/rest/api/3/issue/${issueKey}`;
|
|
287
|
+
const response = await fetch(url, {
|
|
288
|
+
headers: {
|
|
289
|
+
Authorization: `Basic ${this.auth}`,
|
|
290
|
+
Accept: 'application/json',
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
if (!response.ok) {
|
|
294
|
+
throw new Error(`Failed to get issue: ${response.status}`);
|
|
295
|
+
}
|
|
296
|
+
return response.json();
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get available transitions for an issue
|
|
300
|
+
*/
|
|
301
|
+
async getTransitions(issueKey) {
|
|
302
|
+
const url = `https://${this.domain}/rest/api/3/issue/${issueKey}/transitions`;
|
|
303
|
+
const response = await fetch(url, {
|
|
304
|
+
headers: {
|
|
305
|
+
Authorization: `Basic ${this.auth}`,
|
|
306
|
+
Accept: 'application/json',
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
if (!response.ok) {
|
|
310
|
+
throw new Error(`Failed to get transitions: ${response.status}`);
|
|
311
|
+
}
|
|
312
|
+
const data = await response.json();
|
|
313
|
+
return data.transitions || [];
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Transition issue to new status and add comment
|
|
317
|
+
*/
|
|
318
|
+
async transitionIssue(issueKey, targetStatus, comment) {
|
|
319
|
+
// First, add comment
|
|
320
|
+
await this.addComment(issueKey, comment);
|
|
321
|
+
// Get available transitions
|
|
322
|
+
const transitions = await this.getTransitions(issueKey);
|
|
323
|
+
// Find transition matching target status
|
|
324
|
+
const transition = transitions.find((t) => t.name.toLowerCase() === targetStatus.toLowerCase() ||
|
|
325
|
+
t.to?.name?.toLowerCase() === targetStatus.toLowerCase());
|
|
326
|
+
if (!transition) {
|
|
327
|
+
// Try common alternatives
|
|
328
|
+
const alternatives = targetStatus === 'Done'
|
|
329
|
+
? ['Closed', 'Resolved', 'Complete']
|
|
330
|
+
: ['Open', 'Reopened', 'In Progress'];
|
|
331
|
+
const altTransition = transitions.find((t) => alternatives.some(alt => t.name.toLowerCase() === alt.toLowerCase() ||
|
|
332
|
+
t.to?.name?.toLowerCase() === alt.toLowerCase()));
|
|
333
|
+
if (!altTransition) {
|
|
334
|
+
throw new Error(`No transition found to "${targetStatus}". Available: ${transitions.map((t) => t.name).join(', ')}`);
|
|
335
|
+
}
|
|
336
|
+
await this.doTransition(issueKey, altTransition.id);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
await this.doTransition(issueKey, transition.id);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Execute transition
|
|
344
|
+
*/
|
|
345
|
+
async doTransition(issueKey, transitionId) {
|
|
346
|
+
const url = `https://${this.domain}/rest/api/3/issue/${issueKey}/transitions`;
|
|
347
|
+
const response = await fetch(url, {
|
|
348
|
+
method: 'POST',
|
|
349
|
+
headers: {
|
|
350
|
+
Authorization: `Basic ${this.auth}`,
|
|
351
|
+
'Content-Type': 'application/json',
|
|
352
|
+
},
|
|
353
|
+
body: JSON.stringify({
|
|
354
|
+
transition: { id: transitionId },
|
|
355
|
+
}),
|
|
356
|
+
});
|
|
357
|
+
if (!response.ok) {
|
|
358
|
+
const error = await response.text();
|
|
359
|
+
throw new Error(`Failed to transition issue: ${response.status} - ${error}`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Add comment to issue
|
|
364
|
+
*/
|
|
365
|
+
async addComment(issueKey, comment) {
|
|
366
|
+
const url = `https://${this.domain}/rest/api/3/issue/${issueKey}/comment`;
|
|
367
|
+
const response = await fetch(url, {
|
|
368
|
+
method: 'POST',
|
|
369
|
+
headers: {
|
|
370
|
+
Authorization: `Basic ${this.auth}`,
|
|
371
|
+
'Content-Type': 'application/json',
|
|
372
|
+
},
|
|
373
|
+
body: JSON.stringify({
|
|
374
|
+
body: {
|
|
375
|
+
type: 'doc',
|
|
376
|
+
version: 1,
|
|
377
|
+
content: [
|
|
378
|
+
{
|
|
379
|
+
type: 'paragraph',
|
|
380
|
+
content: [
|
|
381
|
+
{
|
|
382
|
+
type: 'text',
|
|
383
|
+
text: comment,
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
},
|
|
387
|
+
],
|
|
388
|
+
},
|
|
389
|
+
}),
|
|
390
|
+
});
|
|
391
|
+
if (!response.ok) {
|
|
392
|
+
// Non-fatal, just log warning
|
|
393
|
+
this.logger.log(` ⚠️ Failed to add comment to ${issueKey}`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Convenience function for quick reconciliation
|
|
399
|
+
*/
|
|
400
|
+
export async function reconcileJira(projectRoot = process.cwd(), dryRun = false) {
|
|
401
|
+
const reconciler = new JiraReconciler({ projectRoot, dryRun });
|
|
402
|
+
return reconciler.reconcile();
|
|
403
|
+
}
|
|
404
|
+
export default JiraReconciler;
|
|
405
|
+
//# sourceMappingURL=jira-reconciler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jira-reconciler.js","sourceRoot":"","sources":["../../../src/sync/jira-reconciler.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
* - Phase detection (planning vs execution vs review)
|
|
7
7
|
* - User overrides (manual model selection)
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Strategy (Opus 4.5 Default):
|
|
10
|
+
* - Haiku: Simple/cheap operations, translations, mechanical tasks
|
|
11
|
+
* - Opus: Default for complex work, analysis, architecture, planning
|
|
10
12
|
*/
|
|
11
13
|
/**
|
|
12
14
|
* Available AI models
|
|
13
|
-
* -
|
|
14
|
-
* - haiku: Latest Haiku 4.5 (
|
|
15
|
-
* -
|
|
15
|
+
* - opus: Latest Opus 4.5 (default - planning, analysis, complex work)
|
|
16
|
+
* - haiku: Latest Haiku 4.5 (simple tasks, translations, cheap ops)
|
|
17
|
+
* - sonnet: Sonnet 4 (legacy, rarely used)
|
|
16
18
|
* - auto: System decides based on context
|
|
17
19
|
*/
|
|
18
20
|
export type Model = 'sonnet' | 'haiku' | 'opus' | 'auto';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-selection.d.ts","sourceRoot":"","sources":["../../../src/types/model-selection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model-selection.d.ts","sourceRoot":"","sources":["../../../src/types/model-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAExD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,KAAK,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,eAAe,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,wBAAwB,GAAG,aAAa,GAAG,UAAU,CAAC;IACzH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD"}
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* - Phase detection (planning vs execution vs review)
|
|
7
7
|
* - User overrides (manual model selection)
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Strategy (Opus 4.5 Default):
|
|
10
|
+
* - Haiku: Simple/cheap operations, translations, mechanical tasks
|
|
11
|
+
* - Opus: Default for complex work, analysis, architecture, planning
|
|
10
12
|
*/
|
|
11
13
|
export {};
|
|
12
14
|
//# sourceMappingURL=model-selection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-selection.js","sourceRoot":"","sources":["../../../src/types/model-selection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model-selection.js","sourceRoot":"","sources":["../../../src/types/model-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -30,7 +30,7 @@ export declare class ExternalToolDriftDetector {
|
|
|
30
30
|
* Validate increment ID format to prevent path traversal attacks
|
|
31
31
|
* P0-1: Path traversal vulnerability fix
|
|
32
32
|
*
|
|
33
|
-
* @param incrementId - Increment ID to validate
|
|
33
|
+
* @param incrementId - Increment ID to validate (e.g., "0053-feature" or "0111E-external")
|
|
34
34
|
* @throws Error if increment ID format is invalid
|
|
35
35
|
*/
|
|
36
36
|
private validateIncrementId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-tool-drift-detector.d.ts","sourceRoot":"","sources":["../../../src/utils/external-tool-drift-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAC;AAOpD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uBAAuB,EAAE,OAAO,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,yBAAyB;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAKlE;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;
|
|
1
|
+
{"version":3,"file":"external-tool-drift-detector.d.ts","sourceRoot":"","sources":["../../../src/utils/external-tool-drift-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAC;AAOpD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uBAAuB,EAAE,OAAO,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,yBAAyB;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAKlE;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;;;;;;OAOG;YACW,uBAAuB;IAkBrC;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAcrB;;;;;OAKG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsG5D;;;;;OAKG;IACH,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;CAqB5C"}
|
|
@@ -27,13 +27,14 @@ export class ExternalToolDriftDetector {
|
|
|
27
27
|
* Validate increment ID format to prevent path traversal attacks
|
|
28
28
|
* P0-1: Path traversal vulnerability fix
|
|
29
29
|
*
|
|
30
|
-
* @param incrementId - Increment ID to validate
|
|
30
|
+
* @param incrementId - Increment ID to validate (e.g., "0053-feature" or "0111E-external")
|
|
31
31
|
* @throws Error if increment ID format is invalid
|
|
32
32
|
*/
|
|
33
33
|
validateIncrementId(incrementId) {
|
|
34
|
-
// Expected format: 4 digits + hyphen + kebab-case
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
// Expected format: 4 digits + optional E suffix + hyphen + kebab-case
|
|
35
|
+
// CRITICAL (v0.33.0): Allow E suffix for external increments (e.g., 0111E-name)
|
|
36
|
+
if (!/^\d{4}E?-[a-z0-9-]+$/i.test(incrementId)) {
|
|
37
|
+
throw new Error(`Invalid increment ID format: ${incrementId}. Expected format: XXXX-kebab-case or XXXXE-kebab-case`);
|
|
37
38
|
}
|
|
38
39
|
// Additional safety: reject path traversal attempts
|
|
39
40
|
if (incrementId.includes('..') || incrementId.includes('/') || incrementId.includes('\\')) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-tool-drift-detector.js","sourceRoot":"","sources":["../../../src/utils/external-tool-drift-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,EAAU,aAAa,EAAE,MAAM,aAAa,CAAC;AAEpD,sDAAsD;AACtD,MAAM,qBAAqB,GAAG,EAAE,CAAC,CAAM,oBAAoB;AAC3D,MAAM,uBAAuB,GAAG,EAAE,CAAC,CAAI,mBAAmB;AAC1D,MAAM,wBAAwB,GAAG,GAAG,CAAC,CAAE,8BAA8B;AAWrE,MAAM,OAAO,yBAAyB;IAIpC,YAAY,WAAmB,EAAE,UAA+B,EAAE;QAChE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAChD,CAAC;IAED;;;;;;OAMG;IACK,mBAAmB,CAAC,WAAmB;QAC7C,
|
|
1
|
+
{"version":3,"file":"external-tool-drift-detector.js","sourceRoot":"","sources":["../../../src/utils/external-tool-drift-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Derives feature ID from increment ID using the 1:1 mapping principle:
|
|
5
5
|
* - Each increment maps to exactly one feature folder
|
|
6
|
-
* - Feature ID = FS-{increment_number}
|
|
6
|
+
* - Feature ID = FS-{increment_number} or FS-{increment_number}E for external
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* deriveFeatureId('0081-ado-repo-cloning') → 'FS-081'
|
|
10
10
|
* deriveFeatureId('0100-some-feature') → 'FS-100'
|
|
11
11
|
* deriveFeatureId('1000-future-feature') → 'FS-1000'
|
|
12
|
+
* deriveFeatureId('0111E-external-issue') → 'FS-111E'
|
|
12
13
|
*
|
|
13
14
|
* @see ADR-0140 for the decision rationale
|
|
14
15
|
*/
|
|
@@ -18,12 +19,16 @@
|
|
|
18
19
|
* The feature ID is derived directly from the increment number:
|
|
19
20
|
* - Extract leading digits from increment ID
|
|
20
21
|
* - Format as FS-XXX (minimum 3 digits, more if needed)
|
|
22
|
+
* - Add 'E' suffix for external increments (e.g., 0111E-...)
|
|
21
23
|
*
|
|
22
24
|
* This eliminates the need to store feature_id in metadata.json,
|
|
23
25
|
* as it's 100% derivable from the increment ID.
|
|
24
26
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
+
* CRITICAL (v0.33.0): External increments (with E suffix like 0111E-...)
|
|
28
|
+
* MUST map to external features (FS-111E), not internal ones (FS-111).
|
|
29
|
+
*
|
|
30
|
+
* @param incrementId - Increment ID (e.g., "0081-ado-repo-cloning" or "0111E-external-issue")
|
|
31
|
+
* @returns Feature ID (e.g., "FS-081" or "FS-111E")
|
|
27
32
|
* @throws Error if increment ID format is invalid
|
|
28
33
|
*/
|
|
29
34
|
export declare function deriveFeatureId(incrementId: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-id-derivation.d.ts","sourceRoot":"","sources":["../../../src/utils/feature-id-derivation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"feature-id-derivation.d.ts","sourceRoot":"","sources":["../../../src/utils/feature-id-derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAc3D;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D"}
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Derives feature ID from increment ID using the 1:1 mapping principle:
|
|
5
5
|
* - Each increment maps to exactly one feature folder
|
|
6
|
-
* - Feature ID = FS-{increment_number}
|
|
6
|
+
* - Feature ID = FS-{increment_number} or FS-{increment_number}E for external
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* deriveFeatureId('0081-ado-repo-cloning') → 'FS-081'
|
|
10
10
|
* deriveFeatureId('0100-some-feature') → 'FS-100'
|
|
11
11
|
* deriveFeatureId('1000-future-feature') → 'FS-1000'
|
|
12
|
+
* deriveFeatureId('0111E-external-issue') → 'FS-111E'
|
|
12
13
|
*
|
|
13
14
|
* @see ADR-0140 for the decision rationale
|
|
14
15
|
*/
|
|
@@ -18,23 +19,30 @@
|
|
|
18
19
|
* The feature ID is derived directly from the increment number:
|
|
19
20
|
* - Extract leading digits from increment ID
|
|
20
21
|
* - Format as FS-XXX (minimum 3 digits, more if needed)
|
|
22
|
+
* - Add 'E' suffix for external increments (e.g., 0111E-...)
|
|
21
23
|
*
|
|
22
24
|
* This eliminates the need to store feature_id in metadata.json,
|
|
23
25
|
* as it's 100% derivable from the increment ID.
|
|
24
26
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
+
* CRITICAL (v0.33.0): External increments (with E suffix like 0111E-...)
|
|
28
|
+
* MUST map to external features (FS-111E), not internal ones (FS-111).
|
|
29
|
+
*
|
|
30
|
+
* @param incrementId - Increment ID (e.g., "0081-ado-repo-cloning" or "0111E-external-issue")
|
|
31
|
+
* @returns Feature ID (e.g., "FS-081" or "FS-111E")
|
|
27
32
|
* @throws Error if increment ID format is invalid
|
|
28
33
|
*/
|
|
29
34
|
export function deriveFeatureId(incrementId) {
|
|
30
|
-
|
|
35
|
+
// Match number prefix and optional E suffix
|
|
36
|
+
const match = incrementId.match(/^(\d+)(E)?/);
|
|
31
37
|
if (!match) {
|
|
32
|
-
throw new Error(`Invalid increment ID format: ${incrementId}. Expected format: NNNN-name`);
|
|
38
|
+
throw new Error(`Invalid increment ID format: ${incrementId}. Expected format: NNNN-name or NNNNE-name`);
|
|
33
39
|
}
|
|
34
40
|
const num = parseInt(match[1], 10);
|
|
41
|
+
const isExternal = match[2] === 'E';
|
|
35
42
|
// padStart(3, '0') ensures minimum 3 digits (FS-001 to FS-999)
|
|
36
43
|
// Numbers 1000+ naturally have 4+ digits (FS-1000, FS-1001, etc.)
|
|
37
|
-
|
|
44
|
+
const featureId = `FS-${String(num).padStart(3, '0')}`;
|
|
45
|
+
return isExternal ? `${featureId}E` : featureId;
|
|
38
46
|
}
|
|
39
47
|
/**
|
|
40
48
|
* Extract increment number from increment ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-id-derivation.js","sourceRoot":"","sources":["../../../src/utils/feature-id-derivation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"feature-id-derivation.js","sourceRoot":"","sources":["../../../src/utils/feature-id-derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,4CAA4C;IAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gCAAgC,WAAW,4CAA4C,CAAC,CAAC;IAC3G,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;IAEpC,+DAA+D;IAC/D,kEAAkE;IAClE,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IACvD,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gCAAgC,WAAW,8BAA8B,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,OAAO,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC"}
|