@ekkos/cli 0.2.18 → 1.0.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/README.md +57 -0
- package/dist/agent/daemon.d.ts +27 -0
- package/dist/agent/daemon.js +254 -29
- package/dist/agent/health-check.d.ts +35 -0
- package/dist/agent/health-check.js +243 -0
- package/dist/agent/pty-runner.d.ts +1 -0
- package/dist/agent/pty-runner.js +6 -1
- package/dist/capture/eviction-client.d.ts +139 -0
- package/dist/capture/eviction-client.js +454 -0
- package/dist/capture/index.d.ts +2 -0
- package/dist/capture/index.js +2 -0
- package/dist/capture/jsonl-rewriter.d.ts +96 -0
- package/dist/capture/jsonl-rewriter.js +1369 -0
- package/dist/capture/transcript-repair.d.ts +51 -0
- package/dist/capture/transcript-repair.js +319 -0
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.js +244 -0
- package/dist/commands/dashboard.d.ts +25 -0
- package/dist/commands/dashboard.js +1175 -0
- package/dist/commands/doctor.js +23 -1
- package/dist/commands/run.d.ts +5 -0
- package/dist/commands/run.js +1605 -516
- package/dist/commands/setup-remote.js +146 -37
- package/dist/commands/swarm-dashboard.d.ts +20 -0
- package/dist/commands/swarm-dashboard.js +735 -0
- package/dist/commands/swarm-setup.d.ts +10 -0
- package/dist/commands/swarm-setup.js +956 -0
- package/dist/commands/swarm.d.ts +46 -0
- package/dist/commands/swarm.js +441 -0
- package/dist/commands/test-claude.d.ts +16 -0
- package/dist/commands/test-claude.js +156 -0
- package/dist/commands/usage/blocks.d.ts +8 -0
- package/dist/commands/usage/blocks.js +60 -0
- package/dist/commands/usage/daily.d.ts +9 -0
- package/dist/commands/usage/daily.js +96 -0
- package/dist/commands/usage/dashboard.d.ts +8 -0
- package/dist/commands/usage/dashboard.js +104 -0
- package/dist/commands/usage/formatters.d.ts +41 -0
- package/dist/commands/usage/formatters.js +147 -0
- package/dist/commands/usage/index.d.ts +13 -0
- package/dist/commands/usage/index.js +87 -0
- package/dist/commands/usage/monthly.d.ts +8 -0
- package/dist/commands/usage/monthly.js +66 -0
- package/dist/commands/usage/session.d.ts +11 -0
- package/dist/commands/usage/session.js +193 -0
- package/dist/commands/usage/weekly.d.ts +9 -0
- package/dist/commands/usage/weekly.js +61 -0
- package/dist/commands/usage.d.ts +7 -0
- package/dist/commands/usage.js +214 -0
- package/dist/cron/index.d.ts +7 -0
- package/dist/cron/index.js +13 -0
- package/dist/cron/promoter.d.ts +70 -0
- package/dist/cron/promoter.js +403 -0
- package/dist/deploy/instructions.d.ts +5 -2
- package/dist/deploy/instructions.js +11 -8
- package/dist/index.js +262 -5
- package/dist/lib/tmux-scrollbar.d.ts +14 -0
- package/dist/lib/tmux-scrollbar.js +296 -0
- package/dist/lib/usage-monitor.d.ts +47 -0
- package/dist/lib/usage-monitor.js +124 -0
- package/dist/lib/usage-parser.d.ts +162 -0
- package/dist/lib/usage-parser.js +583 -0
- package/dist/restore/RestoreOrchestrator.d.ts +4 -0
- package/dist/restore/RestoreOrchestrator.js +118 -30
- package/dist/utils/log-rotate.d.ts +18 -0
- package/dist/utils/log-rotate.js +74 -0
- package/dist/utils/platform.d.ts +2 -0
- package/dist/utils/platform.js +3 -1
- package/dist/utils/session-binding.d.ts +5 -0
- package/dist/utils/session-binding.js +46 -0
- package/dist/utils/state.js +4 -0
- package/dist/utils/verify-remote-terminal.d.ts +10 -0
- package/dist/utils/verify-remote-terminal.js +415 -0
- package/package.json +9 -2
- package/templates/CLAUDE.md +135 -23
- package/templates/ekkos-manifest.json +5 -5
- package/templates/hooks/lib/contract.sh +43 -31
- package/templates/hooks/lib/count-tokens.cjs +86 -0
- package/templates/hooks/lib/ekkos-reminders.sh +98 -0
- package/templates/hooks/lib/state.sh +53 -1
- package/templates/hooks/stop.sh +150 -388
- package/templates/hooks/user-prompt-submit.sh +353 -443
- package/templates/windsurf-hooks/README.md +212 -0
- package/templates/windsurf-hooks/hooks.json +9 -2
- package/templates/windsurf-hooks/install.sh +148 -0
- package/templates/windsurf-hooks/lib/contract.sh +2 -0
- package/templates/windsurf-hooks/post-cascade-response.sh +251 -0
- package/templates/windsurf-hooks/pre-user-prompt.sh +435 -0
- package/templates/windsurf-skills/ekkos-memory/SKILL.md +219 -0
- package/templates/agents/README.md +0 -182
- package/templates/agents/code-reviewer.md +0 -166
- package/templates/agents/debug-detective.md +0 -169
- package/templates/agents/ekkOS_Vercel.md +0 -99
- package/templates/agents/extension-manager.md +0 -229
- package/templates/agents/git-companion.md +0 -185
- package/templates/agents/github-test-agent.md +0 -321
- package/templates/agents/railway-manager.md +0 -215
- package/templates/windsurf-hooks/before-submit-prompt.sh +0 -238
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Health check for ekkOS agent daemon
|
|
4
|
+
*
|
|
5
|
+
* Verifies:
|
|
6
|
+
* - Service is installed and loaded
|
|
7
|
+
* - Process is running
|
|
8
|
+
* - Recent activity in logs
|
|
9
|
+
* - Network connectivity to relay server
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.checkDaemonHealth = checkDaemonHealth;
|
|
49
|
+
exports.formatHealthStatus = formatHealthStatus;
|
|
50
|
+
const os = __importStar(require("os"));
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const child_process_1 = require("child_process");
|
|
54
|
+
const ws_1 = __importDefault(require("ws"));
|
|
55
|
+
const RELAY_URL = process.env.RELAY_WS_URL || 'wss://ekkos-relay-production.up.railway.app';
|
|
56
|
+
/**
|
|
57
|
+
* Check agent daemon health
|
|
58
|
+
*/
|
|
59
|
+
async function checkDaemonHealth() {
|
|
60
|
+
const status = {
|
|
61
|
+
ok: true,
|
|
62
|
+
service: {
|
|
63
|
+
installed: false,
|
|
64
|
+
loaded: false,
|
|
65
|
+
running: false,
|
|
66
|
+
},
|
|
67
|
+
logs: {
|
|
68
|
+
recentErrors: [],
|
|
69
|
+
},
|
|
70
|
+
relay: {
|
|
71
|
+
reachable: false,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
// Check if service is installed
|
|
75
|
+
const plistPath = path.join(os.homedir(), 'Library', 'LaunchAgents', 'dev.ekkos.agent.plist');
|
|
76
|
+
status.service.installed = fs.existsSync(plistPath);
|
|
77
|
+
// Check if service is loaded
|
|
78
|
+
try {
|
|
79
|
+
const output = (0, child_process_1.execSync)('launchctl list | grep dev.ekkos.agent', { encoding: 'utf-8' }).trim();
|
|
80
|
+
status.service.loaded = !!output;
|
|
81
|
+
// Extract PID if running
|
|
82
|
+
const pidMatch = output.match(/^(\d+)\s+/);
|
|
83
|
+
if (pidMatch) {
|
|
84
|
+
status.service.pid = parseInt(pidMatch[1], 10);
|
|
85
|
+
status.service.running = status.service.pid > 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Service not loaded
|
|
90
|
+
status.service.loaded = false;
|
|
91
|
+
status.service.running = false;
|
|
92
|
+
}
|
|
93
|
+
// Check logs
|
|
94
|
+
const logDir = path.join(os.homedir(), '.ekkos');
|
|
95
|
+
const errLogPath = path.join(logDir, 'agent.err.log');
|
|
96
|
+
const outLogPath = path.join(logDir, 'agent.out.log');
|
|
97
|
+
if (fs.existsSync(errLogPath)) {
|
|
98
|
+
try {
|
|
99
|
+
const errLog = fs.readFileSync(errLogPath, 'utf-8');
|
|
100
|
+
if (errLog) {
|
|
101
|
+
status.logs.lastActivity = new Date(fs.statSync(errLogPath).mtime);
|
|
102
|
+
status.logs.recentErrors = extractRecentErrors(errLog, 10);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Ignore log read errors
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (fs.existsSync(outLogPath)) {
|
|
110
|
+
try {
|
|
111
|
+
const stat = fs.statSync(outLogPath);
|
|
112
|
+
const mtime = new Date(stat.mtime);
|
|
113
|
+
if (!status.logs.lastActivity || mtime > status.logs.lastActivity) {
|
|
114
|
+
status.logs.lastActivity = mtime;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Ignore
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Check relay connectivity
|
|
122
|
+
try {
|
|
123
|
+
status.relay.reachable = await checkRelayConnectivity();
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
status.relay.reachable = false;
|
|
127
|
+
status.relay.lastError = err.message;
|
|
128
|
+
}
|
|
129
|
+
// Overall health
|
|
130
|
+
status.ok = status.service.running && status.relay.reachable && status.logs.recentErrors.length === 0;
|
|
131
|
+
return status;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Check if relay server is reachable
|
|
135
|
+
*/
|
|
136
|
+
async function checkRelayConnectivity() {
|
|
137
|
+
return new Promise((resolve) => {
|
|
138
|
+
const timeout = setTimeout(() => {
|
|
139
|
+
ws.terminate();
|
|
140
|
+
resolve(false);
|
|
141
|
+
}, 5000);
|
|
142
|
+
const ws = new ws_1.default(`${RELAY_URL}/health`);
|
|
143
|
+
ws.on('open', () => {
|
|
144
|
+
clearTimeout(timeout);
|
|
145
|
+
ws.close();
|
|
146
|
+
resolve(true);
|
|
147
|
+
});
|
|
148
|
+
ws.on('error', () => {
|
|
149
|
+
clearTimeout(timeout);
|
|
150
|
+
resolve(false);
|
|
151
|
+
});
|
|
152
|
+
ws.on('close', () => {
|
|
153
|
+
clearTimeout(timeout);
|
|
154
|
+
resolve(false);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Extract recent error lines from log
|
|
160
|
+
*/
|
|
161
|
+
function extractRecentErrors(log, count) {
|
|
162
|
+
return log
|
|
163
|
+
.split('\n')
|
|
164
|
+
.filter((line) => {
|
|
165
|
+
const lower = line.toLowerCase();
|
|
166
|
+
return lower.includes('error') || lower.includes('failed') || lower.includes('exception');
|
|
167
|
+
})
|
|
168
|
+
.slice(-count);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Format health status for console output
|
|
172
|
+
*/
|
|
173
|
+
function formatHealthStatus(status) {
|
|
174
|
+
const lines = [];
|
|
175
|
+
lines.push('ekkOS Agent Daemon Health Check');
|
|
176
|
+
lines.push('================================\n');
|
|
177
|
+
// Service status
|
|
178
|
+
lines.push(`Service Installation: ${status.service.installed ? '✓' : '✗'} ${status.service.installed ? 'Installed' : 'Not installed'}`);
|
|
179
|
+
lines.push(`Service Loaded: ${status.service.loaded ? '✓' : '✗'} ${status.service.loaded ? 'Loaded' : 'Not loaded'}`);
|
|
180
|
+
if (status.service.running) {
|
|
181
|
+
lines.push(`Service Running: ✓ Running (PID ${status.service.pid})`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
lines.push('Service Running: ✗ Not running');
|
|
185
|
+
}
|
|
186
|
+
lines.push('');
|
|
187
|
+
// Logs status
|
|
188
|
+
if (status.logs.lastActivity) {
|
|
189
|
+
const now = new Date();
|
|
190
|
+
const age = now.getTime() - status.logs.lastActivity.getTime();
|
|
191
|
+
const ageStr = formatAge(age);
|
|
192
|
+
lines.push(`Last Activity: ${ageStr} ago (${status.logs.lastActivity.toISOString()})`);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
lines.push('Last Activity: No logs found');
|
|
196
|
+
}
|
|
197
|
+
if (status.logs.recentErrors.length > 0) {
|
|
198
|
+
lines.push(`Recent Errors (${status.logs.recentErrors.length}):`);
|
|
199
|
+
for (const err of status.logs.recentErrors) {
|
|
200
|
+
lines.push(` - ${err.substring(0, 100)}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
lines.push('');
|
|
204
|
+
// Relay status
|
|
205
|
+
lines.push(`Relay Server: ${status.relay.reachable ? '✓' : '✗'} ${status.relay.reachable ? 'Reachable' : 'Unreachable'}`);
|
|
206
|
+
if (status.relay.lastError) {
|
|
207
|
+
lines.push(` Error: ${status.relay.lastError}`);
|
|
208
|
+
}
|
|
209
|
+
lines.push('');
|
|
210
|
+
// Overall status
|
|
211
|
+
if (status.ok) {
|
|
212
|
+
lines.push('Overall: ✓ Healthy - All systems operational');
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
lines.push('Overall: ✗ Unhealthy - Issues detected');
|
|
216
|
+
if (!status.service.running) {
|
|
217
|
+
lines.push(' → Service is not running. Run: launchctl start dev.ekkos.agent');
|
|
218
|
+
}
|
|
219
|
+
if (!status.relay.reachable) {
|
|
220
|
+
lines.push(' → Cannot reach relay server. Check network connectivity.');
|
|
221
|
+
}
|
|
222
|
+
if (status.logs.recentErrors.length > 0) {
|
|
223
|
+
lines.push(' → Recent errors found in logs. Check ~/.ekkos/agent.err.log');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return lines.join('\n');
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Format age duration
|
|
230
|
+
*/
|
|
231
|
+
function formatAge(ms) {
|
|
232
|
+
const seconds = Math.floor(ms / 1000);
|
|
233
|
+
const minutes = Math.floor(seconds / 60);
|
|
234
|
+
const hours = Math.floor(minutes / 60);
|
|
235
|
+
const days = Math.floor(hours / 24);
|
|
236
|
+
if (days > 0)
|
|
237
|
+
return `${days}d ${hours % 24}h`;
|
|
238
|
+
if (hours > 0)
|
|
239
|
+
return `${hours}h ${minutes % 60}m`;
|
|
240
|
+
if (minutes > 0)
|
|
241
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
242
|
+
return `${seconds}s`;
|
|
243
|
+
}
|
package/dist/agent/pty-runner.js
CHANGED
|
@@ -85,6 +85,7 @@ class PTYRunner {
|
|
|
85
85
|
cwd: this.config.cwd || process.cwd(),
|
|
86
86
|
env: {
|
|
87
87
|
...process.env,
|
|
88
|
+
...(this.config.env || {}),
|
|
88
89
|
TERM: 'xterm-256color',
|
|
89
90
|
COLORTERM: 'truecolor',
|
|
90
91
|
},
|
|
@@ -107,7 +108,10 @@ class PTYRunner {
|
|
|
107
108
|
this.spawnProcess = (0, child_process_1.spawn)('cmd.exe', ['/c', this.config.command, ...this.config.args], {
|
|
108
109
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
109
110
|
cwd,
|
|
110
|
-
env:
|
|
111
|
+
env: {
|
|
112
|
+
...process.env,
|
|
113
|
+
...(this.config.env || {}),
|
|
114
|
+
},
|
|
111
115
|
});
|
|
112
116
|
}
|
|
113
117
|
else {
|
|
@@ -120,6 +124,7 @@ class PTYRunner {
|
|
|
120
124
|
cwd,
|
|
121
125
|
env: {
|
|
122
126
|
...process.env,
|
|
127
|
+
...(this.config.env || {}),
|
|
123
128
|
TERM: 'xterm-256color',
|
|
124
129
|
},
|
|
125
130
|
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EVICTION CLIENT
|
|
3
|
+
* ================
|
|
4
|
+
*
|
|
5
|
+
* Client module for the Handshake Eviction Protocol.
|
|
6
|
+
* Provides functions to call ekkOS_EvictPrepare and ekkOS_EvictConfirm
|
|
7
|
+
* ensuring zero data loss during context eviction.
|
|
8
|
+
*
|
|
9
|
+
* Protocol:
|
|
10
|
+
* 1. prepareEviction() - Write to R2, get ACK
|
|
11
|
+
* 2. (caller deletes locally)
|
|
12
|
+
* 3. confirmEviction() - Mark as committed
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - Retry with exponential backoff
|
|
16
|
+
* - Timeout handling
|
|
17
|
+
* - Fallback detection
|
|
18
|
+
* - Idempotency via clientNonce
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Queue a failed eviction for retry when R2 reconnects
|
|
22
|
+
*/
|
|
23
|
+
export declare function queueEvictionForRetry(messages: Message[], indices: number[], estimatedTokens: number, reason: 'threshold' | 'emergency' | 'manual', options: HandshakeEvictionOptions): void;
|
|
24
|
+
/**
|
|
25
|
+
* Drain the retry queue — called after a successful handshake
|
|
26
|
+
* Non-blocking: runs in background, doesn't delay current eviction
|
|
27
|
+
*/
|
|
28
|
+
export declare function drainRetryQueue(apiUrl: string, authToken: string): Promise<{
|
|
29
|
+
drained: number;
|
|
30
|
+
failed: number;
|
|
31
|
+
remaining: number;
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Get retry queue stats (for monitoring)
|
|
35
|
+
*/
|
|
36
|
+
export declare function getRetryQueueStats(): {
|
|
37
|
+
size: number;
|
|
38
|
+
oldestAge: number | null;
|
|
39
|
+
};
|
|
40
|
+
interface ContentBlock {
|
|
41
|
+
type: 'text' | 'image' | 'tool_use' | 'tool_result' | 'thinking';
|
|
42
|
+
text?: string;
|
|
43
|
+
id?: string;
|
|
44
|
+
name?: string;
|
|
45
|
+
input?: Record<string, unknown>;
|
|
46
|
+
tool_use_id?: string;
|
|
47
|
+
content?: string | ContentBlock[];
|
|
48
|
+
thinking?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface Message {
|
|
51
|
+
role: 'user' | 'assistant';
|
|
52
|
+
content: string | ContentBlock[];
|
|
53
|
+
}
|
|
54
|
+
interface EvictionManifest {
|
|
55
|
+
evictionId: string;
|
|
56
|
+
messageIndices: number[];
|
|
57
|
+
fingerprints: string[];
|
|
58
|
+
estimatedTokens: number;
|
|
59
|
+
evictionReason: 'threshold' | 'emergency' | 'manual';
|
|
60
|
+
}
|
|
61
|
+
interface PrepareResult {
|
|
62
|
+
success: boolean;
|
|
63
|
+
evictionId: string;
|
|
64
|
+
r2Key?: string;
|
|
65
|
+
bytesWritten?: number;
|
|
66
|
+
checksum?: string;
|
|
67
|
+
status?: 'prepared' | 'already_exists';
|
|
68
|
+
error?: string;
|
|
69
|
+
clientNonce: string;
|
|
70
|
+
}
|
|
71
|
+
interface ConfirmResult {
|
|
72
|
+
success: boolean;
|
|
73
|
+
status?: 'committed' | 'already_committed' | 'not_found';
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create deterministic eviction ID from messages
|
|
78
|
+
* Same messages = same evictionId (enables dedup)
|
|
79
|
+
*/
|
|
80
|
+
export declare function createEvictionId(messages: Message[]): string;
|
|
81
|
+
/**
|
|
82
|
+
* Create fingerprint for a message
|
|
83
|
+
*/
|
|
84
|
+
export declare function createFingerprint(msg: Message): string;
|
|
85
|
+
/**
|
|
86
|
+
* Check if the eviction API is available
|
|
87
|
+
* Returns true if proxy is reachable and healthy
|
|
88
|
+
*/
|
|
89
|
+
export declare function checkEvictionHealth(apiUrl: string, authToken: string): Promise<boolean>;
|
|
90
|
+
/**
|
|
91
|
+
* Prepare eviction by writing to R2 via the proxy.
|
|
92
|
+
* Returns ACK with evictionId if successful.
|
|
93
|
+
* Caller must NOT delete locally until this succeeds.
|
|
94
|
+
*/
|
|
95
|
+
export declare function prepareEviction(apiUrl: string, authToken: string, sessionId: string, sessionName: string, userId: string, tenantId: string, messages: Message[], manifest: EvictionManifest, projectPath?: string): Promise<PrepareResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Confirm eviction after local deletion.
|
|
98
|
+
* This is optional but recommended for audit completeness.
|
|
99
|
+
* Failure here is non-critical - data is already safe in R2.
|
|
100
|
+
*/
|
|
101
|
+
export declare function confirmEviction(apiUrl: string, authToken: string, evictionId: string, clientNonce: string, localDeletedCount: number): Promise<ConfirmResult>;
|
|
102
|
+
export interface HandshakeEvictionOptions {
|
|
103
|
+
apiUrl: string;
|
|
104
|
+
authToken: string;
|
|
105
|
+
sessionId: string;
|
|
106
|
+
sessionName: string;
|
|
107
|
+
userId: string;
|
|
108
|
+
tenantId: string;
|
|
109
|
+
projectPath?: string;
|
|
110
|
+
}
|
|
111
|
+
export interface HandshakeEvictionResult {
|
|
112
|
+
success: boolean;
|
|
113
|
+
evictionId: string;
|
|
114
|
+
r2Key?: string;
|
|
115
|
+
bytesWritten?: number;
|
|
116
|
+
status: 'prepared' | 'committed' | 'failed' | 'skipped';
|
|
117
|
+
error?: string;
|
|
118
|
+
clientNonce?: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Full handshake eviction - call this instead of fire-and-forget
|
|
122
|
+
*
|
|
123
|
+
* Returns:
|
|
124
|
+
* - success=true, status='prepared' → Safe to delete locally, then call confirmEviction
|
|
125
|
+
* - success=false → DO NOT delete locally
|
|
126
|
+
*/
|
|
127
|
+
export declare function handshakeEviction(messages: Message[], indices: number[], estimatedTokens: number, reason: 'threshold' | 'emergency' | 'manual', options: HandshakeEvictionOptions): Promise<HandshakeEvictionResult>;
|
|
128
|
+
declare const _default: {
|
|
129
|
+
prepareEviction: typeof prepareEviction;
|
|
130
|
+
confirmEviction: typeof confirmEviction;
|
|
131
|
+
handshakeEviction: typeof handshakeEviction;
|
|
132
|
+
checkEvictionHealth: typeof checkEvictionHealth;
|
|
133
|
+
createEvictionId: typeof createEvictionId;
|
|
134
|
+
createFingerprint: typeof createFingerprint;
|
|
135
|
+
queueEvictionForRetry: typeof queueEvictionForRetry;
|
|
136
|
+
drainRetryQueue: typeof drainRetryQueue;
|
|
137
|
+
getRetryQueueStats: typeof getRetryQueueStats;
|
|
138
|
+
};
|
|
139
|
+
export default _default;
|