@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.
Files changed (101) hide show
  1. package/dist/commands/assign.d.ts +19 -0
  2. package/dist/commands/assign.d.ts.map +1 -0
  3. package/dist/commands/assign.js +200 -0
  4. package/dist/commands/assign.js.map +1 -0
  5. package/dist/commands/epic.d.ts.map +1 -1
  6. package/dist/commands/epic.js +48 -23
  7. package/dist/commands/epic.js.map +1 -1
  8. package/dist/commands/graph/api-client.d.ts +1 -0
  9. package/dist/commands/graph/api-client.d.ts.map +1 -1
  10. package/dist/commands/graph/api-client.js.map +1 -1
  11. package/dist/commands/insights/index.d.ts +12 -0
  12. package/dist/commands/insights/index.d.ts.map +1 -0
  13. package/dist/commands/insights/index.js +12 -0
  14. package/dist/commands/insights/index.js.map +1 -0
  15. package/dist/commands/insights/insights-command.d.ts +20 -0
  16. package/dist/commands/insights/insights-command.d.ts.map +1 -0
  17. package/dist/commands/insights/insights-command.js +369 -0
  18. package/dist/commands/insights/insights-command.js.map +1 -0
  19. package/dist/commands/principles/seed.d.ts +26 -0
  20. package/dist/commands/principles/seed.d.ts.map +1 -0
  21. package/dist/commands/principles/seed.js +150 -0
  22. package/dist/commands/principles/seed.js.map +1 -0
  23. package/dist/commands/start/start-reflection.d.ts +11 -0
  24. package/dist/commands/start/start-reflection.d.ts.map +1 -1
  25. package/dist/commands/start/start-reflection.js +149 -16
  26. package/dist/commands/start/start-reflection.js.map +1 -1
  27. package/dist/commands/sync/index.d.ts +21 -0
  28. package/dist/commands/sync/index.d.ts.map +1 -0
  29. package/dist/commands/sync/index.js +38 -0
  30. package/dist/commands/sync/index.js.map +1 -0
  31. package/dist/commands/sync/node-syncer.d.ts +58 -0
  32. package/dist/commands/sync/node-syncer.d.ts.map +1 -0
  33. package/dist/commands/sync/node-syncer.js +192 -0
  34. package/dist/commands/sync/node-syncer.js.map +1 -0
  35. package/dist/commands/sync/sprint-syncer.d.ts +42 -0
  36. package/dist/commands/sync/sprint-syncer.d.ts.map +1 -0
  37. package/dist/commands/sync/sprint-syncer.js +274 -0
  38. package/dist/commands/sync/sprint-syncer.js.map +1 -0
  39. package/dist/commands/sync/sync-command.d.ts +16 -0
  40. package/dist/commands/sync/sync-command.d.ts.map +1 -0
  41. package/dist/commands/sync/sync-command.js +429 -0
  42. package/dist/commands/sync/sync-command.js.map +1 -0
  43. package/dist/commands/sync/types.d.ts +86 -0
  44. package/dist/commands/sync/types.d.ts.map +1 -0
  45. package/dist/commands/sync/types.js +12 -0
  46. package/dist/commands/sync/types.js.map +1 -0
  47. package/dist/core/session-log-manager.d.ts +3 -1
  48. package/dist/core/session-log-manager.d.ts.map +1 -1
  49. package/dist/core/session-log-manager.js +5 -3
  50. package/dist/core/session-log-manager.js.map +1 -1
  51. package/dist/data/standard-principles.d.ts +43 -0
  52. package/dist/data/standard-principles.d.ts.map +1 -0
  53. package/dist/data/standard-principles.js +323 -0
  54. package/dist/data/standard-principles.js.map +1 -0
  55. package/dist/index.js +54 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/lib/insights/analyzers/anti-patterns.d.ts +32 -0
  58. package/dist/lib/insights/analyzers/anti-patterns.d.ts.map +1 -0
  59. package/dist/lib/insights/analyzers/anti-patterns.js +302 -0
  60. package/dist/lib/insights/analyzers/anti-patterns.js.map +1 -0
  61. package/dist/lib/insights/analyzers/efficiency.d.ts +22 -0
  62. package/dist/lib/insights/analyzers/efficiency.d.ts.map +1 -0
  63. package/dist/lib/insights/analyzers/efficiency.js +311 -0
  64. package/dist/lib/insights/analyzers/efficiency.js.map +1 -0
  65. package/dist/lib/insights/analyzers/index.d.ts +24 -0
  66. package/dist/lib/insights/analyzers/index.d.ts.map +1 -0
  67. package/dist/lib/insights/analyzers/index.js +37 -0
  68. package/dist/lib/insights/analyzers/index.js.map +1 -0
  69. package/dist/lib/insights/analyzers/patterns.d.ts +21 -0
  70. package/dist/lib/insights/analyzers/patterns.d.ts.map +1 -0
  71. package/dist/lib/insights/analyzers/patterns.js +337 -0
  72. package/dist/lib/insights/analyzers/patterns.js.map +1 -0
  73. package/dist/lib/insights/analyzers/quality.d.ts +29 -0
  74. package/dist/lib/insights/analyzers/quality.d.ts.map +1 -0
  75. package/dist/lib/insights/analyzers/quality.js +371 -0
  76. package/dist/lib/insights/analyzers/quality.js.map +1 -0
  77. package/dist/lib/insights/data-collector.d.ts +68 -0
  78. package/dist/lib/insights/data-collector.d.ts.map +1 -0
  79. package/dist/lib/insights/data-collector.js +514 -0
  80. package/dist/lib/insights/data-collector.js.map +1 -0
  81. package/dist/lib/insights/index.d.ts +14 -0
  82. package/dist/lib/insights/index.d.ts.map +1 -0
  83. package/dist/lib/insights/index.js +17 -0
  84. package/dist/lib/insights/index.js.map +1 -0
  85. package/dist/lib/insights/scheduler.d.ts +71 -0
  86. package/dist/lib/insights/scheduler.d.ts.map +1 -0
  87. package/dist/lib/insights/scheduler.js +126 -0
  88. package/dist/lib/insights/scheduler.js.map +1 -0
  89. package/dist/lib/insights/types.d.ts +216 -0
  90. package/dist/lib/insights/types.d.ts.map +1 -0
  91. package/dist/lib/insights/types.js +12 -0
  92. package/dist/lib/insights/types.js.map +1 -0
  93. package/dist/templates/ai-instructions-template.d.ts +1 -0
  94. package/dist/templates/ai-instructions-template.d.ts.map +1 -1
  95. package/dist/templates/ai-instructions-template.js +51 -0
  96. package/dist/templates/ai-instructions-template.js.map +1 -1
  97. package/package.json +1 -1
  98. package/dist/lib/__tests__/task-timeout.test.d.ts +0 -12
  99. package/dist/lib/__tests__/task-timeout.test.d.ts.map +0 -1
  100. package/dist/lib/__tests__/task-timeout.test.js +0 -278
  101. 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"}