specweave 0.22.13 → 0.22.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/README.md +2 -2
- package/CLAUDE.md +269 -51
- package/README.md +33 -10
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js +1 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +4 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.d.ts +9 -0
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js +10 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js.map +1 -1
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js +2 -2
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js.map +1 -1
- package/dist/plugins/specweave-github/lib/types.d.ts +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +313 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +41 -24
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/config/import-config.d.ts +69 -0
- package/dist/src/config/import-config.d.ts.map +1 -0
- package/dist/src/config/import-config.js +136 -0
- package/dist/src/config/import-config.js.map +1 -0
- package/dist/src/config/types.d.ts +10 -10
- package/dist/src/core/living-docs/living-docs-sync.d.ts +2 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +10 -1
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts +2 -2
- package/dist/src/core/living-docs/task-project-specific-generator.js +2 -2
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts +2 -2
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.js +3 -15
- package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +3 -6
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/spec-content-sync.d.ts +4 -1
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/spec-content-sync.js +139 -4
- package/dist/src/core/spec-content-sync.js.map +1 -1
- package/dist/src/core/spec-task-mapper.d.ts.map +1 -1
- package/dist/src/core/spec-task-mapper.js +9 -8
- package/dist/src/core/spec-task-mapper.js.map +1 -1
- package/dist/src/core/status-line-validator.d.ts +63 -0
- package/dist/src/core/status-line-validator.d.ts.map +1 -0
- package/dist/src/core/status-line-validator.js +253 -0
- package/dist/src/core/status-line-validator.js.map +1 -0
- package/dist/src/core/sync/bidirectional-engine.d.ts +10 -1
- package/dist/src/core/sync/bidirectional-engine.d.ts.map +1 -1
- package/dist/src/core/sync/bidirectional-engine.js +10 -1
- package/dist/src/core/sync/bidirectional-engine.js.map +1 -1
- package/dist/src/core/sync/profile-manager.d.ts.map +1 -1
- package/dist/src/core/sync/profile-manager.js +3 -0
- package/dist/src/core/sync/profile-manager.js.map +1 -1
- package/dist/src/core/sync/project-context.d.ts.map +1 -1
- package/dist/src/core/sync/project-context.js +3 -0
- package/dist/src/core/sync/project-context.js.map +1 -1
- package/dist/src/core/sync/status-sync-engine.d.ts +1 -1
- package/dist/src/core/sync/status-sync-engine.js +1 -1
- package/dist/src/core/types/origin-metadata.d.ts +153 -0
- package/dist/src/core/types/origin-metadata.d.ts.map +1 -0
- package/dist/src/core/types/origin-metadata.js +166 -0
- package/dist/src/core/types/origin-metadata.js.map +1 -0
- package/dist/src/core/types/sync-profile.d.ts +8 -2
- package/dist/src/core/types/sync-profile.d.ts.map +1 -1
- package/dist/src/core/types/sync-profile.js.map +1 -1
- package/dist/src/core/types/sync-settings.d.ts +73 -0
- package/dist/src/core/types/sync-settings.d.ts.map +1 -0
- package/dist/src/core/types/sync-settings.js +90 -0
- package/dist/src/core/types/sync-settings.js.map +1 -0
- package/dist/src/core/utils/permission-checker.d.ts +100 -0
- package/dist/src/core/utils/permission-checker.d.ts.map +1 -0
- package/dist/src/core/utils/permission-checker.js +166 -0
- package/dist/src/core/utils/permission-checker.js.map +1 -0
- package/dist/src/generators/spec/spec-parser.js +3 -3
- package/dist/src/generators/spec/spec-parser.js.map +1 -1
- package/dist/src/generators/spec/task-parser.js +4 -4
- package/dist/src/generators/spec/task-parser.js.map +1 -1
- package/dist/src/id-generators/task-id-generator.d.ts +96 -0
- package/dist/src/id-generators/task-id-generator.d.ts.map +1 -0
- package/dist/src/id-generators/task-id-generator.js +143 -0
- package/dist/src/id-generators/task-id-generator.js.map +1 -0
- package/dist/src/id-generators/us-id-generator.d.ts +96 -0
- package/dist/src/id-generators/us-id-generator.d.ts.map +1 -0
- package/dist/src/id-generators/us-id-generator.js +143 -0
- package/dist/src/id-generators/us-id-generator.js.map +1 -0
- package/dist/src/importers/ado-importer.d.ts +43 -0
- package/dist/src/importers/ado-importer.d.ts.map +1 -0
- package/dist/src/importers/ado-importer.js +234 -0
- package/dist/src/importers/ado-importer.js.map +1 -0
- package/dist/src/importers/external-importer.d.ts +96 -0
- package/dist/src/importers/external-importer.d.ts.map +1 -0
- package/dist/src/importers/external-importer.js +13 -0
- package/dist/src/importers/external-importer.js.map +1 -0
- package/dist/src/importers/github-importer.d.ts +37 -0
- package/dist/src/importers/github-importer.d.ts.map +1 -0
- package/dist/src/importers/github-importer.js +161 -0
- package/dist/src/importers/github-importer.js.map +1 -0
- package/dist/src/importers/import-coordinator.d.ts +90 -0
- package/dist/src/importers/import-coordinator.d.ts.map +1 -0
- package/dist/src/importers/import-coordinator.js +182 -0
- package/dist/src/importers/import-coordinator.js.map +1 -0
- package/dist/src/importers/item-converter.d.ts +91 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -0
- package/dist/src/importers/item-converter.js +221 -0
- package/dist/src/importers/item-converter.js.map +1 -0
- package/dist/src/importers/jira-importer.d.ts +42 -0
- package/dist/src/importers/jira-importer.d.ts.map +1 -0
- package/dist/src/importers/jira-importer.js +221 -0
- package/dist/src/importers/jira-importer.js.map +1 -0
- package/dist/src/init/repo/types.d.ts +2 -2
- package/dist/src/integrations/jira/jira-mapper.d.ts +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +149 -0
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -0
- package/dist/src/living-docs/fs-id-allocator.js +325 -0
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -0
- package/dist/src/living-docs/id-registry.d.ts +124 -0
- package/dist/src/living-docs/id-registry.d.ts.map +1 -0
- package/dist/src/living-docs/id-registry.js +230 -0
- package/dist/src/living-docs/id-registry.js.map +1 -0
- package/dist/src/progress/us-progress-tracker.d.ts +68 -0
- package/dist/src/progress/us-progress-tracker.d.ts.map +1 -0
- package/dist/src/progress/us-progress-tracker.js +120 -0
- package/dist/src/progress/us-progress-tracker.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +16 -2
- package/plugins/specweave/agents/architect/AGENT.md +11 -2
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +81 -25
- package/plugins/specweave/commands/specweave-import-docs.md +278 -88
- package/plugins/specweave/commands/specweave-progress.md +45 -97
- package/plugins/specweave/hooks/post-increment-completion.sh +168 -26
- package/plugins/specweave/hooks/post-increment-planning.sh +148 -4
- package/plugins/specweave/hooks/post-task-completion.sh +64 -4
- package/plugins/specweave/lib/hooks/sync-cache.js +294 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.js +32 -1
- package/plugins/specweave/lib/hooks/sync-us-tasks.js +23 -13
- package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ado/lib/conflict-resolver.ts +1 -1
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-backend/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-confluent/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-docs/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-figma/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh +37 -22
- package/plugins/specweave-github/lib/ThreeLayerSyncManager.ts +1 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.js +1 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.js +2 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +4 -1
- package/plugins/specweave-github/lib/github-spec-sync.js +1 -1
- package/plugins/specweave-github/lib/github-spec-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.js +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.ts +10 -1
- package/plugins/specweave-github/lib/progress-comment-builder.js +1 -1
- package/plugins/specweave-github/lib/progress-comment-builder.ts +2 -2
- package/plugins/specweave-github/lib/types.ts +1 -1
- package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kubernetes/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ml/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-mobile/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-payments/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +252 -0
- package/plugins/specweave-testing/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ui/.claude-plugin/plugin.json +1 -1
- package/src/templates/.env.example +5 -0
- package/src/templates/config-permissions-guide.md +413 -0
- package/src/templates/config.json.template +68 -0
- package/src/templates/tasks.md.template +180 -201
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Story ID Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates unique User Story IDs with support for both internal and external origins.
|
|
5
|
+
* - Internal IDs: US-001, US-002, US-003 (no suffix)
|
|
6
|
+
* - External IDs: US-001E, US-002E, US-003E (E suffix)
|
|
7
|
+
*
|
|
8
|
+
* ID generation strategy:
|
|
9
|
+
* 1. Extract numeric part from all existing IDs (ignoring suffix)
|
|
10
|
+
* 2. Find maximum number across both internal and external IDs
|
|
11
|
+
* 3. Increment to get next sequential number
|
|
12
|
+
* 4. Add E suffix for external origin, no suffix for internal
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Parse User Story ID to extract components
|
|
16
|
+
*
|
|
17
|
+
* @param id - User Story ID (e.g., "US-001", "US-002E")
|
|
18
|
+
* @returns Parsed ID components
|
|
19
|
+
* @throws Error if ID format is invalid
|
|
20
|
+
*/
|
|
21
|
+
export function parseUsId(id) {
|
|
22
|
+
// Match: US-001 or US-001E
|
|
23
|
+
const match = id.match(/^US-(\d+)(E)?$/);
|
|
24
|
+
if (!match) {
|
|
25
|
+
throw new Error(`Invalid User Story ID format: ${id}. Expected format: US-XXX or US-XXXE`);
|
|
26
|
+
}
|
|
27
|
+
const number = parseInt(match[1], 10);
|
|
28
|
+
const origin = match[2] === 'E' ? 'external' : 'internal';
|
|
29
|
+
return {
|
|
30
|
+
id,
|
|
31
|
+
number,
|
|
32
|
+
origin
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get next sequential User Story ID
|
|
37
|
+
*
|
|
38
|
+
* Finds maximum numeric ID across all existing IDs (internal + external)
|
|
39
|
+
* and generates next sequential ID with appropriate suffix.
|
|
40
|
+
*
|
|
41
|
+
* @param existingIds - Array of existing User Story IDs
|
|
42
|
+
* @param origin - Origin type for new ID
|
|
43
|
+
* @returns Next sequential User Story ID
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* getNextUsId(['US-001', 'US-002E', 'US-003'], 'internal')
|
|
47
|
+
* // Returns: 'US-004'
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* getNextUsId(['US-001', 'US-002E', 'US-003'], 'external')
|
|
51
|
+
* // Returns: 'US-004E'
|
|
52
|
+
*/
|
|
53
|
+
export function getNextUsId(existingIds, origin) {
|
|
54
|
+
if (existingIds.length === 0) {
|
|
55
|
+
return origin === 'external' ? 'US-001E' : 'US-001';
|
|
56
|
+
}
|
|
57
|
+
// Extract numeric parts from all IDs
|
|
58
|
+
const numbers = [];
|
|
59
|
+
for (const id of existingIds) {
|
|
60
|
+
try {
|
|
61
|
+
const parsed = parseUsId(id);
|
|
62
|
+
numbers.push(parsed.number);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
// Skip invalid IDs (they'll be caught by validation elsewhere)
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Find maximum number
|
|
70
|
+
const maxNumber = numbers.length > 0 ? Math.max(...numbers) : 0;
|
|
71
|
+
// Generate next ID
|
|
72
|
+
const nextNumber = maxNumber + 1;
|
|
73
|
+
const formattedNumber = String(nextNumber).padStart(3, '0');
|
|
74
|
+
return origin === 'external' ? `US-${formattedNumber}E` : `US-${formattedNumber}`;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Validate ID uniqueness
|
|
78
|
+
*
|
|
79
|
+
* @param id - User Story ID to check
|
|
80
|
+
* @param existingIds - Array of existing User Story IDs
|
|
81
|
+
* @throws Error if ID already exists
|
|
82
|
+
*/
|
|
83
|
+
export function validateUsIdUniqueness(id, existingIds) {
|
|
84
|
+
if (existingIds.includes(id)) {
|
|
85
|
+
throw new Error(`ID collision detected: ${id} already exists`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Detect origin from User Story ID
|
|
90
|
+
*
|
|
91
|
+
* @param id - User Story ID
|
|
92
|
+
* @returns Origin type ('internal' or 'external')
|
|
93
|
+
*/
|
|
94
|
+
export function getUsIdOrigin(id) {
|
|
95
|
+
const parsed = parseUsId(id);
|
|
96
|
+
return parsed.origin;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extract numeric part from User Story ID
|
|
100
|
+
*
|
|
101
|
+
* @param id - User Story ID
|
|
102
|
+
* @returns Numeric part
|
|
103
|
+
*/
|
|
104
|
+
export function getUsIdNumber(id) {
|
|
105
|
+
const parsed = parseUsId(id);
|
|
106
|
+
return parsed.number;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Check if ID is external (has E suffix)
|
|
110
|
+
*
|
|
111
|
+
* @param id - User Story ID
|
|
112
|
+
* @returns true if external, false if internal
|
|
113
|
+
*/
|
|
114
|
+
export function isExternalUsId(id) {
|
|
115
|
+
return getUsIdOrigin(id) === 'external';
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Generate range of User Story IDs
|
|
119
|
+
*
|
|
120
|
+
* @param start - Starting number
|
|
121
|
+
* @param count - Number of IDs to generate
|
|
122
|
+
* @param origin - Origin type
|
|
123
|
+
* @returns Array of User Story IDs
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* generateUsIdRange(1, 3, 'internal')
|
|
127
|
+
* // Returns: ['US-001', 'US-002', 'US-003']
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* generateUsIdRange(5, 2, 'external')
|
|
131
|
+
* // Returns: ['US-005E', 'US-006E']
|
|
132
|
+
*/
|
|
133
|
+
export function generateUsIdRange(start, count, origin) {
|
|
134
|
+
const ids = [];
|
|
135
|
+
for (let i = 0; i < count; i++) {
|
|
136
|
+
const number = start + i;
|
|
137
|
+
const formattedNumber = String(number).padStart(3, '0');
|
|
138
|
+
const id = origin === 'external' ? `US-${formattedNumber}E` : `US-${formattedNumber}`;
|
|
139
|
+
ids.push(id);
|
|
140
|
+
}
|
|
141
|
+
return ids;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=us-id-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"us-id-generator.js","sourceRoot":"","sources":["../../../src/id-generators/us-id-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure DevOps Importer
|
|
3
|
+
*
|
|
4
|
+
* Imports Azure DevOps work items as External Items with WIQL support and pagination.
|
|
5
|
+
* Handles PAT authentication and converts ADO-specific data to platform-agnostic format.
|
|
6
|
+
*/
|
|
7
|
+
import type { Importer, ExternalItem, ImportConfig } from './external-importer.js';
|
|
8
|
+
/**
|
|
9
|
+
* Azure DevOps Importer Implementation
|
|
10
|
+
*/
|
|
11
|
+
export declare class ADOImporter implements Importer {
|
|
12
|
+
readonly platform: "ado";
|
|
13
|
+
private orgUrl;
|
|
14
|
+
private project;
|
|
15
|
+
private pat;
|
|
16
|
+
constructor(orgUrl: string, project: string, pat?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Import all work items matching config
|
|
19
|
+
*/
|
|
20
|
+
import(config?: ImportConfig): Promise<ExternalItem[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Paginate through work items using WIQL (200 per page)
|
|
23
|
+
*/
|
|
24
|
+
paginate(config?: ImportConfig): AsyncGenerator<ExternalItem[], void, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Fetch work items in batch (up to 200 IDs)
|
|
27
|
+
*/
|
|
28
|
+
private getWorkItemsBatch;
|
|
29
|
+
/**
|
|
30
|
+
* Make authenticated ADO API request
|
|
31
|
+
*/
|
|
32
|
+
private makeADORequest;
|
|
33
|
+
/**
|
|
34
|
+
* Convert ADO work item to ExternalItem
|
|
35
|
+
*/
|
|
36
|
+
private convertToExternalItem;
|
|
37
|
+
/**
|
|
38
|
+
* Parse acceptance criteria from ADO HTML format
|
|
39
|
+
* ADO stores ACs as HTML, needs to extract plain text
|
|
40
|
+
*/
|
|
41
|
+
private parseAcceptanceCriteria;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ado-importer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ado-importer.d.ts","sourceRoot":"","sources":["../../../src/importers/ado-importer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAmCnF;;GAEG;AACH,qBAAa,WAAY,YAAW,QAAQ;IAC1C,QAAQ,CAAC,QAAQ,EAAG,KAAK,CAAU;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,GAAG,CAAS;gBAER,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAYzD;;OAEG;IACG,MAAM,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAUhE;;OAEG;IACI,QAAQ,CAAC,MAAM,GAAE,YAAiB,GAAG,cAAc,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC;IAoFzF;;OAEG;YACW,iBAAiB;IA2B/B;;OAEG;YACW,cAAc;IA8B5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiE7B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;CAkBhC"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure DevOps Importer
|
|
3
|
+
*
|
|
4
|
+
* Imports Azure DevOps work items as External Items with WIQL support and pagination.
|
|
5
|
+
* Handles PAT authentication and converts ADO-specific data to platform-agnostic format.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Azure DevOps Importer Implementation
|
|
9
|
+
*/
|
|
10
|
+
export class ADOImporter {
|
|
11
|
+
constructor(orgUrl, project, pat) {
|
|
12
|
+
this.platform = 'ado';
|
|
13
|
+
this.orgUrl = orgUrl.replace(/\/+$/, ''); // Remove trailing slashes
|
|
14
|
+
this.project = project;
|
|
15
|
+
this.pat = pat || process.env.ADO_PAT || process.env.AZURE_DEVOPS_PAT || '';
|
|
16
|
+
if (!this.pat) {
|
|
17
|
+
throw new Error('Azure DevOps authentication required: Set ADO_PAT or AZURE_DEVOPS_PAT environment variable');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Import all work items matching config
|
|
22
|
+
*/
|
|
23
|
+
async import(config = {}) {
|
|
24
|
+
const items = [];
|
|
25
|
+
for await (const page of this.paginate(config)) {
|
|
26
|
+
items.push(...page);
|
|
27
|
+
}
|
|
28
|
+
return items;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Paginate through work items using WIQL (200 per page)
|
|
32
|
+
*/
|
|
33
|
+
async *paginate(config = {}) {
|
|
34
|
+
const { timeRangeMonths = 3, includeClosed = false, labels = [], maxItems = Infinity, } = config;
|
|
35
|
+
// Build WIQL query
|
|
36
|
+
const since = new Date();
|
|
37
|
+
since.setMonth(since.getMonth() - timeRangeMonths);
|
|
38
|
+
const sinceStr = since.toISOString().split('T')[0];
|
|
39
|
+
const wiqlParts = [
|
|
40
|
+
`SELECT [System.Id], [System.Title], [System.WorkItemType], [System.State]`,
|
|
41
|
+
`FROM WorkItems`,
|
|
42
|
+
`WHERE [System.TeamProject] = '${this.project}'`,
|
|
43
|
+
`AND [System.CreatedDate] >= '${sinceStr}'`,
|
|
44
|
+
];
|
|
45
|
+
// Status filter
|
|
46
|
+
if (!includeClosed) {
|
|
47
|
+
wiqlParts.push(`AND [System.State] <> 'Closed' AND [System.State] <> 'Removed'`);
|
|
48
|
+
}
|
|
49
|
+
// Tags filter (ADO uses semicolon-separated tags)
|
|
50
|
+
if (labels.length > 0) {
|
|
51
|
+
const tagsCondition = labels.map((tag) => `[System.Tags] CONTAINS '${tag}'`).join(' OR ');
|
|
52
|
+
wiqlParts.push(`AND (${tagsCondition})`);
|
|
53
|
+
}
|
|
54
|
+
wiqlParts.push(`ORDER BY [System.CreatedDate] DESC`);
|
|
55
|
+
const wiql = wiqlParts.join(' ');
|
|
56
|
+
try {
|
|
57
|
+
// Step 1: Execute WIQL query ONCE to get all work item IDs
|
|
58
|
+
const queryResult = await this.makeADORequest(`/_apis/wit/wiql?api-version=7.0`, {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
body: JSON.stringify({ query: wiql }),
|
|
61
|
+
});
|
|
62
|
+
const allWorkItemIds = queryResult.workItems.map((wi) => wi.id);
|
|
63
|
+
// Step 2: Paginate through work item IDs
|
|
64
|
+
let skip = 0;
|
|
65
|
+
const top = 200; // ADO pagination size (max 200)
|
|
66
|
+
let totalFetched = 0;
|
|
67
|
+
while (skip < allWorkItemIds.length && totalFetched < maxItems) {
|
|
68
|
+
// Get IDs for this page
|
|
69
|
+
const ids = allWorkItemIds.slice(skip, skip + top);
|
|
70
|
+
if (ids.length === 0) {
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
// Fetch full work item details
|
|
74
|
+
const workItems = await this.getWorkItemsBatch(ids);
|
|
75
|
+
// Convert to ExternalItems
|
|
76
|
+
const items = workItems.map((wi) => this.convertToExternalItem(wi));
|
|
77
|
+
// Yield page
|
|
78
|
+
if (items.length > 0) {
|
|
79
|
+
yield items.slice(0, maxItems - totalFetched);
|
|
80
|
+
totalFetched += items.length;
|
|
81
|
+
}
|
|
82
|
+
skip += top;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error.status === 401) {
|
|
87
|
+
throw new Error(`Azure DevOps authentication failed: ${error.message}`);
|
|
88
|
+
}
|
|
89
|
+
else if (error.status === 403) {
|
|
90
|
+
throw new Error(`Azure DevOps access forbidden: ${error.message}`);
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Fetch work items in batch (up to 200 IDs)
|
|
97
|
+
*/
|
|
98
|
+
async getWorkItemsBatch(ids) {
|
|
99
|
+
if (ids.length === 0) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const idsParam = ids.join(',');
|
|
103
|
+
const fields = [
|
|
104
|
+
'System.Id',
|
|
105
|
+
'System.Title',
|
|
106
|
+
'System.Description',
|
|
107
|
+
'System.WorkItemType',
|
|
108
|
+
'System.State',
|
|
109
|
+
'System.CreatedDate',
|
|
110
|
+
'System.ChangedDate',
|
|
111
|
+
'System.Tags',
|
|
112
|
+
'Microsoft.VSTS.Common.Priority',
|
|
113
|
+
'Microsoft.VSTS.Common.AcceptanceCriteria',
|
|
114
|
+
'System.Parent',
|
|
115
|
+
].join(',');
|
|
116
|
+
const response = await this.makeADORequest(`/_apis/wit/workitems?ids=${idsParam}&fields=${fields}&$expand=Links&api-version=7.0`);
|
|
117
|
+
return response.value;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Make authenticated ADO API request
|
|
121
|
+
*/
|
|
122
|
+
async makeADORequest(endpoint, options = {}) {
|
|
123
|
+
const url = `${this.orgUrl}/${this.project}${endpoint}`;
|
|
124
|
+
// Create Basic Auth header (PAT as username, empty password)
|
|
125
|
+
const auth = Buffer.from(`:${this.pat}`).toString('base64');
|
|
126
|
+
const response = await fetch(url, {
|
|
127
|
+
method: options.method || 'GET',
|
|
128
|
+
headers: {
|
|
129
|
+
'Authorization': `Basic ${auth}`,
|
|
130
|
+
'Accept': 'application/json',
|
|
131
|
+
'Content-Type': 'application/json',
|
|
132
|
+
...options.headers,
|
|
133
|
+
},
|
|
134
|
+
body: options.body,
|
|
135
|
+
});
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
const errorText = await response.text();
|
|
138
|
+
const error = new Error(`ADO API error: ${response.statusText} - ${errorText}`);
|
|
139
|
+
error.status = response.status;
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
return response.json();
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Convert ADO work item to ExternalItem
|
|
146
|
+
*/
|
|
147
|
+
convertToExternalItem(workItem) {
|
|
148
|
+
// Map ADO work item type to ExternalItem type
|
|
149
|
+
let type = 'task';
|
|
150
|
+
const witType = workItem.fields['System.WorkItemType'].toLowerCase();
|
|
151
|
+
if (witType === 'user story' || witType === 'product backlog item') {
|
|
152
|
+
type = 'user-story';
|
|
153
|
+
}
|
|
154
|
+
else if (witType === 'epic') {
|
|
155
|
+
type = 'epic';
|
|
156
|
+
}
|
|
157
|
+
else if (witType === 'bug') {
|
|
158
|
+
type = 'bug';
|
|
159
|
+
}
|
|
160
|
+
else if (witType === 'feature') {
|
|
161
|
+
type = 'feature';
|
|
162
|
+
}
|
|
163
|
+
// Map ADO priority to ExternalItem priority
|
|
164
|
+
const priorityValue = workItem.fields['Microsoft.VSTS.Common.Priority'];
|
|
165
|
+
let priority;
|
|
166
|
+
if (priorityValue !== undefined) {
|
|
167
|
+
if (priorityValue === 1)
|
|
168
|
+
priority = 'P0';
|
|
169
|
+
else if (priorityValue === 2)
|
|
170
|
+
priority = 'P1';
|
|
171
|
+
else if (priorityValue === 3)
|
|
172
|
+
priority = 'P2';
|
|
173
|
+
else if (priorityValue === 4)
|
|
174
|
+
priority = 'P3';
|
|
175
|
+
else
|
|
176
|
+
priority = 'P4';
|
|
177
|
+
}
|
|
178
|
+
// Extract acceptance criteria (ADO has dedicated field)
|
|
179
|
+
const acceptanceCriteria = workItem.fields['Microsoft.VSTS.Common.AcceptanceCriteria']
|
|
180
|
+
? this.parseAcceptanceCriteria(workItem.fields['Microsoft.VSTS.Common.AcceptanceCriteria'])
|
|
181
|
+
: undefined;
|
|
182
|
+
// Map ADO state to ExternalItem status
|
|
183
|
+
let status = 'open';
|
|
184
|
+
const state = workItem.fields['System.State'].toLowerCase();
|
|
185
|
+
if (state === 'active' || state === 'in progress' || state === 'committed') {
|
|
186
|
+
status = 'in-progress';
|
|
187
|
+
}
|
|
188
|
+
else if (state === 'closed' || state === 'done' || state === 'resolved') {
|
|
189
|
+
status = 'completed';
|
|
190
|
+
}
|
|
191
|
+
// Parse tags (semicolon-separated)
|
|
192
|
+
const tags = workItem.fields['System.Tags']
|
|
193
|
+
? workItem.fields['System.Tags'].split(';').map((t) => t.trim()).filter(Boolean)
|
|
194
|
+
: [];
|
|
195
|
+
return {
|
|
196
|
+
id: `ADO-${workItem.fields['System.Id']}`,
|
|
197
|
+
type,
|
|
198
|
+
title: workItem.fields['System.Title'],
|
|
199
|
+
description: workItem.fields['System.Description'] || '',
|
|
200
|
+
status,
|
|
201
|
+
priority,
|
|
202
|
+
createdAt: new Date(workItem.fields['System.CreatedDate']),
|
|
203
|
+
updatedAt: new Date(workItem.fields['System.ChangedDate']),
|
|
204
|
+
url: workItem._links.html.href,
|
|
205
|
+
labels: tags,
|
|
206
|
+
acceptanceCriteria,
|
|
207
|
+
parentId: workItem.fields['System.Parent']
|
|
208
|
+
? `ADO-${workItem.fields['System.Parent'].id}`
|
|
209
|
+
: undefined,
|
|
210
|
+
platform: 'ado',
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Parse acceptance criteria from ADO HTML format
|
|
215
|
+
* ADO stores ACs as HTML, needs to extract plain text
|
|
216
|
+
*/
|
|
217
|
+
parseAcceptanceCriteria(html) {
|
|
218
|
+
// Strip HTML tags and extract bullet points
|
|
219
|
+
const text = html
|
|
220
|
+
.replace(/<[^>]*>/g, '') // Remove HTML tags
|
|
221
|
+
.replace(/ /g, ' ')
|
|
222
|
+
.replace(/&/g, '&')
|
|
223
|
+
.replace(/</g, '<')
|
|
224
|
+
.replace(/>/g, '>')
|
|
225
|
+
.replace(/"/g, '"');
|
|
226
|
+
// Split by newlines and filter empty lines
|
|
227
|
+
const lines = text
|
|
228
|
+
.split('\n')
|
|
229
|
+
.map((line) => line.trim())
|
|
230
|
+
.filter(Boolean);
|
|
231
|
+
return lines.length > 0 ? lines : undefined;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=ado-importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ado-importer.js","sourceRoot":"","sources":["../../../src/importers/ado-importer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Importer Interface
|
|
3
|
+
*
|
|
4
|
+
* Abstraction layer for importing User Stories and tasks from external tools
|
|
5
|
+
* (GitHub, JIRA, Azure DevOps) into SpecWeave living docs.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - Pagination for large datasets
|
|
9
|
+
* - Time range filtering
|
|
10
|
+
* - Platform-specific conversion
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* External item representation (platform-agnostic)
|
|
14
|
+
*/
|
|
15
|
+
export interface ExternalItem {
|
|
16
|
+
/** Platform-specific ID (e.g., "JIRA-123", "github#456") */
|
|
17
|
+
id: string;
|
|
18
|
+
/** Item type (user-story, epic, task, bug) */
|
|
19
|
+
type: 'user-story' | 'epic' | 'task' | 'bug' | 'feature';
|
|
20
|
+
/** Title/summary */
|
|
21
|
+
title: string;
|
|
22
|
+
/** Description/body */
|
|
23
|
+
description: string;
|
|
24
|
+
/** Status (open, in-progress, completed, closed) */
|
|
25
|
+
status: 'open' | 'in-progress' | 'completed' | 'closed';
|
|
26
|
+
/** Priority (P0-P4) */
|
|
27
|
+
priority?: 'P0' | 'P1' | 'P2' | 'P3' | 'P4';
|
|
28
|
+
/** Creation date */
|
|
29
|
+
createdAt: Date;
|
|
30
|
+
/** Last updated date */
|
|
31
|
+
updatedAt: Date;
|
|
32
|
+
/** External URL */
|
|
33
|
+
url: string;
|
|
34
|
+
/** Labels/tags */
|
|
35
|
+
labels: string[];
|
|
36
|
+
/** Acceptance criteria (extracted from description) */
|
|
37
|
+
acceptanceCriteria?: string[];
|
|
38
|
+
/** Child items (subtasks, linked issues) */
|
|
39
|
+
children?: ExternalItem[];
|
|
40
|
+
/** Parent ID (for hierarchical items) */
|
|
41
|
+
parentId?: string;
|
|
42
|
+
/** Platform this item came from */
|
|
43
|
+
platform: 'github' | 'jira' | 'ado';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Import configuration
|
|
47
|
+
*/
|
|
48
|
+
export interface ImportConfig {
|
|
49
|
+
/** Time range in months (default: 3) */
|
|
50
|
+
timeRangeMonths?: number;
|
|
51
|
+
/** Include closed items (default: false) */
|
|
52
|
+
includeClosed?: boolean;
|
|
53
|
+
/** Filter by labels */
|
|
54
|
+
labels?: string[];
|
|
55
|
+
/** Filter by milestone/epic */
|
|
56
|
+
milestone?: string;
|
|
57
|
+
/** Maximum items to import (default: unlimited) */
|
|
58
|
+
maxItems?: number;
|
|
59
|
+
/** Include child items (subtasks) */
|
|
60
|
+
includeChildren?: boolean;
|
|
61
|
+
/** Page size for pagination (default: 100) */
|
|
62
|
+
pageSize?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Importer interface
|
|
66
|
+
*/
|
|
67
|
+
export interface Importer {
|
|
68
|
+
/** Platform name */
|
|
69
|
+
readonly platform: 'github' | 'jira' | 'ado';
|
|
70
|
+
/**
|
|
71
|
+
* Import items from external platform
|
|
72
|
+
* @param config - Import configuration
|
|
73
|
+
* @returns Array of external items
|
|
74
|
+
*/
|
|
75
|
+
import(config?: ImportConfig): Promise<ExternalItem[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Paginate through items (for large datasets)
|
|
78
|
+
* @param config - Import configuration
|
|
79
|
+
* @returns Async generator yielding items page by page
|
|
80
|
+
*/
|
|
81
|
+
paginate(config?: ImportConfig): AsyncGenerator<ExternalItem[], void, unknown>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Import result
|
|
85
|
+
*/
|
|
86
|
+
export interface ImportResult {
|
|
87
|
+
/** Number of items imported */
|
|
88
|
+
count: number;
|
|
89
|
+
/** Imported items */
|
|
90
|
+
items: ExternalItem[];
|
|
91
|
+
/** Errors encountered during import */
|
|
92
|
+
errors: string[];
|
|
93
|
+
/** Platform */
|
|
94
|
+
platform: 'github' | 'jira' | 'ado';
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=external-importer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-importer.d.ts","sourceRoot":"","sources":["../../../src/importers/external-importer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IAEX,8CAA8C;IAC9C,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAEzD,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IAEd,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IAEpB,oDAAoD;IACpD,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,CAAC;IAExD,uBAAuB;IACvB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAE5C,oBAAoB;IACpB,SAAS,EAAE,IAAI,CAAC;IAEhB,wBAAwB;IACxB,SAAS,EAAE,IAAI,CAAC;IAEhB,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;IAEZ,kBAAkB;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,uDAAuD;IACvD,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE9B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAE1B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,mCAAmC;IACnC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,qCAAqC;IACrC,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,oBAAoB;IACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAE7C;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEvD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;CAChF;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IAEd,qBAAqB;IACrB,KAAK,EAAE,YAAY,EAAE,CAAC;IAEtB,uCAAuC;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,eAAe;IACf,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;CACrC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Importer Interface
|
|
3
|
+
*
|
|
4
|
+
* Abstraction layer for importing User Stories and tasks from external tools
|
|
5
|
+
* (GitHub, JIRA, Azure DevOps) into SpecWeave living docs.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - Pagination for large datasets
|
|
9
|
+
* - Time range filtering
|
|
10
|
+
* - Platform-specific conversion
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=external-importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-importer.js","sourceRoot":"","sources":["../../../src/importers/external-importer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Importer
|
|
3
|
+
*
|
|
4
|
+
* Imports GitHub issues as External Items with pagination support.
|
|
5
|
+
* Handles rate limiting and converts GitHub-specific data to platform-agnostic format.
|
|
6
|
+
*/
|
|
7
|
+
import type { Importer, ExternalItem, ImportConfig } from './external-importer.js';
|
|
8
|
+
/**
|
|
9
|
+
* GitHub Importer Implementation
|
|
10
|
+
*/
|
|
11
|
+
export declare class GitHubImporter implements Importer {
|
|
12
|
+
readonly platform: "github";
|
|
13
|
+
private octokit;
|
|
14
|
+
private owner;
|
|
15
|
+
private repo;
|
|
16
|
+
constructor(owner: string, repo: string, token?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Import all issues matching config
|
|
19
|
+
*/
|
|
20
|
+
import(config?: ImportConfig): Promise<ExternalItem[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Paginate through issues (100 per page)
|
|
23
|
+
*/
|
|
24
|
+
paginate(config?: ImportConfig): AsyncGenerator<ExternalItem[], void, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Convert GitHub issue to ExternalItem
|
|
27
|
+
*/
|
|
28
|
+
private convertToExternalItem;
|
|
29
|
+
/**
|
|
30
|
+
* Extract acceptance criteria from issue body
|
|
31
|
+
* Looks for patterns like:
|
|
32
|
+
* - [ ] AC-001: ...
|
|
33
|
+
* - Acceptance Criteria: ...
|
|
34
|
+
*/
|
|
35
|
+
private extractAcceptanceCriteria;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=github-importer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-importer.d.ts","sourceRoot":"","sources":["../../../src/importers/github-importer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAenF;;GAEG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,QAAQ,CAAC,QAAQ,EAAG,QAAQ,CAAU;IACtC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;gBAET,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAQvD;;OAEG;IACG,MAAM,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAUhE;;OAEG;IACI,QAAQ,CAAC,MAAM,GAAE,YAAiB,GAAG,cAAc,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC;IAkEzF;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8C7B;;;;;OAKG;IACH,OAAO,CAAC,yBAAyB;CA2BlC"}
|