@ai-dossier/cli 0.83.1 → 0.84.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 +31 -6
- package/dist/commands/sched.d.ts.map +1 -1
- package/dist/commands/sched.js +8 -1
- package/dist/commands/sched.js.map +1 -1
- package/dist/commands/usage.d.ts +22 -1
- package/dist/commands/usage.d.ts.map +1 -1
- package/dist/commands/usage.js +202 -17
- package/dist/commands/usage.js.map +1 -1
- package/dist/dry-run-render.d.ts.map +1 -1
- package/dist/dry-run-render.js +8 -1
- package/dist/dry-run-render.js.map +1 -1
- package/dist/sched-run-stats.d.ts +4 -0
- package/dist/sched-run-stats.d.ts.map +1 -1
- package/dist/sched-run-stats.js +1 -1
- package/dist/sched-run-stats.js.map +1 -1
- package/dist/usage/batch-prep.d.ts +50 -11
- package/dist/usage/batch-prep.d.ts.map +1 -1
- package/dist/usage/batch-prep.js +158 -22
- package/dist/usage/batch-prep.js.map +1 -1
- package/dist/usage/ledger.js +1 -1
- package/dist/usage/ledger.js.map +1 -1
- package/dist/usage/store.d.ts +110 -0
- package/dist/usage/store.d.ts.map +1 -0
- package/dist/usage/store.js +445 -0
- package/dist/usage/store.js.map +1 -0
- package/dist/usage/sync.d.ts +67 -0
- package/dist/usage/sync.d.ts.map +1 -0
- package/dist/usage/sync.js +223 -0
- package/dist/usage/sync.js.map +1 -0
- package/dist/usage/types.d.ts +6 -0
- package/dist/usage/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Persisted, mergeable usage ledger (#782).
|
|
4
|
+
*
|
|
5
|
+
* `ai-dossier usage` (#769) derives rows on demand from stores that rotate
|
|
6
|
+
* (Claude Code transcripts are purged) and that live on one host. The store
|
|
7
|
+
* persists them under `~/.dossier/usage/hosts/<host>.jsonl` — ONE FILE PER HOST,
|
|
8
|
+
* so merging hosts can never conflict: a host's file is only rewritten from that
|
|
9
|
+
* host's own collection, or from an import of that same host's bundle.
|
|
10
|
+
*
|
|
11
|
+
* Records are keyed by a stable content key ({@link rowKey}); re-collecting or
|
|
12
|
+
* re-importing the same rows replaces them in place, so every operation is
|
|
13
|
+
* idempotent. The wire format between hosts ("bundle") is the same JSONL.
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.Parser = exports.BUNDLE_VERSION = void 0;
|
|
50
|
+
exports.usageStoreDir = usageStoreDir;
|
|
51
|
+
exports.localHostId = localHostId;
|
|
52
|
+
exports.isValidHostId = isValidHostId;
|
|
53
|
+
exports.hostFile = hostFile;
|
|
54
|
+
exports.rowKey = rowKey;
|
|
55
|
+
exports.limitKey = limitKey;
|
|
56
|
+
exports.emptyHostData = emptyHostData;
|
|
57
|
+
exports.readHostFile = readHostFile;
|
|
58
|
+
exports.listHosts = listHosts;
|
|
59
|
+
exports.writeHostFile = writeHostFile;
|
|
60
|
+
exports.withHostLock = withHostLock;
|
|
61
|
+
exports.mergeHostData = mergeHostData;
|
|
62
|
+
exports.persistLocal = persistLocal;
|
|
63
|
+
exports.newestTs = newestTs;
|
|
64
|
+
exports.buildBundle = buildBundle;
|
|
65
|
+
exports.importBundle = importBundle;
|
|
66
|
+
exports.mergedView = mergedView;
|
|
67
|
+
const node_crypto_1 = require("node:crypto");
|
|
68
|
+
const fs = __importStar(require("node:fs"));
|
|
69
|
+
const os = __importStar(require("node:os"));
|
|
70
|
+
const path = __importStar(require("node:path"));
|
|
71
|
+
const util_1 = require("./util");
|
|
72
|
+
exports.BUNDLE_VERSION = 1;
|
|
73
|
+
/** Root of the persisted ledger. */
|
|
74
|
+
function usageStoreDir(env = process.env) {
|
|
75
|
+
return env.DOSSIER_USAGE_DIR || path.join(os.homedir(), '.dossier', 'usage');
|
|
76
|
+
}
|
|
77
|
+
/** This host's id in rows — `DOSSIER_USAGE_HOST` overrides `os.hostname()` (e.g. to force `wls`). */
|
|
78
|
+
function localHostId(env = process.env) {
|
|
79
|
+
return env.DOSSIER_USAGE_HOST || os.hostname();
|
|
80
|
+
}
|
|
81
|
+
const HOST_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/;
|
|
82
|
+
function isValidHostId(host) {
|
|
83
|
+
return HOST_RE.test(host);
|
|
84
|
+
}
|
|
85
|
+
function hostFile(dir, host) {
|
|
86
|
+
return path.join(dir, 'hosts', `${host}.jsonl`);
|
|
87
|
+
}
|
|
88
|
+
const sha = (parts) => (0, node_crypto_1.createHash)('sha1')
|
|
89
|
+
.update(parts.map((p) => (p === null ? '' : String(p))).join('\u0000'))
|
|
90
|
+
.digest('hex')
|
|
91
|
+
.slice(0, 20);
|
|
92
|
+
/**
|
|
93
|
+
* Stable identity of a row: the message it was read from, not the attribution
|
|
94
|
+
* later joined onto it (issue/batch/unit may be refined by a re-collection).
|
|
95
|
+
*/
|
|
96
|
+
function rowKey(r) {
|
|
97
|
+
return sha([
|
|
98
|
+
r.host,
|
|
99
|
+
r.source,
|
|
100
|
+
r.session_id,
|
|
101
|
+
r.ts,
|
|
102
|
+
r.model,
|
|
103
|
+
r.input,
|
|
104
|
+
r.output,
|
|
105
|
+
r.reasoning,
|
|
106
|
+
r.cache_read,
|
|
107
|
+
r.cache_write,
|
|
108
|
+
]);
|
|
109
|
+
}
|
|
110
|
+
function limitKey(l) {
|
|
111
|
+
return sha([l.host, l.source, l.ts, l.session_id, l.unit, l.status, l.detail]);
|
|
112
|
+
}
|
|
113
|
+
function emptyHostData() {
|
|
114
|
+
return { rows: new Map(), limits: new Map(), at: new Map() };
|
|
115
|
+
}
|
|
116
|
+
function isRow(v) {
|
|
117
|
+
const r = v;
|
|
118
|
+
return (!!r &&
|
|
119
|
+
typeof r.ts === 'string' &&
|
|
120
|
+
!Number.isNaN(Date.parse(r.ts)) &&
|
|
121
|
+
typeof r.host === 'string' &&
|
|
122
|
+
isValidHostId(r.host) &&
|
|
123
|
+
typeof r.session_id === 'string' &&
|
|
124
|
+
typeof r.source === 'string' &&
|
|
125
|
+
typeof r.provider === 'string' &&
|
|
126
|
+
[r.input, r.output, r.reasoning, r.cache_read, r.cache_write].every((n) => typeof n === 'number' && Number.isFinite(n)));
|
|
127
|
+
}
|
|
128
|
+
function isLimit(v) {
|
|
129
|
+
const l = v;
|
|
130
|
+
return (!!l &&
|
|
131
|
+
typeof l.ts === 'string' &&
|
|
132
|
+
!Number.isNaN(Date.parse(l.ts)) &&
|
|
133
|
+
typeof l.host === 'string' &&
|
|
134
|
+
isValidHostId(l.host) &&
|
|
135
|
+
typeof l.detail === 'string');
|
|
136
|
+
}
|
|
137
|
+
/** Parse JSONL text/lines into per-host data. Foreign or malformed lines are counted, never thrown. */
|
|
138
|
+
class Parser {
|
|
139
|
+
byHost = new Map();
|
|
140
|
+
skipped = 0;
|
|
141
|
+
header = null;
|
|
142
|
+
add(line) {
|
|
143
|
+
let rec;
|
|
144
|
+
try {
|
|
145
|
+
rec = JSON.parse(line);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
this.skipped++;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (!rec || typeof rec !== 'object') {
|
|
152
|
+
this.skipped++;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (rec.k === 'header') {
|
|
156
|
+
this.header = { version: rec.version, host: rec.host };
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (rec.k === 'row' && isRow(rec.row)) {
|
|
160
|
+
const d = this.data(rec.row.host);
|
|
161
|
+
const key = rowKey(rec.row);
|
|
162
|
+
d.rows.set(key, rec.row);
|
|
163
|
+
if (typeof rec.at === 'string')
|
|
164
|
+
d.at.set(key, rec.at);
|
|
165
|
+
}
|
|
166
|
+
else if (rec.k === 'limit' && isLimit(rec.limit)) {
|
|
167
|
+
const d = this.data(rec.limit.host);
|
|
168
|
+
const key = limitKey(rec.limit);
|
|
169
|
+
d.limits.set(key, rec.limit);
|
|
170
|
+
if (typeof rec.at === 'string')
|
|
171
|
+
d.at.set(key, rec.at);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
this.skipped++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
data(host) {
|
|
178
|
+
let d = this.byHost.get(host);
|
|
179
|
+
if (!d) {
|
|
180
|
+
d = emptyHostData();
|
|
181
|
+
this.byHost.set(host, d);
|
|
182
|
+
}
|
|
183
|
+
return d;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.Parser = Parser;
|
|
187
|
+
/** Read one host's file. A missing file is an empty ledger. */
|
|
188
|
+
function readHostFile(file) {
|
|
189
|
+
const p = new Parser();
|
|
190
|
+
(0, util_1.forEachLine)(file, (line) => p.add(line));
|
|
191
|
+
return p.byHost.values().next().value ?? emptyHostData();
|
|
192
|
+
}
|
|
193
|
+
/** Hosts that have a persisted file. */
|
|
194
|
+
function listHosts(dir) {
|
|
195
|
+
try {
|
|
196
|
+
return fs
|
|
197
|
+
.readdirSync(path.join(dir, 'hosts'))
|
|
198
|
+
.filter((f) => f.endsWith('.jsonl'))
|
|
199
|
+
.map((f) => f.slice(0, -'.jsonl'.length))
|
|
200
|
+
.filter(isValidHostId)
|
|
201
|
+
.sort();
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function serialize(data) {
|
|
208
|
+
const rows = [...data.rows.entries()].sort((a, b) => a[1].ts.localeCompare(b[1].ts) || a[0].localeCompare(b[0]));
|
|
209
|
+
const limits = [...data.limits.entries()].sort((a, b) => a[1].ts.localeCompare(b[1].ts) || a[0].localeCompare(b[0]));
|
|
210
|
+
const out = [];
|
|
211
|
+
for (const [key, row] of rows)
|
|
212
|
+
out.push(JSON.stringify({ k: 'row', key, row, at: data.at.get(key) }));
|
|
213
|
+
for (const [key, limit] of limits) {
|
|
214
|
+
out.push(JSON.stringify({ k: 'limit', key, limit, at: data.at.get(key) }));
|
|
215
|
+
}
|
|
216
|
+
return out.length ? `${out.join('\n')}\n` : '';
|
|
217
|
+
}
|
|
218
|
+
/** Atomic rewrite (tmp + fsync + rename) so a concurrent reader never sees a torn file. */
|
|
219
|
+
function writeHostFile(file, data) {
|
|
220
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
221
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
222
|
+
const fd = fs.openSync(tmp, 'w', 0o600);
|
|
223
|
+
try {
|
|
224
|
+
fs.writeSync(fd, serialize(data));
|
|
225
|
+
fs.fsyncSync(fd);
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
fs.closeSync(fd);
|
|
229
|
+
}
|
|
230
|
+
fs.renameSync(tmp, file);
|
|
231
|
+
}
|
|
232
|
+
const LOCK_WAIT_MS = 10_000;
|
|
233
|
+
const LOCK_STALE_MS = 60_000;
|
|
234
|
+
/**
|
|
235
|
+
* Serialize read-merge-write cycles on one host file across processes (a cron
|
|
236
|
+
* `usage sync` racing an interactive one, or a sync racing an `import`): the
|
|
237
|
+
* rename keeps readers safe, the lock keeps two writers from losing each other's rows.
|
|
238
|
+
*/
|
|
239
|
+
function withHostLock(file, fn) {
|
|
240
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
241
|
+
const lock = `${file}.lock`;
|
|
242
|
+
const deadline = Date.now() + LOCK_WAIT_MS;
|
|
243
|
+
for (;;) {
|
|
244
|
+
try {
|
|
245
|
+
fs.closeSync(fs.openSync(lock, 'wx'));
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
if (err.code !== 'EEXIST')
|
|
250
|
+
throw err;
|
|
251
|
+
try {
|
|
252
|
+
if (Date.now() - fs.statSync(lock).mtimeMs > LOCK_STALE_MS)
|
|
253
|
+
fs.rmSync(lock, { force: true });
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
// released between the two calls
|
|
257
|
+
}
|
|
258
|
+
if (Date.now() > deadline)
|
|
259
|
+
throw new Error(`timed out waiting for ${lock}`);
|
|
260
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
return fn();
|
|
265
|
+
}
|
|
266
|
+
finally {
|
|
267
|
+
fs.rmSync(lock, { force: true });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/** Upsert `incoming` into `target`: the copy with the newer `at` wins; equal content is unchanged. */
|
|
271
|
+
function mergeHostData(target, incoming) {
|
|
272
|
+
const stats = { added: 0, updated: 0, unchanged: 0 };
|
|
273
|
+
const upsert = (into, from) => {
|
|
274
|
+
for (const [key, value] of from) {
|
|
275
|
+
const prior = into.get(key);
|
|
276
|
+
const inAt = incoming.at.get(key) ?? '';
|
|
277
|
+
if (prior === undefined) {
|
|
278
|
+
stats.added++;
|
|
279
|
+
}
|
|
280
|
+
else if (JSON.stringify(prior) === JSON.stringify(value)) {
|
|
281
|
+
stats.unchanged++;
|
|
282
|
+
if (inAt > (target.at.get(key) ?? ''))
|
|
283
|
+
target.at.set(key, inAt);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
else if (inAt > (target.at.get(key) ?? '')) {
|
|
287
|
+
stats.updated++;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
stats.unchanged++; // a stale relay of a record we already hold newer
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
into.set(key, value);
|
|
294
|
+
target.at.set(key, inAt);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
upsert(target.rows, incoming.rows);
|
|
298
|
+
upsert(target.limits, incoming.limits);
|
|
299
|
+
return stats;
|
|
300
|
+
}
|
|
301
|
+
/** Persist a fresh collection of THIS host's rows/limits into its file (idempotent). */
|
|
302
|
+
function persistLocal(dir, host, rows, limits) {
|
|
303
|
+
const file = hostFile(dir, host);
|
|
304
|
+
return withHostLock(file, () => {
|
|
305
|
+
const data = readHostFile(file);
|
|
306
|
+
const at = new Date().toISOString();
|
|
307
|
+
const fresh = emptyHostData();
|
|
308
|
+
for (const r of rows) {
|
|
309
|
+
if (r.host !== host)
|
|
310
|
+
continue;
|
|
311
|
+
const key = rowKey(r);
|
|
312
|
+
fresh.rows.set(key, r);
|
|
313
|
+
fresh.at.set(key, at);
|
|
314
|
+
}
|
|
315
|
+
for (const l of limits) {
|
|
316
|
+
if (l.host !== host)
|
|
317
|
+
continue;
|
|
318
|
+
const key = limitKey(l);
|
|
319
|
+
fresh.limits.set(key, l);
|
|
320
|
+
fresh.at.set(key, at);
|
|
321
|
+
}
|
|
322
|
+
const stats = mergeHostData(data, fresh);
|
|
323
|
+
if (stats.added > 0 || stats.updated > 0 || !fs.existsSync(file))
|
|
324
|
+
writeHostFile(file, data);
|
|
325
|
+
return { ...stats, total: data.rows.size };
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
/** Newest persisted row time for a host, or null — the incremental-sync cursor. */
|
|
329
|
+
function newestTs(dir, host) {
|
|
330
|
+
let max = null;
|
|
331
|
+
for (const r of readHostFile(hostFile(dir, host)).rows.values()) {
|
|
332
|
+
const t = Date.parse(r.ts);
|
|
333
|
+
if (max === null || t > max)
|
|
334
|
+
max = t;
|
|
335
|
+
}
|
|
336
|
+
return max;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Bundle text: a header line then every record of the chosen hosts with
|
|
340
|
+
* `ts >= sinceMs`. `hosts` null = every persisted host.
|
|
341
|
+
*/
|
|
342
|
+
function buildBundle(dir, from, hosts, sinceMs) {
|
|
343
|
+
const out = [
|
|
344
|
+
JSON.stringify({
|
|
345
|
+
k: 'header',
|
|
346
|
+
version: exports.BUNDLE_VERSION,
|
|
347
|
+
host: from,
|
|
348
|
+
exported_at: new Date().toISOString(),
|
|
349
|
+
}),
|
|
350
|
+
];
|
|
351
|
+
let rows = 0;
|
|
352
|
+
for (const host of hosts ?? listHosts(dir)) {
|
|
353
|
+
const data = readHostFile(hostFile(dir, host));
|
|
354
|
+
for (const [key, row] of data.rows) {
|
|
355
|
+
if (Date.parse(row.ts) < sinceMs)
|
|
356
|
+
continue;
|
|
357
|
+
out.push(JSON.stringify({ k: 'row', key, row, at: data.at.get(key) }));
|
|
358
|
+
rows++;
|
|
359
|
+
}
|
|
360
|
+
for (const [key, limit] of data.limits) {
|
|
361
|
+
if (Date.parse(limit.ts) < sinceMs)
|
|
362
|
+
continue;
|
|
363
|
+
out.push(JSON.stringify({ k: 'limit', key, limit, at: data.at.get(key) }));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return { text: `${out.join('\n')}\n`, rows };
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Merge a bundle into the store, one file per source host. Records for
|
|
370
|
+
* `localHost` are ignored (the local collection is authoritative, and it stops a
|
|
371
|
+
* pushed bundle echoing our own rows back). Idempotent.
|
|
372
|
+
*/
|
|
373
|
+
function importBundle(dir, text, localHost) {
|
|
374
|
+
const parser = new Parser();
|
|
375
|
+
for (const line of text.split('\n'))
|
|
376
|
+
if (line)
|
|
377
|
+
parser.add(line);
|
|
378
|
+
if (parser.header && parser.header.version > exports.BUNDLE_VERSION) {
|
|
379
|
+
throw new Error(`bundle version ${parser.header.version} is newer than this CLI understands (${exports.BUNDLE_VERSION}) — upgrade @ai-dossier/cli`);
|
|
380
|
+
}
|
|
381
|
+
const result = {
|
|
382
|
+
added: 0,
|
|
383
|
+
updated: 0,
|
|
384
|
+
unchanged: 0,
|
|
385
|
+
hosts: [],
|
|
386
|
+
from: parser.header?.host ?? null,
|
|
387
|
+
skipped: parser.skipped,
|
|
388
|
+
ignored_local: 0,
|
|
389
|
+
};
|
|
390
|
+
for (const [host, incoming] of parser.byHost) {
|
|
391
|
+
if (host === localHost) {
|
|
392
|
+
result.ignored_local += incoming.rows.size + incoming.limits.size;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const file = hostFile(dir, host);
|
|
396
|
+
const stats = withHostLock(file, () => {
|
|
397
|
+
const data = readHostFile(file);
|
|
398
|
+
const merged = mergeHostData(data, incoming);
|
|
399
|
+
if (merged.added > 0 || merged.updated > 0)
|
|
400
|
+
writeHostFile(file, data);
|
|
401
|
+
return merged;
|
|
402
|
+
});
|
|
403
|
+
result.added += stats.added;
|
|
404
|
+
result.updated += stats.updated;
|
|
405
|
+
result.unchanged += stats.unchanged;
|
|
406
|
+
result.hosts.push(host);
|
|
407
|
+
}
|
|
408
|
+
result.hosts.sort();
|
|
409
|
+
return result;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Rows/limits for a report: the fresh local collection unioned with everything
|
|
413
|
+
* persisted (fresh wins per key), restricted to `hosts` (null = all).
|
|
414
|
+
*/
|
|
415
|
+
function mergedView(dir, localHost, fresh, hosts, sinceMs, untilMs) {
|
|
416
|
+
const inRange = (ts) => {
|
|
417
|
+
const t = Date.parse(ts);
|
|
418
|
+
return t >= sinceMs && t < untilMs;
|
|
419
|
+
};
|
|
420
|
+
const want = (h) => hosts === null || hosts.includes(h);
|
|
421
|
+
const rows = new Map();
|
|
422
|
+
const limits = new Map();
|
|
423
|
+
for (const h of listHosts(dir)) {
|
|
424
|
+
if (!want(h))
|
|
425
|
+
continue;
|
|
426
|
+
const d = readHostFile(hostFile(dir, h));
|
|
427
|
+
for (const [k, r] of d.rows)
|
|
428
|
+
if (inRange(r.ts))
|
|
429
|
+
rows.set(k, r);
|
|
430
|
+
for (const [k, l] of d.limits)
|
|
431
|
+
if (inRange(l.ts))
|
|
432
|
+
limits.set(k, l);
|
|
433
|
+
}
|
|
434
|
+
for (const r of fresh.rows)
|
|
435
|
+
if (want(r.host) && inRange(r.ts))
|
|
436
|
+
rows.set(rowKey(r), r);
|
|
437
|
+
for (const l of fresh.limits)
|
|
438
|
+
if (want(l.host) && inRange(l.ts))
|
|
439
|
+
limits.set(limitKey(l), l);
|
|
440
|
+
const outRows = [...rows.values()].sort((a, b) => a.ts.localeCompare(b.ts));
|
|
441
|
+
const outLimits = [...limits.values()].sort((a, b) => a.ts.localeCompare(b.ts));
|
|
442
|
+
const present = [...new Set([...outRows.map((r) => r.host), localHost])].sort();
|
|
443
|
+
return { rows: outRows, limits: outLimits, hosts: present };
|
|
444
|
+
}
|
|
445
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/usage/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ai-dossier usage sync` (#782): refresh this host's persisted ledger, then
|
|
3
|
+
* exchange bundles with other hosts over ssh.
|
|
4
|
+
*
|
|
5
|
+
* Transport = the ssh the fleet already relies on (wls is the only host that can
|
|
6
|
+
* reach the others — see scripts/refresh-fleet.sh), streaming the bundle over
|
|
7
|
+
* stdin/stdout: no new secrets, no shared drop, no service. `sync --hosts a,b`
|
|
8
|
+
* is bidirectional so ONE run from wls leaves every host with every host's rows:
|
|
9
|
+
* pull (`ssh a usage export --all`) → merge locally → push (`ssh a usage import -`).
|
|
10
|
+
* The same bundles move by hand with `usage export` / `usage import <file>`.
|
|
11
|
+
*/
|
|
12
|
+
import { type CollectOptions, type LedgerPaths } from './ledger';
|
|
13
|
+
import { type ImportResult } from './store';
|
|
14
|
+
/** First-ever sync looks this far back; later ones resume from the ledger's newest row. */
|
|
15
|
+
export declare const DEFAULT_INITIAL_SYNC_MS: number;
|
|
16
|
+
/** Re-collect this far before the cursor: recent rows' attribution (dispatch/prep) can be refined after the fact. */
|
|
17
|
+
export declare const CURSOR_OVERLAP_MS = 86400000;
|
|
18
|
+
export interface RefreshDeps {
|
|
19
|
+
dir?: string;
|
|
20
|
+
paths?: LedgerPaths;
|
|
21
|
+
host?: string;
|
|
22
|
+
nowMs?: number;
|
|
23
|
+
openOpenCode?: CollectOptions['openOpenCode'];
|
|
24
|
+
}
|
|
25
|
+
export interface RefreshResult {
|
|
26
|
+
host: string;
|
|
27
|
+
since: string;
|
|
28
|
+
collected: number;
|
|
29
|
+
added: number;
|
|
30
|
+
updated: number;
|
|
31
|
+
total: number;
|
|
32
|
+
}
|
|
33
|
+
/** Collect this host's stores since the cursor (or `sinceMs`) and upsert them into its ledger file. */
|
|
34
|
+
export declare function refreshLocal(deps?: RefreshDeps, sinceMs?: number): RefreshResult;
|
|
35
|
+
/**
|
|
36
|
+
* Same resolution as refresh-fleet.sh's REMOTE_PRELUDE: a non-login ssh shell has
|
|
37
|
+
* no nvm on PATH, and a repo-local `node_modules/.bin/ai-dossier` can shadow the
|
|
38
|
+
* global install — so source nvm and prefer the global binary explicitly.
|
|
39
|
+
*/
|
|
40
|
+
export declare const REMOTE_PRELUDE: string;
|
|
41
|
+
export interface SshResult {
|
|
42
|
+
status: number | null;
|
|
43
|
+
stdout: string;
|
|
44
|
+
stderr: string;
|
|
45
|
+
}
|
|
46
|
+
export type SshRunner = (host: string, script: string, input?: string) => SshResult;
|
|
47
|
+
export declare const defaultSsh: SshRunner;
|
|
48
|
+
export interface RemoteSyncResult {
|
|
49
|
+
host: string;
|
|
50
|
+
ok: boolean;
|
|
51
|
+
error?: string;
|
|
52
|
+
pulled?: ImportResult;
|
|
53
|
+
pushed_rows?: number;
|
|
54
|
+
push?: ImportResult | null;
|
|
55
|
+
}
|
|
56
|
+
export interface SyncOptions {
|
|
57
|
+
hosts: readonly string[];
|
|
58
|
+
/** Override the incremental cursor: exchange rows at or after this time. */
|
|
59
|
+
sinceMs?: number;
|
|
60
|
+
push?: boolean;
|
|
61
|
+
pull?: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Exchange bundles with each remote. Per-host failures are reported, never thrown. */
|
|
64
|
+
export declare function syncWithRemotes(opts: SyncOptions, deps?: RefreshDeps & {
|
|
65
|
+
ssh?: SshRunner;
|
|
66
|
+
}): RemoteSyncResult[];
|
|
67
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/usage/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAE,KAAK,cAAc,EAAqC,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AACpG,OAAO,EAEL,KAAK,YAAY,EAQlB,MAAM,SAAS,CAAC;AAMjB,2FAA2F;AAC3F,eAAO,MAAM,uBAAuB,QAAW,CAAC;AAChD,qHAAqH;AACrH,eAAO,MAAM,iBAAiB,WAAM,CAAC;AAErC,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,uGAAuG;AACvG,wBAAgB,YAAY,CAAC,IAAI,GAAE,WAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,aAAa,CAuBpF;AAMD;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAKhB,CAAC;AAEZ,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,SAAS,CAAC;AAKpF,eAAO,MAAM,UAAU,EAAE,SAOxB,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5B;AA4BD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,WAAW,GAAG;IAAE,GAAG,CAAC,EAAE,SAAS,CAAA;CAAO,GAC3C,gBAAgB,EAAE,CAwFpB"}
|