sphica 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/dist/capture.js +121 -81
- package/dist/cli.js +119 -81
- package/dist/deliver.js +119 -81
- package/dist/mcp-record.js +123 -84
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "sphica",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"description": "Records Claude Code and Codex sessions on your machine and keeps past implementation and decisions, with their sources, for your agent to find.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "iroha924",
|
package/dist/capture.js
CHANGED
|
@@ -11801,6 +11801,8 @@ function lock() {
|
|
|
11801
11801
|
return null;
|
|
11802
11802
|
}
|
|
11803
11803
|
var BATCH = 500;
|
|
11804
|
+
var FLUSH_BUDGET_MS = 30000;
|
|
11805
|
+
var TOOL_FLUSH_BUDGET_MS = 2000;
|
|
11804
11806
|
var ROWS = 1000;
|
|
11805
11807
|
var chunks = (xs, n = ROWS) => Array.from({ length: Math.ceil(xs.length / n) }, (_, i) => xs.slice(i * n, (i + 1) * n));
|
|
11806
11808
|
async function write(db, batch, projects) {
|
|
@@ -11876,98 +11878,135 @@ async function write(db, batch, projects) {
|
|
|
11876
11878
|
}
|
|
11877
11879
|
var REJECTED = new Set([18, 19, 20, 25]);
|
|
11878
11880
|
var rejected = (e) => REJECTED.has(sqliteCode(e) ?? -1);
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11881
|
+
var queued = (from) => {
|
|
11882
|
+
try {
|
|
11883
|
+
return fs4.readdirSync(from).filter((f) => f.endsWith(".json") && !f.startsWith(".")).sort().map((name) => ({ name, from }));
|
|
11884
|
+
} catch {
|
|
11885
|
+
return [];
|
|
11886
|
+
}
|
|
11887
|
+
};
|
|
11888
|
+
async function sendBatch(db, names) {
|
|
11889
|
+
const held = unregisteredDir();
|
|
11890
|
+
const records = [];
|
|
11891
|
+
for (const { name, from } of names) {
|
|
11892
|
+
let r;
|
|
11893
|
+
try {
|
|
11894
|
+
r = current(JSON.parse(fs4.readFileSync(path5.join(from, name), "utf8")));
|
|
11895
|
+
} catch {
|
|
11896
|
+
fs4.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
11897
|
+
fs4.renameSync(path5.join(from, name), path5.join(rejectedDir(), name));
|
|
11898
|
+
continue;
|
|
11899
|
+
}
|
|
11900
|
+
if (r)
|
|
11901
|
+
records.push({ name, from, r });
|
|
11902
|
+
else
|
|
11903
|
+
fs4.rmSync(path5.join(from, name), { force: true });
|
|
11904
|
+
}
|
|
11905
|
+
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
11906
|
+
const known = records.filter((x) => projects.has(x.r.project));
|
|
11907
|
+
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
11908
|
+
let sent = 0;
|
|
11909
|
+
const bad = [];
|
|
11885
11910
|
try {
|
|
11886
|
-
|
|
11887
|
-
|
|
11911
|
+
sent = await write(db, known.map((x) => x.r), projects);
|
|
11912
|
+
} catch (e) {
|
|
11913
|
+
if (!rejected(e))
|
|
11914
|
+
throw e;
|
|
11915
|
+
for (const x of known) {
|
|
11888
11916
|
try {
|
|
11889
|
-
|
|
11890
|
-
} catch {
|
|
11891
|
-
|
|
11917
|
+
sent += await write(db, [x.r], projects);
|
|
11918
|
+
} catch (e2) {
|
|
11919
|
+
if (!rejected(e2))
|
|
11920
|
+
throw e2;
|
|
11921
|
+
bad.push(x);
|
|
11892
11922
|
}
|
|
11893
|
-
}
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
const
|
|
11898
|
-
for (const { name, from } of names) {
|
|
11899
|
-
let r;
|
|
11923
|
+
}
|
|
11924
|
+
}
|
|
11925
|
+
if (bad.length) {
|
|
11926
|
+
fs4.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
11927
|
+
for (const x of bad) {
|
|
11900
11928
|
try {
|
|
11901
|
-
|
|
11902
|
-
} catch {
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
continue;
|
|
11906
|
-
}
|
|
11907
|
-
if (r)
|
|
11908
|
-
records.push({ name, from, r });
|
|
11909
|
-
else
|
|
11910
|
-
fs4.rmSync(path5.join(from, name), { force: true });
|
|
11911
|
-
}
|
|
11912
|
-
const db = openWriter("capture", file);
|
|
11913
|
-
client = db;
|
|
11914
|
-
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
11915
|
-
const known = records.filter((x) => projects.has(x.r.project));
|
|
11916
|
-
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
11917
|
-
let sent = 0;
|
|
11918
|
-
const bad = [];
|
|
11919
|
-
try {
|
|
11920
|
-
sent = await write(db, known.map((x) => x.r), projects);
|
|
11921
|
-
} catch (e) {
|
|
11922
|
-
if (!rejected(e))
|
|
11923
|
-
throw e;
|
|
11924
|
-
for (const x of known) {
|
|
11925
|
-
try {
|
|
11926
|
-
sent += await write(db, [x.r], projects);
|
|
11927
|
-
} catch (e2) {
|
|
11928
|
-
if (!rejected(e2))
|
|
11929
|
-
throw e2;
|
|
11930
|
-
bad.push(x);
|
|
11931
|
-
}
|
|
11929
|
+
fs4.renameSync(path5.join(x.from, x.name), path5.join(rejectedDir(), x.name));
|
|
11930
|
+
} catch (e) {
|
|
11931
|
+
if (e.code !== "ENOENT")
|
|
11932
|
+
throw e;
|
|
11932
11933
|
}
|
|
11933
11934
|
}
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11935
|
+
}
|
|
11936
|
+
if (strayed.length) {
|
|
11937
|
+
fs4.mkdirSync(held, { recursive: true, mode: 448 });
|
|
11938
|
+
for (const x of strayed) {
|
|
11939
|
+
if (x.from === held)
|
|
11940
|
+
continue;
|
|
11941
|
+
try {
|
|
11942
|
+
fs4.renameSync(path5.join(x.from, x.name), path5.join(held, x.name));
|
|
11943
|
+
} catch (e) {
|
|
11944
|
+
if (e.code !== "ENOENT")
|
|
11945
|
+
throw e;
|
|
11943
11946
|
}
|
|
11944
11947
|
}
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11948
|
+
}
|
|
11949
|
+
const moved = new Set([...bad, ...strayed].map((x) => x.name));
|
|
11950
|
+
for (const x of records)
|
|
11951
|
+
if (!moved.has(x.name))
|
|
11952
|
+
fs4.rmSync(path5.join(x.from, x.name), { force: true });
|
|
11953
|
+
return { sent, rejected: bad.length };
|
|
11954
|
+
}
|
|
11955
|
+
async function flush(file = dbFile(), budgetMs = FLUSH_BUDGET_MS) {
|
|
11956
|
+
const deadline = Date.now() + budgetMs;
|
|
11957
|
+
const dir = spoolDir();
|
|
11958
|
+
const held = unregisteredDir();
|
|
11959
|
+
const total = { sent: 0, deferred: 0, rejected: 0 };
|
|
11960
|
+
let batches = 0;
|
|
11961
|
+
let queueBatches = 0;
|
|
11962
|
+
for (let first = true;; first = false) {
|
|
11963
|
+
let unlock = lock();
|
|
11964
|
+
while (!unlock && Date.now() < deadline) {
|
|
11965
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(100, deadline - Date.now())));
|
|
11966
|
+
if (Date.now() < deadline)
|
|
11967
|
+
unlock = lock();
|
|
11968
|
+
}
|
|
11969
|
+
if (!unlock)
|
|
11970
|
+
return first ? { ...total, busy: true } : total;
|
|
11971
|
+
let client = null;
|
|
11972
|
+
const send = async (names) => {
|
|
11973
|
+
client ??= openWriter("capture", file);
|
|
11974
|
+
const r = await sendBatch(client, names);
|
|
11975
|
+
total.sent += r.sent;
|
|
11976
|
+
total.rejected += r.rejected;
|
|
11977
|
+
batches++;
|
|
11978
|
+
};
|
|
11979
|
+
const late = () => batches > 0 && Date.now() >= deadline;
|
|
11980
|
+
const sentBefore = batches;
|
|
11981
|
+
try {
|
|
11982
|
+
if (first) {
|
|
11983
|
+
prune(held);
|
|
11984
|
+
for (const part of chunks(queued(held), BATCH)) {
|
|
11985
|
+
if (late())
|
|
11986
|
+
break;
|
|
11987
|
+
await send(part);
|
|
11955
11988
|
}
|
|
11956
11989
|
}
|
|
11990
|
+
while (queueBatches === 0 || !late()) {
|
|
11991
|
+
const part = queued(dir).slice(0, BATCH);
|
|
11992
|
+
if (part.length === 0)
|
|
11993
|
+
break;
|
|
11994
|
+
await send(part);
|
|
11995
|
+
queueBatches++;
|
|
11996
|
+
}
|
|
11997
|
+
prune(held);
|
|
11998
|
+
total.deferred = queued(held).length;
|
|
11999
|
+
if (batches > sentBefore)
|
|
12000
|
+
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: total.deferred });
|
|
12001
|
+
} catch (e) {
|
|
12002
|
+
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
12003
|
+
throw e;
|
|
12004
|
+
} finally {
|
|
12005
|
+
await client?.destroy().catch(() => {});
|
|
12006
|
+
unlock();
|
|
11957
12007
|
}
|
|
11958
|
-
|
|
11959
|
-
|
|
11960
|
-
if (!moved.has(x.name))
|
|
11961
|
-
fs4.rmSync(path5.join(x.from, x.name), { force: true });
|
|
11962
|
-
prune(held);
|
|
11963
|
-
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: strayed.length });
|
|
11964
|
-
return { sent, deferred: strayed.length, rejected: bad.length };
|
|
11965
|
-
} catch (e) {
|
|
11966
|
-
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
11967
|
-
throw e;
|
|
11968
|
-
} finally {
|
|
11969
|
-
await client?.destroy().catch(() => {});
|
|
11970
|
-
unlock();
|
|
12008
|
+
if (Date.now() >= deadline || queued(dir).length === 0)
|
|
12009
|
+
return total;
|
|
11971
12010
|
}
|
|
11972
12011
|
}
|
|
11973
12012
|
async function readInput(stream) {
|
|
@@ -11997,6 +12036,7 @@ if (process.argv[1] && /capture\.(ts|js)$/.test(process.argv[1])) {
|
|
|
11997
12036
|
}
|
|
11998
12037
|
export {
|
|
11999
12038
|
MAX_MESSAGE,
|
|
12039
|
+
TOOL_FLUSH_BUDGET_MS,
|
|
12000
12040
|
answersOf,
|
|
12001
12041
|
branchOf,
|
|
12002
12042
|
captureNotice,
|
package/dist/cli.js
CHANGED
|
@@ -15132,6 +15132,7 @@ function lock() {
|
|
|
15132
15132
|
return null;
|
|
15133
15133
|
}
|
|
15134
15134
|
var BATCH = 500;
|
|
15135
|
+
var FLUSH_BUDGET_MS = 30000;
|
|
15135
15136
|
var ROWS = 1000;
|
|
15136
15137
|
var chunks = (xs, n2 = ROWS) => Array.from({ length: Math.ceil(xs.length / n2) }, (_, i2) => xs.slice(i2 * n2, (i2 + 1) * n2));
|
|
15137
15138
|
async function write(db, batch, projects) {
|
|
@@ -15207,98 +15208,135 @@ async function write(db, batch, projects) {
|
|
|
15207
15208
|
}
|
|
15208
15209
|
var REJECTED = new Set([18, 19, 20, 25]);
|
|
15209
15210
|
var rejected = (e) => REJECTED.has(sqliteCode(e) ?? -1);
|
|
15210
|
-
|
|
15211
|
-
|
|
15212
|
-
|
|
15213
|
-
|
|
15214
|
-
|
|
15215
|
-
|
|
15211
|
+
var queued = (from) => {
|
|
15212
|
+
try {
|
|
15213
|
+
return fs6.readdirSync(from).filter((f) => f.endsWith(".json") && !f.startsWith(".")).sort().map((name) => ({ name, from }));
|
|
15214
|
+
} catch {
|
|
15215
|
+
return [];
|
|
15216
|
+
}
|
|
15217
|
+
};
|
|
15218
|
+
async function sendBatch(db, names) {
|
|
15219
|
+
const held = unregisteredDir();
|
|
15220
|
+
const records = [];
|
|
15221
|
+
for (const { name, from } of names) {
|
|
15222
|
+
let r2;
|
|
15223
|
+
try {
|
|
15224
|
+
r2 = current(JSON.parse(fs6.readFileSync(path7.join(from, name), "utf8")));
|
|
15225
|
+
} catch {
|
|
15226
|
+
fs6.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
15227
|
+
fs6.renameSync(path7.join(from, name), path7.join(rejectedDir(), name));
|
|
15228
|
+
continue;
|
|
15229
|
+
}
|
|
15230
|
+
if (r2)
|
|
15231
|
+
records.push({ name, from, r: r2 });
|
|
15232
|
+
else
|
|
15233
|
+
fs6.rmSync(path7.join(from, name), { force: true });
|
|
15234
|
+
}
|
|
15235
|
+
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
15236
|
+
const known = records.filter((x) => projects.has(x.r.project));
|
|
15237
|
+
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
15238
|
+
let sent = 0;
|
|
15239
|
+
const bad = [];
|
|
15216
15240
|
try {
|
|
15217
|
-
|
|
15218
|
-
|
|
15241
|
+
sent = await write(db, known.map((x) => x.r), projects);
|
|
15242
|
+
} catch (e) {
|
|
15243
|
+
if (!rejected(e))
|
|
15244
|
+
throw e;
|
|
15245
|
+
for (const x of known) {
|
|
15219
15246
|
try {
|
|
15220
|
-
|
|
15221
|
-
} catch {
|
|
15222
|
-
|
|
15247
|
+
sent += await write(db, [x.r], projects);
|
|
15248
|
+
} catch (e2) {
|
|
15249
|
+
if (!rejected(e2))
|
|
15250
|
+
throw e2;
|
|
15251
|
+
bad.push(x);
|
|
15223
15252
|
}
|
|
15224
|
-
}
|
|
15225
|
-
|
|
15226
|
-
|
|
15227
|
-
|
|
15228
|
-
const
|
|
15229
|
-
for (const { name, from } of names) {
|
|
15230
|
-
let r2;
|
|
15253
|
+
}
|
|
15254
|
+
}
|
|
15255
|
+
if (bad.length) {
|
|
15256
|
+
fs6.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
15257
|
+
for (const x of bad) {
|
|
15231
15258
|
try {
|
|
15232
|
-
|
|
15233
|
-
} catch {
|
|
15234
|
-
|
|
15235
|
-
|
|
15236
|
-
continue;
|
|
15237
|
-
}
|
|
15238
|
-
if (r2)
|
|
15239
|
-
records.push({ name, from, r: r2 });
|
|
15240
|
-
else
|
|
15241
|
-
fs6.rmSync(path7.join(from, name), { force: true });
|
|
15242
|
-
}
|
|
15243
|
-
const db = openWriter("capture", file);
|
|
15244
|
-
client = db;
|
|
15245
|
-
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
15246
|
-
const known = records.filter((x) => projects.has(x.r.project));
|
|
15247
|
-
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
15248
|
-
let sent = 0;
|
|
15249
|
-
const bad = [];
|
|
15250
|
-
try {
|
|
15251
|
-
sent = await write(db, known.map((x) => x.r), projects);
|
|
15252
|
-
} catch (e) {
|
|
15253
|
-
if (!rejected(e))
|
|
15254
|
-
throw e;
|
|
15255
|
-
for (const x of known) {
|
|
15256
|
-
try {
|
|
15257
|
-
sent += await write(db, [x.r], projects);
|
|
15258
|
-
} catch (e2) {
|
|
15259
|
-
if (!rejected(e2))
|
|
15260
|
-
throw e2;
|
|
15261
|
-
bad.push(x);
|
|
15262
|
-
}
|
|
15259
|
+
fs6.renameSync(path7.join(x.from, x.name), path7.join(rejectedDir(), x.name));
|
|
15260
|
+
} catch (e) {
|
|
15261
|
+
if (e.code !== "ENOENT")
|
|
15262
|
+
throw e;
|
|
15263
15263
|
}
|
|
15264
15264
|
}
|
|
15265
|
-
|
|
15266
|
-
|
|
15267
|
-
|
|
15268
|
-
|
|
15269
|
-
|
|
15270
|
-
|
|
15271
|
-
|
|
15272
|
-
|
|
15273
|
-
|
|
15265
|
+
}
|
|
15266
|
+
if (strayed.length) {
|
|
15267
|
+
fs6.mkdirSync(held, { recursive: true, mode: 448 });
|
|
15268
|
+
for (const x of strayed) {
|
|
15269
|
+
if (x.from === held)
|
|
15270
|
+
continue;
|
|
15271
|
+
try {
|
|
15272
|
+
fs6.renameSync(path7.join(x.from, x.name), path7.join(held, x.name));
|
|
15273
|
+
} catch (e) {
|
|
15274
|
+
if (e.code !== "ENOENT")
|
|
15275
|
+
throw e;
|
|
15274
15276
|
}
|
|
15275
15277
|
}
|
|
15276
|
-
|
|
15277
|
-
|
|
15278
|
-
|
|
15279
|
-
|
|
15280
|
-
|
|
15281
|
-
|
|
15282
|
-
|
|
15283
|
-
|
|
15284
|
-
|
|
15285
|
-
|
|
15278
|
+
}
|
|
15279
|
+
const moved = new Set([...bad, ...strayed].map((x) => x.name));
|
|
15280
|
+
for (const x of records)
|
|
15281
|
+
if (!moved.has(x.name))
|
|
15282
|
+
fs6.rmSync(path7.join(x.from, x.name), { force: true });
|
|
15283
|
+
return { sent, rejected: bad.length };
|
|
15284
|
+
}
|
|
15285
|
+
async function flush(file = dbFile(), budgetMs = FLUSH_BUDGET_MS) {
|
|
15286
|
+
const deadline = Date.now() + budgetMs;
|
|
15287
|
+
const dir = spoolDir();
|
|
15288
|
+
const held = unregisteredDir();
|
|
15289
|
+
const total = { sent: 0, deferred: 0, rejected: 0 };
|
|
15290
|
+
let batches = 0;
|
|
15291
|
+
let queueBatches = 0;
|
|
15292
|
+
for (let first = true;; first = false) {
|
|
15293
|
+
let unlock = lock();
|
|
15294
|
+
while (!unlock && Date.now() < deadline) {
|
|
15295
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(100, deadline - Date.now())));
|
|
15296
|
+
if (Date.now() < deadline)
|
|
15297
|
+
unlock = lock();
|
|
15298
|
+
}
|
|
15299
|
+
if (!unlock)
|
|
15300
|
+
return first ? { ...total, busy: true } : total;
|
|
15301
|
+
let client = null;
|
|
15302
|
+
const send = async (names) => {
|
|
15303
|
+
client ??= openWriter("capture", file);
|
|
15304
|
+
const r2 = await sendBatch(client, names);
|
|
15305
|
+
total.sent += r2.sent;
|
|
15306
|
+
total.rejected += r2.rejected;
|
|
15307
|
+
batches++;
|
|
15308
|
+
};
|
|
15309
|
+
const late = () => batches > 0 && Date.now() >= deadline;
|
|
15310
|
+
const sentBefore = batches;
|
|
15311
|
+
try {
|
|
15312
|
+
if (first) {
|
|
15313
|
+
prune(held);
|
|
15314
|
+
for (const part of chunks(queued(held), BATCH)) {
|
|
15315
|
+
if (late())
|
|
15316
|
+
break;
|
|
15317
|
+
await send(part);
|
|
15286
15318
|
}
|
|
15287
15319
|
}
|
|
15320
|
+
while (queueBatches === 0 || !late()) {
|
|
15321
|
+
const part = queued(dir).slice(0, BATCH);
|
|
15322
|
+
if (part.length === 0)
|
|
15323
|
+
break;
|
|
15324
|
+
await send(part);
|
|
15325
|
+
queueBatches++;
|
|
15326
|
+
}
|
|
15327
|
+
prune(held);
|
|
15328
|
+
total.deferred = queued(held).length;
|
|
15329
|
+
if (batches > sentBefore)
|
|
15330
|
+
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: total.deferred });
|
|
15331
|
+
} catch (e) {
|
|
15332
|
+
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
15333
|
+
throw e;
|
|
15334
|
+
} finally {
|
|
15335
|
+
await client?.destroy().catch(() => {});
|
|
15336
|
+
unlock();
|
|
15288
15337
|
}
|
|
15289
|
-
|
|
15290
|
-
|
|
15291
|
-
if (!moved.has(x.name))
|
|
15292
|
-
fs6.rmSync(path7.join(x.from, x.name), { force: true });
|
|
15293
|
-
prune(held);
|
|
15294
|
-
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: strayed.length });
|
|
15295
|
-
return { sent, deferred: strayed.length, rejected: bad.length };
|
|
15296
|
-
} catch (e) {
|
|
15297
|
-
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
15298
|
-
throw e;
|
|
15299
|
-
} finally {
|
|
15300
|
-
await client?.destroy().catch(() => {});
|
|
15301
|
-
unlock();
|
|
15338
|
+
if (Date.now() >= deadline || queued(dir).length === 0)
|
|
15339
|
+
return total;
|
|
15302
15340
|
}
|
|
15303
15341
|
}
|
|
15304
15342
|
async function readInput(stream) {
|
package/dist/deliver.js
CHANGED
|
@@ -11847,6 +11847,7 @@ function lock() {
|
|
|
11847
11847
|
return null;
|
|
11848
11848
|
}
|
|
11849
11849
|
var BATCH = 500;
|
|
11850
|
+
var FLUSH_BUDGET_MS = 30000;
|
|
11850
11851
|
var ROWS = 1000;
|
|
11851
11852
|
var chunks = (xs, n = ROWS) => Array.from({ length: Math.ceil(xs.length / n) }, (_, i) => xs.slice(i * n, (i + 1) * n));
|
|
11852
11853
|
async function write(db, batch, projects) {
|
|
@@ -11922,98 +11923,135 @@ async function write(db, batch, projects) {
|
|
|
11922
11923
|
}
|
|
11923
11924
|
var REJECTED = new Set([18, 19, 20, 25]);
|
|
11924
11925
|
var rejected = (e) => REJECTED.has(sqliteCode(e) ?? -1);
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11926
|
+
var queued = (from) => {
|
|
11927
|
+
try {
|
|
11928
|
+
return fs4.readdirSync(from).filter((f) => f.endsWith(".json") && !f.startsWith(".")).sort().map((name) => ({ name, from }));
|
|
11929
|
+
} catch {
|
|
11930
|
+
return [];
|
|
11931
|
+
}
|
|
11932
|
+
};
|
|
11933
|
+
async function sendBatch(db, names) {
|
|
11934
|
+
const held = unregisteredDir();
|
|
11935
|
+
const records = [];
|
|
11936
|
+
for (const { name, from } of names) {
|
|
11937
|
+
let r;
|
|
11938
|
+
try {
|
|
11939
|
+
r = current(JSON.parse(fs4.readFileSync(path5.join(from, name), "utf8")));
|
|
11940
|
+
} catch {
|
|
11941
|
+
fs4.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
11942
|
+
fs4.renameSync(path5.join(from, name), path5.join(rejectedDir(), name));
|
|
11943
|
+
continue;
|
|
11944
|
+
}
|
|
11945
|
+
if (r)
|
|
11946
|
+
records.push({ name, from, r });
|
|
11947
|
+
else
|
|
11948
|
+
fs4.rmSync(path5.join(from, name), { force: true });
|
|
11949
|
+
}
|
|
11950
|
+
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
11951
|
+
const known = records.filter((x) => projects.has(x.r.project));
|
|
11952
|
+
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
11953
|
+
let sent = 0;
|
|
11954
|
+
const bad = [];
|
|
11931
11955
|
try {
|
|
11932
|
-
|
|
11933
|
-
|
|
11956
|
+
sent = await write(db, known.map((x) => x.r), projects);
|
|
11957
|
+
} catch (e) {
|
|
11958
|
+
if (!rejected(e))
|
|
11959
|
+
throw e;
|
|
11960
|
+
for (const x of known) {
|
|
11934
11961
|
try {
|
|
11935
|
-
|
|
11936
|
-
} catch {
|
|
11937
|
-
|
|
11962
|
+
sent += await write(db, [x.r], projects);
|
|
11963
|
+
} catch (e2) {
|
|
11964
|
+
if (!rejected(e2))
|
|
11965
|
+
throw e2;
|
|
11966
|
+
bad.push(x);
|
|
11938
11967
|
}
|
|
11939
|
-
}
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
const
|
|
11944
|
-
for (const { name, from } of names) {
|
|
11945
|
-
let r;
|
|
11968
|
+
}
|
|
11969
|
+
}
|
|
11970
|
+
if (bad.length) {
|
|
11971
|
+
fs4.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
11972
|
+
for (const x of bad) {
|
|
11946
11973
|
try {
|
|
11947
|
-
|
|
11948
|
-
} catch {
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
continue;
|
|
11952
|
-
}
|
|
11953
|
-
if (r)
|
|
11954
|
-
records.push({ name, from, r });
|
|
11955
|
-
else
|
|
11956
|
-
fs4.rmSync(path5.join(from, name), { force: true });
|
|
11957
|
-
}
|
|
11958
|
-
const db = openWriter("capture", file);
|
|
11959
|
-
client = db;
|
|
11960
|
-
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
11961
|
-
const known = records.filter((x) => projects.has(x.r.project));
|
|
11962
|
-
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
11963
|
-
let sent = 0;
|
|
11964
|
-
const bad = [];
|
|
11965
|
-
try {
|
|
11966
|
-
sent = await write(db, known.map((x) => x.r), projects);
|
|
11967
|
-
} catch (e) {
|
|
11968
|
-
if (!rejected(e))
|
|
11969
|
-
throw e;
|
|
11970
|
-
for (const x of known) {
|
|
11971
|
-
try {
|
|
11972
|
-
sent += await write(db, [x.r], projects);
|
|
11973
|
-
} catch (e2) {
|
|
11974
|
-
if (!rejected(e2))
|
|
11975
|
-
throw e2;
|
|
11976
|
-
bad.push(x);
|
|
11977
|
-
}
|
|
11974
|
+
fs4.renameSync(path5.join(x.from, x.name), path5.join(rejectedDir(), x.name));
|
|
11975
|
+
} catch (e) {
|
|
11976
|
+
if (e.code !== "ENOENT")
|
|
11977
|
+
throw e;
|
|
11978
11978
|
}
|
|
11979
11979
|
}
|
|
11980
|
-
|
|
11981
|
-
|
|
11982
|
-
|
|
11983
|
-
|
|
11984
|
-
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
11988
|
-
|
|
11980
|
+
}
|
|
11981
|
+
if (strayed.length) {
|
|
11982
|
+
fs4.mkdirSync(held, { recursive: true, mode: 448 });
|
|
11983
|
+
for (const x of strayed) {
|
|
11984
|
+
if (x.from === held)
|
|
11985
|
+
continue;
|
|
11986
|
+
try {
|
|
11987
|
+
fs4.renameSync(path5.join(x.from, x.name), path5.join(held, x.name));
|
|
11988
|
+
} catch (e) {
|
|
11989
|
+
if (e.code !== "ENOENT")
|
|
11990
|
+
throw e;
|
|
11989
11991
|
}
|
|
11990
11992
|
}
|
|
11991
|
-
|
|
11992
|
-
|
|
11993
|
-
|
|
11994
|
-
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
|
|
11999
|
-
|
|
12000
|
-
|
|
11993
|
+
}
|
|
11994
|
+
const moved = new Set([...bad, ...strayed].map((x) => x.name));
|
|
11995
|
+
for (const x of records)
|
|
11996
|
+
if (!moved.has(x.name))
|
|
11997
|
+
fs4.rmSync(path5.join(x.from, x.name), { force: true });
|
|
11998
|
+
return { sent, rejected: bad.length };
|
|
11999
|
+
}
|
|
12000
|
+
async function flush(file = dbFile(), budgetMs = FLUSH_BUDGET_MS) {
|
|
12001
|
+
const deadline = Date.now() + budgetMs;
|
|
12002
|
+
const dir = spoolDir();
|
|
12003
|
+
const held = unregisteredDir();
|
|
12004
|
+
const total = { sent: 0, deferred: 0, rejected: 0 };
|
|
12005
|
+
let batches = 0;
|
|
12006
|
+
let queueBatches = 0;
|
|
12007
|
+
for (let first = true;; first = false) {
|
|
12008
|
+
let unlock = lock();
|
|
12009
|
+
while (!unlock && Date.now() < deadline) {
|
|
12010
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(100, deadline - Date.now())));
|
|
12011
|
+
if (Date.now() < deadline)
|
|
12012
|
+
unlock = lock();
|
|
12013
|
+
}
|
|
12014
|
+
if (!unlock)
|
|
12015
|
+
return first ? { ...total, busy: true } : total;
|
|
12016
|
+
let client = null;
|
|
12017
|
+
const send = async (names) => {
|
|
12018
|
+
client ??= openWriter("capture", file);
|
|
12019
|
+
const r = await sendBatch(client, names);
|
|
12020
|
+
total.sent += r.sent;
|
|
12021
|
+
total.rejected += r.rejected;
|
|
12022
|
+
batches++;
|
|
12023
|
+
};
|
|
12024
|
+
const late = () => batches > 0 && Date.now() >= deadline;
|
|
12025
|
+
const sentBefore = batches;
|
|
12026
|
+
try {
|
|
12027
|
+
if (first) {
|
|
12028
|
+
prune(held);
|
|
12029
|
+
for (const part of chunks(queued(held), BATCH)) {
|
|
12030
|
+
if (late())
|
|
12031
|
+
break;
|
|
12032
|
+
await send(part);
|
|
12001
12033
|
}
|
|
12002
12034
|
}
|
|
12035
|
+
while (queueBatches === 0 || !late()) {
|
|
12036
|
+
const part = queued(dir).slice(0, BATCH);
|
|
12037
|
+
if (part.length === 0)
|
|
12038
|
+
break;
|
|
12039
|
+
await send(part);
|
|
12040
|
+
queueBatches++;
|
|
12041
|
+
}
|
|
12042
|
+
prune(held);
|
|
12043
|
+
total.deferred = queued(held).length;
|
|
12044
|
+
if (batches > sentBefore)
|
|
12045
|
+
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: total.deferred });
|
|
12046
|
+
} catch (e) {
|
|
12047
|
+
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
12048
|
+
throw e;
|
|
12049
|
+
} finally {
|
|
12050
|
+
await client?.destroy().catch(() => {});
|
|
12051
|
+
unlock();
|
|
12003
12052
|
}
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
if (!moved.has(x.name))
|
|
12007
|
-
fs4.rmSync(path5.join(x.from, x.name), { force: true });
|
|
12008
|
-
prune(held);
|
|
12009
|
-
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: strayed.length });
|
|
12010
|
-
return { sent, deferred: strayed.length, rejected: bad.length };
|
|
12011
|
-
} catch (e) {
|
|
12012
|
-
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
12013
|
-
throw e;
|
|
12014
|
-
} finally {
|
|
12015
|
-
await client?.destroy().catch(() => {});
|
|
12016
|
-
unlock();
|
|
12053
|
+
if (Date.now() >= deadline || queued(dir).length === 0)
|
|
12054
|
+
return total;
|
|
12017
12055
|
}
|
|
12018
12056
|
}
|
|
12019
12057
|
async function readInput(stream) {
|
package/dist/mcp-record.js
CHANGED
|
@@ -46683,6 +46683,8 @@ function lock() {
|
|
|
46683
46683
|
return null;
|
|
46684
46684
|
}
|
|
46685
46685
|
var BATCH = 500;
|
|
46686
|
+
var FLUSH_BUDGET_MS = 30000;
|
|
46687
|
+
var TOOL_FLUSH_BUDGET_MS = 2000;
|
|
46686
46688
|
var ROWS = 1000;
|
|
46687
46689
|
var chunks = (xs, n = ROWS) => Array.from({ length: Math.ceil(xs.length / n) }, (_, i) => xs.slice(i * n, (i + 1) * n));
|
|
46688
46690
|
async function write(db, batch, projects) {
|
|
@@ -46758,98 +46760,135 @@ async function write(db, batch, projects) {
|
|
|
46758
46760
|
}
|
|
46759
46761
|
var REJECTED = new Set([18, 19, 20, 25]);
|
|
46760
46762
|
var rejected = (e) => REJECTED.has(sqliteCode(e) ?? -1);
|
|
46761
|
-
|
|
46762
|
-
const unlock = lock();
|
|
46763
|
-
if (!unlock)
|
|
46764
|
-
return { sent: 0, deferred: 0, rejected: 0, busy: true };
|
|
46765
|
-
const dir = spoolDir();
|
|
46766
|
-
let client = null;
|
|
46763
|
+
var queued = (from) => {
|
|
46767
46764
|
try {
|
|
46768
|
-
|
|
46769
|
-
|
|
46765
|
+
return fs5.readdirSync(from).filter((f) => f.endsWith(".json") && !f.startsWith(".")).sort().map((name) => ({ name, from }));
|
|
46766
|
+
} catch {
|
|
46767
|
+
return [];
|
|
46768
|
+
}
|
|
46769
|
+
};
|
|
46770
|
+
async function sendBatch(db, names) {
|
|
46771
|
+
const held = unregisteredDir();
|
|
46772
|
+
const records = [];
|
|
46773
|
+
for (const { name, from } of names) {
|
|
46774
|
+
let r;
|
|
46775
|
+
try {
|
|
46776
|
+
r = current(JSON.parse(fs5.readFileSync(path5.join(from, name), "utf8")));
|
|
46777
|
+
} catch {
|
|
46778
|
+
fs5.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
46779
|
+
fs5.renameSync(path5.join(from, name), path5.join(rejectedDir(), name));
|
|
46780
|
+
continue;
|
|
46781
|
+
}
|
|
46782
|
+
if (r)
|
|
46783
|
+
records.push({ name, from, r });
|
|
46784
|
+
else
|
|
46785
|
+
fs5.rmSync(path5.join(from, name), { force: true });
|
|
46786
|
+
}
|
|
46787
|
+
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
46788
|
+
const known = records.filter((x) => projects.has(x.r.project));
|
|
46789
|
+
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
46790
|
+
let sent = 0;
|
|
46791
|
+
const bad = [];
|
|
46792
|
+
try {
|
|
46793
|
+
sent = await write(db, known.map((x) => x.r), projects);
|
|
46794
|
+
} catch (e) {
|
|
46795
|
+
if (!rejected(e))
|
|
46796
|
+
throw e;
|
|
46797
|
+
for (const x of known) {
|
|
46770
46798
|
try {
|
|
46771
|
-
|
|
46772
|
-
} catch {
|
|
46773
|
-
|
|
46799
|
+
sent += await write(db, [x.r], projects);
|
|
46800
|
+
} catch (e2) {
|
|
46801
|
+
if (!rejected(e2))
|
|
46802
|
+
throw e2;
|
|
46803
|
+
bad.push(x);
|
|
46774
46804
|
}
|
|
46775
|
-
}
|
|
46776
|
-
|
|
46777
|
-
|
|
46778
|
-
|
|
46779
|
-
const
|
|
46780
|
-
for (const { name, from } of names) {
|
|
46781
|
-
let r;
|
|
46805
|
+
}
|
|
46806
|
+
}
|
|
46807
|
+
if (bad.length) {
|
|
46808
|
+
fs5.mkdirSync(rejectedDir(), { recursive: true, mode: 448 });
|
|
46809
|
+
for (const x of bad) {
|
|
46782
46810
|
try {
|
|
46783
|
-
|
|
46784
|
-
} catch {
|
|
46785
|
-
|
|
46786
|
-
|
|
46787
|
-
continue;
|
|
46788
|
-
}
|
|
46789
|
-
if (r)
|
|
46790
|
-
records.push({ name, from, r });
|
|
46791
|
-
else
|
|
46792
|
-
fs5.rmSync(path5.join(from, name), { force: true });
|
|
46793
|
-
}
|
|
46794
|
-
const db = openWriter("capture", file2);
|
|
46795
|
-
client = db;
|
|
46796
|
-
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
46797
|
-
const known = records.filter((x) => projects.has(x.r.project));
|
|
46798
|
-
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
46799
|
-
let sent = 0;
|
|
46800
|
-
const bad = [];
|
|
46801
|
-
try {
|
|
46802
|
-
sent = await write(db, known.map((x) => x.r), projects);
|
|
46803
|
-
} catch (e) {
|
|
46804
|
-
if (!rejected(e))
|
|
46805
|
-
throw e;
|
|
46806
|
-
for (const x of known) {
|
|
46807
|
-
try {
|
|
46808
|
-
sent += await write(db, [x.r], projects);
|
|
46809
|
-
} catch (e2) {
|
|
46810
|
-
if (!rejected(e2))
|
|
46811
|
-
throw e2;
|
|
46812
|
-
bad.push(x);
|
|
46813
|
-
}
|
|
46811
|
+
fs5.renameSync(path5.join(x.from, x.name), path5.join(rejectedDir(), x.name));
|
|
46812
|
+
} catch (e) {
|
|
46813
|
+
if (e.code !== "ENOENT")
|
|
46814
|
+
throw e;
|
|
46814
46815
|
}
|
|
46815
46816
|
}
|
|
46816
|
-
|
|
46817
|
-
|
|
46818
|
-
|
|
46819
|
-
|
|
46820
|
-
|
|
46821
|
-
|
|
46822
|
-
|
|
46823
|
-
|
|
46824
|
-
|
|
46817
|
+
}
|
|
46818
|
+
if (strayed.length) {
|
|
46819
|
+
fs5.mkdirSync(held, { recursive: true, mode: 448 });
|
|
46820
|
+
for (const x of strayed) {
|
|
46821
|
+
if (x.from === held)
|
|
46822
|
+
continue;
|
|
46823
|
+
try {
|
|
46824
|
+
fs5.renameSync(path5.join(x.from, x.name), path5.join(held, x.name));
|
|
46825
|
+
} catch (e) {
|
|
46826
|
+
if (e.code !== "ENOENT")
|
|
46827
|
+
throw e;
|
|
46825
46828
|
}
|
|
46826
46829
|
}
|
|
46827
|
-
|
|
46828
|
-
|
|
46829
|
-
|
|
46830
|
-
|
|
46831
|
-
|
|
46832
|
-
|
|
46833
|
-
|
|
46834
|
-
|
|
46835
|
-
|
|
46836
|
-
|
|
46830
|
+
}
|
|
46831
|
+
const moved = new Set([...bad, ...strayed].map((x) => x.name));
|
|
46832
|
+
for (const x of records)
|
|
46833
|
+
if (!moved.has(x.name))
|
|
46834
|
+
fs5.rmSync(path5.join(x.from, x.name), { force: true });
|
|
46835
|
+
return { sent, rejected: bad.length };
|
|
46836
|
+
}
|
|
46837
|
+
async function flush(file2 = dbFile(), budgetMs = FLUSH_BUDGET_MS) {
|
|
46838
|
+
const deadline = Date.now() + budgetMs;
|
|
46839
|
+
const dir = spoolDir();
|
|
46840
|
+
const held = unregisteredDir();
|
|
46841
|
+
const total = { sent: 0, deferred: 0, rejected: 0 };
|
|
46842
|
+
let batches = 0;
|
|
46843
|
+
let queueBatches = 0;
|
|
46844
|
+
for (let first = true;; first = false) {
|
|
46845
|
+
let unlock = lock();
|
|
46846
|
+
while (!unlock && Date.now() < deadline) {
|
|
46847
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(100, deadline - Date.now())));
|
|
46848
|
+
if (Date.now() < deadline)
|
|
46849
|
+
unlock = lock();
|
|
46850
|
+
}
|
|
46851
|
+
if (!unlock)
|
|
46852
|
+
return first ? { ...total, busy: true } : total;
|
|
46853
|
+
let client = null;
|
|
46854
|
+
const send = async (names) => {
|
|
46855
|
+
client ??= openWriter("capture", file2);
|
|
46856
|
+
const r = await sendBatch(client, names);
|
|
46857
|
+
total.sent += r.sent;
|
|
46858
|
+
total.rejected += r.rejected;
|
|
46859
|
+
batches++;
|
|
46860
|
+
};
|
|
46861
|
+
const late2 = () => batches > 0 && Date.now() >= deadline;
|
|
46862
|
+
const sentBefore = batches;
|
|
46863
|
+
try {
|
|
46864
|
+
if (first) {
|
|
46865
|
+
prune(held);
|
|
46866
|
+
for (const part of chunks(queued(held), BATCH)) {
|
|
46867
|
+
if (late2())
|
|
46868
|
+
break;
|
|
46869
|
+
await send(part);
|
|
46837
46870
|
}
|
|
46838
46871
|
}
|
|
46872
|
+
while (queueBatches === 0 || !late2()) {
|
|
46873
|
+
const part = queued(dir).slice(0, BATCH);
|
|
46874
|
+
if (part.length === 0)
|
|
46875
|
+
break;
|
|
46876
|
+
await send(part);
|
|
46877
|
+
queueBatches++;
|
|
46878
|
+
}
|
|
46879
|
+
prune(held);
|
|
46880
|
+
total.deferred = queued(held).length;
|
|
46881
|
+
if (batches > sentBefore)
|
|
46882
|
+
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: total.deferred });
|
|
46883
|
+
} catch (e) {
|
|
46884
|
+
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
46885
|
+
throw e;
|
|
46886
|
+
} finally {
|
|
46887
|
+
await client?.destroy().catch(() => {});
|
|
46888
|
+
unlock();
|
|
46839
46889
|
}
|
|
46840
|
-
|
|
46841
|
-
|
|
46842
|
-
if (!moved.has(x.name))
|
|
46843
|
-
fs5.rmSync(path5.join(x.from, x.name), { force: true });
|
|
46844
|
-
prune(held);
|
|
46845
|
-
writeState({ flushedAt: new Date().toISOString(), error: null, deferred: strayed.length });
|
|
46846
|
-
return { sent, deferred: strayed.length, rejected: bad.length };
|
|
46847
|
-
} catch (e) {
|
|
46848
|
-
writeState({ flushedAt: new Date().toISOString(), error: reason(e).slice(0, 300) });
|
|
46849
|
-
throw e;
|
|
46850
|
-
} finally {
|
|
46851
|
-
await client?.destroy().catch(() => {});
|
|
46852
|
-
unlock();
|
|
46890
|
+
if (Date.now() >= deadline || queued(dir).length === 0)
|
|
46891
|
+
return total;
|
|
46853
46892
|
}
|
|
46854
46893
|
}
|
|
46855
46894
|
async function readInput(stream) {
|
|
@@ -48137,7 +48176,7 @@ async function liveUnits(db, projectId2, limit = 40) {
|
|
|
48137
48176
|
// server/src/extract.ts
|
|
48138
48177
|
var newRunId = () => crypto2.randomBytes(9).toString("base64url");
|
|
48139
48178
|
async function pendingText(db, projectId2) {
|
|
48140
|
-
await flush().catch(() => {});
|
|
48179
|
+
await flush(undefined, TOOL_FLUSH_BUDGET_MS).catch(() => {});
|
|
48141
48180
|
const rows = await pendingSessions(db, projectId2);
|
|
48142
48181
|
if (!rows.length)
|
|
48143
48182
|
return "Every captured session has been traced.";
|
|
@@ -48159,14 +48198,14 @@ async function sessionOf(db, projectId2, given) {
|
|
|
48159
48198
|
return s.id;
|
|
48160
48199
|
}
|
|
48161
48200
|
async function beginTrace(db, projectId2, session) {
|
|
48162
|
-
await flush().catch(() => {});
|
|
48201
|
+
await flush(undefined, TOOL_FLUSH_BUDGET_MS).catch(() => {});
|
|
48163
48202
|
const s = await sessionOf(db, projectId2, session);
|
|
48164
48203
|
const run = newRunId();
|
|
48165
48204
|
await openRun(db, { projectId: projectId2, origin: "trace", target: `session:${s}`, sessionId: s, draftId: run });
|
|
48166
48205
|
return run;
|
|
48167
48206
|
}
|
|
48168
48207
|
async function beginGlean(db, projectId2, session) {
|
|
48169
|
-
await flush().catch(() => {});
|
|
48208
|
+
await flush(undefined, TOOL_FLUSH_BUDGET_MS).catch(() => {});
|
|
48170
48209
|
const s = await sessionOf(db, projectId2, session);
|
|
48171
48210
|
const run = newRunId();
|
|
48172
48211
|
await openRun(db, { projectId: projectId2, origin: "glean", target: "glean", sessionId: s, draftId: run });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sphica",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Records Claude Code and Codex sessions on your machine and keeps past implementation and decisions, with their sources, for your agent to find.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|