@ginkoai/cli 2.0.6 → 2.1.1

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 (149) hide show
  1. package/dist/commands/epic/index.d.ts +29 -0
  2. package/dist/commands/epic/index.d.ts.map +1 -0
  3. package/dist/commands/epic/index.js +94 -0
  4. package/dist/commands/epic/index.js.map +1 -0
  5. package/dist/commands/epic/status.d.ts +40 -0
  6. package/dist/commands/epic/status.d.ts.map +1 -0
  7. package/dist/commands/epic/status.js +244 -0
  8. package/dist/commands/epic/status.js.map +1 -0
  9. package/dist/commands/graph/api-client.d.ts +221 -1
  10. package/dist/commands/graph/api-client.d.ts.map +1 -1
  11. package/dist/commands/graph/api-client.js +141 -2
  12. package/dist/commands/graph/api-client.js.map +1 -1
  13. package/dist/commands/graph/load.d.ts.map +1 -1
  14. package/dist/commands/graph/load.js +40 -2
  15. package/dist/commands/graph/load.js.map +1 -1
  16. package/dist/commands/handoff.d.ts +3 -3
  17. package/dist/commands/handoff.d.ts.map +1 -1
  18. package/dist/commands/handoff.js +32 -3
  19. package/dist/commands/handoff.js.map +1 -1
  20. package/dist/commands/migrate/index.d.ts +27 -0
  21. package/dist/commands/migrate/index.d.ts.map +1 -0
  22. package/dist/commands/migrate/index.js +76 -0
  23. package/dist/commands/migrate/index.js.map +1 -0
  24. package/dist/commands/migrate/status-migration.d.ts +58 -0
  25. package/dist/commands/migrate/status-migration.d.ts.map +1 -0
  26. package/dist/commands/migrate/status-migration.js +323 -0
  27. package/dist/commands/migrate/status-migration.js.map +1 -0
  28. package/dist/commands/nudging/index.d.ts +24 -0
  29. package/dist/commands/nudging/index.d.ts.map +1 -0
  30. package/dist/commands/nudging/index.js +175 -0
  31. package/dist/commands/nudging/index.js.map +1 -0
  32. package/dist/commands/sprint/create.d.ts +26 -0
  33. package/dist/commands/sprint/create.d.ts.map +1 -0
  34. package/dist/commands/sprint/create.js +269 -0
  35. package/dist/commands/sprint/create.js.map +1 -0
  36. package/dist/commands/sprint/index.d.ts.map +1 -1
  37. package/dist/commands/sprint/index.js +28 -0
  38. package/dist/commands/sprint/index.js.map +1 -1
  39. package/dist/commands/sprint/quick-fix.d.ts +25 -0
  40. package/dist/commands/sprint/quick-fix.d.ts.map +1 -0
  41. package/dist/commands/sprint/quick-fix.js +151 -0
  42. package/dist/commands/sprint/quick-fix.js.map +1 -0
  43. package/dist/commands/sprint/sprint-pipeline-enhanced.d.ts.map +1 -1
  44. package/dist/commands/sprint/sprint-pipeline-enhanced.js +37 -0
  45. package/dist/commands/sprint/sprint-pipeline-enhanced.js.map +1 -1
  46. package/dist/commands/sprint/status.d.ts +42 -0
  47. package/dist/commands/sprint/status.d.ts.map +1 -0
  48. package/dist/commands/sprint/status.js +298 -0
  49. package/dist/commands/sprint/status.js.map +1 -0
  50. package/dist/commands/start/start-reflection.d.ts +53 -0
  51. package/dist/commands/start/start-reflection.d.ts.map +1 -1
  52. package/dist/commands/start/start-reflection.js +464 -71
  53. package/dist/commands/start/start-reflection.js.map +1 -1
  54. package/dist/commands/sync/sprint-syncer.d.ts +19 -12
  55. package/dist/commands/sync/sprint-syncer.d.ts.map +1 -1
  56. package/dist/commands/sync/sprint-syncer.js +58 -140
  57. package/dist/commands/sync/sprint-syncer.js.map +1 -1
  58. package/dist/commands/sync/sync-command.d.ts.map +1 -1
  59. package/dist/commands/sync/sync-command.js +6 -18
  60. package/dist/commands/sync/sync-command.js.map +1 -1
  61. package/dist/commands/task/index.d.ts +25 -0
  62. package/dist/commands/task/index.d.ts.map +1 -0
  63. package/dist/commands/task/index.js +100 -0
  64. package/dist/commands/task/index.js.map +1 -0
  65. package/dist/commands/task/status.d.ts +46 -0
  66. package/dist/commands/task/status.d.ts.map +1 -0
  67. package/dist/commands/task/status.js +348 -0
  68. package/dist/commands/task/status.js.map +1 -0
  69. package/dist/commands/team/index.d.ts +5 -0
  70. package/dist/commands/team/index.d.ts.map +1 -1
  71. package/dist/commands/team/index.js +28 -0
  72. package/dist/commands/team/index.js.map +1 -1
  73. package/dist/commands/team/status.d.ts +16 -0
  74. package/dist/commands/team/status.d.ts.map +1 -0
  75. package/dist/commands/team/status.js +180 -0
  76. package/dist/commands/team/status.js.map +1 -0
  77. package/dist/index.js +21 -32
  78. package/dist/index.js.map +1 -1
  79. package/dist/lib/adoption-score.d.ts +69 -0
  80. package/dist/lib/adoption-score.d.ts.map +1 -0
  81. package/dist/lib/adoption-score.js +206 -0
  82. package/dist/lib/adoption-score.js.map +1 -0
  83. package/dist/lib/coaching-level.d.ts +127 -0
  84. package/dist/lib/coaching-level.d.ts.map +1 -0
  85. package/dist/lib/coaching-level.js +406 -0
  86. package/dist/lib/coaching-level.js.map +1 -0
  87. package/dist/lib/context-loader-events.d.ts.map +1 -1
  88. package/dist/lib/context-loader-events.js +7 -26
  89. package/dist/lib/context-loader-events.js.map +1 -1
  90. package/dist/lib/event-logger.d.ts +42 -0
  91. package/dist/lib/event-logger.d.ts.map +1 -1
  92. package/dist/lib/event-logger.js +77 -0
  93. package/dist/lib/event-logger.js.map +1 -1
  94. package/dist/lib/output-formatter.d.ts +8 -2
  95. package/dist/lib/output-formatter.d.ts.map +1 -1
  96. package/dist/lib/output-formatter.js +98 -18
  97. package/dist/lib/output-formatter.js.map +1 -1
  98. package/dist/lib/pending-updates.d.ts +148 -0
  99. package/dist/lib/pending-updates.d.ts.map +1 -0
  100. package/dist/lib/pending-updates.js +301 -0
  101. package/dist/lib/pending-updates.js.map +1 -0
  102. package/dist/lib/planning-menu.d.ts +69 -0
  103. package/dist/lib/planning-menu.d.ts.map +1 -0
  104. package/dist/lib/planning-menu.js +342 -0
  105. package/dist/lib/planning-menu.js.map +1 -0
  106. package/dist/lib/sprint-loader.d.ts +86 -14
  107. package/dist/lib/sprint-loader.d.ts.map +1 -1
  108. package/dist/lib/sprint-loader.js +293 -98
  109. package/dist/lib/sprint-loader.js.map +1 -1
  110. package/dist/lib/state-cache.d.ts +142 -0
  111. package/dist/lib/state-cache.d.ts.map +1 -0
  112. package/dist/lib/state-cache.js +259 -0
  113. package/dist/lib/state-cache.js.map +1 -0
  114. package/dist/lib/targeted-coaching.d.ts +71 -0
  115. package/dist/lib/targeted-coaching.d.ts.map +1 -0
  116. package/dist/lib/targeted-coaching.js +318 -0
  117. package/dist/lib/targeted-coaching.js.map +1 -0
  118. package/dist/lib/task-graph-sync.d.ts +105 -0
  119. package/dist/lib/task-graph-sync.d.ts.map +1 -0
  120. package/dist/lib/task-graph-sync.js +178 -0
  121. package/dist/lib/task-graph-sync.js.map +1 -0
  122. package/dist/lib/task-parser.d.ts +109 -0
  123. package/dist/lib/task-parser.d.ts.map +1 -0
  124. package/dist/lib/task-parser.js +407 -0
  125. package/dist/lib/task-parser.js.map +1 -0
  126. package/dist/lib/user-sprint.d.ts +53 -0
  127. package/dist/lib/user-sprint.d.ts.map +1 -1
  128. package/dist/lib/user-sprint.js +137 -2
  129. package/dist/lib/user-sprint.js.map +1 -1
  130. package/dist/lib/work-reconciliation.d.ts +59 -0
  131. package/dist/lib/work-reconciliation.d.ts.map +1 -0
  132. package/dist/lib/work-reconciliation.js +267 -0
  133. package/dist/lib/work-reconciliation.js.map +1 -0
  134. package/dist/templates/ai-instructions-template.d.ts.map +1 -1
  135. package/dist/templates/ai-instructions-template.js +7 -5
  136. package/dist/templates/ai-instructions-template.js.map +1 -1
  137. package/dist/templates/epic-template.md +0 -2
  138. package/dist/types/config.d.ts.map +1 -1
  139. package/dist/types/config.js +7 -5
  140. package/dist/types/config.js.map +1 -1
  141. package/dist/utils/synthesis.d.ts +4 -0
  142. package/dist/utils/synthesis.d.ts.map +1 -1
  143. package/dist/utils/synthesis.js +12 -18
  144. package/dist/utils/synthesis.js.map +1 -1
  145. package/dist/utils/version-check.d.ts +26 -0
  146. package/dist/utils/version-check.d.ts.map +1 -0
  147. package/dist/utils/version-check.js +186 -0
  148. package/dist/utils/version-check.js.map +1 -0
  149. package/package.json +2 -2
