@ginkoai/cli 1.6.2 → 1.7.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 (224) hide show
  1. package/dist/commands/agent/agent-client.d.ts +150 -0
  2. package/dist/commands/agent/agent-client.d.ts.map +1 -0
  3. package/dist/commands/agent/agent-client.js +170 -0
  4. package/dist/commands/agent/agent-client.js.map +1 -0
  5. package/dist/commands/agent/index.d.ts +22 -0
  6. package/dist/commands/agent/index.d.ts.map +1 -0
  7. package/dist/commands/agent/index.js +121 -0
  8. package/dist/commands/agent/index.js.map +1 -0
  9. package/dist/commands/agent/list.d.ts +22 -0
  10. package/dist/commands/agent/list.d.ts.map +1 -0
  11. package/dist/commands/agent/list.js +119 -0
  12. package/dist/commands/agent/list.js.map +1 -0
  13. package/dist/commands/agent/register.d.ts +21 -0
  14. package/dist/commands/agent/register.d.ts.map +1 -0
  15. package/dist/commands/agent/register.js +97 -0
  16. package/dist/commands/agent/register.js.map +1 -0
  17. package/dist/commands/agent/status.d.ts +19 -0
  18. package/dist/commands/agent/status.d.ts.map +1 -0
  19. package/dist/commands/agent/status.js +271 -0
  20. package/dist/commands/agent/status.js.map +1 -0
  21. package/dist/commands/agent/work.d.ts +22 -0
  22. package/dist/commands/agent/work.d.ts.map +1 -0
  23. package/dist/commands/agent/work.js +459 -0
  24. package/dist/commands/agent/work.js.map +1 -0
  25. package/dist/commands/checkpoint/create.d.ts +27 -0
  26. package/dist/commands/checkpoint/create.d.ts.map +1 -0
  27. package/dist/commands/checkpoint/create.js +82 -0
  28. package/dist/commands/checkpoint/create.js.map +1 -0
  29. package/dist/commands/checkpoint/index.d.ts +23 -0
  30. package/dist/commands/checkpoint/index.d.ts.map +1 -0
  31. package/dist/commands/checkpoint/index.js +91 -0
  32. package/dist/commands/checkpoint/index.js.map +1 -0
  33. package/dist/commands/checkpoint/list.d.ts +27 -0
  34. package/dist/commands/checkpoint/list.d.ts.map +1 -0
  35. package/dist/commands/checkpoint/list.js +115 -0
  36. package/dist/commands/checkpoint/list.js.map +1 -0
  37. package/dist/commands/checkpoint/show.d.ts +23 -0
  38. package/dist/commands/checkpoint/show.d.ts.map +1 -0
  39. package/dist/commands/checkpoint/show.js +102 -0
  40. package/dist/commands/checkpoint/show.js.map +1 -0
  41. package/dist/commands/dlq.d.ts +24 -0
  42. package/dist/commands/dlq.d.ts.map +1 -0
  43. package/dist/commands/dlq.js +172 -0
  44. package/dist/commands/dlq.js.map +1 -0
  45. package/dist/commands/escalation/create.d.ts +22 -0
  46. package/dist/commands/escalation/create.d.ts.map +1 -0
  47. package/dist/commands/escalation/create.js +122 -0
  48. package/dist/commands/escalation/create.js.map +1 -0
  49. package/dist/commands/escalation/escalation-client.d.ts +101 -0
  50. package/dist/commands/escalation/escalation-client.d.ts.map +1 -0
  51. package/dist/commands/escalation/escalation-client.js +129 -0
  52. package/dist/commands/escalation/escalation-client.js.map +1 -0
  53. package/dist/commands/escalation/index.d.ts +22 -0
  54. package/dist/commands/escalation/index.d.ts.map +1 -0
  55. package/dist/commands/escalation/index.js +94 -0
  56. package/dist/commands/escalation/index.js.map +1 -0
  57. package/dist/commands/escalation/list.d.ts +24 -0
  58. package/dist/commands/escalation/list.d.ts.map +1 -0
  59. package/dist/commands/escalation/list.js +170 -0
  60. package/dist/commands/escalation/list.js.map +1 -0
  61. package/dist/commands/escalation/resolve.d.ts +20 -0
  62. package/dist/commands/escalation/resolve.d.ts.map +1 -0
  63. package/dist/commands/escalation/resolve.js +102 -0
  64. package/dist/commands/escalation/resolve.js.map +1 -0
  65. package/dist/commands/graph/api-client.d.ts +21 -1
  66. package/dist/commands/graph/api-client.d.ts.map +1 -1
  67. package/dist/commands/graph/api-client.js +23 -0
  68. package/dist/commands/graph/api-client.js.map +1 -1
  69. package/dist/commands/handoff.d.ts.map +1 -1
  70. package/dist/commands/handoff.js +9 -1
  71. package/dist/commands/handoff.js.map +1 -1
  72. package/dist/commands/log.d.ts +3 -0
  73. package/dist/commands/log.d.ts.map +1 -1
  74. package/dist/commands/log.js +73 -14
  75. package/dist/commands/log.js.map +1 -1
  76. package/dist/commands/notifications/history.d.ts +21 -0
  77. package/dist/commands/notifications/history.d.ts.map +1 -0
  78. package/dist/commands/notifications/history.js +160 -0
  79. package/dist/commands/notifications/history.js.map +1 -0
  80. package/dist/commands/notifications/index.d.ts +22 -0
  81. package/dist/commands/notifications/index.d.ts.map +1 -0
  82. package/dist/commands/notifications/index.js +87 -0
  83. package/dist/commands/notifications/index.js.map +1 -0
  84. package/dist/commands/notifications/list.d.ts +19 -0
  85. package/dist/commands/notifications/list.d.ts.map +1 -0
  86. package/dist/commands/notifications/list.js +132 -0
  87. package/dist/commands/notifications/list.js.map +1 -0
  88. package/dist/commands/notifications/test.d.ts +19 -0
  89. package/dist/commands/notifications/test.d.ts.map +1 -0
  90. package/dist/commands/notifications/test.js +217 -0
  91. package/dist/commands/notifications/test.js.map +1 -0
  92. package/dist/commands/orchestrate.d.ts +25 -0
  93. package/dist/commands/orchestrate.d.ts.map +1 -0
  94. package/dist/commands/orchestrate.js +858 -0
  95. package/dist/commands/orchestrate.js.map +1 -0
  96. package/dist/commands/sprint/deps.d.ts +29 -0
  97. package/dist/commands/sprint/deps.d.ts.map +1 -0
  98. package/dist/commands/sprint/deps.js +269 -0
  99. package/dist/commands/sprint/deps.js.map +1 -0
  100. package/dist/commands/sprint/index.d.ts +10 -5
  101. package/dist/commands/sprint/index.d.ts.map +1 -1
  102. package/dist/commands/sprint/index.js +26 -5
  103. package/dist/commands/sprint/index.js.map +1 -1
  104. package/dist/commands/start/index.d.ts.map +1 -1
  105. package/dist/commands/start/index.js +6 -0
  106. package/dist/commands/start/index.js.map +1 -1
  107. package/dist/commands/start/start-reflection.d.ts.map +1 -1
  108. package/dist/commands/start/start-reflection.js +8 -0
  109. package/dist/commands/start/start-reflection.js.map +1 -1
  110. package/dist/commands/verify.d.ts +17 -0
  111. package/dist/commands/verify.d.ts.map +1 -0
  112. package/dist/commands/verify.js +232 -0
  113. package/dist/commands/verify.js.map +1 -0
  114. package/dist/core/session-log-manager.d.ts +1 -1
  115. package/dist/core/session-log-manager.d.ts.map +1 -1
  116. package/dist/index.js +78 -1
  117. package/dist/index.js.map +1 -1
  118. package/dist/lib/__tests__/task-timeout.test.d.ts +12 -0
  119. package/dist/lib/__tests__/task-timeout.test.d.ts.map +1 -0
  120. package/dist/lib/__tests__/task-timeout.test.js +278 -0
  121. package/dist/lib/__tests__/task-timeout.test.js.map +1 -0
  122. package/dist/lib/agent-heartbeat.d.ts +68 -0
  123. package/dist/lib/agent-heartbeat.d.ts.map +1 -0
  124. package/dist/lib/agent-heartbeat.js +117 -0
  125. package/dist/lib/agent-heartbeat.js.map +1 -0
  126. package/dist/lib/checkpoint.d.ts +85 -0
  127. package/dist/lib/checkpoint.d.ts.map +1 -0
  128. package/dist/lib/checkpoint.js +323 -0
  129. package/dist/lib/checkpoint.js.map +1 -0
  130. package/dist/lib/context-metrics.d.ts +230 -0
  131. package/dist/lib/context-metrics.d.ts.map +1 -0
  132. package/dist/lib/context-metrics.js +372 -0
  133. package/dist/lib/context-metrics.js.map +1 -0
  134. package/dist/lib/dead-letter-queue.d.ts +108 -0
  135. package/dist/lib/dead-letter-queue.d.ts.map +1 -0
  136. package/dist/lib/dead-letter-queue.js +378 -0
  137. package/dist/lib/dead-letter-queue.js.map +1 -0
  138. package/dist/lib/event-logger.d.ts +9 -1
  139. package/dist/lib/event-logger.d.ts.map +1 -1
  140. package/dist/lib/event-logger.js +45 -3
  141. package/dist/lib/event-logger.js.map +1 -1
  142. package/dist/lib/event-queue.d.ts.map +1 -1
  143. package/dist/lib/event-queue.js +13 -2
  144. package/dist/lib/event-queue.js.map +1 -1
  145. package/dist/lib/examples/timeout-demo.d.ts +13 -0
  146. package/dist/lib/examples/timeout-demo.d.ts.map +1 -0
  147. package/dist/lib/examples/timeout-demo.js +102 -0
  148. package/dist/lib/examples/timeout-demo.js.map +1 -0
  149. package/dist/lib/examples/timeout-integration-example.d.ts +17 -0
  150. package/dist/lib/examples/timeout-integration-example.d.ts.map +1 -0
  151. package/dist/lib/examples/timeout-integration-example.js +223 -0
  152. package/dist/lib/examples/timeout-integration-example.js.map +1 -0
  153. package/dist/lib/notification-hooks.d.ts +103 -0
  154. package/dist/lib/notification-hooks.d.ts.map +1 -0
  155. package/dist/lib/notification-hooks.js +223 -0
  156. package/dist/lib/notification-hooks.js.map +1 -0
  157. package/dist/lib/notifications/discord.d.ts +20 -0
  158. package/dist/lib/notifications/discord.d.ts.map +1 -0
  159. package/dist/lib/notifications/discord.js +140 -0
  160. package/dist/lib/notifications/discord.js.map +1 -0
  161. package/dist/lib/notifications/index.d.ts +66 -0
  162. package/dist/lib/notifications/index.d.ts.map +1 -0
  163. package/dist/lib/notifications/index.js +120 -0
  164. package/dist/lib/notifications/index.js.map +1 -0
  165. package/dist/lib/notifications/slack.d.ts +20 -0
  166. package/dist/lib/notifications/slack.d.ts.map +1 -0
  167. package/dist/lib/notifications/slack.js +186 -0
  168. package/dist/lib/notifications/slack.js.map +1 -0
  169. package/dist/lib/notifications/teams.d.ts +20 -0
  170. package/dist/lib/notifications/teams.d.ts.map +1 -0
  171. package/dist/lib/notifications/teams.js +146 -0
  172. package/dist/lib/notifications/teams.js.map +1 -0
  173. package/dist/lib/notifications/webhook.d.ts +23 -0
  174. package/dist/lib/notifications/webhook.d.ts.map +1 -0
  175. package/dist/lib/notifications/webhook.js +65 -0
  176. package/dist/lib/notifications/webhook.js.map +1 -0
  177. package/dist/lib/orchestrator-state.d.ts +194 -0
  178. package/dist/lib/orchestrator-state.d.ts.map +1 -0
  179. package/dist/lib/orchestrator-state.js +332 -0
  180. package/dist/lib/orchestrator-state.js.map +1 -0
  181. package/dist/lib/realtime-cursor.d.ts +107 -0
  182. package/dist/lib/realtime-cursor.d.ts.map +1 -0
  183. package/dist/lib/realtime-cursor.js +260 -0
  184. package/dist/lib/realtime-cursor.js.map +1 -0
  185. package/dist/lib/rollback.d.ts +86 -0
  186. package/dist/lib/rollback.d.ts.map +1 -0
  187. package/dist/lib/rollback.js +405 -0
  188. package/dist/lib/rollback.js.map +1 -0
  189. package/dist/lib/sprint-loader.d.ts +39 -2
  190. package/dist/lib/sprint-loader.d.ts.map +1 -1
  191. package/dist/lib/sprint-loader.js +269 -5
  192. package/dist/lib/sprint-loader.js.map +1 -1
  193. package/dist/lib/stale-agent-detector.d.ts +102 -0
  194. package/dist/lib/stale-agent-detector.d.ts.map +1 -0
  195. package/dist/lib/stale-agent-detector.js +156 -0
  196. package/dist/lib/stale-agent-detector.js.map +1 -0
  197. package/dist/lib/task-dependencies.d.ts +143 -0
  198. package/dist/lib/task-dependencies.d.ts.map +1 -0
  199. package/dist/lib/task-dependencies.js +357 -0
  200. package/dist/lib/task-dependencies.js.map +1 -0
  201. package/dist/lib/task-timeout.d.ts +153 -0
  202. package/dist/lib/task-timeout.d.ts.map +1 -0
  203. package/dist/lib/task-timeout.js +505 -0
  204. package/dist/lib/task-timeout.js.map +1 -0
  205. package/dist/lib/verification/build-check.d.ts +55 -0
  206. package/dist/lib/verification/build-check.d.ts.map +1 -0
  207. package/dist/lib/verification/build-check.js +111 -0
  208. package/dist/lib/verification/build-check.js.map +1 -0
  209. package/dist/lib/verification/index.d.ts +19 -0
  210. package/dist/lib/verification/index.d.ts.map +1 -0
  211. package/dist/lib/verification/index.js +17 -0
  212. package/dist/lib/verification/index.js.map +1 -0
  213. package/dist/lib/verification/lint-check.d.ts +34 -0
  214. package/dist/lib/verification/lint-check.d.ts.map +1 -0
  215. package/dist/lib/verification/lint-check.js +215 -0
  216. package/dist/lib/verification/lint-check.js.map +1 -0
  217. package/dist/lib/verification/test-runner.d.ts +50 -0
  218. package/dist/lib/verification/test-runner.d.ts.map +1 -0
  219. package/dist/lib/verification/test-runner.js +225 -0
  220. package/dist/lib/verification/test-runner.js.map +1 -0
  221. package/dist/utils/command-helpers.d.ts.map +1 -1
  222. package/dist/utils/command-helpers.js +7 -0
  223. package/dist/utils/command-helpers.js.map +1 -1
  224. package/package.json +1 -1
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [checkpoint, resilience, rollback, epic-004-sprint5, task-1]
6
+ * @related: [rollback.ts, event-logger.ts, orchestrator-state.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [fs-extra, uuid, simple-git]
10
+ */
11
+ /**
12
+ * Checkpoint interface (EPIC-004 Sprint 5 TASK-1)
13
+ *
14
+ * Checkpoints are lightweight references to work state, not full snapshots.
15
+ * They capture git commit, modified files, and event stream position.
16
+ * Actual rollback uses git operations, not stored copies.
17
+ */
18
+ export interface Checkpoint {
19
+ id: string;
20
+ taskId: string;
21
+ agentId: string;
22
+ timestamp: Date;
23
+ gitCommit: string;
24
+ filesModified: string[];
25
+ eventsSince: string;
26
+ metadata: Record<string, any>;
27
+ message?: string;
28
+ }
29
+ /**
30
+ * Create a checkpoint
31
+ *
32
+ * Captures current work state:
33
+ * - Git commit hash
34
+ * - Modified files since task start
35
+ * - Last event ID from event stream
36
+ * - Optional message and metadata
37
+ *
38
+ * @param taskId - Task ID this checkpoint belongs to
39
+ * @param agentId - Agent creating checkpoint (optional, auto-detected)
40
+ * @param message - Optional description
41
+ * @param metadata - Optional additional data
42
+ */
43
+ export declare function createCheckpoint(taskId: string, agentId?: string, message?: string, metadata?: Record<string, any>): Promise<Checkpoint>;
44
+ /**
45
+ * Get a specific checkpoint by ID
46
+ *
47
+ * @param checkpointId - Checkpoint ID
48
+ * @returns Checkpoint object or null if not found
49
+ */
50
+ export declare function getCheckpoint(checkpointId: string): Promise<Checkpoint | null>;
51
+ /**
52
+ * List checkpoints, optionally filtered by task ID
53
+ *
54
+ * @param taskId - Optional task ID to filter by
55
+ * @returns Array of checkpoints, sorted by timestamp (newest first)
56
+ */
57
+ export declare function listCheckpoints(taskId?: string): Promise<Checkpoint[]>;
58
+ /**
59
+ * Delete a checkpoint
60
+ *
61
+ * @param checkpointId - Checkpoint ID to delete
62
+ */
63
+ export declare function deleteCheckpoint(checkpointId: string): Promise<void>;
64
+ /**
65
+ * Get checkpoints for a specific task, grouped by day
66
+ * Useful for displaying checkpoint history
67
+ */
68
+ export declare function getCheckpointsByTask(taskId: string): Promise<Map<string, Checkpoint[]>>;
69
+ /**
70
+ * Get the most recent checkpoint for a task
71
+ */
72
+ export declare function getLatestCheckpoint(taskId: string): Promise<Checkpoint | null>;
73
+ /**
74
+ * Check if a checkpoint exists
75
+ */
76
+ export declare function checkpointExists(checkpointId: string): Promise<boolean>;
77
+ /**
78
+ * Export checkpoint data for backup or transfer
79
+ */
80
+ export declare function exportCheckpoint(checkpointId: string): Promise<string>;
81
+ /**
82
+ * Import checkpoint data from backup
83
+ */
84
+ export declare function importCheckpoint(checkpointData: string): Promise<Checkpoint>;
85
+ //# sourceMappingURL=checkpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/lib/checkpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA+ID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,OAAO,CAAC,UAAU,CAAC,CAqCrB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAkBpF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAoC5E;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAe7F;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAGpF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAmBlF"}
@@ -0,0 +1,323 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [checkpoint, resilience, rollback, epic-004-sprint5, task-1]
6
+ * @related: [rollback.ts, event-logger.ts, orchestrator-state.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [fs-extra, uuid, simple-git]
10
+ */
11
+ import fs from 'fs-extra';
12
+ import path from 'path';
13
+ import { v4 as uuidv4 } from 'uuid';
14
+ import simpleGit from 'simple-git';
15
+ import { getGinkoDir, getProjectRoot, getUserEmail } from '../utils/helpers.js';
16
+ import { execSync } from 'child_process';
17
+ /**
18
+ * Generate checkpoint ID
19
+ * Format: cp_<timestamp>_<random>
20
+ */
21
+ function generateCheckpointId() {
22
+ const timestamp = Date.now();
23
+ const random = uuidv4().split('-')[0]; // Use first segment of UUID
24
+ return `cp_${timestamp}_${random}`;
25
+ }
26
+ /**
27
+ * Get path to checkpoint storage directory
28
+ */
29
+ async function getCheckpointStorageDir() {
30
+ const ginkoDir = await getGinkoDir();
31
+ const checkpointDir = path.join(ginkoDir, 'checkpoints');
32
+ await fs.ensureDir(checkpointDir);
33
+ return checkpointDir;
34
+ }
35
+ /**
36
+ * Get path to checkpoint file for a specific checkpoint
37
+ */
38
+ async function getCheckpointFilePath(checkpointId) {
39
+ const checkpointDir = await getCheckpointStorageDir();
40
+ return path.join(checkpointDir, `${checkpointId}.json`);
41
+ }
42
+ /**
43
+ * Get current git commit hash
44
+ */
45
+ async function getCurrentCommitHash() {
46
+ try {
47
+ const projectRoot = await getProjectRoot();
48
+ const git = simpleGit(projectRoot);
49
+ const log = await git.log({ maxCount: 1 });
50
+ return log.latest?.hash || 'unknown';
51
+ }
52
+ catch (error) {
53
+ console.warn('[CHECKPOINT] Failed to get git commit hash:', error);
54
+ return 'unknown';
55
+ }
56
+ }
57
+ /**
58
+ * Get modified files since task start
59
+ * Uses git status --porcelain to capture all changes
60
+ */
61
+ async function getModifiedFiles() {
62
+ try {
63
+ const projectRoot = await getProjectRoot();
64
+ const output = execSync('git status --porcelain', {
65
+ encoding: 'utf8',
66
+ cwd: projectRoot
67
+ }).trim();
68
+ if (!output) {
69
+ return [];
70
+ }
71
+ // Parse git status output
72
+ // Format: "XY filename" where XY is status code
73
+ return output.split('\n').map(line => {
74
+ // Remove leading status code (first 3 characters)
75
+ return line.substring(3).trim();
76
+ }).filter(Boolean);
77
+ }
78
+ catch (error) {
79
+ console.warn('[CHECKPOINT] Failed to get modified files:', error);
80
+ return [];
81
+ }
82
+ }
83
+ /**
84
+ * Get last event ID from event stream
85
+ * Reads from current-events.jsonl to find most recent event
86
+ */
87
+ async function getLastEventId() {
88
+ try {
89
+ const ginkoDir = await getGinkoDir();
90
+ const userEmail = await getUserEmail();
91
+ const userSlug = userEmail.replace('@', '-at-').replace(/\./g, '-');
92
+ const eventsFile = path.join(ginkoDir, 'sessions', userSlug, 'current-events.jsonl');
93
+ if (!await fs.pathExists(eventsFile)) {
94
+ return 'none';
95
+ }
96
+ // Read last line of JSONL file
97
+ const content = await fs.readFile(eventsFile, 'utf8');
98
+ const lines = content.trim().split('\n');
99
+ if (lines.length === 0) {
100
+ return 'none';
101
+ }
102
+ const lastLine = lines[lines.length - 1];
103
+ const event = JSON.parse(lastLine);
104
+ return event.id || 'none';
105
+ }
106
+ catch (error) {
107
+ console.warn('[CHECKPOINT] Failed to get last event ID:', error);
108
+ return 'none';
109
+ }
110
+ }
111
+ /**
112
+ * Get agent ID from environment or local config
113
+ */
114
+ async function getAgentId() {
115
+ // Check environment variable first (for agent mode)
116
+ if (process.env.GINKO_AGENT_ID) {
117
+ return process.env.GINKO_AGENT_ID;
118
+ }
119
+ // Check local agent config
120
+ try {
121
+ const ginkoDir = await getGinkoDir();
122
+ const agentConfigPath = path.join(ginkoDir, 'agent.json');
123
+ if (await fs.pathExists(agentConfigPath)) {
124
+ const config = await fs.readJson(agentConfigPath);
125
+ if (config.agentId) {
126
+ return config.agentId;
127
+ }
128
+ }
129
+ }
130
+ catch (error) {
131
+ console.warn('[CHECKPOINT] Failed to get agent ID from config:', error);
132
+ }
133
+ // Fallback to user email for human users
134
+ const userEmail = await getUserEmail();
135
+ return `human_${userEmail}`;
136
+ }
137
+ /**
138
+ * Create a checkpoint
139
+ *
140
+ * Captures current work state:
141
+ * - Git commit hash
142
+ * - Modified files since task start
143
+ * - Last event ID from event stream
144
+ * - Optional message and metadata
145
+ *
146
+ * @param taskId - Task ID this checkpoint belongs to
147
+ * @param agentId - Agent creating checkpoint (optional, auto-detected)
148
+ * @param message - Optional description
149
+ * @param metadata - Optional additional data
150
+ */
151
+ export async function createCheckpoint(taskId, agentId, message, metadata) {
152
+ // Generate checkpoint ID
153
+ const checkpointId = generateCheckpointId();
154
+ // Detect agent ID if not provided
155
+ const resolvedAgentId = agentId || await getAgentId();
156
+ // Capture current state
157
+ const [gitCommit, filesModified, eventsSince] = await Promise.all([
158
+ getCurrentCommitHash(),
159
+ getModifiedFiles(),
160
+ getLastEventId()
161
+ ]);
162
+ // Create checkpoint object
163
+ const checkpoint = {
164
+ id: checkpointId,
165
+ taskId,
166
+ agentId: resolvedAgentId,
167
+ timestamp: new Date(),
168
+ gitCommit,
169
+ filesModified,
170
+ eventsSince,
171
+ metadata: metadata || {},
172
+ message
173
+ };
174
+ // Save checkpoint to file
175
+ const checkpointPath = await getCheckpointFilePath(checkpointId);
176
+ await fs.writeJSON(checkpointPath, checkpoint, { spaces: 2 });
177
+ console.log(`[CHECKPOINT] Created checkpoint ${checkpointId} for task ${taskId}`);
178
+ console.log(`[CHECKPOINT] Commit: ${gitCommit.substring(0, 7)}`);
179
+ console.log(`[CHECKPOINT] Files: ${filesModified.length} modified`);
180
+ console.log(`[CHECKPOINT] Events: ${eventsSince}`);
181
+ return checkpoint;
182
+ }
183
+ /**
184
+ * Get a specific checkpoint by ID
185
+ *
186
+ * @param checkpointId - Checkpoint ID
187
+ * @returns Checkpoint object or null if not found
188
+ */
189
+ export async function getCheckpoint(checkpointId) {
190
+ try {
191
+ const checkpointPath = await getCheckpointFilePath(checkpointId);
192
+ if (!await fs.pathExists(checkpointPath)) {
193
+ return null;
194
+ }
195
+ const checkpoint = await fs.readJSON(checkpointPath);
196
+ // Convert date strings back to Date objects
197
+ checkpoint.timestamp = new Date(checkpoint.timestamp);
198
+ return checkpoint;
199
+ }
200
+ catch (error) {
201
+ console.warn(`[CHECKPOINT] Failed to load checkpoint ${checkpointId}:`, error);
202
+ return null;
203
+ }
204
+ }
205
+ /**
206
+ * List checkpoints, optionally filtered by task ID
207
+ *
208
+ * @param taskId - Optional task ID to filter by
209
+ * @returns Array of checkpoints, sorted by timestamp (newest first)
210
+ */
211
+ export async function listCheckpoints(taskId) {
212
+ try {
213
+ const checkpointDir = await getCheckpointStorageDir();
214
+ const files = await fs.readdir(checkpointDir);
215
+ // Filter for .json files
216
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
217
+ // Load all checkpoints
218
+ const checkpoints = [];
219
+ for (const file of jsonFiles) {
220
+ try {
221
+ const filePath = path.join(checkpointDir, file);
222
+ const checkpoint = await fs.readJSON(filePath);
223
+ // Convert date strings back to Date objects
224
+ checkpoint.timestamp = new Date(checkpoint.timestamp);
225
+ // Filter by task ID if provided
226
+ if (!taskId || checkpoint.taskId === taskId) {
227
+ checkpoints.push(checkpoint);
228
+ }
229
+ }
230
+ catch (error) {
231
+ console.warn(`[CHECKPOINT] Failed to load checkpoint from ${file}:`, error);
232
+ }
233
+ }
234
+ // Sort by timestamp (newest first)
235
+ checkpoints.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
236
+ return checkpoints;
237
+ }
238
+ catch (error) {
239
+ console.warn('[CHECKPOINT] Failed to list checkpoints:', error);
240
+ return [];
241
+ }
242
+ }
243
+ /**
244
+ * Delete a checkpoint
245
+ *
246
+ * @param checkpointId - Checkpoint ID to delete
247
+ */
248
+ export async function deleteCheckpoint(checkpointId) {
249
+ try {
250
+ const checkpointPath = await getCheckpointFilePath(checkpointId);
251
+ if (await fs.pathExists(checkpointPath)) {
252
+ await fs.remove(checkpointPath);
253
+ console.log(`[CHECKPOINT] Deleted checkpoint ${checkpointId}`);
254
+ }
255
+ else {
256
+ console.warn(`[CHECKPOINT] Checkpoint ${checkpointId} not found`);
257
+ }
258
+ }
259
+ catch (error) {
260
+ console.error(`[CHECKPOINT] Failed to delete checkpoint ${checkpointId}:`, error);
261
+ throw error;
262
+ }
263
+ }
264
+ /**
265
+ * Get checkpoints for a specific task, grouped by day
266
+ * Useful for displaying checkpoint history
267
+ */
268
+ export async function getCheckpointsByTask(taskId) {
269
+ const checkpoints = await listCheckpoints(taskId);
270
+ const grouped = new Map();
271
+ for (const checkpoint of checkpoints) {
272
+ const dateKey = checkpoint.timestamp.toISOString().split('T')[0]; // YYYY-MM-DD
273
+ if (!grouped.has(dateKey)) {
274
+ grouped.set(dateKey, []);
275
+ }
276
+ grouped.get(dateKey).push(checkpoint);
277
+ }
278
+ return grouped;
279
+ }
280
+ /**
281
+ * Get the most recent checkpoint for a task
282
+ */
283
+ export async function getLatestCheckpoint(taskId) {
284
+ const checkpoints = await listCheckpoints(taskId);
285
+ return checkpoints.length > 0 ? checkpoints[0] : null;
286
+ }
287
+ /**
288
+ * Check if a checkpoint exists
289
+ */
290
+ export async function checkpointExists(checkpointId) {
291
+ const checkpointPath = await getCheckpointFilePath(checkpointId);
292
+ return await fs.pathExists(checkpointPath);
293
+ }
294
+ /**
295
+ * Export checkpoint data for backup or transfer
296
+ */
297
+ export async function exportCheckpoint(checkpointId) {
298
+ const checkpoint = await getCheckpoint(checkpointId);
299
+ if (!checkpoint) {
300
+ throw new Error(`Checkpoint ${checkpointId} not found`);
301
+ }
302
+ return JSON.stringify(checkpoint, null, 2);
303
+ }
304
+ /**
305
+ * Import checkpoint data from backup
306
+ */
307
+ export async function importCheckpoint(checkpointData) {
308
+ const checkpoint = JSON.parse(checkpointData);
309
+ // Validate required fields
310
+ if (!checkpoint.id || !checkpoint.taskId || !checkpoint.agentId) {
311
+ throw new Error('Invalid checkpoint data: missing required fields');
312
+ }
313
+ // Convert timestamp to Date if it's a string
314
+ if (typeof checkpoint.timestamp === 'string') {
315
+ checkpoint.timestamp = new Date(checkpoint.timestamp);
316
+ }
317
+ // Save checkpoint
318
+ const checkpointPath = await getCheckpointFilePath(checkpoint.id);
319
+ await fs.writeJSON(checkpointPath, checkpoint, { spaces: 2 });
320
+ console.log(`[CHECKPOINT] Imported checkpoint ${checkpoint.id}`);
321
+ return checkpoint;
322
+ }
323
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/lib/checkpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,230 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2025-12-07
5
+ * @tags: [context-metrics, token-estimation, pressure-monitoring, epic-004, sprint-4]
6
+ * @related: [orchestrate.ts, event-logger.ts, agent-heartbeat.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: []
10
+ */
11
+ /**
12
+ * Context Metrics Module (EPIC-004 Sprint 4 TASK-9)
13
+ *
14
+ * Provides external measurement of context pressure for orchestrator agents.
15
+ * Unlike model self-reported metrics, this tracks observable indicators:
16
+ * - Token estimation via character counting heuristic
17
+ * - Message/conversation turn counts
18
+ * - Tool call frequency
19
+ * - Session activity volume
20
+ *
21
+ * The orchestrator uses these metrics to decide when to checkpoint and respawn.
22
+ */
23
+ /**
24
+ * Context metrics for orchestrator monitoring
25
+ */
26
+ export interface ContextMetrics {
27
+ /** Estimated token count via character-based heuristic */
28
+ estimatedTokens: number;
29
+ /** Model's maximum context window */
30
+ contextLimit: number;
31
+ /** Pressure ratio: estimatedTokens / contextLimit (0.0 - 1.0) */
32
+ pressure: number;
33
+ /** Number of conversation turns/messages */
34
+ messageCount: number;
35
+ /** Number of tool invocations */
36
+ toolCallCount: number;
37
+ /** Events logged since session start */
38
+ eventsSinceStart: number;
39
+ /** Model identifier for limit lookup */
40
+ model: string;
41
+ /** Timestamp of measurement */
42
+ measuredAt: Date;
43
+ }
44
+ /**
45
+ * Pressure zone classification
46
+ */
47
+ export type PressureZone = 'optimal' | 'elevated' | 'warning' | 'critical';
48
+ /**
49
+ * Pressure thresholds for zone classification
50
+ */
51
+ export interface PressureThresholds {
52
+ /** Below this is optimal (default: 0.5) */
53
+ optimal: number;
54
+ /** Below this is elevated (default: 0.7) */
55
+ elevated: number;
56
+ /** Below this is warning (default: 0.85) */
57
+ warning: number;
58
+ }
59
+ /**
60
+ * Model context limits configuration
61
+ * Values are approximate and based on model documentation
62
+ */
63
+ export declare const MODEL_LIMITS: Record<string, number>;
64
+ /**
65
+ * Default pressure thresholds
66
+ */
67
+ export declare const DEFAULT_THRESHOLDS: PressureThresholds;
68
+ /**
69
+ * Estimate token count from text using character-based heuristic.
70
+ *
71
+ * Heuristic: ~4 characters per token for English text.
72
+ * This is a rough approximation that works well for typical code/prose.
73
+ *
74
+ * More accurate methods:
75
+ * - tiktoken (OpenAI's tokenizer)
76
+ * - Anthropic SDK count_tokens
77
+ *
78
+ * We use character heuristic for:
79
+ * - Zero dependencies
80
+ * - Fast calculation
81
+ * - Good enough for pressure monitoring (within ~10%)
82
+ *
83
+ * @param text - Text to estimate tokens for
84
+ * @returns Estimated token count
85
+ */
86
+ export declare function estimateTokens(text: string): number;
87
+ /**
88
+ * Estimate tokens for structured content (messages, tool calls, etc.)
89
+ *
90
+ * @param content - Structured content to estimate
91
+ * @returns Estimated token count with breakdown
92
+ */
93
+ export declare function estimateStructuredTokens(content: {
94
+ messages?: Array<{
95
+ role: string;
96
+ content: string;
97
+ }>;
98
+ toolCalls?: Array<{
99
+ name: string;
100
+ input: unknown;
101
+ output?: unknown;
102
+ }>;
103
+ systemPrompt?: string;
104
+ context?: string;
105
+ }): {
106
+ total: number;
107
+ breakdown: Record<string, number>;
108
+ };
109
+ /**
110
+ * Get context limit for a model
111
+ *
112
+ * @param model - Model identifier
113
+ * @returns Context limit in tokens
114
+ */
115
+ export declare function getContextLimit(model: string): number;
116
+ /**
117
+ * Calculate pressure ratio
118
+ *
119
+ * @param estimatedTokens - Current estimated token usage
120
+ * @param contextLimit - Model's context limit
121
+ * @returns Pressure ratio (0.0 - 1.0, clamped)
122
+ */
123
+ export declare function calculatePressure(estimatedTokens: number, contextLimit: number): number;
124
+ /**
125
+ * Classify pressure into zones
126
+ *
127
+ * @param pressure - Pressure ratio (0.0 - 1.0)
128
+ * @param thresholds - Optional custom thresholds
129
+ * @returns Pressure zone classification
130
+ */
131
+ export declare function getPressureZone(pressure: number, thresholds?: PressureThresholds): PressureZone;
132
+ /**
133
+ * Get pressure zone color for display
134
+ *
135
+ * @param zone - Pressure zone
136
+ * @returns Chalk color name
137
+ */
138
+ export declare function getPressureColor(zone: PressureZone): string;
139
+ /**
140
+ * Context pressure monitor for orchestrator agents.
141
+ *
142
+ * Tracks metrics over time and provides pressure monitoring.
143
+ * Designed to be updated each orchestration cycle.
144
+ */
145
+ export declare class ContextMonitor {
146
+ private model;
147
+ private contextLimit;
148
+ private thresholds;
149
+ private messageCount;
150
+ private toolCallCount;
151
+ private eventsSinceStart;
152
+ private accumulatedTokens;
153
+ private pressureHistory;
154
+ private readonly maxHistorySize;
155
+ constructor(options?: {
156
+ model?: string;
157
+ contextLimit?: number;
158
+ thresholds?: Partial<PressureThresholds>;
159
+ });
160
+ /**
161
+ * Record a message (increments counter and estimates tokens)
162
+ */
163
+ recordMessage(content: string): void;
164
+ /**
165
+ * Record a tool call (increments counter and estimates tokens)
166
+ */
167
+ recordToolCall(name: string, input: unknown, output?: unknown): void;
168
+ /**
169
+ * Record an event (session activity)
170
+ */
171
+ recordEvent(): void;
172
+ /**
173
+ * Add tokens directly (for bulk updates)
174
+ */
175
+ addTokens(count: number): void;
176
+ /**
177
+ * Get current metrics snapshot
178
+ */
179
+ getMetrics(): ContextMetrics;
180
+ /**
181
+ * Get current pressure ratio
182
+ */
183
+ getPressure(): number;
184
+ /**
185
+ * Get current pressure zone
186
+ */
187
+ getZone(): PressureZone;
188
+ /**
189
+ * Check if pressure exceeds a threshold
190
+ */
191
+ isAboveThreshold(threshold: number): boolean;
192
+ /**
193
+ * Check if respawn is recommended (pressure > 80%)
194
+ */
195
+ shouldRespawn(): boolean;
196
+ /**
197
+ * Check if warning should be logged (pressure > 70%)
198
+ */
199
+ shouldWarn(): boolean;
200
+ /**
201
+ * Get pressure trend (increasing, stable, decreasing)
202
+ */
203
+ getTrend(): 'increasing' | 'stable' | 'decreasing';
204
+ /**
205
+ * Reset metrics (for new session)
206
+ */
207
+ reset(): void;
208
+ /**
209
+ * Record pressure snapshot for history
210
+ */
211
+ private recordPressure;
212
+ /**
213
+ * Format metrics for display
214
+ */
215
+ formatMetrics(): string;
216
+ }
217
+ /**
218
+ * Get or create the global context monitor
219
+ */
220
+ export declare function getContextMonitor(options?: {
221
+ model?: string;
222
+ contextLimit?: number;
223
+ thresholds?: Partial<PressureThresholds>;
224
+ }): ContextMonitor;
225
+ /**
226
+ * Reset the global context monitor (for testing or session restart)
227
+ */
228
+ export declare function resetContextMonitor(): void;
229
+ export default ContextMonitor;
230
+ //# sourceMappingURL=context-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-metrics.d.ts","sourceRoot":"","sources":["../../src/lib/context-metrics.ts"],"names":[],"mappings":"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"}