@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.
- package/dist/commands/epic/index.d.ts +29 -0
- package/dist/commands/epic/index.d.ts.map +1 -0
- package/dist/commands/epic/index.js +94 -0
- package/dist/commands/epic/index.js.map +1 -0
- package/dist/commands/epic/status.d.ts +40 -0
- package/dist/commands/epic/status.d.ts.map +1 -0
- package/dist/commands/epic/status.js +244 -0
- package/dist/commands/epic/status.js.map +1 -0
- package/dist/commands/graph/api-client.d.ts +221 -1
- package/dist/commands/graph/api-client.d.ts.map +1 -1
- package/dist/commands/graph/api-client.js +141 -2
- package/dist/commands/graph/api-client.js.map +1 -1
- package/dist/commands/graph/load.d.ts.map +1 -1
- package/dist/commands/graph/load.js +40 -2
- package/dist/commands/graph/load.js.map +1 -1
- package/dist/commands/handoff.d.ts +3 -3
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +32 -3
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/migrate/index.d.ts +27 -0
- package/dist/commands/migrate/index.d.ts.map +1 -0
- package/dist/commands/migrate/index.js +76 -0
- package/dist/commands/migrate/index.js.map +1 -0
- package/dist/commands/migrate/status-migration.d.ts +58 -0
- package/dist/commands/migrate/status-migration.d.ts.map +1 -0
- package/dist/commands/migrate/status-migration.js +323 -0
- package/dist/commands/migrate/status-migration.js.map +1 -0
- package/dist/commands/nudging/index.d.ts +24 -0
- package/dist/commands/nudging/index.d.ts.map +1 -0
- package/dist/commands/nudging/index.js +175 -0
- package/dist/commands/nudging/index.js.map +1 -0
- package/dist/commands/sprint/create.d.ts +26 -0
- package/dist/commands/sprint/create.d.ts.map +1 -0
- package/dist/commands/sprint/create.js +269 -0
- package/dist/commands/sprint/create.js.map +1 -0
- package/dist/commands/sprint/index.d.ts.map +1 -1
- package/dist/commands/sprint/index.js +28 -0
- package/dist/commands/sprint/index.js.map +1 -1
- package/dist/commands/sprint/quick-fix.d.ts +25 -0
- package/dist/commands/sprint/quick-fix.d.ts.map +1 -0
- package/dist/commands/sprint/quick-fix.js +151 -0
- package/dist/commands/sprint/quick-fix.js.map +1 -0
- package/dist/commands/sprint/sprint-pipeline-enhanced.d.ts.map +1 -1
- package/dist/commands/sprint/sprint-pipeline-enhanced.js +37 -0
- package/dist/commands/sprint/sprint-pipeline-enhanced.js.map +1 -1
- package/dist/commands/sprint/status.d.ts +42 -0
- package/dist/commands/sprint/status.d.ts.map +1 -0
- package/dist/commands/sprint/status.js +298 -0
- package/dist/commands/sprint/status.js.map +1 -0
- package/dist/commands/start/start-reflection.d.ts +53 -0
- package/dist/commands/start/start-reflection.d.ts.map +1 -1
- package/dist/commands/start/start-reflection.js +464 -71
- package/dist/commands/start/start-reflection.js.map +1 -1
- package/dist/commands/sync/sprint-syncer.d.ts +19 -12
- package/dist/commands/sync/sprint-syncer.d.ts.map +1 -1
- package/dist/commands/sync/sprint-syncer.js +58 -140
- package/dist/commands/sync/sprint-syncer.js.map +1 -1
- package/dist/commands/sync/sync-command.d.ts.map +1 -1
- package/dist/commands/sync/sync-command.js +6 -18
- package/dist/commands/sync/sync-command.js.map +1 -1
- package/dist/commands/task/index.d.ts +25 -0
- package/dist/commands/task/index.d.ts.map +1 -0
- package/dist/commands/task/index.js +100 -0
- package/dist/commands/task/index.js.map +1 -0
- package/dist/commands/task/status.d.ts +46 -0
- package/dist/commands/task/status.d.ts.map +1 -0
- package/dist/commands/task/status.js +348 -0
- package/dist/commands/task/status.js.map +1 -0
- package/dist/commands/team/index.d.ts +5 -0
- package/dist/commands/team/index.d.ts.map +1 -1
- package/dist/commands/team/index.js +28 -0
- package/dist/commands/team/index.js.map +1 -1
- package/dist/commands/team/status.d.ts +16 -0
- package/dist/commands/team/status.d.ts.map +1 -0
- package/dist/commands/team/status.js +180 -0
- package/dist/commands/team/status.js.map +1 -0
- package/dist/index.js +21 -32
- package/dist/index.js.map +1 -1
- package/dist/lib/adoption-score.d.ts +69 -0
- package/dist/lib/adoption-score.d.ts.map +1 -0
- package/dist/lib/adoption-score.js +206 -0
- package/dist/lib/adoption-score.js.map +1 -0
- package/dist/lib/coaching-level.d.ts +127 -0
- package/dist/lib/coaching-level.d.ts.map +1 -0
- package/dist/lib/coaching-level.js +406 -0
- package/dist/lib/coaching-level.js.map +1 -0
- package/dist/lib/context-loader-events.d.ts.map +1 -1
- package/dist/lib/context-loader-events.js +7 -26
- package/dist/lib/context-loader-events.js.map +1 -1
- package/dist/lib/event-logger.d.ts +42 -0
- package/dist/lib/event-logger.d.ts.map +1 -1
- package/dist/lib/event-logger.js +77 -0
- package/dist/lib/event-logger.js.map +1 -1
- package/dist/lib/output-formatter.d.ts +8 -2
- package/dist/lib/output-formatter.d.ts.map +1 -1
- package/dist/lib/output-formatter.js +98 -18
- package/dist/lib/output-formatter.js.map +1 -1
- package/dist/lib/pending-updates.d.ts +148 -0
- package/dist/lib/pending-updates.d.ts.map +1 -0
- package/dist/lib/pending-updates.js +301 -0
- package/dist/lib/pending-updates.js.map +1 -0
- package/dist/lib/planning-menu.d.ts +69 -0
- package/dist/lib/planning-menu.d.ts.map +1 -0
- package/dist/lib/planning-menu.js +342 -0
- package/dist/lib/planning-menu.js.map +1 -0
- package/dist/lib/sprint-loader.d.ts +86 -14
- package/dist/lib/sprint-loader.d.ts.map +1 -1
- package/dist/lib/sprint-loader.js +293 -98
- package/dist/lib/sprint-loader.js.map +1 -1
- package/dist/lib/state-cache.d.ts +142 -0
- package/dist/lib/state-cache.d.ts.map +1 -0
- package/dist/lib/state-cache.js +259 -0
- package/dist/lib/state-cache.js.map +1 -0
- package/dist/lib/targeted-coaching.d.ts +71 -0
- package/dist/lib/targeted-coaching.d.ts.map +1 -0
- package/dist/lib/targeted-coaching.js +318 -0
- package/dist/lib/targeted-coaching.js.map +1 -0
- package/dist/lib/task-graph-sync.d.ts +105 -0
- package/dist/lib/task-graph-sync.d.ts.map +1 -0
- package/dist/lib/task-graph-sync.js +178 -0
- package/dist/lib/task-graph-sync.js.map +1 -0
- package/dist/lib/task-parser.d.ts +109 -0
- package/dist/lib/task-parser.d.ts.map +1 -0
- package/dist/lib/task-parser.js +407 -0
- package/dist/lib/task-parser.js.map +1 -0
- package/dist/lib/user-sprint.d.ts +53 -0
- package/dist/lib/user-sprint.d.ts.map +1 -1
- package/dist/lib/user-sprint.js +137 -2
- package/dist/lib/user-sprint.js.map +1 -1
- package/dist/lib/work-reconciliation.d.ts +59 -0
- package/dist/lib/work-reconciliation.d.ts.map +1 -0
- package/dist/lib/work-reconciliation.js +267 -0
- package/dist/lib/work-reconciliation.js.map +1 -0
- package/dist/templates/ai-instructions-template.d.ts.map +1 -1
- package/dist/templates/ai-instructions-template.js +7 -5
- package/dist/templates/ai-instructions-template.js.map +1 -1
- package/dist/templates/epic-template.md +0 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +7 -5
- package/dist/types/config.js.map +1 -1
- package/dist/utils/synthesis.d.ts +4 -0
- package/dist/utils/synthesis.d.ts.map +1 -1
- package/dist/utils/synthesis.js +12 -18
- package/dist/utils/synthesis.js.map +1 -1
- package/dist/utils/version-check.d.ts +26 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +186 -0
- package/dist/utils/version-check.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2026-01-19
|
|
5
|
+
* @tags: [offline, queue, sync, EPIC-015]
|
|
6
|
+
* @related: [state-cache.ts, api-client.ts]
|
|
7
|
+
* @priority: medium
|
|
8
|
+
* @complexity: medium
|
|
9
|
+
* @dependencies: [fs-extra, path]
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Pending Updates Queue (EPIC-015 Sprint 2 Task 6)
|
|
13
|
+
*
|
|
14
|
+
* Provides offline queueing for status updates when API is unavailable:
|
|
15
|
+
* - Queue status updates when offline
|
|
16
|
+
* - Process queued updates when back online
|
|
17
|
+
* - "Local wins" conflict resolution (queued update takes precedence)
|
|
18
|
+
* - Max 3 retry attempts before permanent failure
|
|
19
|
+
*
|
|
20
|
+
* Queue location: .ginko/pending-updates.json
|
|
21
|
+
* Uses atomic writes (temp file + rename) to prevent partial writes.
|
|
22
|
+
*/
|
|
23
|
+
import fs from 'fs-extra';
|
|
24
|
+
import path from 'path';
|
|
25
|
+
import { randomUUID } from 'crypto';
|
|
26
|
+
import { getGinkoDir } from '../utils/helpers.js';
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Constants
|
|
29
|
+
// =============================================================================
|
|
30
|
+
const QUEUE_FILE = 'pending-updates.json';
|
|
31
|
+
const QUEUE_VERSION = 1;
|
|
32
|
+
const MAX_ATTEMPTS = 3;
|
|
33
|
+
// =============================================================================
|
|
34
|
+
// Queue Management
|
|
35
|
+
// =============================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Load pending updates from disk
|
|
38
|
+
*
|
|
39
|
+
* @returns Array of pending updates, empty array if no queue file exists
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const updates = await loadPendingUpdates();
|
|
44
|
+
* console.log(`${updates.length} updates pending`);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export async function loadPendingUpdates() {
|
|
48
|
+
try {
|
|
49
|
+
const queuePath = await getQueuePath();
|
|
50
|
+
if (!await fs.pathExists(queuePath)) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const data = await fs.readJSON(queuePath);
|
|
54
|
+
// Validate queue structure
|
|
55
|
+
if (!isValidQueue(data)) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
return data.updates || [];
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// File doesn't exist, is invalid JSON, or other read error
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Queue a status update for later sync
|
|
67
|
+
* Used when API call fails due to network error
|
|
68
|
+
*
|
|
69
|
+
* @param update - Update to queue (id, queued_at, attempts added automatically)
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* await queueUpdate({
|
|
74
|
+
* type: 'task_status',
|
|
75
|
+
* entity_id: 'e015_s02_t01',
|
|
76
|
+
* new_status: 'complete'
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export async function queueUpdate(update) {
|
|
81
|
+
const updates = await loadPendingUpdates();
|
|
82
|
+
// Check if there's already a pending update for this entity
|
|
83
|
+
// If so, replace it (latest update wins)
|
|
84
|
+
const existingIndex = updates.findIndex(u => u.entity_id === update.entity_id && u.type === update.type);
|
|
85
|
+
const newUpdate = {
|
|
86
|
+
id: randomUUID(),
|
|
87
|
+
...update,
|
|
88
|
+
queued_at: new Date().toISOString(),
|
|
89
|
+
attempts: 0,
|
|
90
|
+
};
|
|
91
|
+
if (existingIndex >= 0) {
|
|
92
|
+
// Replace existing update for same entity
|
|
93
|
+
updates[existingIndex] = newUpdate;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Add new update
|
|
97
|
+
updates.push(newUpdate);
|
|
98
|
+
}
|
|
99
|
+
await saveQueue(updates);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Remove a specific update from the queue
|
|
103
|
+
*
|
|
104
|
+
* @param updateId - UUID of the update to remove
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* await removeUpdate('abc-123-def');
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export async function removeUpdate(updateId) {
|
|
112
|
+
const updates = await loadPendingUpdates();
|
|
113
|
+
const filtered = updates.filter(u => u.id !== updateId);
|
|
114
|
+
if (filtered.length !== updates.length) {
|
|
115
|
+
await saveQueue(filtered);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Clear all pending updates from the queue
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* await clearPendingUpdates();
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export async function clearPendingUpdates() {
|
|
127
|
+
try {
|
|
128
|
+
const queuePath = await getQueuePath();
|
|
129
|
+
if (await fs.pathExists(queuePath)) {
|
|
130
|
+
await fs.remove(queuePath);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
// Ignore errors when clearing queue
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Check if there are pending updates
|
|
139
|
+
*
|
|
140
|
+
* @returns true if queue has at least one update
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* if (await hasPendingUpdates()) {
|
|
145
|
+
* console.log('Pending updates need to sync');
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
export async function hasPendingUpdates() {
|
|
150
|
+
const updates = await loadPendingUpdates();
|
|
151
|
+
return updates.length > 0;
|
|
152
|
+
}
|
|
153
|
+
// =============================================================================
|
|
154
|
+
// Sync Processing
|
|
155
|
+
// =============================================================================
|
|
156
|
+
/**
|
|
157
|
+
* Process all pending updates, syncing them to the API
|
|
158
|
+
*
|
|
159
|
+
* Processing logic:
|
|
160
|
+
* - Iterates oldest-first (FIFO order)
|
|
161
|
+
* - On success: removes update from queue
|
|
162
|
+
* - On failure: increments attempts, keeps in queue (max 3 attempts)
|
|
163
|
+
* - Conflict resolution: "local wins" (queued update takes precedence)
|
|
164
|
+
*
|
|
165
|
+
* @param client - Authenticated GraphApiClient instance
|
|
166
|
+
* @returns Counts of succeeded and failed updates
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const client = new GraphApiClient();
|
|
171
|
+
* const result = await processPendingUpdates(client);
|
|
172
|
+
* console.log(`Synced ${result.succeeded}, failed ${result.failed}`);
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export async function processPendingUpdates(client) {
|
|
176
|
+
const updates = await loadPendingUpdates();
|
|
177
|
+
if (updates.length === 0) {
|
|
178
|
+
return { succeeded: 0, failed: 0 };
|
|
179
|
+
}
|
|
180
|
+
let succeeded = 0;
|
|
181
|
+
let failed = 0;
|
|
182
|
+
const remaining = [];
|
|
183
|
+
// Get graph ID from environment
|
|
184
|
+
const graphId = process.env.GINKO_GRAPH_ID || '';
|
|
185
|
+
if (!graphId) {
|
|
186
|
+
// Can't process without graph ID, keep all updates
|
|
187
|
+
return { succeeded: 0, failed: updates.length };
|
|
188
|
+
}
|
|
189
|
+
// Sort by queued_at to process oldest first
|
|
190
|
+
const sortedUpdates = [...updates].sort((a, b) => new Date(a.queued_at).getTime() - new Date(b.queued_at).getTime());
|
|
191
|
+
for (const update of sortedUpdates) {
|
|
192
|
+
try {
|
|
193
|
+
await processUpdate(client, graphId, update);
|
|
194
|
+
succeeded++;
|
|
195
|
+
// Don't add to remaining - it was successful
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
// Increment attempts
|
|
199
|
+
update.attempts++;
|
|
200
|
+
if (update.attempts >= MAX_ATTEMPTS) {
|
|
201
|
+
// Max attempts reached, count as failed and don't keep
|
|
202
|
+
failed++;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// Keep in queue for retry
|
|
206
|
+
remaining.push(update);
|
|
207
|
+
failed++;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Save remaining updates (excluding succeeded and permanently failed)
|
|
212
|
+
await saveQueue(remaining);
|
|
213
|
+
return { succeeded, failed };
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Process a single update by calling the appropriate API method
|
|
217
|
+
*/
|
|
218
|
+
async function processUpdate(client, graphId, update) {
|
|
219
|
+
switch (update.type) {
|
|
220
|
+
case 'task_status':
|
|
221
|
+
await client.updateTaskStatus(graphId, update.entity_id, update.new_status, update.reason);
|
|
222
|
+
break;
|
|
223
|
+
case 'sprint_status':
|
|
224
|
+
await client.updateSprintStatus(graphId, update.entity_id, update.new_status);
|
|
225
|
+
break;
|
|
226
|
+
case 'epic_status':
|
|
227
|
+
await client.updateEpicStatus(graphId, update.entity_id, update.new_status);
|
|
228
|
+
break;
|
|
229
|
+
default:
|
|
230
|
+
throw new Error(`Unknown update type: ${update.type}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// =============================================================================
|
|
234
|
+
// Helper Functions
|
|
235
|
+
// =============================================================================
|
|
236
|
+
/**
|
|
237
|
+
* Get the full path to the queue file
|
|
238
|
+
*/
|
|
239
|
+
async function getQueuePath() {
|
|
240
|
+
const ginkoDir = await getGinkoDir();
|
|
241
|
+
return path.join(ginkoDir, QUEUE_FILE);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Save updates to queue file using atomic write
|
|
245
|
+
*/
|
|
246
|
+
async function saveQueue(updates) {
|
|
247
|
+
const queuePath = await getQueuePath();
|
|
248
|
+
const queueDir = path.dirname(queuePath);
|
|
249
|
+
const tempPath = `${queuePath}.tmp.${Date.now()}`;
|
|
250
|
+
// Ensure .ginko directory exists
|
|
251
|
+
await fs.ensureDir(queueDir);
|
|
252
|
+
const queue = {
|
|
253
|
+
version: QUEUE_VERSION,
|
|
254
|
+
updates,
|
|
255
|
+
};
|
|
256
|
+
// Atomic write: write to temp file, then rename
|
|
257
|
+
try {
|
|
258
|
+
await fs.writeJSON(tempPath, queue, { spaces: 2 });
|
|
259
|
+
await fs.rename(tempPath, queuePath);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
// Clean up temp file if rename failed
|
|
263
|
+
try {
|
|
264
|
+
await fs.remove(tempPath);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// Ignore cleanup errors
|
|
268
|
+
}
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Validate that queue data has correct structure and version
|
|
274
|
+
*/
|
|
275
|
+
function isValidQueue(data) {
|
|
276
|
+
if (!data || typeof data !== 'object') {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const queue = data;
|
|
280
|
+
// Check version
|
|
281
|
+
if (queue.version !== QUEUE_VERSION) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
// Check updates array exists
|
|
285
|
+
if (!Array.isArray(queue.updates)) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
// =============================================================================
|
|
291
|
+
// Exports for Testing
|
|
292
|
+
// =============================================================================
|
|
293
|
+
export const _internal = {
|
|
294
|
+
getQueuePath,
|
|
295
|
+
saveQueue,
|
|
296
|
+
isValidQueue,
|
|
297
|
+
processUpdate,
|
|
298
|
+
QUEUE_VERSION,
|
|
299
|
+
MAX_ATTEMPTS,
|
|
300
|
+
};
|
|
301
|
+
//# sourceMappingURL=pending-updates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-updates.js","sourceRoot":"","sources":["../../src/lib/pending-updates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2026-01-26
|
|
5
|
+
* @tags: [planning, menu, coaching, structure-detection, epic-016-s04]
|
|
6
|
+
* @related: [start-reflection.ts, user-sprint.ts, event-logger.ts]
|
|
7
|
+
* @priority: high
|
|
8
|
+
* @complexity: medium
|
|
9
|
+
* @dependencies: [prompts, chalk, event-logger]
|
|
10
|
+
*/
|
|
11
|
+
import { WorkStructureStatus } from './user-sprint.js';
|
|
12
|
+
import { CoachingLevel } from './coaching-level.js';
|
|
13
|
+
export type PlanningChoice = 'epic' | 'sprint' | 'quick-fix' | 'adhoc';
|
|
14
|
+
export interface PlanningMenuResult {
|
|
15
|
+
choice: PlanningChoice | null;
|
|
16
|
+
cancelled: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface PlanningRouteResult {
|
|
19
|
+
success: boolean;
|
|
20
|
+
sprintId?: string;
|
|
21
|
+
taskId?: string;
|
|
22
|
+
message?: string;
|
|
23
|
+
shouldContinueStart?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Display the guided planning menu and get user selection
|
|
27
|
+
*
|
|
28
|
+
* Called when ginko start detects no structured work.
|
|
29
|
+
* Logs selection for coaching insights analysis (t05).
|
|
30
|
+
* Uses adoption-based quieting to adjust verbosity.
|
|
31
|
+
*
|
|
32
|
+
* @param status - Work structure status from checkWorkStructure()
|
|
33
|
+
* @returns Menu selection result
|
|
34
|
+
*/
|
|
35
|
+
export declare function showPlanningMenu(status?: WorkStructureStatus): Promise<PlanningMenuResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Log the planning menu selection for coaching analysis (t05)
|
|
38
|
+
*
|
|
39
|
+
* Enables the insights system to:
|
|
40
|
+
* - Track pattern adoption over time
|
|
41
|
+
* - Identify users who frequently choose ad-hoc
|
|
42
|
+
* - Measure effectiveness of planning prompts
|
|
43
|
+
*
|
|
44
|
+
* Also records adoption signals for quieting behavior.
|
|
45
|
+
*/
|
|
46
|
+
declare function logPlanningChoice(choice: PlanningChoice, coachingLevel?: CoachingLevel, overallScore?: number): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Route the planning menu choice to appropriate handler
|
|
49
|
+
*
|
|
50
|
+
* Routes:
|
|
51
|
+
* - epic → launches ginko epic command
|
|
52
|
+
* - sprint → launches sprint creation flow (t03)
|
|
53
|
+
* - quick-fix → launches quick-fix flow (t04)
|
|
54
|
+
* - adhoc → marks session as ad-hoc, continues to normal start
|
|
55
|
+
*
|
|
56
|
+
* @param choice - User's menu selection
|
|
57
|
+
* @returns Route result with success status and metadata
|
|
58
|
+
*/
|
|
59
|
+
export declare function routePlanningChoice(choice: PlanningChoice): Promise<PlanningRouteResult>;
|
|
60
|
+
export declare const __testing: {
|
|
61
|
+
PLANNING_MENU_CHOICES: {
|
|
62
|
+
title: string;
|
|
63
|
+
description: string;
|
|
64
|
+
value: PlanningChoice;
|
|
65
|
+
}[];
|
|
66
|
+
logPlanningChoice: typeof logPlanningChoice;
|
|
67
|
+
};
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=planning-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planning-menu.d.ts","sourceRoot":"","sources":["../../src/lib/planning-menu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkBH,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAWvD,OAAO,EAEL,aAAa,EAId,MAAM,qBAAqB,CAAC;AAO7B,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAiCD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CA0E7B;AAED;;;;;;;;;GASG;AACH,iBAAe,iBAAiB,CAC9B,MAAM,EAAE,cAAc,EACtB,aAAa,CAAC,EAAE,aAAa,EAC7B,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAsCf;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,mBAAmB,CAAC,CAiB9B;AAkJD,eAAO,MAAM,SAAS;;;;eA1VD,cAAc;;;CA6VlC,CAAC"}
|