@agentlensai/cli 0.10.0 → 0.11.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/__tests__/migrate.test.d.ts +8 -0
- package/dist/__tests__/migrate.test.d.ts.map +1 -0
- package/dist/__tests__/migrate.test.js +148 -0
- package/dist/__tests__/migrate.test.js.map +1 -0
- package/dist/commands/migrate.d.ts +30 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +342 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/migrate.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration CLI Tests (S-8.4)
|
|
3
|
+
*
|
|
4
|
+
* Tests for the `agentlens migrate` command: SQLite export,
|
|
5
|
+
* progress tracking, resume, and reverse migration.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
8
|
+
import { existsSync, writeFileSync, readFileSync, mkdirSync, unlinkSync, rmSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { exportFromSqlite } from '../commands/migrate.js';
|
|
12
|
+
// ═══════════════════════════════════════════
|
|
13
|
+
// SQLite Export Tests
|
|
14
|
+
// ═══════════════════════════════════════════
|
|
15
|
+
describe('S-8.4: Migration CLI', () => {
|
|
16
|
+
describe('exportFromSqlite', () => {
|
|
17
|
+
it('throws if database file not found', async () => {
|
|
18
|
+
await expect(exportFromSqlite('/nonexistent/db.sqlite')).rejects.toThrow('SQLite database not found');
|
|
19
|
+
});
|
|
20
|
+
// Note: Tests that require better-sqlite3 are integration tests.
|
|
21
|
+
// Unit tests mock at the boundary.
|
|
22
|
+
it('throws if better-sqlite3 is not available', async () => {
|
|
23
|
+
// Create a dummy file so the existence check passes
|
|
24
|
+
const tmpFile = join(tmpdir(), `test-migrate-${Date.now()}.db`);
|
|
25
|
+
writeFileSync(tmpFile, '');
|
|
26
|
+
// The import will fail because better-sqlite3 isn't typically available in test env
|
|
27
|
+
// This test verifies the error message is helpful
|
|
28
|
+
try {
|
|
29
|
+
await exportFromSqlite(tmpFile);
|
|
30
|
+
// If better-sqlite3 IS installed, the file won't be a valid SQLite DB
|
|
31
|
+
// so it will throw a different error — that's fine too
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
expect(err.message).toMatch(/better-sqlite3|not a database|SQLite/i);
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
try {
|
|
38
|
+
unlinkSync(tmpFile);
|
|
39
|
+
}
|
|
40
|
+
catch { }
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('NDJSON format', () => {
|
|
45
|
+
it('each record has _type and _version fields', () => {
|
|
46
|
+
const records = [
|
|
47
|
+
{ _type: 'agent', _version: 1, id: 'a1', name: 'Test' },
|
|
48
|
+
{ _type: 'session', _version: 1, id: 's1', agent_id: 'a1' },
|
|
49
|
+
{ _type: 'event', _version: 1, id: 'e1', session_id: 's1', type: 'llm_call' },
|
|
50
|
+
];
|
|
51
|
+
for (const rec of records) {
|
|
52
|
+
const line = JSON.stringify(rec);
|
|
53
|
+
const parsed = JSON.parse(line);
|
|
54
|
+
expect(parsed._type).toBeDefined();
|
|
55
|
+
expect(parsed._version).toBe(1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
it('checksum record has sha256 and counts', () => {
|
|
59
|
+
const checksum = {
|
|
60
|
+
_type: 'checksum',
|
|
61
|
+
sha256: 'a'.repeat(64),
|
|
62
|
+
counts: { agent: 1, session: 2, event: 5 },
|
|
63
|
+
exported_at: '2026-01-15T12:00:00Z',
|
|
64
|
+
};
|
|
65
|
+
const parsed = JSON.parse(JSON.stringify(checksum));
|
|
66
|
+
expect(parsed.sha256).toHaveLength(64);
|
|
67
|
+
expect(parsed.counts.agent).toBe(1);
|
|
68
|
+
expect(parsed.counts.session).toBe(2);
|
|
69
|
+
expect(parsed.counts.event).toBe(5);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('progress tracking', () => {
|
|
73
|
+
it('state file tracks migration progress', () => {
|
|
74
|
+
const state = {
|
|
75
|
+
direction: 'up',
|
|
76
|
+
phase: 'upload',
|
|
77
|
+
exportFile: '/tmp/export.ndjson',
|
|
78
|
+
lastUploadedLine: 250,
|
|
79
|
+
totalLines: 1000,
|
|
80
|
+
counts: { agent: 5, session: 20, event: 225 },
|
|
81
|
+
};
|
|
82
|
+
// Verify state structure is serializable
|
|
83
|
+
const serialized = JSON.stringify(state);
|
|
84
|
+
const deserialized = JSON.parse(serialized);
|
|
85
|
+
expect(deserialized.lastUploadedLine).toBe(250);
|
|
86
|
+
expect(deserialized.phase).toBe('upload');
|
|
87
|
+
});
|
|
88
|
+
it('resume starts from lastUploadedLine', () => {
|
|
89
|
+
const state = {
|
|
90
|
+
direction: 'up',
|
|
91
|
+
phase: 'upload',
|
|
92
|
+
lastUploadedLine: 500,
|
|
93
|
+
totalLines: 1000,
|
|
94
|
+
};
|
|
95
|
+
// Simulate batch calculation
|
|
96
|
+
const batchSize = 100;
|
|
97
|
+
const startLine = state.lastUploadedLine;
|
|
98
|
+
const batches = [];
|
|
99
|
+
for (let i = startLine; i < state.totalLines; i += batchSize) {
|
|
100
|
+
batches.push(i);
|
|
101
|
+
}
|
|
102
|
+
expect(batches[0]).toBe(500); // Starts from where we left off
|
|
103
|
+
expect(batches.length).toBe(5); // 500-1000 in batches of 100
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('verification', () => {
|
|
107
|
+
it('count comparison detects mismatches', () => {
|
|
108
|
+
const localCounts = { agent: 5, session: 20, event: 100 };
|
|
109
|
+
const remoteCounts = { agent: 5, session: 20, event: 95 };
|
|
110
|
+
const mismatches = [];
|
|
111
|
+
for (const [type, count] of Object.entries(localCounts)) {
|
|
112
|
+
const remote = remoteCounts[type] ?? 0;
|
|
113
|
+
if (remote < count) {
|
|
114
|
+
mismatches.push(type);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
expect(mismatches).toContain('event');
|
|
118
|
+
expect(mismatches).not.toContain('agent');
|
|
119
|
+
});
|
|
120
|
+
it('count comparison passes when all match', () => {
|
|
121
|
+
const localCounts = { agent: 5, session: 20, event: 100 };
|
|
122
|
+
const remoteCounts = { agent: 5, session: 20, event: 100 };
|
|
123
|
+
let allMatch = true;
|
|
124
|
+
for (const [type, count] of Object.entries(localCounts)) {
|
|
125
|
+
const remote = remoteCounts[type] ?? 0;
|
|
126
|
+
if (remote < count)
|
|
127
|
+
allMatch = false;
|
|
128
|
+
}
|
|
129
|
+
expect(allMatch).toBe(true);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe('reverse migration (cloud → self-hosted)', () => {
|
|
133
|
+
it('NDJSON export file can be parsed line by line', () => {
|
|
134
|
+
const ndjson = [
|
|
135
|
+
'{"_type":"agent","_version":1,"id":"a1","name":"Test"}',
|
|
136
|
+
'{"_type":"session","_version":1,"id":"s1","agent_id":"a1","created_at":"2026-01-15T10:00:00Z"}',
|
|
137
|
+
'{"_type":"event","_version":1,"id":"e1","session_id":"s1","type":"llm_call","timestamp":"2026-01-15T10:00:01Z","data":{}}',
|
|
138
|
+
'{"_type":"checksum","sha256":"abc123","counts":{"agent":1,"session":1,"event":1},"exported_at":"2026-01-15T12:00:00Z"}',
|
|
139
|
+
].join('\n');
|
|
140
|
+
const lines = ndjson.split('\n').filter(Boolean);
|
|
141
|
+
expect(lines.length).toBe(4);
|
|
142
|
+
const records = lines.map((l) => JSON.parse(l));
|
|
143
|
+
const types = records.map((r) => r._type);
|
|
144
|
+
expect(types).toEqual(['agent', 'session', 'event', 'checksum']);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=migrate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.test.js","sourceRoot":"","sources":["../../src/__tests__/migrate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentlens migrate — Self-Hosted ↔ Cloud Migration (S-8.4)
|
|
3
|
+
*
|
|
4
|
+
* Reads from local SQLite, transforms to cloud NDJSON format,
|
|
5
|
+
* and uploads via cloud API. Supports resume on failure and
|
|
6
|
+
* reverse migration (cloud → self-hosted export → SQLite import).
|
|
7
|
+
*/
|
|
8
|
+
export interface MigrateOptions {
|
|
9
|
+
direction: 'up' | 'down';
|
|
10
|
+
sqlitePath?: string;
|
|
11
|
+
cloudUrl?: string;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
batchSize?: number;
|
|
14
|
+
resumeFile?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface MigrateState {
|
|
17
|
+
direction: string;
|
|
18
|
+
phase: 'export' | 'upload' | 'verify' | 'done';
|
|
19
|
+
exportFile?: string;
|
|
20
|
+
lastUploadedLine: number;
|
|
21
|
+
totalLines: number;
|
|
22
|
+
counts: Record<string, number>;
|
|
23
|
+
}
|
|
24
|
+
export declare function runMigrateCommand(args: string[]): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Read from local SQLite and produce NDJSON lines.
|
|
27
|
+
* Uses dynamic import for better-sqlite3 so it's optional.
|
|
28
|
+
*/
|
|
29
|
+
export declare function exportFromSqlite(dbPath: string): Promise<string[]>;
|
|
30
|
+
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAYD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BrE;AAuKD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsExE"}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentlens migrate — Self-Hosted ↔ Cloud Migration (S-8.4)
|
|
3
|
+
*
|
|
4
|
+
* Reads from local SQLite, transforms to cloud NDJSON format,
|
|
5
|
+
* and uploads via cloud API. Supports resume on failure and
|
|
6
|
+
* reverse migration (cloud → self-hosted export → SQLite import).
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
11
|
+
import { createHash } from 'node:crypto';
|
|
12
|
+
import { loadConfig } from '../lib/config.js';
|
|
13
|
+
const STATE_DIR = join(homedir(), '.agentlens');
|
|
14
|
+
const DEFAULT_STATE_FILE = join(STATE_DIR, 'migrate-state.json');
|
|
15
|
+
const DEFAULT_SQLITE_PATH = join(process.cwd(), 'agentlens.db');
|
|
16
|
+
// ─── Main Command ────────────────────────────────────────────
|
|
17
|
+
export async function runMigrateCommand(args) {
|
|
18
|
+
const subcommand = args[0];
|
|
19
|
+
switch (subcommand) {
|
|
20
|
+
case 'up':
|
|
21
|
+
await migrateUp(args.slice(1));
|
|
22
|
+
break;
|
|
23
|
+
case 'down':
|
|
24
|
+
await migrateDown(args.slice(1));
|
|
25
|
+
break;
|
|
26
|
+
case 'status':
|
|
27
|
+
showMigrateStatus();
|
|
28
|
+
break;
|
|
29
|
+
case 'clean':
|
|
30
|
+
cleanMigrateState();
|
|
31
|
+
break;
|
|
32
|
+
case '--help':
|
|
33
|
+
case '-h':
|
|
34
|
+
case undefined:
|
|
35
|
+
showHelp();
|
|
36
|
+
break;
|
|
37
|
+
default:
|
|
38
|
+
console.error(`Unknown migrate subcommand: ${subcommand}`);
|
|
39
|
+
showHelp();
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function showHelp() {
|
|
44
|
+
console.log(`agentlens migrate — Self-Hosted ↔ Cloud Migration
|
|
45
|
+
|
|
46
|
+
Usage:
|
|
47
|
+
agentlens migrate up [options] Migrate self-hosted SQLite → Cloud
|
|
48
|
+
agentlens migrate down [options] Export Cloud → local NDJSON file
|
|
49
|
+
agentlens migrate status Show current migration state
|
|
50
|
+
agentlens migrate clean Remove migration state file
|
|
51
|
+
|
|
52
|
+
Options (up):
|
|
53
|
+
--db <path> SQLite database path (default: ./agentlens.db)
|
|
54
|
+
--batch-size <n> Records per upload batch (default: 500)
|
|
55
|
+
--resume Resume a previously interrupted migration
|
|
56
|
+
|
|
57
|
+
Options (down):
|
|
58
|
+
--output <path> Output NDJSON file (default: ./agentlens-export.ndjson)
|
|
59
|
+
|
|
60
|
+
Common:
|
|
61
|
+
--url <url> Cloud API URL (overrides config)
|
|
62
|
+
--api-key <key> Cloud API key (overrides config)
|
|
63
|
+
`);
|
|
64
|
+
}
|
|
65
|
+
// ─── Migrate Up (Self-Hosted → Cloud) ────────────────────────
|
|
66
|
+
async function migrateUp(args) {
|
|
67
|
+
const options = parseArgs(args);
|
|
68
|
+
const sqlitePath = options['db'] ?? DEFAULT_SQLITE_PATH;
|
|
69
|
+
const batchSize = parseInt(options['batch-size'] ?? '500', 10);
|
|
70
|
+
const resume = args.includes('--resume');
|
|
71
|
+
const config = loadConfig();
|
|
72
|
+
const cloudUrl = options['url'] ?? config.url;
|
|
73
|
+
const apiKey = options['api-key'] ?? config.apiKey;
|
|
74
|
+
if (!apiKey) {
|
|
75
|
+
console.error('Error: API key required. Set via `agentlens config set api-key <key>` or --api-key');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
// Check for resume state
|
|
79
|
+
let state = null;
|
|
80
|
+
if (resume && existsSync(DEFAULT_STATE_FILE)) {
|
|
81
|
+
state = JSON.parse(readFileSync(DEFAULT_STATE_FILE, 'utf-8'));
|
|
82
|
+
console.log(`Resuming migration from line ${state.lastUploadedLine}/${state.totalLines}`);
|
|
83
|
+
}
|
|
84
|
+
// Phase 1: Export from SQLite
|
|
85
|
+
let ndjsonLines;
|
|
86
|
+
if (state?.exportFile && existsSync(state.exportFile)) {
|
|
87
|
+
console.log('Using cached export file...');
|
|
88
|
+
ndjsonLines = readFileSync(state.exportFile, 'utf-8').split('\n').filter(Boolean);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.log(`Exporting from SQLite: ${sqlitePath}`);
|
|
92
|
+
ndjsonLines = await exportFromSqlite(sqlitePath);
|
|
93
|
+
// Cache export
|
|
94
|
+
const exportFile = join(STATE_DIR, 'migrate-export.ndjson');
|
|
95
|
+
writeFileSync(exportFile, ndjsonLines.join('\n') + '\n', 'utf-8');
|
|
96
|
+
state = {
|
|
97
|
+
direction: 'up',
|
|
98
|
+
phase: 'upload',
|
|
99
|
+
exportFile,
|
|
100
|
+
lastUploadedLine: 0,
|
|
101
|
+
totalLines: ndjsonLines.length,
|
|
102
|
+
counts: {},
|
|
103
|
+
};
|
|
104
|
+
saveState(state);
|
|
105
|
+
console.log(`Exported ${ndjsonLines.length} records`);
|
|
106
|
+
}
|
|
107
|
+
// Phase 2: Upload to cloud in batches
|
|
108
|
+
const startLine = state?.lastUploadedLine ?? 0;
|
|
109
|
+
const total = ndjsonLines.length;
|
|
110
|
+
let uploaded = startLine;
|
|
111
|
+
for (let i = startLine; i < total; i += batchSize) {
|
|
112
|
+
const batch = ndjsonLines.slice(i, Math.min(i + batchSize, total));
|
|
113
|
+
const progress = Math.min(100, Math.round(((i + batch.length) / total) * 100));
|
|
114
|
+
process.stdout.write(`\rUploading... ${progressBar(progress)} ${progress}% (${i + batch.length}/${total})`);
|
|
115
|
+
await uploadBatch(cloudUrl, apiKey, batch);
|
|
116
|
+
uploaded = i + batch.length;
|
|
117
|
+
// Save progress for resume
|
|
118
|
+
state.lastUploadedLine = uploaded;
|
|
119
|
+
saveState(state);
|
|
120
|
+
}
|
|
121
|
+
console.log('\n');
|
|
122
|
+
// Phase 3: Verify
|
|
123
|
+
state.phase = 'verify';
|
|
124
|
+
saveState(state);
|
|
125
|
+
console.log('Verifying migration...');
|
|
126
|
+
const verified = await verifyMigration(cloudUrl, apiKey, ndjsonLines);
|
|
127
|
+
if (verified) {
|
|
128
|
+
console.log('✅ Migration verified successfully!');
|
|
129
|
+
state.phase = 'done';
|
|
130
|
+
saveState(state);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log('⚠️ Verification found count mismatches. Run `agentlens migrate status` for details.');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// ─── Migrate Down (Cloud → Self-Hosted) ─────────────────────
|
|
137
|
+
async function migrateDown(args) {
|
|
138
|
+
const options = parseArgs(args);
|
|
139
|
+
const outputPath = options['output'] ?? join(process.cwd(), 'agentlens-export.ndjson');
|
|
140
|
+
const config = loadConfig();
|
|
141
|
+
const cloudUrl = options['url'] ?? config.url;
|
|
142
|
+
const apiKey = options['api-key'] ?? config.apiKey;
|
|
143
|
+
if (!apiKey) {
|
|
144
|
+
console.error('Error: API key required.');
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
console.log('Exporting from cloud...');
|
|
148
|
+
const response = await fetch(`${cloudUrl}/api/export`, {
|
|
149
|
+
headers: {
|
|
150
|
+
Authorization: `Bearer ${apiKey}`,
|
|
151
|
+
Accept: 'application/x-ndjson',
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
console.error(`Export failed: ${response.status} ${response.statusText}`);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
const body = await response.text();
|
|
159
|
+
writeFileSync(outputPath, body, 'utf-8');
|
|
160
|
+
const lineCount = body.split('\n').filter(Boolean).length;
|
|
161
|
+
console.log(`✅ Exported ${lineCount} records to ${outputPath}`);
|
|
162
|
+
}
|
|
163
|
+
// ─── Status & Clean ──────────────────────────────────────────
|
|
164
|
+
function showMigrateStatus() {
|
|
165
|
+
if (!existsSync(DEFAULT_STATE_FILE)) {
|
|
166
|
+
console.log('No migration in progress.');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const state = JSON.parse(readFileSync(DEFAULT_STATE_FILE, 'utf-8'));
|
|
170
|
+
console.log(`Migration status:
|
|
171
|
+
Direction: ${state.direction}
|
|
172
|
+
Phase: ${state.phase}
|
|
173
|
+
Progress: ${state.lastUploadedLine}/${state.totalLines} records
|
|
174
|
+
${state.phase === 'done' ? '✅ Complete' : '⏳ In progress'}`);
|
|
175
|
+
}
|
|
176
|
+
function cleanMigrateState() {
|
|
177
|
+
if (existsSync(DEFAULT_STATE_FILE)) {
|
|
178
|
+
unlinkSync(DEFAULT_STATE_FILE);
|
|
179
|
+
console.log('Migration state cleaned.');
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.log('No migration state to clean.');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// ─── SQLite Export ───────────────────────────────────────────
|
|
186
|
+
/**
|
|
187
|
+
* Read from local SQLite and produce NDJSON lines.
|
|
188
|
+
* Uses dynamic import for better-sqlite3 so it's optional.
|
|
189
|
+
*/
|
|
190
|
+
export async function exportFromSqlite(dbPath) {
|
|
191
|
+
if (!existsSync(dbPath)) {
|
|
192
|
+
throw new Error(`SQLite database not found: ${dbPath}`);
|
|
193
|
+
}
|
|
194
|
+
// Dynamic import — better-sqlite3 is optional dep
|
|
195
|
+
let Database;
|
|
196
|
+
try {
|
|
197
|
+
const modName = 'better-sqlite3';
|
|
198
|
+
const mod = await import(modName);
|
|
199
|
+
Database = mod.default ?? mod;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
throw new Error('better-sqlite3 is required for SQLite migration. Install it: npm install better-sqlite3');
|
|
203
|
+
}
|
|
204
|
+
const db = new Database(dbPath, { readonly: true });
|
|
205
|
+
const lines = [];
|
|
206
|
+
try {
|
|
207
|
+
// Agents
|
|
208
|
+
const agents = safeAll(db, 'SELECT * FROM agents ORDER BY id');
|
|
209
|
+
for (const row of agents) {
|
|
210
|
+
lines.push(JSON.stringify({ _type: 'agent', _version: 1, ...row }));
|
|
211
|
+
}
|
|
212
|
+
// Sessions
|
|
213
|
+
const sessions = safeAll(db, 'SELECT * FROM sessions ORDER BY created_at');
|
|
214
|
+
for (const row of sessions) {
|
|
215
|
+
lines.push(JSON.stringify({ _type: 'session', _version: 1, ...parseJsonFields(row, ['metadata']) }));
|
|
216
|
+
}
|
|
217
|
+
// Events
|
|
218
|
+
const events = safeAll(db, 'SELECT * FROM events ORDER BY timestamp');
|
|
219
|
+
for (const row of events) {
|
|
220
|
+
lines.push(JSON.stringify({ _type: 'event', _version: 1, ...parseJsonFields(row, ['data']) }));
|
|
221
|
+
}
|
|
222
|
+
// Health scores
|
|
223
|
+
const healthScores = safeAll(db, 'SELECT * FROM health_scores ORDER BY timestamp');
|
|
224
|
+
for (const row of healthScores) {
|
|
225
|
+
lines.push(JSON.stringify({ _type: 'health_score', _version: 1, ...parseJsonFields(row, ['dimensions', 'metadata']) }));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
db.close();
|
|
230
|
+
}
|
|
231
|
+
// Add checksum
|
|
232
|
+
const hash = createHash('sha256');
|
|
233
|
+
for (const line of lines) {
|
|
234
|
+
hash.update(line + '\n');
|
|
235
|
+
}
|
|
236
|
+
const counts = {};
|
|
237
|
+
for (const line of lines) {
|
|
238
|
+
const type = JSON.parse(line)._type;
|
|
239
|
+
counts[type] = (counts[type] ?? 0) + 1;
|
|
240
|
+
}
|
|
241
|
+
lines.push(JSON.stringify({
|
|
242
|
+
_type: 'checksum',
|
|
243
|
+
sha256: hash.digest('hex'),
|
|
244
|
+
counts,
|
|
245
|
+
exported_at: new Date().toISOString(),
|
|
246
|
+
}));
|
|
247
|
+
return lines;
|
|
248
|
+
}
|
|
249
|
+
// ─── Upload Helpers ──────────────────────────────────────────
|
|
250
|
+
async function uploadBatch(cloudUrl, apiKey, lines) {
|
|
251
|
+
const body = lines.join('\n') + '\n';
|
|
252
|
+
const response = await fetch(`${cloudUrl}/api/import`, {
|
|
253
|
+
method: 'POST',
|
|
254
|
+
headers: {
|
|
255
|
+
Authorization: `Bearer ${apiKey}`,
|
|
256
|
+
'Content-Type': 'application/x-ndjson',
|
|
257
|
+
},
|
|
258
|
+
body,
|
|
259
|
+
});
|
|
260
|
+
if (!response.ok) {
|
|
261
|
+
const text = await response.text().catch(() => '');
|
|
262
|
+
throw new Error(`Upload failed: ${response.status} ${response.statusText} ${text}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async function verifyMigration(cloudUrl, apiKey, ndjsonLines) {
|
|
266
|
+
// Count local records by type
|
|
267
|
+
const localCounts = {};
|
|
268
|
+
for (const line of ndjsonLines) {
|
|
269
|
+
try {
|
|
270
|
+
const parsed = JSON.parse(line);
|
|
271
|
+
if (parsed._type && parsed._type !== 'checksum') {
|
|
272
|
+
localCounts[parsed._type] = (localCounts[parsed._type] ?? 0) + 1;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch { /* skip */ }
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
const response = await fetch(`${cloudUrl}/api/export/counts`, {
|
|
279
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
280
|
+
});
|
|
281
|
+
if (!response.ok)
|
|
282
|
+
return false;
|
|
283
|
+
const remoteCounts = (await response.json());
|
|
284
|
+
let allMatch = true;
|
|
285
|
+
for (const [type, count] of Object.entries(localCounts)) {
|
|
286
|
+
const remote = remoteCounts[type] ?? 0;
|
|
287
|
+
if (remote < count) {
|
|
288
|
+
console.log(` ⚠️ ${type}: local=${count}, cloud=${remote}`);
|
|
289
|
+
allMatch = false;
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
console.log(` ✓ ${type}: ${remote} records`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return allMatch;
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
console.log(' Could not verify (API error). Check manually.');
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// ─── Utility ─────────────────────────────────────────────────
|
|
303
|
+
function progressBar(pct) {
|
|
304
|
+
const filled = Math.round(pct / 5);
|
|
305
|
+
return '[' + '█'.repeat(filled) + '░'.repeat(20 - filled) + ']';
|
|
306
|
+
}
|
|
307
|
+
function saveState(state) {
|
|
308
|
+
const { mkdirSync } = require('node:fs');
|
|
309
|
+
mkdirSync(STATE_DIR, { recursive: true });
|
|
310
|
+
writeFileSync(DEFAULT_STATE_FILE, JSON.stringify(state, null, 2), 'utf-8');
|
|
311
|
+
}
|
|
312
|
+
function parseArgs(args) {
|
|
313
|
+
const result = {};
|
|
314
|
+
for (let i = 0; i < args.length; i++) {
|
|
315
|
+
if (args[i].startsWith('--') && i + 1 < args.length && !args[i + 1].startsWith('--')) {
|
|
316
|
+
result[args[i].slice(2)] = args[i + 1];
|
|
317
|
+
i++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
function safeAll(db, sql) {
|
|
323
|
+
try {
|
|
324
|
+
return db.prepare(sql).all();
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
return [];
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function parseJsonFields(row, fields) {
|
|
331
|
+
const result = { ...row };
|
|
332
|
+
for (const field of fields) {
|
|
333
|
+
if (typeof result[field] === 'string') {
|
|
334
|
+
try {
|
|
335
|
+
result[field] = JSON.parse(result[field]);
|
|
336
|
+
}
|
|
337
|
+
catch { /* keep as string */ }
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return result;
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { runRecallCommand } from './commands/recall.js';
|
|
|
16
16
|
import { runReflectCommand } from './commands/reflect.js';
|
|
17
17
|
import { runSessionsCommand } from './commands/sessions.js';
|
|
18
18
|
import { runTailCommand } from './commands/tail.js';
|
|
19
|
+
import { runMigrateCommand } from './commands/migrate.js';
|
|
19
20
|
const HELP = `AgentLens CLI — Observability for AI agents
|
|
20
21
|
|
|
21
22
|
Usage: agentlens <command> [options]
|
|
@@ -28,6 +29,7 @@ Commands:
|
|
|
28
29
|
health Agent health scores and trends
|
|
29
30
|
lessons Manage agent lessons (list, create, get, update, delete, search)
|
|
30
31
|
llm LLM call tracking (stats, models, recent)
|
|
32
|
+
migrate Migrate data between self-hosted and cloud
|
|
31
33
|
optimize Cost optimization recommendations
|
|
32
34
|
recall Semantic search over agent memory
|
|
33
35
|
reflect Pattern analysis across agent sessions
|
|
@@ -67,6 +69,9 @@ async function main() {
|
|
|
67
69
|
case 'llm':
|
|
68
70
|
await runLlmCommand(rest);
|
|
69
71
|
break;
|
|
72
|
+
case 'migrate':
|
|
73
|
+
await runMigrateCommand(rest);
|
|
74
|
+
break;
|
|
70
75
|
case 'optimize':
|
|
71
76
|
await runOptimizeCommand(rest);
|
|
72
77
|
break;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|