@@ -0,0 +1,318 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-01-26
5
+ * @tags: [coaching, insights, targeted, adaptive, epic-016-s05]
6
+ * @related: [coaching-level.ts, start-reflection.ts, handoff.ts]
7
+ * @priority: medium
8
+ * @complexity: medium
9
+ * @dependencies: [fs-extra, path]
10
+ */
11
+ /**
12
+ * Targeted Coaching Elaborations (EPIC-016 Sprint 5 Task 3)
13
+ *
14
+ * When a specific metric is low, provides focused coaching in that area.
15
+ *
16
+ * Metric-Specific Coaching:
17
+ * | Low Metric | Coaching Focus |
18
+ * |----------------------|---------------------------------------------------------|
19
+ * | Session Efficiency | "Consider using `ginko handoff` to preserve context" |
20
+ * | Pattern Adoption | Extra guidance on Epic→Sprint→Task structure |
21
+ * | Collaboration Quality| Prompts about logging decisions, handoff quality |
22
+ * | Anti-Patterns | Specific warnings about detected anti-patterns |
23
+ *
24
+ * Features:
25
+ * - Track which tips shown to avoid repetition
26
+ * - Inject tips at relevant moments (start, handoff)
27
+ * - No tip spam (shown once per session max)
28
+ */
29
+ import fs from 'fs-extra';
30
+ import path from 'path';
31
+ import chalk from 'chalk';
32
+ import { getUserEmail, getGinkoDir } from '../utils/helpers.js';
33
+ import { isMetricLow } from './coaching-level.js';
34
+ import { logTargetedTipShown } from './event-logger.js';
35
+ // =============================================================================
36
+ // Constants
37
+ // =============================================================================
38
+ const TIPS_RECORD_FILE = 'shown-tips.json';
39
+ const LOW_THRESHOLD = 70;
40
+ /**
41
+ * All available coaching tips organized by metric
42
+ */
43
+ export const COACHING_TIPS = [
44
+ // Session Efficiency Tips
45
+ {
46
+ id: 'efficiency-handoff',
47
+ metric: 'sessionEfficiency',
48
+ context: ['start', 'handoff'],
49
+ message: 'Consider using `ginko handoff` to preserve context between sessions',
50
+ action: 'ginko handoff',
51
+ priority: 10,
52
+ },
53
+ {
54
+ id: 'efficiency-context-loading',
55
+ metric: 'sessionEfficiency',
56
+ context: ['start'],
57
+ message: 'Sessions with good handoffs start 40% faster on average',
58
+ priority: 5,
59
+ },
60
+ {
61
+ id: 'efficiency-log-decisions',
62
+ metric: 'sessionEfficiency',
63
+ context: ['handoff'],
64
+ message: 'Log key decisions with `ginko log` before handoff for better context transfer',
65
+ action: 'ginko log',
66
+ priority: 8,
67
+ },
68
+ // Pattern Adoption Tips
69
+ {
70
+ id: 'patterns-structure',
71
+ metric: 'patternAdoption',
72
+ context: ['start', 'planning'],
73
+ message: 'Try organizing work into Epic→Sprint→Task structure for better tracking',
74
+ priority: 10,
75
+ },
76
+ {
77
+ id: 'patterns-sprint-create',
78
+ metric: 'patternAdoption',
79
+ context: ['planning'],
80
+ message: 'Use `ginko sprint create` to break down work into trackable tasks',
81
+ action: 'ginko sprint create',
82
+ priority: 8,
83
+ },
84
+ {
85
+ id: 'patterns-quick-fix',
86
+ metric: 'patternAdoption',
87
+ context: ['start'],
88
+ message: 'For small fixes, try `ginko sprint qf "description"` for minimal tracking overhead',
89
+ action: 'ginko sprint qf',
90
+ priority: 6,
91
+ },
92
+ // Collaboration Quality Tips
93
+ {
94
+ id: 'quality-log-decisions',
95
+ metric: 'collaborationQuality',
96
+ context: ['start', 'task_complete'],
97
+ message: 'Log important decisions with `ginko log` to help future collaborators',
98
+ action: 'ginko log',
99
+ priority: 10,
100
+ },
101
+ {
102
+ id: 'quality-handoff-content',
103
+ metric: 'collaborationQuality',
104
+ context: ['handoff'],
105
+ message: 'Include what you learned, not just what you did, in handoffs',
106
+ priority: 8,
107
+ },
108
+ {
109
+ id: 'quality-team-sync',
110
+ metric: 'collaborationQuality',
111
+ context: ['start'],
112
+ message: 'Run `ginko sync` periodically to stay aligned with team updates',
113
+ action: 'ginko sync',
114
+ priority: 6,
115
+ },
116
+ // Anti-Patterns Tips
117
+ {
118
+ id: 'antipatterns-review',
119
+ metric: 'antiPatterns',
120
+ context: ['start'],
121
+ message: 'Review recent gotcha warnings - you may be hitting known issues',
122
+ priority: 10,
123
+ },
124
+ {
125
+ id: 'antipatterns-patterns',
126
+ metric: 'antiPatterns',
127
+ context: ['start', 'task_complete'],
128
+ message: 'Check task patterns with `ginko graph explore <task-id>` for guidance',
129
+ action: 'ginko graph explore',
130
+ priority: 8,
131
+ },
132
+ {
133
+ id: 'antipatterns-adr',
134
+ metric: 'antiPatterns',
135
+ context: ['start'],
136
+ message: 'ADR constraints on your current task may help avoid common pitfalls',
137
+ priority: 6,
138
+ },
139
+ ];
140
+ // =============================================================================
141
+ // Shown Tips Tracking
142
+ // =============================================================================
143
+ async function getShownTipsPath() {
144
+ const ginkoDir = await getGinkoDir();
145
+ const userEmail = await getUserEmail();
146
+ const userSlug = userEmail.replace('@', '-at-').replace(/\./g, '-');
147
+ return path.join(ginkoDir, 'sessions', userSlug, TIPS_RECORD_FILE);
148
+ }
149
+ async function loadShownTips() {
150
+ const filePath = await getShownTipsPath();
151
+ try {
152
+ if (await fs.pathExists(filePath)) {
153
+ const data = await fs.readJSON(filePath);
154
+ // Check if this is the same session (within 8 hours)
155
+ const lastUpdated = new Date(data.lastUpdated).getTime();
156
+ const now = Date.now();
157
+ const eightHours = 8 * 60 * 60 * 1000;
158
+ if (now - lastUpdated < eightHours) {
159
+ return data;
160
+ }
161
+ }
162
+ }
163
+ catch {
164
+ // File corrupted or invalid
165
+ }
166
+ // Start fresh session
167
+ return {
168
+ sessionId: generateSessionId(),
169
+ shownTipIds: [],
170
+ lastUpdated: new Date().toISOString(),
171
+ };
172
+ }
173
+ async function saveShownTips(record) {
174
+ const filePath = await getShownTipsPath();
175
+ await fs.ensureDir(path.dirname(filePath));
176
+ record.lastUpdated = new Date().toISOString();
177
+ await fs.writeJSON(filePath, record, { spaces: 2 });
178
+ }
179
+ function generateSessionId() {
180
+ return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
181
+ }
182
+ async function markTipAsShown(tipId) {
183
+ const record = await loadShownTips();
184
+ if (!record.shownTipIds.includes(tipId)) {
185
+ record.shownTipIds.push(tipId);
186
+ await saveShownTips(record);
187
+ }
188
+ }
189
+ async function isTipShown(tipId) {
190
+ const record = await loadShownTips();
191
+ return record.shownTipIds.includes(tipId);
192
+ }
193
+ // =============================================================================
194
+ // Tip Selection
195
+ // =============================================================================
196
+ /**
197
+ * Get applicable tips for a given context and coaching context
198
+ *
199
+ * @param coachingCtx - Coaching context with metric scores
200
+ * @param context - Current context (start, handoff, etc.)
201
+ * @param limit - Maximum number of tips to return
202
+ * @returns Array of applicable tips, prioritized
203
+ */
204
+ export async function getApplicableTips(coachingCtx, context, limit = 1) {
205
+ // Only show tips in supportive or standard mode
206
+ if (coachingCtx.level === 'minimal') {
207
+ return [];
208
+ }
209
+ const applicableTips = [];
210
+ // Find tips for low metrics
211
+ for (const tip of COACHING_TIPS) {
212
+ // Check if tip applies to this context
213
+ if (!tip.context.includes(context)) {
214
+ continue;
215
+ }
216
+ // Check if the metric is low
217
+ const metricValue = getMetricValue(coachingCtx, tip.metric);
218
+ if (!isMetricLow(metricValue, LOW_THRESHOLD)) {
219
+ continue;
220
+ }
221
+ // Check if already shown this session
222
+ if (await isTipShown(tip.id)) {
223
+ continue;
224
+ }
225
+ applicableTips.push(tip);
226
+ }
227
+ // Sort by priority (highest first) and limit
228
+ return applicableTips
229
+ .sort((a, b) => b.priority - a.priority)
230
+ .slice(0, limit);
231
+ }
232
+ function getMetricValue(ctx, metric) {
233
+ switch (metric) {
234
+ case 'sessionEfficiency':
235
+ return ctx.metrics.sessionEfficiency;
236
+ case 'patternAdoption':
237
+ return ctx.metrics.patternAdoption;
238
+ case 'collaborationQuality':
239
+ return ctx.metrics.collaborationQuality;
240
+ case 'antiPatterns':
241
+ return ctx.metrics.antiPatterns;
242
+ }
243
+ }
244
+ // =============================================================================
245
+ // Display Functions
246
+ // =============================================================================
247
+ /**
248
+ * Display a coaching tip to the console
249
+ */
250
+ export function displayTip(tip) {
251
+ const icon = getTipIcon(tip.metric);
252
+ console.log(chalk.cyan(`${icon} Coaching tip:`));
253
+ console.log(chalk.white(` ${tip.message}`));
254
+ if (tip.action) {
255
+ console.log(chalk.dim(` Try: ${tip.action}`));
256
+ }
257
+ console.log('');
258
+ }
259
+ /**
260
+ * Show targeted coaching tips for the current context
261
+ *
262
+ * @param coachingCtx - Coaching context with metric scores
263
+ * @param context - Current context
264
+ * @returns Number of tips shown
265
+ */
266
+ export async function showTargetedCoaching(coachingCtx, context) {
267
+ const tips = await getApplicableTips(coachingCtx, context);
268
+ for (const tip of tips) {
269
+ displayTip(tip);
270
+ await markTipAsShown(tip.id);
271
+ // EPIC-016 Sprint 5 t05: Log tip shown for feedback loop
272
+ logTargetedTipShown(tip.id, tip.metric, coachingCtx.level).catch(() => {
273
+ // Non-critical - don't fail on logging errors
274
+ });
275
+ }
276
+ return tips.length;
277
+ }
278
+ /**
279
+ * Get coaching tip for a specific metric (for inline use)
280
+ */
281
+ export async function getTipForMetric(coachingCtx, metric, context) {
282
+ const tips = await getApplicableTips(coachingCtx, context);
283
+ const tip = tips.find(t => t.metric === metric);
284
+ return tip ? tip.message : null;
285
+ }
286
+ function getTipIcon(metric) {
287
+ switch (metric) {
288
+ case 'sessionEfficiency':
289
+ return '⚡';
290
+ case 'patternAdoption':
291
+ return '📋';
292
+ case 'collaborationQuality':
293
+ return '🤝';
294
+ case 'antiPatterns':
295
+ return '⚠️';
296
+ }
297
+ }
298
+ // =============================================================================
299
+ // Metric Display Names
300
+ // =============================================================================
301
+ export const METRIC_DISPLAY_NAMES = {
302
+ sessionEfficiency: 'Session Efficiency',
303
+ patternAdoption: 'Pattern Adoption',
304
+ collaborationQuality: 'Collaboration Quality',
305
+ antiPatterns: 'Anti-Patterns',
306
+ };
307
+ // =============================================================================
308
+ // Testing Exports
309
+ // =============================================================================
310
+ export const __testing = {
311
+ LOW_THRESHOLD,
312
+ loadShownTips,
313
+ saveShownTips,
314
+ markTipAsShown,
315
+ isTipShown,
316
+ getMetricValue,
317
+ };
318
+ //# sourceMappingURL=targeted-coaching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targeted-coaching.js","sourceRoot":"","sources":["../../src/lib/targeted-coaching.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAmB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAwBxD,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAC3C,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,0BAA0B;IAC1B;QACE,EAAE,EAAE,oBAAoB;QACxB,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;QAC7B,OAAO,EAAE,qEAAqE;QAC9E,MAAM,EAAE,eAAe;QACvB,QAAQ,EAAE,EAAE;KACb;IACD;QACE,EAAE,EAAE,4BAA4B;QAChC,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,OAAO,EAAE,yDAAyD;QAClE,QAAQ,EAAE,CAAC;KACZ;IACD;QACE,EAAE,EAAE,0BAA0B;QAC9B,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,CAAC,SAAS,CAAC;QACpB,OAAO,EAAE,+EAA+E;QACxF,MAAM,EAAE,WAAW;QACnB,QAAQ,EAAE,CAAC;KACZ;IAED,wBAAwB;IACxB;QACE,EAAE,EAAE,oBAAoB;QACxB,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC;QAC9B,OAAO,EAAE,yEAAyE;QAClF,QAAQ,EAAE,EAAE;KACb;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,OAAO,EAAE,mEAAmE;QAC5E,MAAM,EAAE,qBAAqB;QAC7B,QAAQ,EAAE,CAAC;KACZ;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,OAAO,EAAE,oFAAoF;QAC7F,MAAM,EAAE,iBAAiB;QACzB,QAAQ,EAAE,CAAC;KACZ;IAED,6BAA6B;IAC7B;QACE,EAAE,EAAE,uBAAuB;QAC3B,MAAM,EAAE,sBAAsB;QAC9B,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;QACnC,OAAO,EAAE,uEAAuE;QAChF,MAAM,EAAE,WAAW;QACnB,QAAQ,EAAE,EAAE;KACb;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,MAAM,EAAE,sBAAsB;QAC9B,OAAO,EAAE,CAAC,SAAS,CAAC;QACpB,OAAO,EAAE,8DAA8D;QACvE,QAAQ,EAAE,CAAC;KACZ;IACD;QACE,EAAE,EAAE,mBAAmB;QACvB,MAAM,EAAE,sBAAsB;QAC9B,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,OAAO,EAAE,iEAAiE;QAC1E,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,CAAC;KACZ;IAED,qBAAqB;IACrB;QACE,EAAE,EAAE,qBAAqB;QACzB,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,OAAO,EAAE,iEAAiE;QAC1E,QAAQ,EAAE,EAAE;KACb;IACD;QACE,EAAE,EAAE,uBAAuB;QAC3B,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;QACnC,OAAO,EAAE,uEAAuE;QAChF,MAAM,EAAE,qBAAqB;QAC7B,QAAQ,EAAE,CAAC;KACZ;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,OAAO,EAAE,qEAAqE;QAC9E,QAAQ,EAAE,CAAC;KACZ;CACF,CAAC;AAEF,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF,KAAK,UAAU,gBAAgB;IAC7B,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AACrE,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,MAAM,QAAQ,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAE1C,IAAI,CAAC;QACH,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEzC,qDAAqD;YACrD,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACzD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;YAEtC,IAAI,GAAG,GAAG,WAAW,GAAG,UAAU,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IAED,sBAAsB;IACtB,OAAO;QACL,SAAS,EAAE,iBAAiB,EAAE;QAC9B,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,MAAuB;IAClD,MAAM,QAAQ,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,WAAW,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,KAAa;IACzC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,KAAa;IACrC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IACrC,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAA4B,EAC5B,OAA6B,EAC7B,QAAgB,CAAC;IAEjB,gDAAgD;IAChD,IAAI,WAAW,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,cAAc,GAAkB,EAAE,CAAC;IAEzC,4BAA4B;IAC5B,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,uCAAuC;QACvC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,SAAS;QACX,CAAC;QAED,6BAA6B;QAC7B,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,CAAC;YAC7C,SAAS;QACX,CAAC;QAED,sCAAsC;QACtC,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,6CAA6C;IAC7C,OAAO,cAAc;SAClB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;SACvC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,cAAc,CAAC,GAAoB,EAAE,MAAkB;IAC9D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,mBAAmB;YACtB,OAAO,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACvC,KAAK,iBAAiB;YACpB,OAAO,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC;QACrC,KAAK,sBAAsB;YACzB,OAAO,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC;QAC1C,KAAK,cAAc;YACjB,OAAO,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC;IACpC,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAgB;IACzC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9C,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,WAA4B,EAC5B,OAA6B;IAE7B,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAE3D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,UAAU,CAAC,GAAG,CAAC,CAAC;QAChB,MAAM,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE7B,yDAAyD;QACzD,mBAAmB,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACpE,8CAA8C;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAA4B,EAC5B,MAAkB,EAClB,OAA6B;IAE7B,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAChD,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAED,SAAS,UAAU,CAAC,MAAkB;IACpC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,mBAAmB;YACtB,OAAO,GAAG,CAAC;QACb,KAAK,iBAAiB;YACpB,OAAO,IAAI,CAAC;QACd,KAAK,sBAAsB;YACzB,OAAO,IAAI,CAAC;QACd,KAAK,cAAc;YACjB,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF,MAAM,CAAC,MAAM,oBAAoB,GAA+B;IAC9D,iBAAiB,EAAE,oBAAoB;IACvC,eAAe,EAAE,kBAAkB;IACnC,oBAAoB,EAAE,uBAAuB;IAC7C,YAAY,EAAE,eAAe;CAC9B,CAAC;AAEF,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,aAAa;IACb,aAAa;IACb,aAAa;IACb,cAAc;IACd,UAAU;IACV,cAAc;CACf,CAAC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-01-19
5
+ * @tags: [task-sync, graph, neo4j, epic-015, sprint-0a]
6
+ * @related: [task-parser.ts, ../commands/graph/api-client.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [api-client]
10
+ */
11
+ /**
12
+ * Task Graph Sync (EPIC-015 Sprint 0a Tasks 2-3)
13
+ *
14
+ * Syncs parsed tasks to Neo4j graph via the dashboard API.
15
+ * Creates Task nodes and BELONGS_TO relationships.
16
+ *
17
+ * Key principle (ADR-060): Content from Git, State from Graph.
18
+ * - On CREATE: Uses initial_status from markdown
19
+ * - On UPDATE: Preserves existing status (graph-authoritative)
20
+ */
21
+ import { GraphApiClient } from '../commands/graph/api-client.js';
22
+ import { ParsedTask, SprintParseResult } from './task-parser.js';
23
+ /**
24
+ * Response from task sync API
25
+ */
26
+ export interface TaskSyncResponse {
27
+ success: boolean;
28
+ created: number;
29
+ updated: number;
30
+ relationships: number;
31
+ tasks: string[];
32
+ }
33
+ /**
34
+ * Options for task sync
35
+ */
36
+ export interface TaskSyncOptions {
37
+ /** Create BELONGS_TO relationships (default: true) */
38
+ createRelationships?: boolean;
39
+ /** Batch size for API calls (default: 50) */
40
+ batchSize?: number;
41
+ /** Progress callback */
42
+ onProgress?: (synced: number, total: number) => void;
43
+ }
44
+ /**
45
+ * Result of syncing multiple sprints
46
+ */
47
+ export interface BatchSyncResult {
48
+ success: boolean;
49
+ totalTasks: number;
50
+ created: number;
51
+ updated: number;
52
+ relationships: number;
53
+ errors: string[];
54
+ }
55
+ /**
56
+ * Sync tasks to graph via API
57
+ *
58
+ * @param tasks - Array of parsed tasks
59
+ * @param graphId - Graph namespace ID
60
+ * @param client - GraphApiClient instance
61
+ * @param options - Sync options
62
+ * @returns TaskSyncResponse
63
+ */
64
+ export declare function syncTasksToGraph(tasks: ParsedTask[], graphId: string, client: GraphApiClient, options?: TaskSyncOptions): Promise<TaskSyncResponse>;
65
+ /**
66
+ * Sync a single sprint's tasks to graph
67
+ *
68
+ * @param sprintResult - Parsed sprint with tasks
69
+ * @param client - GraphApiClient instance (optional, will create if not provided)
70
+ * @param options - Sync options
71
+ * @returns TaskSyncResponse
72
+ */
73
+ export declare function syncSprintTasksToGraph(sprintResult: SprintParseResult, client?: GraphApiClient, options?: TaskSyncOptions): Promise<TaskSyncResponse>;
74
+ /**
75
+ * Sync multiple sprints' tasks to graph
76
+ *
77
+ * @param sprintResults - Array of parsed sprints with tasks
78
+ * @param options - Sync options
79
+ * @returns BatchSyncResult
80
+ */
81
+ export declare function syncAllSprintTasksToGraph(sprintResults: SprintParseResult[], options?: TaskSyncOptions): Promise<BatchSyncResult>;
82
+ /**
83
+ * Get task sync status from graph
84
+ *
85
+ * @param graphId - Graph namespace ID
86
+ * @param sprintId - Optional sprint ID filter
87
+ * @param epicId - Optional epic ID filter
88
+ * @param client - GraphApiClient instance
89
+ * @returns Array of task status objects
90
+ */
91
+ export declare function getTasksFromGraph(graphId: string, client: GraphApiClient, filters?: {
92
+ sprintId?: string;
93
+ epicId?: string;
94
+ }): Promise<Array<{
95
+ id: string;
96
+ title: string;
97
+ status: string;
98
+ priority: string;
99
+ sprint_id: string;
100
+ epic_id: string;
101
+ estimate: string | null;
102
+ assignee: string | null;
103
+ synced_at: string | null;
104
+ }>>;
105
+ //# sourceMappingURL=task-graph-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-graph-sync.d.ts","sourceRoot":"","sources":["../../src/lib/task-graph-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,UAAU,EAAE,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CA+C3B;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,iBAAiB,EAC/B,MAAM,CAAC,EAAE,cAAc,EACvB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,iBAAiB,EAAE,EAClC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,eAAe,CAAC,CAqE1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAAC,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC,CAAC,CAEF"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-01-19
5
+ * @tags: [task-sync, graph, neo4j, epic-015, sprint-0a]
6
+ * @related: [task-parser.ts, ../commands/graph/api-client.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [api-client]
10
+ */
11
+ /**
12
+ * Task Graph Sync (EPIC-015 Sprint 0a Tasks 2-3)
13
+ *
14
+ * Syncs parsed tasks to Neo4j graph via the dashboard API.
15
+ * Creates Task nodes and BELONGS_TO relationships.
16
+ *
17
+ * Key principle (ADR-060): Content from Git, State from Graph.
18
+ * - On CREATE: Uses initial_status from markdown
19
+ * - On UPDATE: Preserves existing status (graph-authoritative)
20
+ */
21
+ import { GraphApiClient } from '../commands/graph/api-client.js';
22
+ import { loadGraphConfig, isGraphInitialized } from '../commands/graph/config.js';
23
+ /**
24
+ * Sync tasks to graph via API
25
+ *
26
+ * @param tasks - Array of parsed tasks
27
+ * @param graphId - Graph namespace ID
28
+ * @param client - GraphApiClient instance
29
+ * @param options - Sync options
30
+ * @returns TaskSyncResponse
31
+ */
32
+ export async function syncTasksToGraph(tasks, graphId, client, options = {}) {
33
+ const { createRelationships = true, batchSize = 50, onProgress } = options;
34
+ if (tasks.length === 0) {
35
+ return {
36
+ success: true,
37
+ created: 0,
38
+ updated: 0,
39
+ relationships: 0,
40
+ tasks: [],
41
+ };
42
+ }
43
+ // Process in batches
44
+ const batches = [];
45
+ for (let i = 0; i < tasks.length; i += batchSize) {
46
+ batches.push(tasks.slice(i, i + batchSize));
47
+ }
48
+ let totalCreated = 0;
49
+ let totalUpdated = 0;
50
+ let totalRelationships = 0;
51
+ const allTaskIds = [];
52
+ for (let i = 0; i < batches.length; i++) {
53
+ const batch = batches[i];
54
+ const response = await client.syncTasks(graphId, batch, createRelationships);
55
+ totalCreated += response.created;
56
+ totalUpdated += response.updated;
57
+ totalRelationships += response.relationships;
58
+ allTaskIds.push(...response.tasks);
59
+ if (onProgress) {
60
+ const synced = Math.min((i + 1) * batchSize, tasks.length);
61
+ onProgress(synced, tasks.length);
62
+ }
63
+ }
64
+ return {
65
+ success: true,
66
+ created: totalCreated,
67
+ updated: totalUpdated,
68
+ relationships: totalRelationships,
69
+ tasks: allTaskIds,
70
+ };
71
+ }
72
+ /**
73
+ * Sync a single sprint's tasks to graph
74
+ *
75
+ * @param sprintResult - Parsed sprint with tasks
76
+ * @param client - GraphApiClient instance (optional, will create if not provided)
77
+ * @param options - Sync options
78
+ * @returns TaskSyncResponse
79
+ */
80
+ export async function syncSprintTasksToGraph(sprintResult, client, options = {}) {
81
+ // Check if graph is initialized
82
+ if (!await isGraphInitialized()) {
83
+ throw new Error('Graph not initialized. Run "ginko graph init" first.');
84
+ }
85
+ // Load config to get graphId
86
+ const config = await loadGraphConfig();
87
+ if (!config) {
88
+ throw new Error('Failed to load graph configuration');
89
+ }
90
+ // Create client if not provided
91
+ const apiClient = client || new GraphApiClient(config.apiEndpoint);
92
+ return syncTasksToGraph(sprintResult.tasks, config.graphId, apiClient, options);
93
+ }
94
+ /**
95
+ * Sync multiple sprints' tasks to graph
96
+ *
97
+ * @param sprintResults - Array of parsed sprints with tasks
98
+ * @param options - Sync options
99
+ * @returns BatchSyncResult
100
+ */
101
+ export async function syncAllSprintTasksToGraph(sprintResults, options = {}) {
102
+ // Check if graph is initialized
103
+ if (!await isGraphInitialized()) {
104
+ return {
105
+ success: false,
106
+ totalTasks: 0,
107
+ created: 0,
108
+ updated: 0,
109
+ relationships: 0,
110
+ errors: ['Graph not initialized. Run "ginko graph init" first.'],
111
+ };
112
+ }
113
+ // Load config
114
+ const config = await loadGraphConfig();
115
+ if (!config) {
116
+ return {
117
+ success: false,
118
+ totalTasks: 0,
119
+ created: 0,
120
+ updated: 0,
121
+ relationships: 0,
122
+ errors: ['Failed to load graph configuration'],
123
+ };
124
+ }
125
+ // Collect all tasks
126
+ const allTasks = [];
127
+ for (const result of sprintResults) {
128
+ allTasks.push(...result.tasks);
129
+ }
130
+ if (allTasks.length === 0) {
131
+ return {
132
+ success: true,
133
+ totalTasks: 0,
134
+ created: 0,
135
+ updated: 0,
136
+ relationships: 0,
137
+ errors: [],
138
+ };
139
+ }
140
+ // Create client
141
+ const client = new GraphApiClient(config.apiEndpoint);
142
+ const errors = [];
143
+ try {
144
+ const response = await syncTasksToGraph(allTasks, config.graphId, client, options);
145
+ return {
146
+ success: true,
147
+ totalTasks: allTasks.length,
148
+ created: response.created,
149
+ updated: response.updated,
150
+ relationships: response.relationships,
151
+ errors,
152
+ };
153
+ }
154
+ catch (error) {
155
+ errors.push(error instanceof Error ? error.message : 'Unknown error during sync');
156
+ return {
157
+ success: false,
158
+ totalTasks: allTasks.length,
159
+ created: 0,
160
+ updated: 0,
161
+ relationships: 0,
162
+ errors,
163
+ };
164
+ }
165
+ }
166
+ /**
167
+ * Get task sync status from graph
168
+ *
169
+ * @param graphId - Graph namespace ID
170
+ * @param sprintId - Optional sprint ID filter
171
+ * @param epicId - Optional epic ID filter
172
+ * @param client - GraphApiClient instance
173
+ * @returns Array of task status objects
174
+ */
175
+ export async function getTasksFromGraph(graphId, client, filters) {
176
+ return client.getTasks(graphId, filters);
177
+ }
178
+ //# sourceMappingURL=task-graph-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-graph-sync.js","sourceRoot":"","sources":["../../src/lib/task-graph-sync.ts"],"names":[],"mappings":"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"}