@ginkoai/cli 1.7.2 → 2.0.0-beta.2
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/dist/commands/assign.d.ts +19 -0
- package/dist/commands/assign.d.ts.map +1 -0
- package/dist/commands/assign.js +200 -0
- package/dist/commands/assign.js.map +1 -0
- package/dist/commands/epic.d.ts.map +1 -1
- package/dist/commands/epic.js +48 -23
- package/dist/commands/epic.js.map +1 -1
- package/dist/commands/graph/api-client.d.ts +1 -0
- package/dist/commands/graph/api-client.d.ts.map +1 -1
- package/dist/commands/graph/api-client.js.map +1 -1
- package/dist/commands/insights/index.d.ts +12 -0
- package/dist/commands/insights/index.d.ts.map +1 -0
- package/dist/commands/insights/index.js +12 -0
- package/dist/commands/insights/index.js.map +1 -0
- package/dist/commands/insights/insights-command.d.ts +20 -0
- package/dist/commands/insights/insights-command.d.ts.map +1 -0
- package/dist/commands/insights/insights-command.js +369 -0
- package/dist/commands/insights/insights-command.js.map +1 -0
- package/dist/commands/principles/seed.d.ts +26 -0
- package/dist/commands/principles/seed.d.ts.map +1 -0
- package/dist/commands/principles/seed.js +150 -0
- package/dist/commands/principles/seed.js.map +1 -0
- package/dist/commands/start/start-reflection.d.ts +11 -0
- package/dist/commands/start/start-reflection.d.ts.map +1 -1
- package/dist/commands/start/start-reflection.js +149 -16
- package/dist/commands/start/start-reflection.js.map +1 -1
- package/dist/commands/sync/index.d.ts +21 -0
- package/dist/commands/sync/index.d.ts.map +1 -0
- package/dist/commands/sync/index.js +38 -0
- package/dist/commands/sync/index.js.map +1 -0
- package/dist/commands/sync/node-syncer.d.ts +58 -0
- package/dist/commands/sync/node-syncer.d.ts.map +1 -0
- package/dist/commands/sync/node-syncer.js +192 -0
- package/dist/commands/sync/node-syncer.js.map +1 -0
- package/dist/commands/sync/sprint-syncer.d.ts +42 -0
- package/dist/commands/sync/sprint-syncer.d.ts.map +1 -0
- package/dist/commands/sync/sprint-syncer.js +274 -0
- package/dist/commands/sync/sprint-syncer.js.map +1 -0
- package/dist/commands/sync/sync-command.d.ts +16 -0
- package/dist/commands/sync/sync-command.d.ts.map +1 -0
- package/dist/commands/sync/sync-command.js +429 -0
- package/dist/commands/sync/sync-command.js.map +1 -0
- package/dist/commands/sync/types.d.ts +86 -0
- package/dist/commands/sync/types.d.ts.map +1 -0
- package/dist/commands/sync/types.js +12 -0
- package/dist/commands/sync/types.js.map +1 -0
- package/dist/core/session-log-manager.d.ts +3 -1
- package/dist/core/session-log-manager.d.ts.map +1 -1
- package/dist/core/session-log-manager.js +5 -3
- package/dist/core/session-log-manager.js.map +1 -1
- package/dist/data/standard-principles.d.ts +43 -0
- package/dist/data/standard-principles.d.ts.map +1 -0
- package/dist/data/standard-principles.js +323 -0
- package/dist/data/standard-principles.js.map +1 -0
- package/dist/index.js +54 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/insights/analyzers/anti-patterns.d.ts +32 -0
- package/dist/lib/insights/analyzers/anti-patterns.d.ts.map +1 -0
- package/dist/lib/insights/analyzers/anti-patterns.js +302 -0
- package/dist/lib/insights/analyzers/anti-patterns.js.map +1 -0
- package/dist/lib/insights/analyzers/efficiency.d.ts +22 -0
- package/dist/lib/insights/analyzers/efficiency.d.ts.map +1 -0
- package/dist/lib/insights/analyzers/efficiency.js +311 -0
- package/dist/lib/insights/analyzers/efficiency.js.map +1 -0
- package/dist/lib/insights/analyzers/index.d.ts +24 -0
- package/dist/lib/insights/analyzers/index.d.ts.map +1 -0
- package/dist/lib/insights/analyzers/index.js +37 -0
- package/dist/lib/insights/analyzers/index.js.map +1 -0
- package/dist/lib/insights/analyzers/patterns.d.ts +21 -0
- package/dist/lib/insights/analyzers/patterns.d.ts.map +1 -0
- package/dist/lib/insights/analyzers/patterns.js +337 -0
- package/dist/lib/insights/analyzers/patterns.js.map +1 -0
- package/dist/lib/insights/analyzers/quality.d.ts +29 -0
- package/dist/lib/insights/analyzers/quality.d.ts.map +1 -0
- package/dist/lib/insights/analyzers/quality.js +371 -0
- package/dist/lib/insights/analyzers/quality.js.map +1 -0
- package/dist/lib/insights/data-collector.d.ts +68 -0
- package/dist/lib/insights/data-collector.d.ts.map +1 -0
- package/dist/lib/insights/data-collector.js +514 -0
- package/dist/lib/insights/data-collector.js.map +1 -0
- package/dist/lib/insights/index.d.ts +14 -0
- package/dist/lib/insights/index.d.ts.map +1 -0
- package/dist/lib/insights/index.js +17 -0
- package/dist/lib/insights/index.js.map +1 -0
- package/dist/lib/insights/scheduler.d.ts +71 -0
- package/dist/lib/insights/scheduler.d.ts.map +1 -0
- package/dist/lib/insights/scheduler.js +126 -0
- package/dist/lib/insights/scheduler.js.map +1 -0
- package/dist/lib/insights/types.d.ts +216 -0
- package/dist/lib/insights/types.d.ts.map +1 -0
- package/dist/lib/insights/types.js +12 -0
- package/dist/lib/insights/types.js.map +1 -0
- package/dist/templates/ai-instructions-template.d.ts +1 -0
- package/dist/templates/ai-instructions-template.d.ts.map +1 -1
- package/dist/templates/ai-instructions-template.js +51 -0
- package/dist/templates/ai-instructions-template.js.map +1 -1
- package/package.json +1 -1
- package/dist/lib/__tests__/task-timeout.test.d.ts +0 -12
- package/dist/lib/__tests__/task-timeout.test.d.ts.map +0 -1
- package/dist/lib/__tests__/task-timeout.test.js +0 -278
- package/dist/lib/__tests__/task-timeout.test.js.map +0 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-12-15
|
|
5
|
+
* @tags: [sync, node-syncer, cloud-to-local, ADR-054]
|
|
6
|
+
* @related: [sync-command.ts, types.ts]
|
|
7
|
+
* @priority: high
|
|
8
|
+
* @complexity: medium
|
|
9
|
+
* @dependencies: [crypto, fs, path]
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Node Syncer (ADR-054)
|
|
13
|
+
*
|
|
14
|
+
* Handles syncing individual nodes from cloud graph to local git files.
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from 'fs/promises';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import * as crypto from 'crypto';
|
|
19
|
+
/**
|
|
20
|
+
* Compute SHA-256 hash of content
|
|
21
|
+
*/
|
|
22
|
+
export function computeHash(content) {
|
|
23
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get file path for a node based on its type and ID
|
|
27
|
+
*/
|
|
28
|
+
export function getFilePath(projectRoot, node) {
|
|
29
|
+
const type = node.type;
|
|
30
|
+
const slug = node.slug || slugify(node.title);
|
|
31
|
+
switch (type) {
|
|
32
|
+
case 'ADR':
|
|
33
|
+
return path.join(projectRoot, 'docs', 'adr', `${node.id}-${slug}.md`);
|
|
34
|
+
case 'PRD':
|
|
35
|
+
return path.join(projectRoot, 'docs', 'prd', `${node.id}-${slug}.md`);
|
|
36
|
+
case 'Pattern':
|
|
37
|
+
return path.join(projectRoot, 'docs', 'patterns', `PATTERN-${slug}.md`);
|
|
38
|
+
case 'Gotcha':
|
|
39
|
+
return path.join(projectRoot, 'docs', 'gotchas', `GOTCHA-${slug}.md`);
|
|
40
|
+
case 'Charter':
|
|
41
|
+
return path.join(projectRoot, 'docs', 'PROJECT-CHARTER.md');
|
|
42
|
+
default:
|
|
43
|
+
throw new Error(`Unknown node type: ${type}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convert title to URL-friendly slug
|
|
48
|
+
*/
|
|
49
|
+
function slugify(text) {
|
|
50
|
+
if (!text) {
|
|
51
|
+
return 'untitled';
|
|
52
|
+
}
|
|
53
|
+
return text
|
|
54
|
+
.toLowerCase()
|
|
55
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
56
|
+
.replace(/^-+|-+$/g, '')
|
|
57
|
+
.substring(0, 50) || 'untitled';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if a file exists
|
|
61
|
+
*/
|
|
62
|
+
export async function fileExists(filePath) {
|
|
63
|
+
try {
|
|
64
|
+
await fs.access(filePath);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Read file content, return null if doesn't exist
|
|
73
|
+
*/
|
|
74
|
+
export async function readFileContent(filePath) {
|
|
75
|
+
try {
|
|
76
|
+
return await fs.readFile(filePath, 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Write content to file, creating directories as needed
|
|
84
|
+
*/
|
|
85
|
+
export async function writeFileContent(filePath, content) {
|
|
86
|
+
const dir = path.dirname(filePath);
|
|
87
|
+
await fs.mkdir(dir, { recursive: true });
|
|
88
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Format node content as markdown file
|
|
92
|
+
*/
|
|
93
|
+
export function formatNodeAsMarkdown(node) {
|
|
94
|
+
const frontmatter = generateFrontmatter(node);
|
|
95
|
+
const body = node.content || '';
|
|
96
|
+
return `---\n${frontmatter}---\n\n# ${node.title}\n\n${body}`;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Generate YAML frontmatter for node
|
|
100
|
+
*/
|
|
101
|
+
function generateFrontmatter(node) {
|
|
102
|
+
const lines = [];
|
|
103
|
+
lines.push(`type: ${node.type.toLowerCase()}`);
|
|
104
|
+
lines.push(`status: ${node.status || 'draft'}`);
|
|
105
|
+
lines.push(`updated: ${new Date().toISOString().split('T')[0]}`);
|
|
106
|
+
if (node.tags && node.tags.length > 0) {
|
|
107
|
+
lines.push(`tags: [${node.tags.join(', ')}]`);
|
|
108
|
+
}
|
|
109
|
+
lines.push(`synced-from: dashboard`);
|
|
110
|
+
lines.push(`synced-at: ${new Date().toISOString()}`);
|
|
111
|
+
return lines.join('\n') + '\n';
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Detect if there's a conflict between graph and local versions
|
|
115
|
+
*/
|
|
116
|
+
export async function detectConflict(node, projectRoot) {
|
|
117
|
+
const filePath = getFilePath(projectRoot, node);
|
|
118
|
+
const localContent = await readFileContent(filePath);
|
|
119
|
+
if (!localContent) {
|
|
120
|
+
// File doesn't exist locally - no conflict
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const localHash = computeHash(localContent);
|
|
124
|
+
// If local hash matches what we last synced, no conflict
|
|
125
|
+
if (node.gitHash && localHash === node.gitHash) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
// If local hash matches current graph content, no conflict
|
|
129
|
+
if (localHash === node.contentHash) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
// Conflict: local file changed since last sync
|
|
133
|
+
return {
|
|
134
|
+
node,
|
|
135
|
+
localContent,
|
|
136
|
+
localHash,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Apply a sync resolution
|
|
141
|
+
*/
|
|
142
|
+
export async function applyResolution(conflict, resolution, projectRoot) {
|
|
143
|
+
const filePath = getFilePath(projectRoot, conflict.node);
|
|
144
|
+
switch (resolution) {
|
|
145
|
+
case 'use-graph':
|
|
146
|
+
// Overwrite local with graph version
|
|
147
|
+
const graphContent = formatNodeAsMarkdown(conflict.node);
|
|
148
|
+
await writeFileContent(filePath, graphContent);
|
|
149
|
+
return { applied: true, content: graphContent };
|
|
150
|
+
case 'use-local':
|
|
151
|
+
// Keep local, just mark as synced (content returned for API update)
|
|
152
|
+
return { applied: true, content: conflict.localContent };
|
|
153
|
+
case 'skip':
|
|
154
|
+
// Don't do anything
|
|
155
|
+
return { applied: false, content: '' };
|
|
156
|
+
case 'merge':
|
|
157
|
+
// Future: implement 3-way merge
|
|
158
|
+
// For now, treat as skip
|
|
159
|
+
console.warn('Merge not yet implemented, skipping');
|
|
160
|
+
return { applied: false, content: '' };
|
|
161
|
+
default:
|
|
162
|
+
return { applied: false, content: '' };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Sync a single node from graph to local
|
|
167
|
+
*/
|
|
168
|
+
export async function syncNode(node, projectRoot, options = {}) {
|
|
169
|
+
const filePath = getFilePath(projectRoot, node);
|
|
170
|
+
// Check for conflicts (unless force mode)
|
|
171
|
+
if (!options.force) {
|
|
172
|
+
const conflict = await detectConflict(node, projectRoot);
|
|
173
|
+
if (conflict) {
|
|
174
|
+
return {
|
|
175
|
+
success: false,
|
|
176
|
+
filePath,
|
|
177
|
+
hash: '',
|
|
178
|
+
conflict,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Write graph content to local file
|
|
183
|
+
const content = formatNodeAsMarkdown(node);
|
|
184
|
+
await writeFileContent(filePath, content);
|
|
185
|
+
const hash = computeHash(content);
|
|
186
|
+
return {
|
|
187
|
+
success: true,
|
|
188
|
+
filePath,
|
|
189
|
+
hash,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=node-syncer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-syncer.js","sourceRoot":"","sources":["../../../src/commands/sync/node-syncer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-12-22
|
|
5
|
+
* @tags: [sync, sprint-syncer, cloud-to-local, ADR-054, EPIC-006]
|
|
6
|
+
* @related: [sync-command.ts, types.ts, node-syncer.ts]
|
|
7
|
+
* @priority: high
|
|
8
|
+
* @complexity: medium
|
|
9
|
+
* @dependencies: [fs, path, glob]
|
|
10
|
+
*/
|
|
11
|
+
import type { SprintSyncResult, TaskStatusUpdate, SprintFile } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Find all sprint markdown files in the project
|
|
14
|
+
*/
|
|
15
|
+
export declare function findSprintFiles(projectRoot: string): Promise<SprintFile[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Extract task IDs and their current status from sprint markdown
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractTasksFromMarkdown(content: string): Map<string, {
|
|
20
|
+
status: string;
|
|
21
|
+
lineNum: number;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Update sprint markdown with new task statuses
|
|
25
|
+
*/
|
|
26
|
+
export declare function updateSprintMarkdown(content: string, updates: TaskStatusUpdate[]): {
|
|
27
|
+
updated: string;
|
|
28
|
+
changes: string[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Fetch task statuses from graph API
|
|
32
|
+
*/
|
|
33
|
+
export declare function fetchTaskStatuses(graphId: string, token: string, sprintId: string, apiBase: string): Promise<TaskStatusUpdate[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Sync a single sprint file with graph data
|
|
36
|
+
*/
|
|
37
|
+
export declare function syncSprintFile(sprintFile: SprintFile, graphId: string, token: string, apiBase: string): Promise<SprintSyncResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Update CURRENT-SPRINT.md to match the active sprint
|
|
40
|
+
*/
|
|
41
|
+
export declare function updateCurrentSprintFile(projectRoot: string, activeSprintPath: string): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=sprint-syncer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sprint-syncer.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/sprint-syncer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA2CjF;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBhF;AA2BD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA2B1G;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,EAAE,GAC1B;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA8ExC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA6C7B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,CAqC3B;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CAIf"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-12-22
|
|
5
|
+
* @tags: [sync, sprint-syncer, cloud-to-local, ADR-054, EPIC-006]
|
|
6
|
+
* @related: [sync-command.ts, types.ts, node-syncer.ts]
|
|
7
|
+
* @priority: high
|
|
8
|
+
* @complexity: medium
|
|
9
|
+
* @dependencies: [fs, path, glob]
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Sprint Syncer (ADR-054 Extension)
|
|
13
|
+
*
|
|
14
|
+
* Handles syncing Sprint and Task status from cloud graph to local markdown.
|
|
15
|
+
* Unlike knowledge nodes which replace entire files, sprint sync updates
|
|
16
|
+
* specific task status checkboxes within existing markdown files.
|
|
17
|
+
*/
|
|
18
|
+
import * as fs from 'fs/promises';
|
|
19
|
+
import * as path from 'path';
|
|
20
|
+
import glob from 'glob';
|
|
21
|
+
import { promisify } from 'util';
|
|
22
|
+
const globAsync = promisify(glob);
|
|
23
|
+
/**
|
|
24
|
+
* Map graph status to markdown checkbox format
|
|
25
|
+
*/
|
|
26
|
+
function statusToCheckbox(status) {
|
|
27
|
+
switch (status) {
|
|
28
|
+
case 'complete':
|
|
29
|
+
return '[x]';
|
|
30
|
+
case 'in_progress':
|
|
31
|
+
return '[@]';
|
|
32
|
+
case 'blocked':
|
|
33
|
+
return '[Z]';
|
|
34
|
+
case 'todo':
|
|
35
|
+
default:
|
|
36
|
+
return '[ ]';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Map graph status to display text
|
|
41
|
+
*/
|
|
42
|
+
function statusToText(status) {
|
|
43
|
+
switch (status) {
|
|
44
|
+
case 'complete':
|
|
45
|
+
return 'Complete';
|
|
46
|
+
case 'in_progress':
|
|
47
|
+
return 'In Progress';
|
|
48
|
+
case 'blocked':
|
|
49
|
+
return 'Blocked';
|
|
50
|
+
case 'todo':
|
|
51
|
+
default:
|
|
52
|
+
return 'Pending';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Find all sprint markdown files in the project
|
|
57
|
+
*/
|
|
58
|
+
export async function findSprintFiles(projectRoot) {
|
|
59
|
+
const pattern = path.join(projectRoot, 'docs/sprints/SPRINT-*.md');
|
|
60
|
+
const files = await globAsync(pattern);
|
|
61
|
+
const sprintFiles = [];
|
|
62
|
+
for (const filePath of files) {
|
|
63
|
+
// Skip CURRENT-SPRINT.md as it's a copy
|
|
64
|
+
if (filePath.includes('CURRENT-SPRINT.md'))
|
|
65
|
+
continue;
|
|
66
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
67
|
+
const sprintId = extractSprintId(content, filePath);
|
|
68
|
+
if (sprintId) {
|
|
69
|
+
sprintFiles.push({
|
|
70
|
+
path: filePath,
|
|
71
|
+
sprintId,
|
|
72
|
+
content,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return sprintFiles;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Extract sprint ID from file content or filename
|
|
80
|
+
* Looks for patterns like e006_s02 or adhoc_251209_s01
|
|
81
|
+
*/
|
|
82
|
+
function extractSprintId(content, filePath) {
|
|
83
|
+
// Try to find sprint ID in content (from task IDs)
|
|
84
|
+
const taskIdMatch = content.match(/\*\*ID:\*\*\s*(e\d{3}_s\d{2}|adhoc_\d{6}_s\d{2})_t\d{2}/);
|
|
85
|
+
if (taskIdMatch) {
|
|
86
|
+
// Extract sprint portion from task ID
|
|
87
|
+
const fullId = taskIdMatch[1];
|
|
88
|
+
return fullId;
|
|
89
|
+
}
|
|
90
|
+
// Try to extract from filename pattern
|
|
91
|
+
// e.g., SPRINT-2025-12-epic006-sprint2.md -> e006_s02
|
|
92
|
+
const filenameMatch = path.basename(filePath).match(/epic(\d{3})-sprint(\d+)/i);
|
|
93
|
+
if (filenameMatch) {
|
|
94
|
+
const epicNum = filenameMatch[1].padStart(3, '0');
|
|
95
|
+
const sprintNum = filenameMatch[2].padStart(2, '0');
|
|
96
|
+
return `e${epicNum}_s${sprintNum}`;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Extract task IDs and their current status from sprint markdown
|
|
102
|
+
*/
|
|
103
|
+
export function extractTasksFromMarkdown(content) {
|
|
104
|
+
const tasks = new Map();
|
|
105
|
+
const lines = content.split('\n');
|
|
106
|
+
let currentTaskId = null;
|
|
107
|
+
for (let i = 0; i < lines.length; i++) {
|
|
108
|
+
const line = lines[i];
|
|
109
|
+
// Look for task ID line: **ID:** e006_s02_t01
|
|
110
|
+
const idMatch = line.match(/\*\*ID:\*\*\s*(\w+)/);
|
|
111
|
+
if (idMatch) {
|
|
112
|
+
currentTaskId = idMatch[1];
|
|
113
|
+
}
|
|
114
|
+
// Look for status line: **Status:** [ ] Pending
|
|
115
|
+
const statusMatch = line.match(/\*\*Status:\*\*\s*\[([ xX@Z])\]/);
|
|
116
|
+
if (statusMatch && currentTaskId) {
|
|
117
|
+
tasks.set(currentTaskId, {
|
|
118
|
+
status: statusMatch[1],
|
|
119
|
+
lineNum: i,
|
|
120
|
+
});
|
|
121
|
+
currentTaskId = null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return tasks;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Update sprint markdown with new task statuses
|
|
128
|
+
*/
|
|
129
|
+
export function updateSprintMarkdown(content, updates) {
|
|
130
|
+
const lines = content.split('\n');
|
|
131
|
+
const changes = [];
|
|
132
|
+
let currentTaskId = null;
|
|
133
|
+
let totalTasks = 0;
|
|
134
|
+
let completedTasks = 0;
|
|
135
|
+
// First pass: update task statuses
|
|
136
|
+
for (let i = 0; i < lines.length; i++) {
|
|
137
|
+
const line = lines[i];
|
|
138
|
+
// Track task ID
|
|
139
|
+
const idMatch = line.match(/\*\*ID:\*\*\s*(\w+)/);
|
|
140
|
+
if (idMatch) {
|
|
141
|
+
currentTaskId = idMatch[1];
|
|
142
|
+
}
|
|
143
|
+
// Update status line if we have an update for this task
|
|
144
|
+
const statusMatch = line.match(/(\*\*Status:\*\*\s*)\[([ xX@Z])\](\s*\w+)?/);
|
|
145
|
+
if (statusMatch && currentTaskId) {
|
|
146
|
+
totalTasks++;
|
|
147
|
+
const update = updates.find(u => u.taskId === currentTaskId);
|
|
148
|
+
if (update) {
|
|
149
|
+
const newCheckbox = statusToCheckbox(update.newStatus);
|
|
150
|
+
const newText = statusToText(update.newStatus);
|
|
151
|
+
const newLine = `${statusMatch[1]}${newCheckbox} ${newText}`;
|
|
152
|
+
if (lines[i] !== newLine) {
|
|
153
|
+
changes.push(`${currentTaskId}: ${statusMatch[2]} -> ${newCheckbox}`);
|
|
154
|
+
lines[i] = newLine;
|
|
155
|
+
}
|
|
156
|
+
if (update.newStatus === 'complete') {
|
|
157
|
+
completedTasks++;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Count existing complete tasks
|
|
162
|
+
if (statusMatch[2].toLowerCase() === 'x') {
|
|
163
|
+
completedTasks++;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
currentTaskId = null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Second pass: update progress line
|
|
170
|
+
const progressPercent = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;
|
|
171
|
+
const progressComplete = progressPercent === 100 ? ' \u2713' : '';
|
|
172
|
+
for (let i = 0; i < lines.length; i++) {
|
|
173
|
+
const progressMatch = lines[i].match(/(\*\*Progress:\*\*\s*)\d+%\s*\(\d+\/\d+\s*tasks?\s*complete\)(\s*[✓✔])?/i);
|
|
174
|
+
if (progressMatch) {
|
|
175
|
+
const newProgress = `${progressMatch[1]}${progressPercent}% (${completedTasks}/${totalTasks} tasks complete)${progressComplete}`;
|
|
176
|
+
if (lines[i] !== newProgress) {
|
|
177
|
+
changes.push(`Progress: ${progressPercent}% (${completedTasks}/${totalTasks})`);
|
|
178
|
+
lines[i] = newProgress;
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Third pass: update success criteria checkboxes if all tasks complete
|
|
184
|
+
if (progressPercent === 100) {
|
|
185
|
+
for (let i = 0; i < lines.length; i++) {
|
|
186
|
+
// Update unchecked success criteria to checked
|
|
187
|
+
if (lines[i].match(/^- \[ \]/)) {
|
|
188
|
+
lines[i] = lines[i].replace(/^- \[ \]/, '- [x]');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
updated: lines.join('\n'),
|
|
194
|
+
changes,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Fetch task statuses from graph API
|
|
199
|
+
*/
|
|
200
|
+
export async function fetchTaskStatuses(graphId, token, sprintId, apiBase) {
|
|
201
|
+
const url = new URL(`${apiBase}/api/v1/graph/nodes`);
|
|
202
|
+
url.searchParams.set('graphId', graphId);
|
|
203
|
+
url.searchParams.set('labels', 'Task');
|
|
204
|
+
url.searchParams.set('limit', '100');
|
|
205
|
+
const response = await fetch(url.toString(), {
|
|
206
|
+
headers: {
|
|
207
|
+
Authorization: `Bearer ${token}`,
|
|
208
|
+
'Content-Type': 'application/json',
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
if (!response.ok) {
|
|
212
|
+
throw new Error(`Failed to fetch tasks: ${response.status}`);
|
|
213
|
+
}
|
|
214
|
+
const data = (await response.json());
|
|
215
|
+
const updates = [];
|
|
216
|
+
// Filter tasks belonging to this sprint
|
|
217
|
+
for (const node of data.nodes || []) {
|
|
218
|
+
const taskId = node.properties?.id;
|
|
219
|
+
const status = node.properties?.status;
|
|
220
|
+
// Check if task belongs to this sprint (starts with sprint ID)
|
|
221
|
+
if (taskId && taskId.startsWith(sprintId) && status) {
|
|
222
|
+
updates.push({
|
|
223
|
+
taskId,
|
|
224
|
+
newStatus: status,
|
|
225
|
+
sprintId,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return updates;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Sync a single sprint file with graph data
|
|
233
|
+
*/
|
|
234
|
+
export async function syncSprintFile(sprintFile, graphId, token, apiBase) {
|
|
235
|
+
const result = {
|
|
236
|
+
sprintId: sprintFile.sprintId,
|
|
237
|
+
filePath: sprintFile.path,
|
|
238
|
+
tasksUpdated: 0,
|
|
239
|
+
changes: [],
|
|
240
|
+
error: null,
|
|
241
|
+
};
|
|
242
|
+
try {
|
|
243
|
+
// Fetch task statuses from graph
|
|
244
|
+
const updates = await fetchTaskStatuses(graphId, token, sprintFile.sprintId, apiBase);
|
|
245
|
+
if (updates.length === 0) {
|
|
246
|
+
result.changes.push('No tasks found in graph for this sprint');
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
// Update markdown content
|
|
250
|
+
const { updated, changes } = updateSprintMarkdown(sprintFile.content, updates);
|
|
251
|
+
if (changes.length === 0) {
|
|
252
|
+
result.changes.push('Already in sync');
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
// Write updated content
|
|
256
|
+
await fs.writeFile(sprintFile.path, updated, 'utf-8');
|
|
257
|
+
result.tasksUpdated = changes.filter(c => c.includes('->')).length;
|
|
258
|
+
result.changes = changes;
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
result.error = error instanceof Error ? error.message : String(error);
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Update CURRENT-SPRINT.md to match the active sprint
|
|
268
|
+
*/
|
|
269
|
+
export async function updateCurrentSprintFile(projectRoot, activeSprintPath) {
|
|
270
|
+
const currentSprintPath = path.join(projectRoot, 'docs/sprints/CURRENT-SPRINT.md');
|
|
271
|
+
const content = await fs.readFile(activeSprintPath, 'utf-8');
|
|
272
|
+
await fs.writeFile(currentSprintPath, content, 'utf-8');
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=sprint-syncer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sprint-syncer.js","sourceRoot":"","sources":["../../../src/commands/sync/sprint-syncer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: command
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-12-15
|
|
5
|
+
* @tags: [sync, cloud-to-local, git, ADR-054]
|
|
6
|
+
* @related: [index.ts, node-syncer.ts, types.ts]
|
|
7
|
+
* @priority: critical
|
|
8
|
+
* @complexity: high
|
|
9
|
+
* @dependencies: [chalk, prompts, simple-git]
|
|
10
|
+
*/
|
|
11
|
+
import type { SyncOptions, SyncResult } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Main sync command implementation
|
|
14
|
+
*/
|
|
15
|
+
export declare function syncCommand(options: SyncOptions): Promise<SyncResult>;
|
|
16
|
+
//# sourceMappingURL=sync-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-command.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/sync-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA6BH,OAAO,KAAK,EACV,WAAW,EAEX,UAAU,EAKX,MAAM,YAAY,CAAC;AA8PpB;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAsN3E"}
|