@ginkoai/cli 1.6.2 → 1.7.0
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/agent/agent-client.d.ts +150 -0
- package/dist/commands/agent/agent-client.d.ts.map +1 -0
- package/dist/commands/agent/agent-client.js +170 -0
- package/dist/commands/agent/agent-client.js.map +1 -0
- package/dist/commands/agent/index.d.ts +22 -0
- package/dist/commands/agent/index.d.ts.map +1 -0
- package/dist/commands/agent/index.js +121 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/agent/list.d.ts +22 -0
- package/dist/commands/agent/list.d.ts.map +1 -0
- package/dist/commands/agent/list.js +119 -0
- package/dist/commands/agent/list.js.map +1 -0
- package/dist/commands/agent/register.d.ts +21 -0
- package/dist/commands/agent/register.d.ts.map +1 -0
- package/dist/commands/agent/register.js +97 -0
- package/dist/commands/agent/register.js.map +1 -0
- package/dist/commands/agent/status.d.ts +19 -0
- package/dist/commands/agent/status.d.ts.map +1 -0
- package/dist/commands/agent/status.js +271 -0
- package/dist/commands/agent/status.js.map +1 -0
- package/dist/commands/agent/work.d.ts +22 -0
- package/dist/commands/agent/work.d.ts.map +1 -0
- package/dist/commands/agent/work.js +459 -0
- package/dist/commands/agent/work.js.map +1 -0
- package/dist/commands/checkpoint/create.d.ts +27 -0
- package/dist/commands/checkpoint/create.d.ts.map +1 -0
- package/dist/commands/checkpoint/create.js +82 -0
- package/dist/commands/checkpoint/create.js.map +1 -0
- package/dist/commands/checkpoint/index.d.ts +23 -0
- package/dist/commands/checkpoint/index.d.ts.map +1 -0
- package/dist/commands/checkpoint/index.js +91 -0
- package/dist/commands/checkpoint/index.js.map +1 -0
- package/dist/commands/checkpoint/list.d.ts +27 -0
- package/dist/commands/checkpoint/list.d.ts.map +1 -0
- package/dist/commands/checkpoint/list.js +115 -0
- package/dist/commands/checkpoint/list.js.map +1 -0
- package/dist/commands/checkpoint/show.d.ts +23 -0
- package/dist/commands/checkpoint/show.d.ts.map +1 -0
- package/dist/commands/checkpoint/show.js +102 -0
- package/dist/commands/checkpoint/show.js.map +1 -0
- package/dist/commands/dlq.d.ts +24 -0
- package/dist/commands/dlq.d.ts.map +1 -0
- package/dist/commands/dlq.js +172 -0
- package/dist/commands/dlq.js.map +1 -0
- package/dist/commands/escalation/create.d.ts +22 -0
- package/dist/commands/escalation/create.d.ts.map +1 -0
- package/dist/commands/escalation/create.js +122 -0
- package/dist/commands/escalation/create.js.map +1 -0
- package/dist/commands/escalation/escalation-client.d.ts +101 -0
- package/dist/commands/escalation/escalation-client.d.ts.map +1 -0
- package/dist/commands/escalation/escalation-client.js +129 -0
- package/dist/commands/escalation/escalation-client.js.map +1 -0
- package/dist/commands/escalation/index.d.ts +22 -0
- package/dist/commands/escalation/index.d.ts.map +1 -0
- package/dist/commands/escalation/index.js +94 -0
- package/dist/commands/escalation/index.js.map +1 -0
- package/dist/commands/escalation/list.d.ts +24 -0
- package/dist/commands/escalation/list.d.ts.map +1 -0
- package/dist/commands/escalation/list.js +170 -0
- package/dist/commands/escalation/list.js.map +1 -0
- package/dist/commands/escalation/resolve.d.ts +20 -0
- package/dist/commands/escalation/resolve.d.ts.map +1 -0
- package/dist/commands/escalation/resolve.js +102 -0
- package/dist/commands/escalation/resolve.js.map +1 -0
- package/dist/commands/graph/api-client.d.ts +21 -1
- package/dist/commands/graph/api-client.d.ts.map +1 -1
- package/dist/commands/graph/api-client.js +23 -0
- package/dist/commands/graph/api-client.js.map +1 -1
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +9 -1
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/log.d.ts +3 -0
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +73 -14
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/notifications/history.d.ts +21 -0
- package/dist/commands/notifications/history.d.ts.map +1 -0
- package/dist/commands/notifications/history.js +160 -0
- package/dist/commands/notifications/history.js.map +1 -0
- package/dist/commands/notifications/index.d.ts +22 -0
- package/dist/commands/notifications/index.d.ts.map +1 -0
- package/dist/commands/notifications/index.js +87 -0
- package/dist/commands/notifications/index.js.map +1 -0
- package/dist/commands/notifications/list.d.ts +19 -0
- package/dist/commands/notifications/list.d.ts.map +1 -0
- package/dist/commands/notifications/list.js +132 -0
- package/dist/commands/notifications/list.js.map +1 -0
- package/dist/commands/notifications/test.d.ts +19 -0
- package/dist/commands/notifications/test.d.ts.map +1 -0
- package/dist/commands/notifications/test.js +217 -0
- package/dist/commands/notifications/test.js.map +1 -0
- package/dist/commands/orchestrate.d.ts +25 -0
- package/dist/commands/orchestrate.d.ts.map +1 -0
- package/dist/commands/orchestrate.js +858 -0
- package/dist/commands/orchestrate.js.map +1 -0
- package/dist/commands/sprint/deps.d.ts +29 -0
- package/dist/commands/sprint/deps.d.ts.map +1 -0
- package/dist/commands/sprint/deps.js +269 -0
- package/dist/commands/sprint/deps.js.map +1 -0
- package/dist/commands/sprint/index.d.ts +10 -5
- package/dist/commands/sprint/index.d.ts.map +1 -1
- package/dist/commands/sprint/index.js +26 -5
- package/dist/commands/sprint/index.js.map +1 -1
- package/dist/commands/start/index.d.ts.map +1 -1
- package/dist/commands/start/index.js +6 -0
- package/dist/commands/start/index.js.map +1 -1
- package/dist/commands/start/start-reflection.d.ts.map +1 -1
- package/dist/commands/start/start-reflection.js +8 -0
- package/dist/commands/start/start-reflection.js.map +1 -1
- package/dist/commands/verify.d.ts +17 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +232 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/core/session-log-manager.d.ts +1 -1
- package/dist/core/session-log-manager.d.ts.map +1 -1
- package/dist/index.js +78 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/task-timeout.test.d.ts +12 -0
- package/dist/lib/__tests__/task-timeout.test.d.ts.map +1 -0
- package/dist/lib/__tests__/task-timeout.test.js +278 -0
- package/dist/lib/__tests__/task-timeout.test.js.map +1 -0
- package/dist/lib/agent-heartbeat.d.ts +68 -0
- package/dist/lib/agent-heartbeat.d.ts.map +1 -0
- package/dist/lib/agent-heartbeat.js +117 -0
- package/dist/lib/agent-heartbeat.js.map +1 -0
- package/dist/lib/checkpoint.d.ts +85 -0
- package/dist/lib/checkpoint.d.ts.map +1 -0
- package/dist/lib/checkpoint.js +323 -0
- package/dist/lib/checkpoint.js.map +1 -0
- package/dist/lib/context-metrics.d.ts +230 -0
- package/dist/lib/context-metrics.d.ts.map +1 -0
- package/dist/lib/context-metrics.js +372 -0
- package/dist/lib/context-metrics.js.map +1 -0
- package/dist/lib/dead-letter-queue.d.ts +108 -0
- package/dist/lib/dead-letter-queue.d.ts.map +1 -0
- package/dist/lib/dead-letter-queue.js +378 -0
- package/dist/lib/dead-letter-queue.js.map +1 -0
- package/dist/lib/event-logger.d.ts +9 -1
- package/dist/lib/event-logger.d.ts.map +1 -1
- package/dist/lib/event-logger.js +45 -3
- package/dist/lib/event-logger.js.map +1 -1
- package/dist/lib/event-queue.d.ts.map +1 -1
- package/dist/lib/event-queue.js +13 -2
- package/dist/lib/event-queue.js.map +1 -1
- package/dist/lib/examples/timeout-demo.d.ts +13 -0
- package/dist/lib/examples/timeout-demo.d.ts.map +1 -0
- package/dist/lib/examples/timeout-demo.js +102 -0
- package/dist/lib/examples/timeout-demo.js.map +1 -0
- package/dist/lib/examples/timeout-integration-example.d.ts +17 -0
- package/dist/lib/examples/timeout-integration-example.d.ts.map +1 -0
- package/dist/lib/examples/timeout-integration-example.js +223 -0
- package/dist/lib/examples/timeout-integration-example.js.map +1 -0
- package/dist/lib/notification-hooks.d.ts +103 -0
- package/dist/lib/notification-hooks.d.ts.map +1 -0
- package/dist/lib/notification-hooks.js +223 -0
- package/dist/lib/notification-hooks.js.map +1 -0
- package/dist/lib/notifications/discord.d.ts +20 -0
- package/dist/lib/notifications/discord.d.ts.map +1 -0
- package/dist/lib/notifications/discord.js +140 -0
- package/dist/lib/notifications/discord.js.map +1 -0
- package/dist/lib/notifications/index.d.ts +66 -0
- package/dist/lib/notifications/index.d.ts.map +1 -0
- package/dist/lib/notifications/index.js +120 -0
- package/dist/lib/notifications/index.js.map +1 -0
- package/dist/lib/notifications/slack.d.ts +20 -0
- package/dist/lib/notifications/slack.d.ts.map +1 -0
- package/dist/lib/notifications/slack.js +186 -0
- package/dist/lib/notifications/slack.js.map +1 -0
- package/dist/lib/notifications/teams.d.ts +20 -0
- package/dist/lib/notifications/teams.d.ts.map +1 -0
- package/dist/lib/notifications/teams.js +146 -0
- package/dist/lib/notifications/teams.js.map +1 -0
- package/dist/lib/notifications/webhook.d.ts +23 -0
- package/dist/lib/notifications/webhook.d.ts.map +1 -0
- package/dist/lib/notifications/webhook.js +65 -0
- package/dist/lib/notifications/webhook.js.map +1 -0
- package/dist/lib/orchestrator-state.d.ts +194 -0
- package/dist/lib/orchestrator-state.d.ts.map +1 -0
- package/dist/lib/orchestrator-state.js +332 -0
- package/dist/lib/orchestrator-state.js.map +1 -0
- package/dist/lib/realtime-cursor.d.ts +107 -0
- package/dist/lib/realtime-cursor.d.ts.map +1 -0
- package/dist/lib/realtime-cursor.js +260 -0
- package/dist/lib/realtime-cursor.js.map +1 -0
- package/dist/lib/rollback.d.ts +86 -0
- package/dist/lib/rollback.d.ts.map +1 -0
- package/dist/lib/rollback.js +405 -0
- package/dist/lib/rollback.js.map +1 -0
- package/dist/lib/sprint-loader.d.ts +39 -2
- package/dist/lib/sprint-loader.d.ts.map +1 -1
- package/dist/lib/sprint-loader.js +255 -4
- package/dist/lib/sprint-loader.js.map +1 -1
- package/dist/lib/stale-agent-detector.d.ts +102 -0
- package/dist/lib/stale-agent-detector.d.ts.map +1 -0
- package/dist/lib/stale-agent-detector.js +156 -0
- package/dist/lib/stale-agent-detector.js.map +1 -0
- package/dist/lib/task-dependencies.d.ts +143 -0
- package/dist/lib/task-dependencies.d.ts.map +1 -0
- package/dist/lib/task-dependencies.js +357 -0
- package/dist/lib/task-dependencies.js.map +1 -0
- package/dist/lib/task-timeout.d.ts +153 -0
- package/dist/lib/task-timeout.d.ts.map +1 -0
- package/dist/lib/task-timeout.js +505 -0
- package/dist/lib/task-timeout.js.map +1 -0
- package/dist/lib/verification/build-check.d.ts +55 -0
- package/dist/lib/verification/build-check.d.ts.map +1 -0
- package/dist/lib/verification/build-check.js +111 -0
- package/dist/lib/verification/build-check.js.map +1 -0
- package/dist/lib/verification/index.d.ts +19 -0
- package/dist/lib/verification/index.d.ts.map +1 -0
- package/dist/lib/verification/index.js +17 -0
- package/dist/lib/verification/index.js.map +1 -0
- package/dist/lib/verification/lint-check.d.ts +34 -0
- package/dist/lib/verification/lint-check.d.ts.map +1 -0
- package/dist/lib/verification/lint-check.js +215 -0
- package/dist/lib/verification/lint-check.js.map +1 -0
- package/dist/lib/verification/test-runner.d.ts +50 -0
- package/dist/lib/verification/test-runner.d.ts.map +1 -0
- package/dist/lib/verification/test-runner.js +225 -0
- package/dist/lib/verification/test-runner.js.map +1 -0
- package/dist/utils/command-helpers.d.ts.map +1 -1
- package/dist/utils/command-helpers.js +7 -0
- package/dist/utils/command-helpers.js.map +1 -1
- 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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"}
|