specweave 0.32.2 → 0.32.5
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 +51 -9
- 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-multiproject.js +1 -1
- package/dist/src/cli/commands/init-multiproject.js.map +1 -1
- 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/commands/migrate-to-multiproject.js +2 -2
- package/dist/src/cli/commands/migrate-to-multiproject.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/cross-project-sync.d.ts +97 -0
- package/dist/src/core/living-docs/cross-project-sync.d.ts.map +1 -0
- package/dist/src/core/living-docs/cross-project-sync.js +135 -0
- package/dist/src/core/living-docs/cross-project-sync.js.map +1 -0
- package/dist/src/core/living-docs/external-sync-orchestrator.d.ts +106 -0
- package/dist/src/core/living-docs/external-sync-orchestrator.d.ts.map +1 -0
- package/dist/src/core/living-docs/external-sync-orchestrator.js +146 -0
- package/dist/src/core/living-docs/external-sync-orchestrator.js.map +1 -0
- 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 +7 -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 +94 -10
- 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/living-docs/sync-helpers/generators.d.ts +8 -1
- package/dist/src/core/living-docs/sync-helpers/generators.d.ts.map +1 -1
- package/dist/src/core/living-docs/sync-helpers/generators.js +18 -1
- package/dist/src/core/living-docs/sync-helpers/generators.js.map +1 -1
- package/dist/src/core/living-docs/sync-helpers/index.d.ts +1 -1
- package/dist/src/core/living-docs/sync-helpers/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/sync-helpers/index.js.map +1 -1
- package/dist/src/core/living-docs/sync-helpers/parsers.d.ts +3 -1
- package/dist/src/core/living-docs/sync-helpers/parsers.d.ts.map +1 -1
- package/dist/src/core/living-docs/sync-helpers/parsers.js +24 -2
- package/dist/src/core/living-docs/sync-helpers/parsers.js.map +1 -1
- package/dist/src/core/living-docs/types.d.ts +6 -0
- package/dist/src/core/living-docs/types.d.ts.map +1 -1
- package/dist/src/core/living-docs/validators/index.d.ts +7 -0
- package/dist/src/core/living-docs/validators/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/validators/index.js +7 -0
- package/dist/src/core/living-docs/validators/index.js.map +1 -0
- package/dist/src/core/living-docs/validators/project-validator.d.ts +92 -0
- package/dist/src/core/living-docs/validators/project-validator.d.ts.map +1 -0
- package/dist/src/core/living-docs/validators/project-validator.js +142 -0
- package/dist/src/core/living-docs/validators/project-validator.js.map +1 -0
- 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/core/project/project-manager.d.ts.map +1 -1
- package/dist/src/core/project/project-manager.js +19 -17
- package/dist/src/core/project/project-manager.js.map +1 -1
- package/dist/src/core/types/config.d.ts +4 -2
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/core/types/increment-metadata.d.ts +34 -0
- package/dist/src/core/types/increment-metadata.d.ts.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/cross-cutting-detector.d.ts +66 -0
- package/dist/src/utils/cross-cutting-detector.d.ts.map +1 -0
- package/dist/src/utils/cross-cutting-detector.js +179 -0
- package/dist/src/utils/cross-cutting-detector.js.map +1 -0
- 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/dist/src/utils/project-detection.d.ts +12 -8
- package/dist/src/utils/project-detection.d.ts.map +1 -1
- package/dist/src/utils/project-detection.js +13 -19
- package/dist/src/utils/project-detection.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-status.md +64 -0
- package/plugins/specweave/commands/specweave-validate.md +27 -1
- package/plugins/specweave/hooks/hooks.json +11 -1
- package/plugins/specweave/hooks/spec-project-validator.sh +81 -25
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +135 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +34 -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 +135 -29
- 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/skills/spec-generator/SKILL.md +78 -7
- 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
- package/plugins/specweave/commands/specweave-switch-project.md +0 -168
|
@@ -0,0 +1,106 @@
|
|
|
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 { Logger } from '../utils/logger.js';
|
|
17
|
+
export interface JiraReconcileOptions {
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
dryRun?: boolean;
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
}
|
|
22
|
+
export interface IncrementJiraState {
|
|
23
|
+
incrementId: string;
|
|
24
|
+
incrementPath: string;
|
|
25
|
+
metadataStatus: string;
|
|
26
|
+
featureId?: string;
|
|
27
|
+
issue?: {
|
|
28
|
+
key: string;
|
|
29
|
+
url?: string;
|
|
30
|
+
};
|
|
31
|
+
userStoryIssues: Array<{
|
|
32
|
+
userStoryId: string;
|
|
33
|
+
issueKey: string;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
export interface JiraReconcileResult {
|
|
37
|
+
scanned: number;
|
|
38
|
+
mismatches: number;
|
|
39
|
+
closed: number;
|
|
40
|
+
reopened: number;
|
|
41
|
+
errors: string[];
|
|
42
|
+
details: Array<{
|
|
43
|
+
incrementId: string;
|
|
44
|
+
action: 'close' | 'reopen' | 'skip' | 'error';
|
|
45
|
+
issueKey: string;
|
|
46
|
+
reason: string;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
export declare class JiraReconciler {
|
|
50
|
+
private projectRoot;
|
|
51
|
+
private dryRun;
|
|
52
|
+
private logger;
|
|
53
|
+
private domain;
|
|
54
|
+
private auth;
|
|
55
|
+
constructor(options: JiraReconcileOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Main reconciliation entry point
|
|
58
|
+
*/
|
|
59
|
+
reconcile(): Promise<JiraReconcileResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Reconcile a single increment
|
|
62
|
+
*/
|
|
63
|
+
private reconcileIncrement;
|
|
64
|
+
/**
|
|
65
|
+
* Reconcile a single issue
|
|
66
|
+
*/
|
|
67
|
+
private reconcileIssue;
|
|
68
|
+
/**
|
|
69
|
+
* Scan increments directory for non-archived increments
|
|
70
|
+
*/
|
|
71
|
+
private scanIncrements;
|
|
72
|
+
/**
|
|
73
|
+
* Load config.json
|
|
74
|
+
*/
|
|
75
|
+
private loadConfig;
|
|
76
|
+
/**
|
|
77
|
+
* Initialize JIRA credentials
|
|
78
|
+
*/
|
|
79
|
+
private initCredentials;
|
|
80
|
+
/**
|
|
81
|
+
* Get issue from JIRA API
|
|
82
|
+
*/
|
|
83
|
+
private getIssue;
|
|
84
|
+
/**
|
|
85
|
+
* Get available transitions for an issue
|
|
86
|
+
*/
|
|
87
|
+
private getTransitions;
|
|
88
|
+
/**
|
|
89
|
+
* Transition issue to new status and add comment
|
|
90
|
+
*/
|
|
91
|
+
private transitionIssue;
|
|
92
|
+
/**
|
|
93
|
+
* Execute transition
|
|
94
|
+
*/
|
|
95
|
+
private doTransition;
|
|
96
|
+
/**
|
|
97
|
+
* Add comment to issue
|
|
98
|
+
*/
|
|
99
|
+
private addComment;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Convenience function for quick reconciliation
|
|
103
|
+
*/
|
|
104
|
+
export declare function reconcileJira(projectRoot?: string, dryRun?: boolean): Promise<JiraReconcileResult>;
|
|
105
|
+
export default JiraReconciler;
|
|
106
|
+
//# sourceMappingURL=jira-reconciler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jira-reconciler.d.ts","sourceRoot":"","sources":["../../../src/sync/jira-reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,eAAe,EAAE,KAAK,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;QAC9C,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAUD,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,IAAI,CAAc;gBAEd,OAAO,EAAE,oBAAoB;IAMzC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAqE/C;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,cAAc;IA+F5B;;OAEG;YACW,cAAc;IA4D5B;;OAEG;YACW,UAAU;IAWxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;YACW,QAAQ;IAiBtB;;OAEG;YACW,cAAc;IAkB5B;;OAEG;YACW,eAAe;IAwC7B;;OAEG;YACW,YAAY;IAoB1B;;OAEG;YACW,UAAU;CAiCzB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,GAAE,MAAsB,EACnC,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,mBAAmB,CAAC,CAG9B;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Cutting Feature Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects when a feature spans multiple projects based on keywords,
|
|
5
|
+
* tech stack mentions, and component references.
|
|
6
|
+
*
|
|
7
|
+
* @module utils/cross-cutting-detector
|
|
8
|
+
* @since v0.33.0
|
|
9
|
+
*/
|
|
10
|
+
import { Logger } from './logger.js';
|
|
11
|
+
/**
|
|
12
|
+
* Result of cross-cutting detection
|
|
13
|
+
*/
|
|
14
|
+
export interface CrossCuttingResult {
|
|
15
|
+
isCrossCutting: boolean;
|
|
16
|
+
confidence: 'high' | 'medium' | 'low';
|
|
17
|
+
suggestedProjects: string[];
|
|
18
|
+
detectedPatterns: DetectedPattern[];
|
|
19
|
+
reason?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Pattern that triggered detection
|
|
23
|
+
*/
|
|
24
|
+
export interface DetectedPattern {
|
|
25
|
+
type: 'keyword' | 'tech-stack' | 'component' | 'explicit';
|
|
26
|
+
matched: string;
|
|
27
|
+
suggestedProject?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Cross-Cutting Detector
|
|
31
|
+
*/
|
|
32
|
+
export declare class CrossCuttingDetector {
|
|
33
|
+
private logger;
|
|
34
|
+
private customMappings;
|
|
35
|
+
constructor(options?: {
|
|
36
|
+
logger?: Logger;
|
|
37
|
+
customMappings?: Record<string, string[]>;
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Detect if a description indicates cross-cutting concerns
|
|
41
|
+
*/
|
|
42
|
+
detect(description: string): CrossCuttingResult;
|
|
43
|
+
/**
|
|
44
|
+
* Add custom project mappings
|
|
45
|
+
*/
|
|
46
|
+
addCustomMapping(project: string, keywords: string[]): void;
|
|
47
|
+
/**
|
|
48
|
+
* Load custom mappings from config
|
|
49
|
+
*/
|
|
50
|
+
loadMappingsFromConfig(projectMappings: Record<string, unknown>): void;
|
|
51
|
+
/**
|
|
52
|
+
* Escape regex special characters
|
|
53
|
+
*/
|
|
54
|
+
private escapeRegex;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Convenience function for one-off detection
|
|
58
|
+
*/
|
|
59
|
+
export declare function detectCrossCutting(description: string, options?: {
|
|
60
|
+
customMappings?: Record<string, string[]>;
|
|
61
|
+
}): CrossCuttingResult;
|
|
62
|
+
/**
|
|
63
|
+
* Get suggested project for a single-project feature
|
|
64
|
+
*/
|
|
65
|
+
export declare function suggestSingleProject(description: string): string | null;
|
|
66
|
+
//# sourceMappingURL=cross-cutting-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-cutting-detector.d.ts","sourceRoot":"","sources":["../../../src/utils/cross-cutting-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,UAAU,CAAC;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAgDD;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAgC;gBAE1C,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;KAAO;IAKxF;;OAEG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB;IA+E/C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAO3D;;OAEG;IACH,sBAAsB,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAUtE;;OAEG;IACH,OAAO,CAAC,WAAW;CAGpB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAAE,GACtD,kBAAkB,CAGpB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYvE"}
|