open-walnut 0.6.16 → 0.6.17
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 +7 -0
- package/dist/actions/inbox-triage-batch.js +556 -449
- package/dist/build-info.json +3 -3
- package/dist/cli-fast.js +2 -2
- package/dist/cli.js +564 -457
- package/dist/daemon-binaries/acp-worker.js.version +1 -1
- package/dist/daemon-binaries/dtach-linux-x64 +0 -0
- package/dist/integrations/calendar/index.js +556 -449
- package/dist/integrations/jira/index.js +556 -449
- package/dist/integrations/mail/index.js +2 -2
- package/dist/integrations/ms-todo/index.js +556 -449
- package/dist/web/server.js +577 -470
- package/package.json +1 -1
package/dist/web/server.js
CHANGED
|
@@ -11691,6 +11691,7 @@ function createOfflineHostCore(deps4) {
|
|
|
11691
11691
|
const MAX_ARGS_BYTES = 256 * 1024;
|
|
11692
11692
|
const WRITE_BUDGET = 30;
|
|
11693
11693
|
const WRITE_WINDOW_MS = 6e4;
|
|
11694
|
+
const LOCK_RETRY_MS = [100, 300, 900];
|
|
11694
11695
|
const DEFAULT_REPLY_SECS = 3600;
|
|
11695
11696
|
const IMPLICIT_REPLY_SECS = 6 * 3600;
|
|
11696
11697
|
const DRAIN_BATCH = 200;
|
|
@@ -11837,7 +11838,7 @@ function createOfflineHostCore(deps4) {
|
|
|
11837
11838
|
...opts2.admit ? { admit: opts2.admit } : {}
|
|
11838
11839
|
});
|
|
11839
11840
|
if (!r8.ok) {
|
|
11840
|
-
if (r8.code === "journal_unwritable") deps4.log("error", "offline host: journal write refused", { home, kind, code: r8.code, why: r8.why, error: r8.message });
|
|
11841
|
+
if (r8.code === "journal_unwritable" && r8.why !== "locked") deps4.log("error", "offline host: journal write refused", { home, kind, code: r8.code, why: r8.why, error: r8.message });
|
|
11841
11842
|
return r8;
|
|
11842
11843
|
}
|
|
11843
11844
|
if (!r8.duplicate) {
|
|
@@ -11852,6 +11853,19 @@ function createOfflineHostCore(deps4) {
|
|
|
11852
11853
|
if (r8.ok) return null;
|
|
11853
11854
|
return fail6(r8.code, r8.message, { ...r8.retryAfterMs !== void 0 ? { retryAfterMs: r8.retryAfterMs } : {}, ...r8.why ? { detail: { why: r8.why } } : {} });
|
|
11854
11855
|
}
|
|
11856
|
+
const lockRefused = (r8) => !r8.ok && r8.error.code === "journal_unwritable" && r8.error.detail?.why === "locked";
|
|
11857
|
+
async function whenUnlocked(home, op2, run12) {
|
|
11858
|
+
const t0 = Date.now();
|
|
11859
|
+
let r8 = run12();
|
|
11860
|
+
for (const ms2 of LOCK_RETRY_MS) {
|
|
11861
|
+
if (!lockRefused(r8)) return r8;
|
|
11862
|
+
deps4.log("warn", "offline host: the journal is locked by another process; trying the write again", { home, op: op2, waitedMs: Date.now() - t0, retryInMs: ms2 });
|
|
11863
|
+
await new Promise((resolve2) => setTimeout(resolve2, ms2));
|
|
11864
|
+
r8 = run12();
|
|
11865
|
+
}
|
|
11866
|
+
if (lockRefused(r8)) deps4.log("error", "offline host: the journal stayed locked; write refused", { home, op: op2, waitedMs: Date.now() - t0 });
|
|
11867
|
+
return r8;
|
|
11868
|
+
}
|
|
11855
11869
|
function configure(slice) {
|
|
11856
11870
|
if (!slice || slice.v !== 1 || typeof slice.home !== "string" || !slice.home) throw new Error("host.slice: bad slice");
|
|
11857
11871
|
const prev = slices.get(slice.home);
|
|
@@ -12585,10 +12599,8 @@ ${kit10.buildReplyTrailer(row)}`;
|
|
|
12585
12599
|
if (no) return no;
|
|
12586
12600
|
deps4.log("info", "offline host: write queued", { home, op: name, taskId: task.id, callerSid: callerSid5, kind: "task-fields", seq: saved.ok ? saved.seq : void 0 });
|
|
12587
12601
|
} else {
|
|
12588
|
-
const denied = admitWrite(callerSid5) ?? roomFor(home);
|
|
12589
|
-
if (denied) return denied;
|
|
12590
12602
|
const base = slices.get(home)?.tasks.find((t3) => t3.id === task.id)?.updated_at;
|
|
12591
|
-
const no = refusal2(append(home, { kind: "op", op: name, args: { ...args, id: task.id }, callerSid: callerSid5, ...base ? { base } : {} }));
|
|
12603
|
+
const no = refusal2(append(home, { kind: "op", op: name, args: { ...args, id: task.id }, callerSid: callerSid5, ...base ? { base } : {} }, false, { admit: () => admitWrite(callerSid5) ?? roomFor(home) }));
|
|
12592
12604
|
if (no) return no;
|
|
12593
12605
|
deps4.log("info", "offline host: write queued", { home, op: name, taskId: task.id, callerSid: callerSid5 });
|
|
12594
12606
|
}
|
|
@@ -13030,7 +13042,7 @@ ${kit10.buildReplyTrailer(row)}`;
|
|
|
13030
13042
|
const fromCopy = deps4.replica ? deps4.replica.answer(home, name, args, offlineNote(home)) : null;
|
|
13031
13043
|
if (fromCopy) return fromCopy;
|
|
13032
13044
|
if (deps4.boards && deps4.boards.BOARD_OPS.indexOf(name) !== -1) return opBoard(home, callerSid5, name, args);
|
|
13033
|
-
if (QUEUED_OPS.includes(name)) return opQueued(home, callerSid5, name, args);
|
|
13045
|
+
if (QUEUED_OPS.includes(name)) return whenUnlocked(home, name, () => opQueued(home, callerSid5, name, args));
|
|
13034
13046
|
return needsServer(name ? `"${name}"` : "That call");
|
|
13035
13047
|
}
|
|
13036
13048
|
}
|
|
@@ -13543,6 +13555,10 @@ ${mid}` : "";
|
|
|
13543
13555
|
handle: handle4,
|
|
13544
13556
|
handleLocal,
|
|
13545
13557
|
handleFollower,
|
|
13558
|
+
/** handleFollower, waiting out another process's journal lock (whenUnlocked): the twins' follower.op. */
|
|
13559
|
+
handleFollowerWaiting: (home, req) => whenUnlocked(home, String(req.op ?? ""), () => handleFollower(home, req)),
|
|
13560
|
+
/** noteSession, waiting out another process's journal lock (whenUnlocked): the twins' host ask. */
|
|
13561
|
+
noteSessionWaiting: (home, rec3, opId, by) => whenUnlocked(home, "session", () => noteSession(home, rec3, opId, by)),
|
|
13546
13562
|
pendingFor,
|
|
13547
13563
|
journalStats,
|
|
13548
13564
|
onResult,
|
|
@@ -28499,7 +28515,7 @@ function dispatchCommand(ws, id, cmd) {
|
|
|
28499
28515
|
case 'follower.sessions': return cmdFollowerSessions(ws, id);
|
|
28500
28516
|
case 'follower.send': return daemonCommands.run(function () { return cmdFollowerSend(ws, id, cmd); });
|
|
28501
28517
|
case 'follower.permission': return daemonCommands.run(function () { return cmdFollowerPermission(ws, id, cmd); });
|
|
28502
|
-
case 'follower.op': return cmdFollowerOp(ws, id, cmd);
|
|
28518
|
+
case 'follower.op': return daemonCommands.run(function () { return cmdFollowerOp(ws, id, cmd); });
|
|
28503
28519
|
case 'follower.pending': return cmdFollowerPending(ws, id, cmd);
|
|
28504
28520
|
// A new ask while the Mac is away ('replica-start-v1', WP12). Twin of daemon-standalone.ts.
|
|
28505
28521
|
case 'follower.start': return daemonCommands.run(function () { return cmdFollowerStart(ws, id, cmd); });
|
|
@@ -29913,14 +29929,15 @@ async function cmdFollowerPermission(ws, id, cmd) {
|
|
|
29913
29929
|
// The replica's write while the Mac is away (replica-ops-v1, journal v2). Its own gate:
|
|
29914
29930
|
// the follower's own Walnut, the quiet window unless the Mac is still taking the
|
|
29915
29931
|
// journal, and the daemon dir's owner. Twin of daemon-standalone.ts cmdFollowerOp.
|
|
29916
|
-
function cmdFollowerOp(ws, id, cmd) {
|
|
29932
|
+
async function cmdFollowerOp(ws, id, cmd) {
|
|
29917
29933
|
var home = followerHomeOf(ws);
|
|
29918
29934
|
if (!home) return sendError(ws, id, 'follower.op: send follower.hello first');
|
|
29919
29935
|
if (!followerMayWrite(home)) return sendError(ws, id, 'follower.op: your Mac answers again; write through it', { errorKind: 'leader_answers' });
|
|
29920
29936
|
if (!ownsDaemonDir()) {
|
|
29921
29937
|
return sendError(ws, id, 'follower.op: this daemon no longer owns its directory', { errorKind: 'journal_unwritable', detail: { why: 'not_owner' } });
|
|
29922
29938
|
}
|
|
29923
|
-
|
|
29939
|
+
// Waits out another process's journal lock (about 1.3 s) before it answers.
|
|
29940
|
+
var r = await offlineHost.handleFollowerWaiting(home, { op: cmd.op, args: cmd.args, actor: cmd.actor, opId: cmd.opId, base: cmd.base });
|
|
29924
29941
|
if (r.ok) return sendOk(ws, id, r.result);
|
|
29925
29942
|
sendError(ws, id, 'follower.op: ' + r.error.message, Object.assign({ errorKind: r.error.code },
|
|
29926
29943
|
r.error.detail !== undefined ? { detail: r.error.detail } : {}, r.error.retryAfterMs !== undefined ? { retryAfterMs: r.error.retryAfterMs } : {}));
|
|
@@ -30070,7 +30087,7 @@ async function startHostAsk(home, p, cmd) {
|
|
|
30070
30087
|
throw err;
|
|
30071
30088
|
}
|
|
30072
30089
|
if (DIE_AFTER_ASK_SPAWN) process.kill(process.pid, 'SIGKILL');
|
|
30073
|
-
var saved = offlineHost.
|
|
30090
|
+
var saved = await offlineHost.noteSessionWaiting(home, p.record, opId, cmd.actor);
|
|
30074
30091
|
hostStart.releasePending(home, p.sid);
|
|
30075
30092
|
if (!saved.ok) {
|
|
30076
30093
|
// Nothing would tell the Mac about this CLI: it must not run unseen. Not stamped as an
|
|
@@ -138297,8 +138314,9 @@ async function buildCopyManifest(kind) {
|
|
|
138297
138314
|
}
|
|
138298
138315
|
return manifest;
|
|
138299
138316
|
}
|
|
138300
|
-
function keepsCopiesTarget(t3) {
|
|
138301
|
-
|
|
138317
|
+
function keepsCopiesTarget(t3, kind) {
|
|
138318
|
+
if (t3.kind === "host") return t3.program?.() === "replica";
|
|
138319
|
+
return t3.kind === "companion" && (kind === void 0 || COMPANION_COPY_KINDS.has(kind));
|
|
138302
138320
|
}
|
|
138303
138321
|
function manifestDigest(manifest, ordered = false) {
|
|
138304
138322
|
let d8 = manifestDigests.get(manifest);
|
|
@@ -138412,7 +138430,7 @@ async function choiceOf(target2) {
|
|
|
138412
138430
|
}
|
|
138413
138431
|
async function syncCopyKinds(kinds, deps4 = {}) {
|
|
138414
138432
|
const now = deps4.now ?? Date.now;
|
|
138415
|
-
const all = (deps4.targets ?? await defaultTargets())().filter(keepsCopiesTarget);
|
|
138433
|
+
const all = (deps4.targets ?? await defaultTargets())().filter((t3) => kinds.some((k8) => keepsCopiesTarget(t3, k8.kind)));
|
|
138416
138434
|
const ready2 = [];
|
|
138417
138435
|
for (const target2 of all) if (await target2.available()) ready2.push({ target: target2, choice: await choiceOf(target2) });
|
|
138418
138436
|
const results = [];
|
|
@@ -138420,7 +138438,7 @@ async function syncCopyKinds(kinds, deps4 = {}) {
|
|
|
138420
138438
|
const asOf2 = now();
|
|
138421
138439
|
const manifests = /* @__PURE__ */ new Map();
|
|
138422
138440
|
for (const kind of kinds) {
|
|
138423
|
-
if (!ready2.some((r8) => r8.choice[kind.choice])) continue;
|
|
138441
|
+
if (!ready2.some((r8) => r8.choice[kind.choice] && keepsCopiesTarget(r8.target, kind.kind))) continue;
|
|
138424
138442
|
try {
|
|
138425
138443
|
manifests.set(kind.kind, await buildCopyManifest(kind));
|
|
138426
138444
|
} catch (err2) {
|
|
@@ -138429,6 +138447,7 @@ async function syncCopyKinds(kinds, deps4 = {}) {
|
|
|
138429
138447
|
}
|
|
138430
138448
|
for (const { target: target2, choice } of ready2) {
|
|
138431
138449
|
for (const kind of kinds) {
|
|
138450
|
+
if (!keepsCopiesTarget(target2, kind.kind)) continue;
|
|
138432
138451
|
const manifest = manifests.get(kind.kind);
|
|
138433
138452
|
const st2 = kindState(target2, kind.kind);
|
|
138434
138453
|
if (!choice[kind.choice]) {
|
|
@@ -138474,7 +138493,7 @@ async function purgeKind(kind, target2, st2) {
|
|
|
138474
138493
|
async function confirmCopyKindRemoval(targetId, kind, opts2 = {}) {
|
|
138475
138494
|
const { replicaTargets: replicaTargets2 } = await Promise.resolve().then(() => (init_replica_targets(), replica_targets_exports));
|
|
138476
138495
|
const target2 = replicaTargets2().find((t3) => t3.id === targetId);
|
|
138477
|
-
if (!target2 || target2
|
|
138496
|
+
if (!target2 || !keepsCopiesTarget(target2, kind) || !peekKindState(targetId, kind)) return false;
|
|
138478
138497
|
if (!confirmKindRemoval(target2, kind, opts2)) return false;
|
|
138479
138498
|
log.session.warn("copies: the user confirmed a removal of most rows", { target: targetId, kind, entries: peekKindState(targetId, kind)?.confirmFor?.entries });
|
|
138480
138499
|
copySoon(kind);
|
|
@@ -138589,6 +138608,7 @@ var init_copy_kind = __esm({
|
|
|
138589
138608
|
init_kind_leader();
|
|
138590
138609
|
init_search_digest();
|
|
138591
138610
|
init_replica_status();
|
|
138611
|
+
init_gate();
|
|
138592
138612
|
COPY_DEBOUNCE_MS = 3e3;
|
|
138593
138613
|
COPY_SWEEP_MS = 5 * 6e4;
|
|
138594
138614
|
COPY_FIRST_ROUND_MS = 15e3;
|
|
@@ -144407,6 +144427,7 @@ var init_routines = __esm({
|
|
|
144407
144427
|
var routines_follower_exports = {};
|
|
144408
144428
|
__export(routines_follower_exports, {
|
|
144409
144429
|
_resetRoutinesCopyForTesting: () => _resetRoutinesCopyForTesting,
|
|
144430
|
+
companionRoutinesCopy: () => companionRoutinesCopy,
|
|
144410
144431
|
readRoutinesCopy: () => readRoutinesCopy,
|
|
144411
144432
|
routinesFollower: () => routinesFollower
|
|
144412
144433
|
});
|
|
@@ -144502,6 +144523,10 @@ async function readRoutinesCopy(opts2 = {}) {
|
|
|
144502
144523
|
const shown = opts2.includeDisabled ? all : all.filter((j8) => j8.enabled);
|
|
144503
144524
|
return shown.sort((a8, b8) => (a8.state.nextRunAtMs ?? 0) - (b8.state.nextRunAtMs ?? 0));
|
|
144504
144525
|
}
|
|
144526
|
+
async function companionRoutinesCopy(opts2 = {}) {
|
|
144527
|
+
if (!await copyKindHeld("routines")) return null;
|
|
144528
|
+
return await readRoutinesCopy(opts2) ?? [];
|
|
144529
|
+
}
|
|
144505
144530
|
function _resetRoutinesCopyForTesting() {
|
|
144506
144531
|
io2 = copyStateIo("routines");
|
|
144507
144532
|
serial3 = serialChain();
|
|
@@ -144517,8 +144542,8 @@ var init_routines_follower = __esm({
|
|
|
144517
144542
|
init_gate();
|
|
144518
144543
|
init_state_io();
|
|
144519
144544
|
init_routines();
|
|
144520
|
-
jobsFile = () => CRON_FILE;
|
|
144521
|
-
statesFile = () => path112.join(path112.dirname(CRON_FILE), "cron-state.json");
|
|
144545
|
+
jobsFile = () => copyPath(CRON_FILE);
|
|
144546
|
+
statesFile = () => copyPath(path112.join(path112.dirname(CRON_FILE), "cron-state.json"));
|
|
144522
144547
|
io2 = copyStateIo("routines");
|
|
144523
144548
|
serial3 = serialChain();
|
|
144524
144549
|
follower2 = null;
|
|
@@ -161110,8 +161135,8 @@ import path130 from "path";
|
|
|
161110
161135
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
161111
161136
|
function getVersion() {
|
|
161112
161137
|
if (cachedVersion) return cachedVersion;
|
|
161113
|
-
if ("0.6.
|
|
161114
|
-
cachedVersion = "0.6.
|
|
161138
|
+
if ("0.6.17") {
|
|
161139
|
+
cachedVersion = "0.6.17";
|
|
161115
161140
|
versionKnown = true;
|
|
161116
161141
|
return cachedVersion;
|
|
161117
161142
|
}
|
|
@@ -185571,6 +185596,132 @@ var init_cloud_owned_session = __esm({
|
|
|
185571
185596
|
}
|
|
185572
185597
|
});
|
|
185573
185598
|
|
|
185599
|
+
// src/core/replication/kinds/personas.ts
|
|
185600
|
+
var personas_exports = {};
|
|
185601
|
+
__export(personas_exports, {
|
|
185602
|
+
PERSONAS_KIND: () => PERSONAS_KIND,
|
|
185603
|
+
PERSONAS_REMOVAL_FLOOR: () => PERSONAS_REMOVAL_FLOOR,
|
|
185604
|
+
PERSONAS_SCHEMA_VERSION: () => PERSONAS_SCHEMA_VERSION,
|
|
185605
|
+
_resetPersonasCopyForTesting: () => _resetPersonasCopyForTesting,
|
|
185606
|
+
personasFollower: () => personasFollower,
|
|
185607
|
+
readPersonaCopy: () => readPersonaCopy
|
|
185608
|
+
});
|
|
185609
|
+
function tools(v3) {
|
|
185610
|
+
return Array.isArray(v3) && v3.length > 0 && v3.every((t3) => typeof t3 === "string" && TOOL_RE.test(t3)) ? [...v3] : void 0;
|
|
185611
|
+
}
|
|
185612
|
+
async function leaderRows() {
|
|
185613
|
+
const [{ getConsoleAgents: getConsoleAgents2 }, { buildLaneProfile: buildLaneProfile2 }, { getConfig: getConfig2 }, { getAskWalnutLaunchPrefs: getAskWalnutLaunchPrefs2 }] = await Promise.all([
|
|
185614
|
+
Promise.resolve().then(() => (init_agent_registry(), agent_registry_exports)),
|
|
185615
|
+
Promise.resolve().then(() => (init_personal_ai_lane(), personal_ai_lane_exports)),
|
|
185616
|
+
Promise.resolve().then(() => (init_config_manager(), config_manager_exports)),
|
|
185617
|
+
Promise.resolve().then(() => (init_ask_walnut_launch(), ask_walnut_launch_exports))
|
|
185618
|
+
]);
|
|
185619
|
+
const config = await getConfig2();
|
|
185620
|
+
const launch = await getAskWalnutLaunchPrefs2().catch(() => ({}));
|
|
185621
|
+
const agents = [{ id: "general", name: "Walnut" }, ...(await getConsoleAgents2()).filter((a8) => a8.id !== "general").map((a8) => ({ id: a8.id, name: a8.name }))];
|
|
185622
|
+
const rows = [];
|
|
185623
|
+
for (const a8 of agents) {
|
|
185624
|
+
if (!ID_RE.test(a8.id)) continue;
|
|
185625
|
+
try {
|
|
185626
|
+
const { profile, effort } = await buildLaneProfile2(config, a8.id);
|
|
185627
|
+
const prompt = profile.systemPrompt ?? "";
|
|
185628
|
+
if (!prompt || Buffer.byteLength(prompt, "utf8") > MAX_PROMPT_BYTES) continue;
|
|
185629
|
+
rows.push({
|
|
185630
|
+
key: a8.id,
|
|
185631
|
+
agentId: a8.id,
|
|
185632
|
+
name: String(a8.name ?? a8.id).slice(0, 120),
|
|
185633
|
+
systemPrompt: prompt,
|
|
185634
|
+
systemPromptMode: profile.systemPromptMode === "replace" ? "replace" : "append",
|
|
185635
|
+
...tools(profile.allowedTools) ? { allowedTools: tools(profile.allowedTools) } : {},
|
|
185636
|
+
...tools(profile.tools) ? { tools: tools(profile.tools) } : {},
|
|
185637
|
+
...effort ? { effort } : {},
|
|
185638
|
+
...launch.model ? { launchModel: launch.model } : {},
|
|
185639
|
+
...launch.effort ? { launchEffort: launch.effort } : {}
|
|
185640
|
+
});
|
|
185641
|
+
} catch (err2) {
|
|
185642
|
+
log.session.warn("copies: an agent persona was not rendered for the host", { agentId: a8.id, error: err2 instanceof Error ? err2.message : String(err2) });
|
|
185643
|
+
}
|
|
185644
|
+
}
|
|
185645
|
+
return rows;
|
|
185646
|
+
}
|
|
185647
|
+
function hashOf4(row) {
|
|
185648
|
+
let h8 = hashes3.get(row);
|
|
185649
|
+
if (h8 === void 0) {
|
|
185650
|
+
h8 = sha12(JSON.stringify(row));
|
|
185651
|
+
hashes3.set(row, h8);
|
|
185652
|
+
}
|
|
185653
|
+
return h8;
|
|
185654
|
+
}
|
|
185655
|
+
function isRow3(v3) {
|
|
185656
|
+
const r8 = v3;
|
|
185657
|
+
if (!r8 || typeof r8 !== "object" || Array.isArray(r8)) return false;
|
|
185658
|
+
if (Object.keys(r8).some((k8) => !ROW_KEYS.has(k8))) return false;
|
|
185659
|
+
if (typeof r8.key !== "string" || r8.key !== r8.agentId || !ID_RE.test(r8.key) || typeof r8.name !== "string") return false;
|
|
185660
|
+
if (typeof r8.systemPrompt !== "string" || !r8.systemPrompt || Buffer.byteLength(r8.systemPrompt, "utf8") > MAX_PROMPT_BYTES) return false;
|
|
185661
|
+
if (r8.systemPromptMode !== "append" && r8.systemPromptMode !== "replace") return false;
|
|
185662
|
+
for (const k8 of ["allowedTools", "tools"]) if (r8[k8] !== void 0 && !tools(r8[k8])) return false;
|
|
185663
|
+
for (const k8 of ["effort", "launchModel", "launchEffort"]) if (r8[k8] !== void 0 && (typeof r8[k8] !== "string" || !/^[A-Za-z0-9._:[\]/-]{1,128}$/.test(r8[k8]))) return false;
|
|
185664
|
+
return true;
|
|
185665
|
+
}
|
|
185666
|
+
function admit(r8) {
|
|
185667
|
+
return secretShapedValue(r8.systemPrompt) === null && secretShapedValue(r8.name) === null;
|
|
185668
|
+
}
|
|
185669
|
+
async function readPersonaCopy(agentId) {
|
|
185670
|
+
const rows = await copy.read();
|
|
185671
|
+
return rows?.[agentId] ?? null;
|
|
185672
|
+
}
|
|
185673
|
+
function _resetPersonasCopyForTesting() {
|
|
185674
|
+
copy.reset();
|
|
185675
|
+
}
|
|
185676
|
+
var PERSONAS_SCHEMA_VERSION, PERSONAS_REMOVAL_FLOOR, MAX_PROMPT_BYTES, ID_RE, TOOL_RE, hashes3, PERSONAS_KIND, ROW_KEYS, copy, personasFollower;
|
|
185677
|
+
var init_personas = __esm({
|
|
185678
|
+
"src/core/replication/kinds/personas.ts"() {
|
|
185679
|
+
"use strict";
|
|
185680
|
+
init_logging();
|
|
185681
|
+
init_config_allowlist();
|
|
185682
|
+
init_kind();
|
|
185683
|
+
init_file_copy();
|
|
185684
|
+
PERSONAS_SCHEMA_VERSION = 1;
|
|
185685
|
+
PERSONAS_REMOVAL_FLOOR = 0;
|
|
185686
|
+
MAX_PROMPT_BYTES = 120 * 1024;
|
|
185687
|
+
ID_RE = /^[A-Za-z0-9_-]{1,80}$/;
|
|
185688
|
+
TOOL_RE = /^[A-Za-z0-9_.:*()/ -]{1,200}$/;
|
|
185689
|
+
hashes3 = /* @__PURE__ */ new WeakMap();
|
|
185690
|
+
PERSONAS_KIND = {
|
|
185691
|
+
kind: "personas",
|
|
185692
|
+
schemaVersion: PERSONAS_SCHEMA_VERSION,
|
|
185693
|
+
key: (r8) => r8.key,
|
|
185694
|
+
hash: hashOf4,
|
|
185695
|
+
ordered: false,
|
|
185696
|
+
digest: false,
|
|
185697
|
+
choice: "personas",
|
|
185698
|
+
rows: leaderRows,
|
|
185699
|
+
watch: (soon) => {
|
|
185700
|
+
let stop2 = null;
|
|
185701
|
+
let stopped2 = false;
|
|
185702
|
+
void Promise.resolve().then(() => (init_config_manager(), config_manager_exports)).then((cm) => {
|
|
185703
|
+
if (!stopped2) stop2 = cm.onConfigWritten(soon);
|
|
185704
|
+
});
|
|
185705
|
+
return () => {
|
|
185706
|
+
stopped2 = true;
|
|
185707
|
+
stop2?.();
|
|
185708
|
+
};
|
|
185709
|
+
}
|
|
185710
|
+
};
|
|
185711
|
+
ROW_KEYS = /* @__PURE__ */ new Set(["key", "agentId", "name", "systemPrompt", "systemPromptMode", "allowedTools", "tools", "effort", "launchModel", "launchEffort"]);
|
|
185712
|
+
copy = createFileCopy({
|
|
185713
|
+
kind: "personas",
|
|
185714
|
+
schemaVersion: PERSONAS_SCHEMA_VERSION,
|
|
185715
|
+
label: "personas copy",
|
|
185716
|
+
removalFloor: PERSONAS_REMOVAL_FLOOR,
|
|
185717
|
+
isRow: isRow3,
|
|
185718
|
+
key: (r8) => r8.key,
|
|
185719
|
+
admit
|
|
185720
|
+
});
|
|
185721
|
+
personasFollower = copy.follower;
|
|
185722
|
+
}
|
|
185723
|
+
});
|
|
185724
|
+
|
|
185574
185725
|
// src/core/sessions/cloud-chat-lane.ts
|
|
185575
185726
|
var cloud_chat_lane_exports = {};
|
|
185576
185727
|
__export(cloud_chat_lane_exports, {
|
|
@@ -185709,7 +185860,9 @@ async function resolveCloudChatLane(lane, agentId, conversationId, cwd, firstMes
|
|
|
185709
185860
|
CATCH_UP_BANNER_CLOSE: CATCH_UP_BANNER_CLOSE2,
|
|
185710
185861
|
buildConversationSeed: buildConversationSeed2
|
|
185711
185862
|
} = await Promise.resolve().then(() => (init_chat_history(), chat_history_exports));
|
|
185712
|
-
const {
|
|
185863
|
+
const { readPersonaCopy: readPersonaCopy2 } = await Promise.resolve().then(() => (init_personas(), personas_exports));
|
|
185864
|
+
const persona = await readPersonaCopy2(agentId).catch(() => null);
|
|
185865
|
+
const { profile: base, effort, seed } = await buildLaneProfile2(config, agentId, { conversationId, ...persona ? { persona } : {} });
|
|
185713
185866
|
const profile = toCloudChatProfile(base, CONVERSATION_SEED_HEADER2);
|
|
185714
185867
|
const sessionId = crypto46.randomUUID();
|
|
185715
185868
|
const seedInProfile = !!seed && (seed.text !== "" || seed.stats.turnsTotal === 0);
|
|
@@ -192678,9 +192831,9 @@ function sanitizeHealthSync(body7, now = Date.now()) {
|
|
|
192678
192831
|
const tz = isValidTz(b8.tz) ? b8.tz : "";
|
|
192679
192832
|
const spec = metricSpec(type);
|
|
192680
192833
|
const generic = isGenericType(type);
|
|
192681
|
-
const storeId = typeof b8.storeId === "string" &&
|
|
192834
|
+
const storeId = typeof b8.storeId === "string" && ID_RE2.test(b8.storeId) ? b8.storeId : void 0;
|
|
192682
192835
|
const dev = b8.device && typeof b8.device === "object" ? b8.device : {};
|
|
192683
|
-
const installId = typeof dev.installId === "string" &&
|
|
192836
|
+
const installId = typeof dev.installId === "string" && ID_RE2.test(dev.installId) ? dev.installId : void 0;
|
|
192684
192837
|
const device = { installId, model: str10(dev.model, 64), os: str10(dev.os, 64) };
|
|
192685
192838
|
const hasDevice = Object.values(device).some((v3) => v3 !== void 0);
|
|
192686
192839
|
const deleted = [...new Set(deletedIn.filter((u3) => typeof u3 === "string" && UUID_RE3.test(u3)))];
|
|
@@ -192748,14 +192901,14 @@ function relayPayload(batch) {
|
|
|
192748
192901
|
samples: batch.samples.map(({ tz, ...rest }) => tz === batch.tz ? rest : { ...rest, tz })
|
|
192749
192902
|
};
|
|
192750
192903
|
}
|
|
192751
|
-
var UUID_RE3,
|
|
192904
|
+
var UUID_RE3, ID_RE2, MIN_INSTANT, FUTURE_SLACK_MS2, MAX_SPAN_MS;
|
|
192752
192905
|
var init_sanitize = __esm({
|
|
192753
192906
|
"src/core/health/sanitize.ts"() {
|
|
192754
192907
|
"use strict";
|
|
192755
192908
|
init_catalog();
|
|
192756
192909
|
init_day_key();
|
|
192757
192910
|
UUID_RE3 = /^[A-Za-z0-9][A-Za-z0-9-]{0,63}$/;
|
|
192758
|
-
|
|
192911
|
+
ID_RE2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/;
|
|
192759
192912
|
MIN_INSTANT = Date.UTC(2010, 0, 1);
|
|
192760
192913
|
FUTURE_SLACK_MS2 = 36 * 36e5;
|
|
192761
192914
|
MAX_SPAN_MS = 2 * 864e5;
|
|
@@ -205327,7 +205480,7 @@ async function saveRecordingAudio(audioBase64, format2) {
|
|
|
205327
205480
|
return { id, audioPath };
|
|
205328
205481
|
}
|
|
205329
205482
|
async function writeRecordingResult(id, meta) {
|
|
205330
|
-
if (!
|
|
205483
|
+
if (!ID_RE3.test(id)) throw new Error(`Invalid recording id: ${id}`);
|
|
205331
205484
|
await mkdir7(dir(), { recursive: true });
|
|
205332
205485
|
const stamped = { timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...meta };
|
|
205333
205486
|
await writeFile6(join17(dir(), `${id}.json`), JSON.stringify(stamped, null, 2));
|
|
@@ -205336,7 +205489,7 @@ async function writeRecordingResult(id, meta) {
|
|
|
205336
205489
|
return stamped.timestamp;
|
|
205337
205490
|
}
|
|
205338
205491
|
async function writeRecordingSecondary(id, secondary, expectTimestamp) {
|
|
205339
|
-
if (!
|
|
205492
|
+
if (!ID_RE3.test(id)) throw new Error(`Invalid recording id: ${id}`);
|
|
205340
205493
|
const path297 = join17(dir(), `${id}.json`);
|
|
205341
205494
|
let existing;
|
|
205342
205495
|
try {
|
|
@@ -205358,7 +205511,7 @@ async function listRecordings(limit = 20) {
|
|
|
205358
205511
|
const out = [];
|
|
205359
205512
|
for (const jf of jsonFiles) {
|
|
205360
205513
|
const id = jf.slice(0, -5);
|
|
205361
|
-
if (!
|
|
205514
|
+
if (!ID_RE3.test(id)) continue;
|
|
205362
205515
|
try {
|
|
205363
205516
|
const raw = JSON.parse(await readFile8(join17(dir(), jf), "utf-8"));
|
|
205364
205517
|
out.push({
|
|
@@ -205378,7 +205531,7 @@ async function listRecordings(limit = 20) {
|
|
|
205378
205531
|
return out;
|
|
205379
205532
|
}
|
|
205380
205533
|
async function readRecordingAudio(id) {
|
|
205381
|
-
if (!
|
|
205534
|
+
if (!ID_RE3.test(id)) return null;
|
|
205382
205535
|
let files;
|
|
205383
205536
|
try {
|
|
205384
205537
|
files = await readdir4(dir());
|
|
@@ -205406,13 +205559,13 @@ async function pruneOldRecordings() {
|
|
|
205406
205559
|
}
|
|
205407
205560
|
}
|
|
205408
205561
|
}
|
|
205409
|
-
var MAX_RECORDINGS,
|
|
205562
|
+
var MAX_RECORDINGS, ID_RE3, AUDIO_EXTS;
|
|
205410
205563
|
var init_recordings = __esm({
|
|
205411
205564
|
"src/core/stt/recordings.ts"() {
|
|
205412
205565
|
"use strict";
|
|
205413
205566
|
init_constants();
|
|
205414
205567
|
MAX_RECORDINGS = 100;
|
|
205415
|
-
|
|
205568
|
+
ID_RE3 = /^[0-9A-Za-z-]+$/;
|
|
205416
205569
|
AUDIO_EXTS = ["webm", "mp4", "ogg", "wav", "mp3", "m4a", "flac"];
|
|
205417
205570
|
}
|
|
205418
205571
|
});
|
|
@@ -208124,7 +208277,7 @@ async function adoptDeviceRecord(input, opts2 = {}) {
|
|
|
208124
208277
|
const existing = devices.find((d8) => d8.tokenHash === tokenHash);
|
|
208125
208278
|
if (existing) return { result: { name: existing.name, adopted: false } };
|
|
208126
208279
|
const finalName = freeName(devices, name);
|
|
208127
|
-
const wanted = typeof input.id === "string" &&
|
|
208280
|
+
const wanted = typeof input.id === "string" && ID_RE4.test(input.id) ? input.id : void 0;
|
|
208128
208281
|
const idFree = wanted !== void 0 && !devices.some((d8) => d8.id === wanted || d8.ownerId === wanted);
|
|
208129
208282
|
const record2 = {
|
|
208130
208283
|
name: finalName,
|
|
@@ -208159,7 +208312,7 @@ async function revokeAdopted(tokenHash) {
|
|
|
208159
208312
|
if (out.revoked) log.web.info("device-adoption: twin pairing revoked", { name: record2.name, adoptedFrom: record2.adoptedFrom ?? null });
|
|
208160
208313
|
return out.revoked ? { name: record2.name, refused: false, push: out.push } : { name: null, refused: false, push: null };
|
|
208161
208314
|
}
|
|
208162
|
-
var AdoptionError, HASH_RE,
|
|
208315
|
+
var AdoptionError, HASH_RE, ID_RE4, INFO_FIELD_MAX2, NAME_MAX;
|
|
208163
208316
|
var init_device_adoption = __esm({
|
|
208164
208317
|
"src/core/device-adoption.ts"() {
|
|
208165
208318
|
"use strict";
|
|
@@ -208177,7 +208330,7 @@ var init_device_adoption = __esm({
|
|
|
208177
208330
|
}
|
|
208178
208331
|
};
|
|
208179
208332
|
HASH_RE = /^[0-9a-f]{64}$/;
|
|
208180
|
-
|
|
208333
|
+
ID_RE4 = /^d[0-9a-f]{16}$/;
|
|
208181
208334
|
INFO_FIELD_MAX2 = 120;
|
|
208182
208335
|
NAME_MAX = 64;
|
|
208183
208336
|
}
|
|
@@ -214780,10 +214933,13 @@ async function cleanupLaneClaudeMd(homeDir2 = WALNUT_HOME) {
|
|
|
214780
214933
|
}
|
|
214781
214934
|
}
|
|
214782
214935
|
async function buildLaneProfile(config, agentId, opts2) {
|
|
214783
|
-
const
|
|
214784
|
-
const
|
|
214936
|
+
const persona = opts2?.persona;
|
|
214937
|
+
const skillsIndex = persona ? "" : await buildSessionSkillsPrompt().catch(() => "");
|
|
214938
|
+
const memoryContext = persona ? "" : await buildLaneMemoryContext().catch(() => "");
|
|
214785
214939
|
let profile;
|
|
214786
|
-
if (
|
|
214940
|
+
if (persona) {
|
|
214941
|
+
profile = mergeProfiles({ systemPrompt: persona.systemPrompt, systemPromptMode: persona.systemPromptMode }, walnutMcpProfile());
|
|
214942
|
+
} else if (agentId === "general") {
|
|
214787
214943
|
profile = personalAiProfile(config.user?.name ?? "the user", skillsIndex, memoryContext);
|
|
214788
214944
|
} else {
|
|
214789
214945
|
const { getAgent: getAgent2 } = await Promise.resolve().then(() => (init_agent_registry(), agent_registry_exports));
|
|
@@ -214793,7 +214949,8 @@ async function buildLaneProfile(config, agentId, opts2) {
|
|
|
214793
214949
|
const contextBlock = await loadContextSources2(agentDef, {}).catch(() => "");
|
|
214794
214950
|
profile = consoleAgentProfile(agentDef, skillsIndex, contextBlock);
|
|
214795
214951
|
}
|
|
214796
|
-
const
|
|
214952
|
+
const personaEffort = persona?.effort && LANE_EFFORTS.has(persona.effort) ? persona.effort : void 0;
|
|
214953
|
+
const effort = personaEffort ?? config.agent?.session_effort ?? "medium";
|
|
214797
214954
|
if (!opts2?.conversationId) return { profile, effort };
|
|
214798
214955
|
const base = profile.systemPrompt ?? "";
|
|
214799
214956
|
const headroom = MAX_LANE_PROMPT_BYTES - Buffer.byteLength(base, "utf-8") - LANE_SEED_RESERVE_BYTES;
|
|
@@ -215063,7 +215220,7 @@ async function resolveLane(lane, agentId, conversationId, firstMessage, engine)
|
|
|
215063
215220
|
});
|
|
215064
215221
|
return { sessionId, created: true, engine: "claude" };
|
|
215065
215222
|
}
|
|
215066
|
-
var inFlight13, LANE_MEMORY_HEADER, MANAGED_LANE_CONTEXT_MARKERS, MAX_LANE_PROMPT_BYTES, LANE_SEED_RESERVE_BYTES, LANE_SEED_MIN_BYTES, walnutProfileRefreshAt, WALNUT_PROFILE_REFRESH_TTL_MS;
|
|
215223
|
+
var LANE_EFFORTS, inFlight13, LANE_MEMORY_HEADER, MANAGED_LANE_CONTEXT_MARKERS, MAX_LANE_PROMPT_BYTES, LANE_SEED_RESERVE_BYTES, LANE_SEED_MIN_BYTES, walnutProfileRefreshAt, WALNUT_PROFILE_REFRESH_TTL_MS;
|
|
215067
215224
|
var init_personal_ai_lane = __esm({
|
|
215068
215225
|
"src/core/sessions/personal-ai-lane.ts"() {
|
|
215069
215226
|
"use strict";
|
|
@@ -215078,6 +215235,7 @@ var init_personal_ai_lane = __esm({
|
|
|
215078
215235
|
init_default_engine();
|
|
215079
215236
|
init_ask_profile_prefix();
|
|
215080
215237
|
init_logging();
|
|
215238
|
+
LANE_EFFORTS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max"]);
|
|
215081
215239
|
inFlight13 = /* @__PURE__ */ new Map();
|
|
215082
215240
|
LANE_MEMORY_HEADER = "## Standing memory (injected by Walnut)";
|
|
215083
215241
|
MANAGED_LANE_CONTEXT_MARKERS = [
|
|
@@ -251129,7 +251287,7 @@ function changed3() {
|
|
|
251129
251287
|
}).catch(() => {
|
|
251130
251288
|
});
|
|
251131
251289
|
}
|
|
251132
|
-
function
|
|
251290
|
+
function isRow4(v3) {
|
|
251133
251291
|
const t3 = v3;
|
|
251134
251292
|
return !!t3 && typeof t3 === "object" && typeof t3.id === "string" && !!t3.id && typeof t3.title === "string";
|
|
251135
251293
|
}
|
|
@@ -251201,7 +251359,7 @@ function makeTasksFollower() {
|
|
|
251201
251359
|
refuse: refuse10,
|
|
251202
251360
|
load: load3,
|
|
251203
251361
|
save,
|
|
251204
|
-
isRow:
|
|
251362
|
+
isRow: isRow4,
|
|
251205
251363
|
key: (t3) => t3.id,
|
|
251206
251364
|
localKeys: async () => (await (await Promise.resolve().then(() => (init_task_manager(), task_manager_exports))).taskStoreForReplica()).tasks.map((t3) => t3.id),
|
|
251207
251365
|
apply: applyToStore,
|
|
@@ -251341,9 +251499,13 @@ var init_task_replica_store = __esm({
|
|
|
251341
251499
|
// src/core/replication/kinds/gate.ts
|
|
251342
251500
|
var gate_exports = {};
|
|
251343
251501
|
__export(gate_exports, {
|
|
251502
|
+
COMPANION_COPY_KINDS: () => COMPANION_COPY_KINDS,
|
|
251503
|
+
COPY_AS_OF_HEADER: () => COPY_AS_OF_HEADER,
|
|
251344
251504
|
KIND_NOT_COPIED: () => KIND_NOT_COPIED,
|
|
251505
|
+
copyKindAsOf: () => copyKindAsOf,
|
|
251345
251506
|
copyKindHeld: () => copyKindHeld,
|
|
251346
251507
|
copyKindOff: () => copyKindOff,
|
|
251508
|
+
copyPath: () => copyPath,
|
|
251347
251509
|
copyRefusal: () => copyRefusal,
|
|
251348
251510
|
copyStateFile: () => copyStateFile,
|
|
251349
251511
|
keepsCopies: () => keepsCopies,
|
|
@@ -251351,8 +251513,16 @@ __export(gate_exports, {
|
|
|
251351
251513
|
});
|
|
251352
251514
|
import fsp107 from "fs/promises";
|
|
251353
251515
|
import path202 from "path";
|
|
251354
|
-
function keepsCopies() {
|
|
251355
|
-
|
|
251516
|
+
function keepsCopies(kind) {
|
|
251517
|
+
if (isHostReplicaProgram()) return true;
|
|
251518
|
+
if (followerKind() !== "companion") return false;
|
|
251519
|
+
return kind === void 0 || COMPANION_COPY_KINDS.has(kind);
|
|
251520
|
+
}
|
|
251521
|
+
function copyPath(live6) {
|
|
251522
|
+
if (followerKind() !== "companion") return live6;
|
|
251523
|
+
const rel = path202.relative(WALNUT_HOME, live6);
|
|
251524
|
+
if (!rel || rel.startsWith("..") || path202.isAbsolute(rel)) throw new Error(`copyPath: ${live6} is not under the data dir`);
|
|
251525
|
+
return path202.join(WALNUT_HOME, "cache", "replica", "home", rel);
|
|
251356
251526
|
}
|
|
251357
251527
|
async function copyRefusal() {
|
|
251358
251528
|
if (!keepsCopies()) return { status: 404, error: "unknown_kind" };
|
|
@@ -251373,20 +251543,26 @@ async function copyKindOff(kind) {
|
|
|
251373
251543
|
}
|
|
251374
251544
|
}
|
|
251375
251545
|
async function copyKindHeld(kind) {
|
|
251546
|
+
return await copyKindAsOf(kind) !== null;
|
|
251547
|
+
}
|
|
251548
|
+
async function copyKindAsOf(kind) {
|
|
251376
251549
|
try {
|
|
251377
251550
|
const raw = JSON.parse(await fsp107.readFile(copyStateFile(kind), "utf8"));
|
|
251378
|
-
|
|
251551
|
+
if (!(raw?.v === 1 && raw.off !== true && !!raw.hashes && typeof raw.hashes === "object")) return null;
|
|
251552
|
+
return Number(raw.asOf) || 0;
|
|
251379
251553
|
} catch {
|
|
251380
|
-
return
|
|
251554
|
+
return null;
|
|
251381
251555
|
}
|
|
251382
251556
|
}
|
|
251383
|
-
var KIND_NOT_COPIED;
|
|
251557
|
+
var COMPANION_COPY_KINDS, COPY_AS_OF_HEADER, KIND_NOT_COPIED;
|
|
251384
251558
|
var init_gate = __esm({
|
|
251385
251559
|
"src/core/replication/kinds/gate.ts"() {
|
|
251386
251560
|
"use strict";
|
|
251387
251561
|
init_constants();
|
|
251388
251562
|
init_server_role();
|
|
251389
251563
|
init_kind_follower();
|
|
251564
|
+
COMPANION_COPY_KINDS = /* @__PURE__ */ new Set(["requests", "routines", "prefs", "personas"]);
|
|
251565
|
+
COPY_AS_OF_HEADER = "x-walnut-copy-as-of";
|
|
251390
251566
|
KIND_NOT_COPIED = "kind_not_copied";
|
|
251391
251567
|
}
|
|
251392
251568
|
});
|
|
@@ -251505,7 +251681,7 @@ async function readLeaderConfig() {
|
|
|
251505
251681
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("config.yaml is not a mapping");
|
|
251506
251682
|
return parsed;
|
|
251507
251683
|
}
|
|
251508
|
-
async function
|
|
251684
|
+
async function leaderRows2() {
|
|
251509
251685
|
const { rows, refused: refused2, unknown } = configCopyRows(await readLeaderConfig());
|
|
251510
251686
|
const note = JSON.stringify({ refused: refused2.map((r8) => [r8.key, r8.findings.map((f8) => `${f8.path}:${f8.reason}`)]), unknown });
|
|
251511
251687
|
if ((refused2.length > 0 || unknown.length > 0) && note !== lastWarned2) {
|
|
@@ -251517,30 +251693,30 @@ async function leaderRows() {
|
|
|
251517
251693
|
}
|
|
251518
251694
|
return rows;
|
|
251519
251695
|
}
|
|
251520
|
-
function
|
|
251521
|
-
let h8 =
|
|
251696
|
+
function hashOf5(row) {
|
|
251697
|
+
let h8 = hashes4.get(row);
|
|
251522
251698
|
if (h8 === void 0) {
|
|
251523
251699
|
h8 = sha12(JSON.stringify(row));
|
|
251524
|
-
|
|
251700
|
+
hashes4.set(row, h8);
|
|
251525
251701
|
}
|
|
251526
251702
|
return h8;
|
|
251527
251703
|
}
|
|
251528
|
-
function
|
|
251704
|
+
function isRow5(v3) {
|
|
251529
251705
|
const r8 = v3;
|
|
251530
251706
|
return !!r8 && typeof r8 === "object" && typeof r8.key === "string" && !!r8.key && "value" in r8 && Object.keys(r8).length === 2;
|
|
251531
251707
|
}
|
|
251532
251708
|
async function readConfigCopy() {
|
|
251533
|
-
const rows = await
|
|
251709
|
+
const rows = await copy2.read();
|
|
251534
251710
|
if (!rows) return null;
|
|
251535
251711
|
const out = {};
|
|
251536
251712
|
for (const r8 of Object.values(rows)) if (configRowAdmissible(r8)) out[r8.key] = r8.value;
|
|
251537
251713
|
return out;
|
|
251538
251714
|
}
|
|
251539
251715
|
function _resetConfigCopyForTesting() {
|
|
251540
|
-
|
|
251716
|
+
copy2.reset();
|
|
251541
251717
|
lastWarned2 = "";
|
|
251542
251718
|
}
|
|
251543
|
-
var CONFIG_SCHEMA_VERSION, CONFIG_REMOVAL_FLOOR, lastWarned2,
|
|
251719
|
+
var CONFIG_SCHEMA_VERSION, CONFIG_REMOVAL_FLOOR, lastWarned2, hashes4, CONFIG_KIND, copy2, configFollower;
|
|
251544
251720
|
var init_config12 = __esm({
|
|
251545
251721
|
"src/core/replication/kinds/config.ts"() {
|
|
251546
251722
|
"use strict";
|
|
@@ -251552,16 +251728,16 @@ var init_config12 = __esm({
|
|
|
251552
251728
|
CONFIG_SCHEMA_VERSION = 1;
|
|
251553
251729
|
CONFIG_REMOVAL_FLOOR = 0;
|
|
251554
251730
|
lastWarned2 = "";
|
|
251555
|
-
|
|
251731
|
+
hashes4 = /* @__PURE__ */ new WeakMap();
|
|
251556
251732
|
CONFIG_KIND = {
|
|
251557
251733
|
kind: "config",
|
|
251558
251734
|
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
251559
251735
|
key: (r8) => r8.key,
|
|
251560
|
-
hash:
|
|
251736
|
+
hash: hashOf5,
|
|
251561
251737
|
ordered: false,
|
|
251562
251738
|
digest: false,
|
|
251563
251739
|
choice: "config",
|
|
251564
|
-
rows:
|
|
251740
|
+
rows: leaderRows2,
|
|
251565
251741
|
watch: (soon) => {
|
|
251566
251742
|
let stop2 = null;
|
|
251567
251743
|
let stopped2 = false;
|
|
@@ -251574,16 +251750,16 @@ var init_config12 = __esm({
|
|
|
251574
251750
|
};
|
|
251575
251751
|
}
|
|
251576
251752
|
};
|
|
251577
|
-
|
|
251753
|
+
copy2 = createFileCopy({
|
|
251578
251754
|
kind: "config",
|
|
251579
251755
|
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
251580
251756
|
label: "config copy",
|
|
251581
251757
|
removalFloor: CONFIG_REMOVAL_FLOOR,
|
|
251582
|
-
isRow:
|
|
251758
|
+
isRow: isRow5,
|
|
251583
251759
|
key: (r8) => r8.key,
|
|
251584
251760
|
admit: configRowAdmissible
|
|
251585
251761
|
});
|
|
251586
|
-
configFollower =
|
|
251762
|
+
configFollower = copy2.follower;
|
|
251587
251763
|
}
|
|
251588
251764
|
});
|
|
251589
251765
|
|
|
@@ -251779,7 +251955,7 @@ function prefAdmissible(p6) {
|
|
|
251779
251955
|
function strings(v3) {
|
|
251780
251956
|
return Array.isArray(v3) ? v3.filter((x3) => typeof x3 === "string") : [];
|
|
251781
251957
|
}
|
|
251782
|
-
async function
|
|
251958
|
+
async function leaderRows3() {
|
|
251783
251959
|
const raw = await readJsonFile(UI_PREFS_FILE, {}, { readErrors: "throw" });
|
|
251784
251960
|
const rows = [];
|
|
251785
251961
|
for (const [k8, v3] of Object.entries(raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {})) {
|
|
@@ -251791,15 +251967,15 @@ async function leaderRows2() {
|
|
|
251791
251967
|
rows.push({ key: "favorites", favorites: { projects: strings(fav?.projects), notes: strings(fav?.notes) } });
|
|
251792
251968
|
return rows;
|
|
251793
251969
|
}
|
|
251794
|
-
function
|
|
251795
|
-
let h8 =
|
|
251970
|
+
function hashOf6(row) {
|
|
251971
|
+
let h8 = hashes5.get(row);
|
|
251796
251972
|
if (h8 === void 0) {
|
|
251797
251973
|
h8 = sha12(JSON.stringify(row));
|
|
251798
|
-
|
|
251974
|
+
hashes5.set(row, h8);
|
|
251799
251975
|
}
|
|
251800
251976
|
return h8;
|
|
251801
251977
|
}
|
|
251802
|
-
function
|
|
251978
|
+
function isRow6(v3) {
|
|
251803
251979
|
const r8 = v3;
|
|
251804
251980
|
if (!r8 || typeof r8 !== "object" || typeof r8.key !== "string") return false;
|
|
251805
251981
|
if (r8.key === "favorites") {
|
|
@@ -251809,27 +251985,27 @@ function isRow5(v3) {
|
|
|
251809
251985
|
const p6 = prefOf(r8.pref);
|
|
251810
251986
|
return Object.keys(r8).length === 2 && r8.key.startsWith(UI) && copyableUiPrefKey(r8.key.slice(UI.length)) && !!p6 && typeof r8.pref === "object";
|
|
251811
251987
|
}
|
|
251812
|
-
function
|
|
251988
|
+
function admit2(r8) {
|
|
251813
251989
|
if ("favorites" in r8) return [...r8.favorites.projects, ...r8.favorites.notes].every((s4) => typeof s4 === "string" && secretShapedValue(s4) === null);
|
|
251814
251990
|
return prefAdmissible(r8.pref);
|
|
251815
251991
|
}
|
|
251816
251992
|
async function readUiPrefsCopy() {
|
|
251817
|
-
const rows = await
|
|
251993
|
+
const rows = await copy3.read();
|
|
251818
251994
|
if (!rows) return null;
|
|
251819
251995
|
const out = {};
|
|
251820
251996
|
for (const r8 of Object.values(rows)) if ("pref" in r8) out[r8.key.slice(UI.length)] = r8.pref;
|
|
251821
251997
|
return out;
|
|
251822
251998
|
}
|
|
251823
251999
|
async function readFavoritesCopy() {
|
|
251824
|
-
const rows = await
|
|
252000
|
+
const rows = await copy3.read();
|
|
251825
252001
|
if (!rows) return null;
|
|
251826
252002
|
const f8 = rows.favorites;
|
|
251827
252003
|
return f8 && "favorites" in f8 ? f8.favorites : { projects: [], notes: [] };
|
|
251828
252004
|
}
|
|
251829
252005
|
function _resetPrefsCopyForTesting() {
|
|
251830
|
-
|
|
252006
|
+
copy3.reset();
|
|
251831
252007
|
}
|
|
251832
|
-
var PREFS_SCHEMA_VERSION, PREFS_REMOVAL_FLOOR, UI, MAX_VALUE_LEN2,
|
|
252008
|
+
var PREFS_SCHEMA_VERSION, PREFS_REMOVAL_FLOOR, UI, MAX_VALUE_LEN2, hashes5, PREFS_KIND, copy3, prefsFollower;
|
|
251833
252009
|
var init_prefs = __esm({
|
|
251834
252010
|
"src/core/replication/kinds/prefs.ts"() {
|
|
251835
252011
|
"use strict";
|
|
@@ -251843,16 +252019,16 @@ var init_prefs = __esm({
|
|
|
251843
252019
|
PREFS_REMOVAL_FLOOR = 0;
|
|
251844
252020
|
UI = "ui:";
|
|
251845
252021
|
MAX_VALUE_LEN2 = 8 * 1024;
|
|
251846
|
-
|
|
252022
|
+
hashes5 = /* @__PURE__ */ new WeakMap();
|
|
251847
252023
|
PREFS_KIND = {
|
|
251848
252024
|
kind: "prefs",
|
|
251849
252025
|
schemaVersion: PREFS_SCHEMA_VERSION,
|
|
251850
252026
|
key: (r8) => r8.key,
|
|
251851
|
-
hash:
|
|
252027
|
+
hash: hashOf6,
|
|
251852
252028
|
ordered: false,
|
|
251853
252029
|
digest: false,
|
|
251854
252030
|
choice: "prefs",
|
|
251855
|
-
rows:
|
|
252031
|
+
rows: leaderRows3,
|
|
251856
252032
|
watch: (soon) => {
|
|
251857
252033
|
const stops = [];
|
|
251858
252034
|
let stopped2 = false;
|
|
@@ -251865,16 +252041,16 @@ var init_prefs = __esm({
|
|
|
251865
252041
|
};
|
|
251866
252042
|
}
|
|
251867
252043
|
};
|
|
251868
|
-
|
|
252044
|
+
copy3 = createFileCopy({
|
|
251869
252045
|
kind: "prefs",
|
|
251870
252046
|
schemaVersion: PREFS_SCHEMA_VERSION,
|
|
251871
252047
|
label: "prefs copy",
|
|
251872
252048
|
removalFloor: PREFS_REMOVAL_FLOOR,
|
|
251873
|
-
isRow:
|
|
252049
|
+
isRow: isRow6,
|
|
251874
252050
|
key: (r8) => r8.key,
|
|
251875
|
-
admit
|
|
252051
|
+
admit: admit2
|
|
251876
252052
|
});
|
|
251877
|
-
prefsFollower =
|
|
252053
|
+
prefsFollower = copy3.follower;
|
|
251878
252054
|
}
|
|
251879
252055
|
});
|
|
251880
252056
|
|
|
@@ -255022,7 +255198,7 @@ import crypto64 from "crypto";
|
|
|
255022
255198
|
import fs111 from "fs";
|
|
255023
255199
|
import path205 from "path";
|
|
255024
255200
|
function isDeviceCopyId(id) {
|
|
255025
|
-
return typeof id === "string" &&
|
|
255201
|
+
return typeof id === "string" && ID_RE5.test(id);
|
|
255026
255202
|
}
|
|
255027
255203
|
function sha256Hex2(text5) {
|
|
255028
255204
|
return crypto64.createHash("sha256").update(text5, "utf-8").digest("hex");
|
|
@@ -255112,14 +255288,14 @@ function createDeviceCopy(file) {
|
|
|
255112
255288
|
}
|
|
255113
255289
|
};
|
|
255114
255290
|
}
|
|
255115
|
-
var HASH_RE2, NAME_MAX2, MAX_DEVICES,
|
|
255291
|
+
var HASH_RE2, NAME_MAX2, MAX_DEVICES, ID_RE5;
|
|
255116
255292
|
var init_device_copy = __esm({
|
|
255117
255293
|
"src/host-server/device-copy.ts"() {
|
|
255118
255294
|
"use strict";
|
|
255119
255295
|
HASH_RE2 = /^[0-9a-f]{64}$/;
|
|
255120
255296
|
NAME_MAX2 = 64;
|
|
255121
255297
|
MAX_DEVICES = 500;
|
|
255122
|
-
|
|
255298
|
+
ID_RE5 = /^[A-Za-z0-9._:-]{1,80}$/;
|
|
255123
255299
|
}
|
|
255124
255300
|
});
|
|
255125
255301
|
|
|
@@ -255140,11 +255316,11 @@ function replicaDeviceCopyFile(home = WALNUT_HOME) {
|
|
|
255140
255316
|
return path206.join(home, "replica", "devices.json");
|
|
255141
255317
|
}
|
|
255142
255318
|
function replicaDeviceCopy() {
|
|
255143
|
-
|
|
255144
|
-
return
|
|
255319
|
+
copy4 ??= createDeviceCopy(replicaDeviceCopyFile());
|
|
255320
|
+
return copy4;
|
|
255145
255321
|
}
|
|
255146
255322
|
function _resetReplicaAuthForTesting() {
|
|
255147
|
-
|
|
255323
|
+
copy4 = null;
|
|
255148
255324
|
}
|
|
255149
255325
|
function verifyReplicaToken(token) {
|
|
255150
255326
|
const name = replicaDeviceCopy().verify(token);
|
|
@@ -255187,14 +255363,14 @@ async function replicaAuthMiddleware(req, res, next) {
|
|
|
255187
255363
|
req.deviceName = cred.name;
|
|
255188
255364
|
next();
|
|
255189
255365
|
}
|
|
255190
|
-
var
|
|
255366
|
+
var copy4, PUBLIC_GET_PATHS, REPLICA_FAILURE_KEY;
|
|
255191
255367
|
var init_auth11 = __esm({
|
|
255192
255368
|
"src/replica/auth.ts"() {
|
|
255193
255369
|
"use strict";
|
|
255194
255370
|
init_constants();
|
|
255195
255371
|
init_device_copy();
|
|
255196
255372
|
init_logging();
|
|
255197
|
-
|
|
255373
|
+
copy4 = null;
|
|
255198
255374
|
PUBLIC_GET_PATHS = /* @__PURE__ */ new Set(["/v1/instance"]);
|
|
255199
255375
|
REPLICA_FAILURE_KEY = "host-replica";
|
|
255200
255376
|
}
|
|
@@ -290793,6 +290969,147 @@ var init_task_v1 = __esm({
|
|
|
290793
290969
|
}
|
|
290794
290970
|
});
|
|
290795
290971
|
|
|
290972
|
+
// src/core/replication/kinds/requests.ts
|
|
290973
|
+
var requests_exports = {};
|
|
290974
|
+
__export(requests_exports, {
|
|
290975
|
+
REQUESTS_KIND: () => REQUESTS_KIND,
|
|
290976
|
+
REQUESTS_REMOVAL_FLOOR: () => REQUESTS_REMOVAL_FLOOR,
|
|
290977
|
+
REQUESTS_SCHEMA_VERSION: () => REQUESTS_SCHEMA_VERSION,
|
|
290978
|
+
_resetRequestsCopyForTesting: () => _resetRequestsCopyForTesting,
|
|
290979
|
+
forwardRequest: () => forwardRequest,
|
|
290980
|
+
readRequestCopy: () => readRequestCopy,
|
|
290981
|
+
requestsFollower: () => requestsFollower
|
|
290982
|
+
});
|
|
290983
|
+
import fsp136 from "fs/promises";
|
|
290984
|
+
import path259 from "path";
|
|
290985
|
+
function forwardRequest(local, incoming) {
|
|
290986
|
+
if (local && FINAL.has(local.status) && !FINAL.has(incoming.status)) return local;
|
|
290987
|
+
return incoming;
|
|
290988
|
+
}
|
|
290989
|
+
function hashOf7(row) {
|
|
290990
|
+
let h8 = hashes6.get(row);
|
|
290991
|
+
if (h8 === void 0) {
|
|
290992
|
+
h8 = sha12(JSON.stringify(row));
|
|
290993
|
+
hashes6.set(row, h8);
|
|
290994
|
+
}
|
|
290995
|
+
return h8;
|
|
290996
|
+
}
|
|
290997
|
+
async function load7() {
|
|
290998
|
+
if (state12) return state12;
|
|
290999
|
+
let s4 = { asOf: 0, at: 0, order: [], hashes: {} };
|
|
291000
|
+
try {
|
|
291001
|
+
const raw = JSON.parse(await fsp136.readFile(STATE_FILE2(), "utf8"));
|
|
291002
|
+
if (raw?.v === 1 && raw.hashes && typeof raw.hashes === "object") s4 = { asOf: Number(raw.asOf) || 0, at: Number(raw.at) || 0, order: [], hashes: raw.hashes };
|
|
291003
|
+
} catch {
|
|
291004
|
+
}
|
|
291005
|
+
state12 = s4;
|
|
291006
|
+
return s4;
|
|
291007
|
+
}
|
|
291008
|
+
async function save2() {
|
|
291009
|
+
if (state12) await writeCopyFile(STATE_FILE2(), { v: 1, asOf: state12.asOf, at: state12.at, hashes: state12.hashes });
|
|
291010
|
+
}
|
|
291011
|
+
async function readStore10() {
|
|
291012
|
+
try {
|
|
291013
|
+
const raw = JSON.parse(await fsp136.readFile(STORE_FILE(), "utf8"));
|
|
291014
|
+
return Array.isArray(raw?.requests) ? raw.requests.filter(isRow7) : [];
|
|
291015
|
+
} catch {
|
|
291016
|
+
return [];
|
|
291017
|
+
}
|
|
291018
|
+
}
|
|
291019
|
+
function isRow7(v3) {
|
|
291020
|
+
const r8 = v3;
|
|
291021
|
+
return !!r8 && typeof r8 === "object" && typeof r8.id === "string" && !!r8.id && typeof r8.fromSessionId === "string" && typeof r8.status === "string" && typeof r8.createdAt === "string";
|
|
291022
|
+
}
|
|
291023
|
+
function requestsFollower() {
|
|
291024
|
+
follower3 ??= createRowSetFollower({
|
|
291025
|
+
kind: "requests",
|
|
291026
|
+
schemaVersion: REQUESTS_SCHEMA_VERSION,
|
|
291027
|
+
label: "requests copy",
|
|
291028
|
+
log: log.session,
|
|
291029
|
+
removalFloor: REQUESTS_REMOVAL_FLOOR,
|
|
291030
|
+
ordered: false,
|
|
291031
|
+
serial: (fn) => serial5(fn),
|
|
291032
|
+
refuse: copyRefusal,
|
|
291033
|
+
load: load7,
|
|
291034
|
+
save: save2,
|
|
291035
|
+
isRow: isRow7,
|
|
291036
|
+
key: (r8) => r8.id,
|
|
291037
|
+
localKeys: async () => (await readStore10()).map((r8) => r8.id),
|
|
291038
|
+
apply: async ({ rows, removeIds }) => {
|
|
291039
|
+
const byId = new Map((await readStore10()).map((r8) => [r8.id, r8]));
|
|
291040
|
+
for (const id of removeIds ?? []) byId.delete(id);
|
|
291041
|
+
for (const r8 of rows ?? []) {
|
|
291042
|
+
const kept = forwardRequest(byId.get(r8.id), r8);
|
|
291043
|
+
if (kept !== r8) log.session.info("requests copy: kept a settled request the leader has not settled yet", { requestId: r8.id, local: kept.status, leader: r8.status });
|
|
291044
|
+
byId.set(r8.id, kept);
|
|
291045
|
+
}
|
|
291046
|
+
await writeCopyFile(STORE_FILE(), { requests: [...byId.values()] });
|
|
291047
|
+
return { skipped: [] };
|
|
291048
|
+
},
|
|
291049
|
+
held: async () => (await Promise.resolve().then(() => (init_journal_overlay(), journal_overlay_exports))).journalHeld("requests"),
|
|
291050
|
+
changed: () => {
|
|
291051
|
+
},
|
|
291052
|
+
purge: async () => {
|
|
291053
|
+
const removed = (await readStore10()).length;
|
|
291054
|
+
await fsp136.rm(STORE_FILE(), { force: true });
|
|
291055
|
+
await markCopyOff("requests");
|
|
291056
|
+
state12 = null;
|
|
291057
|
+
return { removed };
|
|
291058
|
+
}
|
|
291059
|
+
});
|
|
291060
|
+
return follower3;
|
|
291061
|
+
}
|
|
291062
|
+
async function readRequestCopy(id) {
|
|
291063
|
+
if (!await copyKindHeld("requests")) return null;
|
|
291064
|
+
return (await readStore10()).find((r8) => r8.id === id) ?? null;
|
|
291065
|
+
}
|
|
291066
|
+
function _resetRequestsCopyForTesting() {
|
|
291067
|
+
state12 = null;
|
|
291068
|
+
follower3 = null;
|
|
291069
|
+
serial5 = serialChain();
|
|
291070
|
+
}
|
|
291071
|
+
var REQUESTS_SCHEMA_VERSION, REQUESTS_REMOVAL_FLOOR, FINAL, hashes6, REQUESTS_KIND, STATE_FILE2, STORE_FILE, state12, serial5, follower3;
|
|
291072
|
+
var init_requests = __esm({
|
|
291073
|
+
"src/core/replication/kinds/requests.ts"() {
|
|
291074
|
+
"use strict";
|
|
291075
|
+
init_constants();
|
|
291076
|
+
init_logging();
|
|
291077
|
+
init_kind();
|
|
291078
|
+
init_kind_follower();
|
|
291079
|
+
init_gate();
|
|
291080
|
+
REQUESTS_SCHEMA_VERSION = 1;
|
|
291081
|
+
REQUESTS_REMOVAL_FLOOR = 50;
|
|
291082
|
+
FINAL = /* @__PURE__ */ new Set(["replied", "notified", "expired"]);
|
|
291083
|
+
hashes6 = /* @__PURE__ */ new WeakMap();
|
|
291084
|
+
REQUESTS_KIND = {
|
|
291085
|
+
kind: "requests",
|
|
291086
|
+
schemaVersion: REQUESTS_SCHEMA_VERSION,
|
|
291087
|
+
key: (r8) => r8.id,
|
|
291088
|
+
hash: hashOf7,
|
|
291089
|
+
ordered: false,
|
|
291090
|
+
digest: false,
|
|
291091
|
+
choice: "requests",
|
|
291092
|
+
rows: async () => (await Promise.resolve().then(() => (init_session_requests(), session_requests_exports))).listAllSessionRequests(),
|
|
291093
|
+
watch: (soon) => {
|
|
291094
|
+
let stop2 = null;
|
|
291095
|
+
let stopped2 = false;
|
|
291096
|
+
void Promise.resolve().then(() => (init_session_requests(), session_requests_exports)).then(({ onSessionRequestsWritten: onSessionRequestsWritten2 }) => {
|
|
291097
|
+
if (!stopped2) stop2 = onSessionRequestsWritten2(soon);
|
|
291098
|
+
});
|
|
291099
|
+
return () => {
|
|
291100
|
+
stopped2 = true;
|
|
291101
|
+
stop2?.();
|
|
291102
|
+
};
|
|
291103
|
+
}
|
|
291104
|
+
};
|
|
291105
|
+
STATE_FILE2 = () => path259.join(WALNUT_HOME, "cache", "replica", "requests.json");
|
|
291106
|
+
STORE_FILE = () => copyPath(path259.join(WALNUT_HOME, "session-requests.json"));
|
|
291107
|
+
state12 = null;
|
|
291108
|
+
serial5 = serialChain();
|
|
291109
|
+
follower3 = null;
|
|
291110
|
+
}
|
|
291111
|
+
});
|
|
291112
|
+
|
|
290796
291113
|
// src/web/routes/messages-v1.ts
|
|
290797
291114
|
import { Router as Router86 } from "express";
|
|
290798
291115
|
function header(req, name) {
|
|
@@ -290853,7 +291170,15 @@ var init_messages_v1 = __esm({
|
|
|
290853
291170
|
return;
|
|
290854
291171
|
}
|
|
290855
291172
|
const { getSessionRequest: getSessionRequest2 } = await Promise.resolve().then(() => (init_session_requests(), session_requests_exports));
|
|
290856
|
-
|
|
291173
|
+
let request3 = await getSessionRequest2(id);
|
|
291174
|
+
if (!request3) {
|
|
291175
|
+
const [{ readRequestCopy: readRequestCopy2 }, { copyKindAsOf: copyKindAsOf2, COPY_AS_OF_HEADER: COPY_AS_OF_HEADER2 }] = await Promise.all([
|
|
291176
|
+
Promise.resolve().then(() => (init_requests(), requests_exports)),
|
|
291177
|
+
Promise.resolve().then(() => (init_gate(), gate_exports))
|
|
291178
|
+
]);
|
|
291179
|
+
request3 = await readRequestCopy2(id) ?? void 0;
|
|
291180
|
+
if (request3) res.setHeader(COPY_AS_OF_HEADER2, String(await copyKindAsOf2("requests") ?? 0));
|
|
291181
|
+
}
|
|
290857
291182
|
if (!request3) {
|
|
290858
291183
|
sendV1Error(res, 404, "not_found", `No such request: ${id}`);
|
|
290859
291184
|
return;
|
|
@@ -292097,6 +292422,17 @@ var init_search_memory_v1 = __esm({
|
|
|
292097
292422
|
});
|
|
292098
292423
|
searchMemoryV1Router.get("/favorites", async (_req, res, next) => {
|
|
292099
292424
|
try {
|
|
292425
|
+
const [{ readFavoritesCopy: readFavoritesCopy2 }, { copyKindAsOf: copyKindAsOf2, COPY_AS_OF_HEADER: COPY_AS_OF_HEADER2 }] = await Promise.all([
|
|
292426
|
+
Promise.resolve().then(() => (init_prefs(), prefs_exports)),
|
|
292427
|
+
Promise.resolve().then(() => (init_gate(), gate_exports))
|
|
292428
|
+
]);
|
|
292429
|
+
const asOf2 = await copyKindAsOf2("prefs");
|
|
292430
|
+
const fav = asOf2 === null ? null : await readFavoritesCopy2();
|
|
292431
|
+
if (fav) {
|
|
292432
|
+
res.setHeader(COPY_AS_OF_HEADER2, String(asOf2));
|
|
292433
|
+
res.json({ projects: fav.projects ?? [], notes: fav.notes ?? [] });
|
|
292434
|
+
return;
|
|
292435
|
+
}
|
|
292100
292436
|
const { readFavorites: readFavorites2 } = await Promise.resolve().then(() => (init_favorites(), favorites_exports));
|
|
292101
292437
|
res.json(await readFavorites2());
|
|
292102
292438
|
} catch (err2) {
|
|
@@ -292259,9 +292595,9 @@ var init_leader = __esm({
|
|
|
292259
292595
|
|
|
292260
292596
|
// src/web/routes/pastes.ts
|
|
292261
292597
|
import { Router as Router91 } from "express";
|
|
292262
|
-
import
|
|
292598
|
+
import path260 from "path";
|
|
292263
292599
|
import { createHash as createHash41 } from "crypto";
|
|
292264
|
-
import
|
|
292600
|
+
import fsp137 from "fs/promises";
|
|
292265
292601
|
var pastesRouter, MAX_PASTE_CHARS;
|
|
292266
292602
|
var init_pastes = __esm({
|
|
292267
292603
|
"src/web/routes/pastes.ts"() {
|
|
@@ -292281,11 +292617,11 @@ var init_pastes = __esm({
|
|
|
292281
292617
|
res.status(413).json({ error: `Paste too large (max ${MAX_PASTE_CHARS} chars)` });
|
|
292282
292618
|
return;
|
|
292283
292619
|
}
|
|
292284
|
-
await
|
|
292620
|
+
await fsp137.mkdir(PASTES_DIR, { recursive: true });
|
|
292285
292621
|
const hash3 = createHash41("sha256").update(text5).digest("hex").slice(0, 12);
|
|
292286
292622
|
const filename = `${Date.now()}-${hash3}.txt`;
|
|
292287
|
-
const filePath =
|
|
292288
|
-
await
|
|
292623
|
+
const filePath = path260.join(PASTES_DIR, filename);
|
|
292624
|
+
await fsp137.writeFile(filePath, text5, "utf8");
|
|
292289
292625
|
log.web.info("paste spilled to disk", { filePath, chars: text5.length });
|
|
292290
292626
|
res.json({ path: filePath, filename, chars: text5.length });
|
|
292291
292627
|
} catch (err2) {
|
|
@@ -292301,8 +292637,8 @@ __export(file_content_replica_copy_exports, {
|
|
|
292301
292637
|
primaryDataDirRelPath: () => primaryDataDirRelPath,
|
|
292302
292638
|
resolveReplicaCopy: () => resolveReplicaCopy
|
|
292303
292639
|
});
|
|
292304
|
-
import
|
|
292305
|
-
import
|
|
292640
|
+
import path261 from "path";
|
|
292641
|
+
import fsp138 from "fs/promises";
|
|
292306
292642
|
function dataDirIndex(parts, tilde) {
|
|
292307
292643
|
if (tilde) return parts[1] === DATA_DIR_NAME ? 1 : -1;
|
|
292308
292644
|
if ((parts[0] === "Users" || parts[0] === "home") && parts[2] === DATA_DIR_NAME) return 2;
|
|
@@ -292332,12 +292668,12 @@ async function resolveReplicaCopy(requestPath) {
|
|
|
292332
292668
|
const rel = primaryDataDirRelPath(requestPath);
|
|
292333
292669
|
if (rel === null || deniedName(rel)) return null;
|
|
292334
292670
|
try {
|
|
292335
|
-
const root6 = await
|
|
292336
|
-
const real = await
|
|
292337
|
-
if (!real.startsWith(root6 +
|
|
292338
|
-
const realRel =
|
|
292339
|
-
if (isSecretPath(
|
|
292340
|
-
const st2 = await
|
|
292671
|
+
const root6 = await fsp138.realpath(WALNUT_HOME);
|
|
292672
|
+
const real = await fsp138.realpath(path261.join(WALNUT_HOME, rel));
|
|
292673
|
+
if (!real.startsWith(root6 + path261.sep)) return null;
|
|
292674
|
+
const realRel = path261.relative(root6, real).split(path261.sep).join("/");
|
|
292675
|
+
if (isSecretPath(path261.join(WALNUT_HOME, realRel)) || deniedName(realRel)) return null;
|
|
292676
|
+
const st2 = await fsp138.stat(real);
|
|
292341
292677
|
if (!st2.isFile()) return null;
|
|
292342
292678
|
if (!await isTracked(root6, realRel)) return null;
|
|
292343
292679
|
return { localPath: real, size: st2.size };
|
|
@@ -292377,11 +292713,11 @@ var init_file_content_replica_copy = __esm({
|
|
|
292377
292713
|
// src/web/routes/media-v1.ts
|
|
292378
292714
|
import { Router as Router92 } from "express";
|
|
292379
292715
|
import crypto75 from "crypto";
|
|
292380
|
-
import
|
|
292381
|
-
import
|
|
292716
|
+
import path262 from "path";
|
|
292717
|
+
import fsp139 from "fs/promises";
|
|
292382
292718
|
function cachePathFor(host, filePath) {
|
|
292383
292719
|
const hash3 = crypto75.createHash("sha256").update(filePath).digest("hex").slice(0, 16);
|
|
292384
|
-
return
|
|
292720
|
+
return path262.join(REMOTE_IMAGES_DIR, host, `${hash3}-${path262.basename(filePath)}`);
|
|
292385
292721
|
}
|
|
292386
292722
|
async function hostForSession(sessionId) {
|
|
292387
292723
|
if (CLOUD_MODE) {
|
|
@@ -292446,11 +292782,11 @@ var init_media_v1 = __esm({
|
|
|
292446
292782
|
try {
|
|
292447
292783
|
const filePath = req.query.path;
|
|
292448
292784
|
const session2 = typeof req.query.session === "string" && SID_RE6.test(req.query.session) ? req.query.session : void 0;
|
|
292449
|
-
if (!filePath || typeof filePath !== "string" || !
|
|
292785
|
+
if (!filePath || typeof filePath !== "string" || !path262.isAbsolute(filePath) || filePath.includes("..")) {
|
|
292450
292786
|
res.status(400).json({ error: { code: "bad_request", message: "path must be an absolute file path" } });
|
|
292451
292787
|
return;
|
|
292452
292788
|
}
|
|
292453
|
-
const ext2 =
|
|
292789
|
+
const ext2 = path262.extname(filePath).slice(1).toLowerCase();
|
|
292454
292790
|
const mime = EXT_TO_MIME3[ext2];
|
|
292455
292791
|
if (!mime) {
|
|
292456
292792
|
res.status(400).json({ error: { code: "bad_request", message: "file type not allowed" } });
|
|
@@ -292458,8 +292794,8 @@ var init_media_v1 = __esm({
|
|
|
292458
292794
|
}
|
|
292459
292795
|
let buffer2 = null;
|
|
292460
292796
|
try {
|
|
292461
|
-
const st2 = await
|
|
292462
|
-
if (st2.isFile() && st2.size <= MAX_FILE_SIZE3) buffer2 = await
|
|
292797
|
+
const st2 = await fsp139.stat(filePath);
|
|
292798
|
+
if (st2.isFile() && st2.size <= MAX_FILE_SIZE3) buffer2 = await fsp139.readFile(filePath);
|
|
292463
292799
|
} catch {
|
|
292464
292800
|
}
|
|
292465
292801
|
let waitedOnPending = false;
|
|
@@ -292480,8 +292816,8 @@ var init_media_v1 = __esm({
|
|
|
292480
292816
|
if (buffer2) {
|
|
292481
292817
|
try {
|
|
292482
292818
|
const cachePath3 = cachePathFor(host, filePath);
|
|
292483
|
-
await
|
|
292484
|
-
await
|
|
292819
|
+
await fsp139.mkdir(path262.dirname(cachePath3), { recursive: true });
|
|
292820
|
+
await fsp139.writeFile(cachePath3, buffer2);
|
|
292485
292821
|
} catch {
|
|
292486
292822
|
}
|
|
292487
292823
|
break;
|
|
@@ -292491,9 +292827,9 @@ var init_media_v1 = __esm({
|
|
|
292491
292827
|
for (const host of hosts2) {
|
|
292492
292828
|
try {
|
|
292493
292829
|
const cached8 = cachePathFor(host, filePath);
|
|
292494
|
-
const st2 = await
|
|
292830
|
+
const st2 = await fsp139.stat(cached8);
|
|
292495
292831
|
if (st2.isFile() && st2.size <= MAX_FILE_SIZE3) {
|
|
292496
|
-
buffer2 = await
|
|
292832
|
+
buffer2 = await fsp139.readFile(cached8);
|
|
292497
292833
|
break;
|
|
292498
292834
|
}
|
|
292499
292835
|
} catch {
|
|
@@ -292503,7 +292839,7 @@ var init_media_v1 = __esm({
|
|
|
292503
292839
|
if (!buffer2 && hosts2.length > 0 && hosts2.every((h8) => h8 === "__local__") && !(await Promise.resolve().then(() => (init_bridge_registry(), bridge_registry_exports))).bridgeForHost("__local__").connected) {
|
|
292504
292840
|
const { resolveReplicaCopy: resolveReplicaCopy2 } = await Promise.resolve().then(() => (init_file_content_replica_copy(), file_content_replica_copy_exports));
|
|
292505
292841
|
const copy5 = await resolveReplicaCopy2(filePath);
|
|
292506
|
-
if (copy5 && copy5.size <= MAX_FILE_SIZE3) buffer2 = await
|
|
292842
|
+
if (copy5 && copy5.size <= MAX_FILE_SIZE3) buffer2 = await fsp139.readFile(copy5.localPath);
|
|
292507
292843
|
}
|
|
292508
292844
|
}
|
|
292509
292845
|
if (!buffer2) {
|
|
@@ -292528,6 +292864,19 @@ var init_media_v1 = __esm({
|
|
|
292528
292864
|
|
|
292529
292865
|
// src/web/routes/routines-v1.ts
|
|
292530
292866
|
import { Router as Router93 } from "express";
|
|
292867
|
+
async function answeredFromCopy(res, includeDisabled, answer5) {
|
|
292868
|
+
const [{ companionRoutinesCopy: companionRoutinesCopy2 }, { copyKindAsOf: copyKindAsOf2, COPY_AS_OF_HEADER: COPY_AS_OF_HEADER2 }] = await Promise.all([
|
|
292869
|
+
Promise.resolve().then(() => (init_routines_follower(), routines_follower_exports)),
|
|
292870
|
+
Promise.resolve().then(() => (init_gate(), gate_exports))
|
|
292871
|
+
]);
|
|
292872
|
+
const jobs2 = await companionRoutinesCopy2({ includeDisabled });
|
|
292873
|
+
if (!jobs2) return false;
|
|
292874
|
+
res.setHeader(COPY_AS_OF_HEADER2, String(await copyKindAsOf2("routines") ?? 0));
|
|
292875
|
+
const body7 = answer5(jobs2);
|
|
292876
|
+
if (body7 === null) sendV1Error(res, 404, "not_found", "No such routine in the copy of your Mac's routines");
|
|
292877
|
+
else res.json(body7);
|
|
292878
|
+
return true;
|
|
292879
|
+
}
|
|
292531
292880
|
function validRid(req, res) {
|
|
292532
292881
|
const id = String(req.params.id ?? "");
|
|
292533
292882
|
if (!RID_RE.test(id)) {
|
|
@@ -292574,6 +292923,7 @@ var init_routines_v1 = __esm({
|
|
|
292574
292923
|
try {
|
|
292575
292924
|
const includeDisabled = req.query.includeDisabled === "true";
|
|
292576
292925
|
if (CLOUD_MODE) {
|
|
292926
|
+
if (await answeredFromCopy(res, includeDisabled, (jobs2) => ({ jobs: jobs2 }))) return;
|
|
292577
292927
|
await relayControlAction(res, "server.routines", SERVER_RELAY_SID16, { includeDisabled }, 200);
|
|
292578
292928
|
return;
|
|
292579
292929
|
}
|
|
@@ -292598,6 +292948,7 @@ var init_routines_v1 = __esm({
|
|
|
292598
292948
|
routinesV1Router.get("/routines/status", async (_req, res, next) => {
|
|
292599
292949
|
try {
|
|
292600
292950
|
if (CLOUD_MODE) {
|
|
292951
|
+
if (await answeredFromCopy(res, true, (jobs2) => ({ enabled: false, storePath: "", jobs: jobs2.length, nextWakeAtMs: null }))) return;
|
|
292601
292952
|
await relayControlAction(res, "server.routines.status", SERVER_RELAY_SID16, void 0, 200);
|
|
292602
292953
|
return;
|
|
292603
292954
|
}
|
|
@@ -292669,6 +293020,10 @@ var init_routines_v1 = __esm({
|
|
|
292669
293020
|
const id = validRid(req, res);
|
|
292670
293021
|
if (!id) return;
|
|
292671
293022
|
if (CLOUD_MODE) {
|
|
293023
|
+
if (await answeredFromCopy(res, true, (jobs2) => {
|
|
293024
|
+
const job2 = jobs2.find((j8) => j8.id === id);
|
|
293025
|
+
return job2 ? { job: job2 } : null;
|
|
293026
|
+
})) return;
|
|
292672
293027
|
await relayControlAction(res, "server.routines.get", SERVER_RELAY_SID16, { id }, 200);
|
|
292673
293028
|
return;
|
|
292674
293029
|
}
|
|
@@ -293863,8 +294218,8 @@ __export(file_content_bridge_exports, {
|
|
|
293863
294218
|
resolveBridgeHost: () => resolveBridgeHost,
|
|
293864
294219
|
serveCloudFileContent: () => serveCloudFileContent
|
|
293865
294220
|
});
|
|
293866
|
-
import
|
|
293867
|
-
import
|
|
294221
|
+
import path263 from "path";
|
|
294222
|
+
import fsp140 from "fs/promises";
|
|
293868
294223
|
function resolveBridgeHost(host) {
|
|
293869
294224
|
return typeof host === "string" && host.length > 0 ? host : PRIMARY_BRIDGE_ALIAS5;
|
|
293870
294225
|
}
|
|
@@ -293935,7 +294290,7 @@ function precheckPath(res, rawPath) {
|
|
|
293935
294290
|
sendV1Error(res, 400, "bad_request", "Invalid path");
|
|
293936
294291
|
return null;
|
|
293937
294292
|
}
|
|
293938
|
-
if (rawPath !== "~" && !rawPath.startsWith("~/") && !
|
|
294293
|
+
if (rawPath !== "~" && !rawPath.startsWith("~/") && !path263.isAbsolute(rawPath)) {
|
|
293939
294294
|
sendV1Error(res, 400, "bad_request", "Path must be absolute");
|
|
293940
294295
|
return null;
|
|
293941
294296
|
}
|
|
@@ -293979,7 +294334,7 @@ async function serveCloudFileContent(req, res) {
|
|
|
293979
294334
|
const hostAlias2 = resolveBridgeHost(req.query.host);
|
|
293980
294335
|
const raw = req.query.raw === "1" || req.query.raw === "true";
|
|
293981
294336
|
const download = req.query.download === "1" || req.query.download === "true";
|
|
293982
|
-
const ext2 =
|
|
294337
|
+
const ext2 = path263.extname(filePath).slice(1).toLowerCase();
|
|
293983
294338
|
const {
|
|
293984
294339
|
assertPathAllowed: assertPathAllowed2,
|
|
293985
294340
|
isSecretPath: isSecretPath2,
|
|
@@ -293989,7 +294344,7 @@ async function serveCloudFileContent(req, res) {
|
|
|
293989
294344
|
FileContentError: FileContentError2
|
|
293990
294345
|
} = await Promise.resolve().then(() => (init_file_content(), file_content_exports));
|
|
293991
294346
|
const explicitHost = typeof req.query.host === "string" && req.query.host.length > 0;
|
|
293992
|
-
const locallyPresent = await
|
|
294347
|
+
const locallyPresent = await fsp140.stat(filePath).then((st2) => st2.isFile()).catch(() => false);
|
|
293993
294348
|
if (!explicitHost && locallyPresent && cloudLocalReadAllowed2(filePath) && !isSecretPath2(filePath)) {
|
|
293994
294349
|
try {
|
|
293995
294350
|
if (raw) {
|
|
@@ -294087,10 +294442,10 @@ async function serveReplicaCopy(req, res, requestPath, copy5, opts2) {
|
|
|
294087
294442
|
return;
|
|
294088
294443
|
}
|
|
294089
294444
|
if (copy5.size <= MAX_BRIDGE_FILE_BYTES) {
|
|
294090
|
-
res.json(jsonPayloadFromBuffer(await
|
|
294445
|
+
res.json(jsonPayloadFromBuffer(await fsp140.readFile(copy5.localPath), opts2.ext, false));
|
|
294091
294446
|
return;
|
|
294092
294447
|
}
|
|
294093
|
-
const fh = await
|
|
294448
|
+
const fh = await fsp140.open(copy5.localPath, "r");
|
|
294094
294449
|
try {
|
|
294095
294450
|
const head2 = Buffer.alloc(MAX_TEXT_PAYLOAD);
|
|
294096
294451
|
const { bytesRead } = await fh.read(head2, 0, head2.length, 0);
|
|
@@ -295164,17 +295519,17 @@ __export(checklist_io_exports, {
|
|
|
295164
295519
|
readHeartbeatChecklist: () => readHeartbeatChecklist,
|
|
295165
295520
|
writeHeartbeatChecklist: () => writeHeartbeatChecklist
|
|
295166
295521
|
});
|
|
295167
|
-
import
|
|
295522
|
+
import fsp141 from "fs/promises";
|
|
295168
295523
|
async function readHeartbeatChecklist() {
|
|
295169
295524
|
try {
|
|
295170
|
-
return await
|
|
295525
|
+
return await fsp141.readFile(HEARTBEAT_FILE, "utf-8");
|
|
295171
295526
|
} catch (err2) {
|
|
295172
295527
|
if (err2.code === "ENOENT") return "";
|
|
295173
295528
|
throw err2;
|
|
295174
295529
|
}
|
|
295175
295530
|
}
|
|
295176
295531
|
async function writeHeartbeatChecklist(content) {
|
|
295177
|
-
await
|
|
295532
|
+
await fsp141.writeFile(HEARTBEAT_FILE, content, "utf-8");
|
|
295178
295533
|
}
|
|
295179
295534
|
var init_checklist_io = __esm({
|
|
295180
295535
|
"src/heartbeat/checklist-io.ts"() {
|
|
@@ -296958,28 +297313,28 @@ __export(boot_guard_exports, {
|
|
|
296958
297313
|
});
|
|
296959
297314
|
import fs142 from "fs";
|
|
296960
297315
|
import os63 from "os";
|
|
296961
|
-
import
|
|
297316
|
+
import path264 from "path";
|
|
296962
297317
|
function canonical3(dir4) {
|
|
296963
|
-
let head2 =
|
|
297318
|
+
let head2 = path264.resolve(dir4);
|
|
296964
297319
|
const rest = [];
|
|
296965
297320
|
for (; ; ) {
|
|
296966
297321
|
try {
|
|
296967
|
-
return
|
|
297322
|
+
return path264.join(fs142.realpathSync(head2), ...rest);
|
|
296968
297323
|
} catch {
|
|
296969
297324
|
}
|
|
296970
|
-
const up =
|
|
296971
|
-
if (up === head2) return
|
|
296972
|
-
rest.unshift(
|
|
297325
|
+
const up = path264.dirname(head2);
|
|
297326
|
+
if (up === head2) return path264.resolve(dir4);
|
|
297327
|
+
rest.unshift(path264.basename(head2));
|
|
296973
297328
|
head2 = up;
|
|
296974
297329
|
}
|
|
296975
297330
|
}
|
|
296976
297331
|
function spellings(dir4) {
|
|
296977
|
-
const resolved =
|
|
297332
|
+
const resolved = path264.resolve(dir4);
|
|
296978
297333
|
return [.../* @__PURE__ */ new Set([resolved, canonical3(resolved), `/private${resolved}`])];
|
|
296979
297334
|
}
|
|
296980
297335
|
function within5(child2, parent) {
|
|
296981
|
-
const rel =
|
|
296982
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
297336
|
+
const rel = path264.relative(parent, child2);
|
|
297337
|
+
return rel === "" || !rel.startsWith("..") && !path264.isAbsolute(rel);
|
|
296983
297338
|
}
|
|
296984
297339
|
function overlaps(a8, b8) {
|
|
296985
297340
|
return spellings(a8).some((x3) => spellings(b8).some((y3) => within5(x3, y3) || within5(y3, x3)));
|
|
@@ -296990,7 +297345,7 @@ function holdsOrIs(outer, inner2) {
|
|
|
296990
297345
|
function accountHomes(env3) {
|
|
296991
297346
|
const homes = /* @__PURE__ */ new Set();
|
|
296992
297347
|
const add3 = (h8) => {
|
|
296993
|
-
if (h8 && h8.trim()) homes.add(
|
|
297348
|
+
if (h8 && h8.trim()) homes.add(path264.resolve(h8.trim()));
|
|
296994
297349
|
};
|
|
296995
297350
|
add3(env3.HOME);
|
|
296996
297351
|
add3(os63.homedir());
|
|
@@ -297048,7 +297403,7 @@ function assertReplicaBootSafe(input) {
|
|
|
297048
297403
|
if (why2) throw new Error(`Host replica refused to start: ${why2}.`);
|
|
297049
297404
|
}
|
|
297050
297405
|
function claimReplicaDir(dir4) {
|
|
297051
|
-
const marker =
|
|
297406
|
+
const marker = path264.join(dir4, REPLICA_DIR_MARKER);
|
|
297052
297407
|
try {
|
|
297053
297408
|
return fs142.lstatSync(marker).isFile();
|
|
297054
297409
|
} catch {
|
|
@@ -297073,7 +297428,7 @@ function claimReplicaDir(dir4) {
|
|
|
297073
297428
|
function tightenReplicaModes(dirs2, limit = 2e4) {
|
|
297074
297429
|
const marked = dirs2.filter((d8) => {
|
|
297075
297430
|
try {
|
|
297076
|
-
return fs142.lstatSync(
|
|
297431
|
+
return fs142.lstatSync(path264.join(d8, REPLICA_DIR_MARKER)).isFile();
|
|
297077
297432
|
} catch {
|
|
297078
297433
|
return false;
|
|
297079
297434
|
}
|
|
@@ -297103,7 +297458,7 @@ function tightenReplicaModes(dirs2, limit = 2e4) {
|
|
|
297103
297458
|
} catch {
|
|
297104
297459
|
return;
|
|
297105
297460
|
}
|
|
297106
|
-
for (const n6 of names2) visit(
|
|
297461
|
+
for (const n6 of names2) visit(path264.join(p6, n6));
|
|
297107
297462
|
} else if (st2.isFile() && (st2.mode & 63) !== 0) {
|
|
297108
297463
|
try {
|
|
297109
297464
|
fs142.chmodSync(p6, st2.mode & 448 | 384);
|
|
@@ -297290,29 +297645,29 @@ __export(search_replica_store_exports, {
|
|
|
297290
297645
|
searchReplicaSync: () => searchReplicaSync,
|
|
297291
297646
|
startSearchReplicaStore: () => startSearchReplicaStore
|
|
297292
297647
|
});
|
|
297293
|
-
import
|
|
297648
|
+
import fsp142 from "fs/promises";
|
|
297294
297649
|
import os64 from "os";
|
|
297295
|
-
import
|
|
297650
|
+
import path265 from "path";
|
|
297296
297651
|
async function wiring() {
|
|
297297
297652
|
return Promise.resolve().then(() => (init_wiring(), wiring_exports));
|
|
297298
297653
|
}
|
|
297299
297654
|
async function loadState() {
|
|
297300
|
-
if (
|
|
297655
|
+
if (state13) return state13;
|
|
297301
297656
|
let s4 = { v: 1, mode: null, syncedAt: null };
|
|
297302
297657
|
try {
|
|
297303
|
-
const raw = JSON.parse(await
|
|
297658
|
+
const raw = JSON.parse(await fsp142.readFile(STATE_FILE3(), "utf8"));
|
|
297304
297659
|
if (raw && raw.v === 1) {
|
|
297305
297660
|
s4 = { v: 1, mode: raw.mode ? companionSearchMode(raw.mode) : null, syncedAt: typeof raw.syncedAt === "number" ? raw.syncedAt : null };
|
|
297306
297661
|
}
|
|
297307
297662
|
} catch {
|
|
297308
297663
|
}
|
|
297309
|
-
|
|
297664
|
+
state13 = s4;
|
|
297310
297665
|
return s4;
|
|
297311
297666
|
}
|
|
297312
297667
|
async function saveState() {
|
|
297313
|
-
if (
|
|
297668
|
+
if (state13) await writeJsonFile(STATE_FILE3(), state13);
|
|
297314
297669
|
}
|
|
297315
|
-
function
|
|
297670
|
+
function serial6(fn) {
|
|
297316
297671
|
const run12 = chain4.then(fn, fn);
|
|
297317
297672
|
chain4 = run12.catch(() => {
|
|
297318
297673
|
});
|
|
@@ -297376,8 +297731,8 @@ async function closeIndex() {
|
|
|
297376
297731
|
allDirty2 = true;
|
|
297377
297732
|
}
|
|
297378
297733
|
function publishReady() {
|
|
297379
|
-
const ready2 = enabled && mapBuilt && map3.size > 0 &&
|
|
297380
|
-
setCompanionSearchReady(ready2, ready2 ?
|
|
297734
|
+
const ready2 = enabled && mapBuilt && map3.size > 0 && state13?.syncedAt != null;
|
|
297735
|
+
setCompanionSearchReady(ready2, ready2 ? state13.syncedAt : null);
|
|
297381
297736
|
}
|
|
297382
297737
|
async function markInSync() {
|
|
297383
297738
|
const s4 = await loadState();
|
|
@@ -297404,7 +297759,7 @@ async function warm(why2) {
|
|
|
297404
297759
|
}
|
|
297405
297760
|
}
|
|
297406
297761
|
function searchReplicaStatus(body7) {
|
|
297407
|
-
return
|
|
297762
|
+
return serial6(async () => {
|
|
297408
297763
|
if (!isFollower()) return { ok: false, status: 400, error: "not_a_replica" };
|
|
297409
297764
|
const s4 = await loadState();
|
|
297410
297765
|
const mode = companionSearchMode(body7.mode);
|
|
@@ -297452,7 +297807,7 @@ function searchReplicaStatus(body7) {
|
|
|
297452
297807
|
});
|
|
297453
297808
|
}
|
|
297454
297809
|
function searchReplicaSync(body7) {
|
|
297455
|
-
return
|
|
297810
|
+
return serial6(async () => {
|
|
297456
297811
|
if (!isFollower()) return { ok: false, status: 400, error: "not_a_replica" };
|
|
297457
297812
|
if (!enabled) return { ok: false, status: 400, error: "search_copy_off" };
|
|
297458
297813
|
if (!Array.isArray(body7.entries)) return { ok: false, status: 400, error: "bad_entries" };
|
|
@@ -297497,7 +297852,7 @@ async function forgetSearchMemo() {
|
|
|
297497
297852
|
}
|
|
297498
297853
|
}
|
|
297499
297854
|
function searchReplicaPut(body7) {
|
|
297500
|
-
return
|
|
297855
|
+
return serial6(async () => {
|
|
297501
297856
|
if (!isFollower()) return { ok: false, status: 400, error: "not_a_replica" };
|
|
297502
297857
|
if (!enabled) return { ok: false, status: 400, error: "search_copy_off" };
|
|
297503
297858
|
if (!Array.isArray(body7.docs)) return { ok: false, status: 400, error: "bad_docs" };
|
|
@@ -297563,7 +297918,7 @@ function startSearchReplicaStore(options = {}) {
|
|
|
297563
297918
|
if (!s4.mode || stopped2) return;
|
|
297564
297919
|
const decision = companionSearchDecision(s4.mode, deps3.totalMb());
|
|
297565
297920
|
if (!decision.enabled) return;
|
|
297566
|
-
await
|
|
297921
|
+
await serial6(async () => {
|
|
297567
297922
|
enabled = true;
|
|
297568
297923
|
reason2 = decision.reason;
|
|
297569
297924
|
await refreshMap2(await openIndex());
|
|
@@ -297596,12 +297951,12 @@ function startSearchReplicaStore(options = {}) {
|
|
|
297596
297951
|
}));
|
|
297597
297952
|
}).catch((err2) => log.memory.warn("search replica: local writes not wired", { error: err2 instanceof Error ? err2.message : String(err2) }));
|
|
297598
297953
|
unsubs.push(onLeaderPresence((answers4) => {
|
|
297599
|
-
if (stopped2 || answers4 || !enabled ||
|
|
297954
|
+
if (stopped2 || answers4 || !enabled || state13?.syncedAt == null) return;
|
|
297600
297955
|
void warm("leader away");
|
|
297601
297956
|
}));
|
|
297602
297957
|
const tick = setInterval(() => {
|
|
297603
297958
|
void (async () => {
|
|
297604
|
-
if (stopped2 || !enabled ||
|
|
297959
|
+
if (stopped2 || !enabled || state13?.syncedAt == null) return;
|
|
297605
297960
|
if (Date.now() - lastWarmAt < WARM_EVERY_MS) return;
|
|
297606
297961
|
if (!await deps3.macAway()) return;
|
|
297607
297962
|
await warm("mac away");
|
|
@@ -297620,7 +297975,7 @@ function startSearchReplicaStore(options = {}) {
|
|
|
297620
297975
|
};
|
|
297621
297976
|
}
|
|
297622
297977
|
function _resetSearchReplicaStoreForTesting(overrides = {}) {
|
|
297623
|
-
|
|
297978
|
+
state13 = null;
|
|
297624
297979
|
enabled = false;
|
|
297625
297980
|
reason2 = "off";
|
|
297626
297981
|
map3.clear();
|
|
@@ -297635,7 +297990,7 @@ function _resetSearchReplicaStoreForTesting(overrides = {}) {
|
|
|
297635
297990
|
deps3 = { totalMb: () => Math.round(os64.totalmem() / (1024 * 1024)), macAway: defaultMacAway, ...overrides };
|
|
297636
297991
|
setCompanionSearchReady(false, null);
|
|
297637
297992
|
}
|
|
297638
|
-
var
|
|
297993
|
+
var STATE_FILE3, MASS_REMOVE_FLOOR2, SCAN_SLICE2, WARM_EVERY_MS, TICK_MS2, defaultMacAway, deps3, state13, enabled, reason2, map3, mapBuilt, allDirty2, dirty2, unlisten, lastWarmAt, warmedOnce, chain4, yieldLoop;
|
|
297639
297994
|
var init_search_replica_store = __esm({
|
|
297640
297995
|
"src/core/replication/search-replica-store.ts"() {
|
|
297641
297996
|
"use strict";
|
|
@@ -297647,7 +298002,7 @@ var init_search_replica_store = __esm({
|
|
|
297647
298002
|
init_replica_refs();
|
|
297648
298003
|
init_search_digest();
|
|
297649
298004
|
init_search_replica_wire();
|
|
297650
|
-
|
|
298005
|
+
STATE_FILE3 = () => path265.join(WALNUT_HOME, "cache", "search-replica.json");
|
|
297651
298006
|
MASS_REMOVE_FLOOR2 = 200;
|
|
297652
298007
|
SCAN_SLICE2 = 500;
|
|
297653
298008
|
WARM_EVERY_MS = 4 * 6e4;
|
|
@@ -297657,7 +298012,7 @@ var init_search_replica_store = __esm({
|
|
|
297657
298012
|
totalMb: () => Math.round(os64.totalmem() / (1024 * 1024)),
|
|
297658
298013
|
macAway: defaultMacAway
|
|
297659
298014
|
};
|
|
297660
|
-
|
|
298015
|
+
state13 = null;
|
|
297661
298016
|
enabled = false;
|
|
297662
298017
|
reason2 = "off";
|
|
297663
298018
|
map3 = new DigestMap();
|
|
@@ -297673,10 +298028,10 @@ var init_search_replica_store = __esm({
|
|
|
297673
298028
|
});
|
|
297674
298029
|
|
|
297675
298030
|
// src/core/replication/kinds/boards.ts
|
|
297676
|
-
import
|
|
297677
|
-
import
|
|
298031
|
+
import fsp143 from "fs/promises";
|
|
298032
|
+
import path266 from "path";
|
|
297678
298033
|
async function leaderBoards(dir4 = boardsDir2()) {
|
|
297679
|
-
const names2 = await
|
|
298034
|
+
const names2 = await fsp143.readdir(dir4).catch(() => []);
|
|
297680
298035
|
const out = [];
|
|
297681
298036
|
const unreadable = [];
|
|
297682
298037
|
const seen2 = /* @__PURE__ */ new Set();
|
|
@@ -297685,9 +298040,9 @@ async function leaderBoards(dir4 = boardsDir2()) {
|
|
|
297685
298040
|
const id = name.slice(0, -".json".length);
|
|
297686
298041
|
if (!TASK_ID_RE3.test(id)) continue;
|
|
297687
298042
|
seen2.add(id);
|
|
297688
|
-
const file =
|
|
298043
|
+
const file = path266.join(dir4, name);
|
|
297689
298044
|
try {
|
|
297690
|
-
const st2 = await
|
|
298045
|
+
const st2 = await fsp143.stat(file);
|
|
297691
298046
|
if (!st2.isFile()) continue;
|
|
297692
298047
|
if (st2.size > BOARD_COPY_MAX_BYTES) {
|
|
297693
298048
|
if (!warnedTooBig.has(id)) log.session.warn("boards copy: a board is too large to copy, it is read from the Mac", { taskId: id, bytes: st2.size });
|
|
@@ -297696,14 +298051,14 @@ async function leaderBoards(dir4 = boardsDir2()) {
|
|
|
297696
298051
|
}
|
|
297697
298052
|
let c8 = cache16.get(id);
|
|
297698
298053
|
if (!c8 || c8.size !== st2.size || c8.mtimeMs !== st2.mtimeMs) {
|
|
297699
|
-
const row = JSON.parse(await
|
|
297700
|
-
if (!
|
|
298054
|
+
const row = JSON.parse(await fsp143.readFile(file, "utf8"));
|
|
298055
|
+
if (!isRow8(row) || row.task_id !== id) {
|
|
297701
298056
|
unreadable.push(id);
|
|
297702
298057
|
continue;
|
|
297703
298058
|
}
|
|
297704
298059
|
c8 = { size: st2.size, mtimeMs: st2.mtimeMs, row, hash: sha12(JSON.stringify(row)) };
|
|
297705
298060
|
cache16.set(id, c8);
|
|
297706
|
-
|
|
298061
|
+
hashOf8.set(row, c8.hash);
|
|
297707
298062
|
}
|
|
297708
298063
|
out.push(c8.row);
|
|
297709
298064
|
} catch (err2) {
|
|
@@ -297718,56 +298073,56 @@ async function leaderBoards(dir4 = boardsDir2()) {
|
|
|
297718
298073
|
if (fresh.length > 0) log.session.warn("boards copy: a board could not be read, the host keeps its copy of it", { taskIds: fresh });
|
|
297719
298074
|
return out;
|
|
297720
298075
|
}
|
|
297721
|
-
function
|
|
298076
|
+
function isRow8(v3) {
|
|
297722
298077
|
const b8 = v3;
|
|
297723
298078
|
return !!b8 && typeof b8 === "object" && !Array.isArray(b8) && typeof b8.task_id === "string" && TASK_ID_RE3.test(b8.task_id) && typeof b8.html === "string" && typeof b8.version === "number";
|
|
297724
298079
|
}
|
|
297725
|
-
async function
|
|
297726
|
-
if (
|
|
298080
|
+
async function load8() {
|
|
298081
|
+
if (state14) return state14;
|
|
297727
298082
|
let s4 = { asOf: 0, at: 0, order: [], hashes: {} };
|
|
297728
298083
|
try {
|
|
297729
|
-
const raw = JSON.parse(await
|
|
298084
|
+
const raw = JSON.parse(await fsp143.readFile(STATE_FILE4(), "utf8"));
|
|
297730
298085
|
if (raw?.v === 1 && raw.hashes && typeof raw.hashes === "object") s4 = { asOf: Number(raw.asOf) || 0, at: Number(raw.at) || 0, order: [], hashes: raw.hashes };
|
|
297731
298086
|
} catch {
|
|
297732
298087
|
}
|
|
297733
|
-
|
|
298088
|
+
state14 = s4;
|
|
297734
298089
|
return s4;
|
|
297735
298090
|
}
|
|
297736
|
-
async function
|
|
297737
|
-
if (
|
|
298091
|
+
async function save3() {
|
|
298092
|
+
if (state14) await writeCopyFile(STATE_FILE4(), { v: 1, asOf: state14.asOf, at: state14.at, hashes: state14.hashes });
|
|
297738
298093
|
}
|
|
297739
298094
|
async function localIds() {
|
|
297740
|
-
const names2 = await
|
|
298095
|
+
const names2 = await fsp143.readdir(boardsDir2()).catch(() => []);
|
|
297741
298096
|
return names2.filter((n6) => n6.endsWith(".json")).map((n6) => n6.slice(0, -".json".length)).filter((id) => TASK_ID_RE3.test(id));
|
|
297742
298097
|
}
|
|
297743
298098
|
function changed4() {
|
|
297744
298099
|
}
|
|
297745
298100
|
function boardsFollower() {
|
|
297746
|
-
|
|
298101
|
+
follower4 ??= createRowSetFollower({
|
|
297747
298102
|
kind: "boards",
|
|
297748
298103
|
schemaVersion: BOARDS_SCHEMA_VERSION,
|
|
297749
298104
|
label: "boards copy",
|
|
297750
298105
|
log: log.session,
|
|
297751
298106
|
removalFloor: BOARDS_REMOVAL_FLOOR,
|
|
297752
298107
|
ordered: false,
|
|
297753
|
-
serial: (fn) =>
|
|
298108
|
+
serial: (fn) => serial7(fn),
|
|
297754
298109
|
refuse: copyRefusal,
|
|
297755
|
-
load:
|
|
297756
|
-
save:
|
|
297757
|
-
isRow:
|
|
298110
|
+
load: load8,
|
|
298111
|
+
save: save3,
|
|
298112
|
+
isRow: isRow8,
|
|
297758
298113
|
key: (b8) => b8.task_id,
|
|
297759
298114
|
localKeys: localIds,
|
|
297760
298115
|
apply: async ({ rows, removeIds }) => {
|
|
297761
298116
|
const skipped = [];
|
|
297762
298117
|
for (const id of removeIds ?? []) {
|
|
297763
|
-
if (TASK_ID_RE3.test(id)) await
|
|
298118
|
+
if (TASK_ID_RE3.test(id)) await fsp143.rm(path266.join(boardsDir2(), `${id}.json`), { force: true });
|
|
297764
298119
|
}
|
|
297765
298120
|
for (const b8 of rows ?? []) {
|
|
297766
298121
|
if (Buffer.byteLength(JSON.stringify(b8)) > BOARD_COPY_MAX_BYTES) {
|
|
297767
298122
|
skipped.push(b8.task_id);
|
|
297768
298123
|
continue;
|
|
297769
298124
|
}
|
|
297770
|
-
await writeCopyFile(
|
|
298125
|
+
await writeCopyFile(path266.join(boardsDir2(), `${b8.task_id}.json`), b8);
|
|
297771
298126
|
}
|
|
297772
298127
|
return { skipped };
|
|
297773
298128
|
},
|
|
@@ -297775,15 +298130,15 @@ function boardsFollower() {
|
|
|
297775
298130
|
changed: changed4,
|
|
297776
298131
|
purge: async () => {
|
|
297777
298132
|
const ids2 = await localIds();
|
|
297778
|
-
for (const id of ids2) await
|
|
298133
|
+
for (const id of ids2) await fsp143.rm(path266.join(boardsDir2(), `${id}.json`), { force: true });
|
|
297779
298134
|
await markCopyOff("boards");
|
|
297780
|
-
|
|
298135
|
+
state14 = null;
|
|
297781
298136
|
return { removed: ids2.length };
|
|
297782
298137
|
}
|
|
297783
298138
|
});
|
|
297784
|
-
return
|
|
298139
|
+
return follower4;
|
|
297785
298140
|
}
|
|
297786
|
-
var BOARDS_SCHEMA_VERSION, BOARDS_REMOVAL_FLOOR, BOARD_COPY_MAX_BYTES, TASK_ID_RE3, boardsDir2, cache16,
|
|
298141
|
+
var BOARDS_SCHEMA_VERSION, BOARDS_REMOVAL_FLOOR, BOARD_COPY_MAX_BYTES, TASK_ID_RE3, boardsDir2, cache16, hashOf8, warnedTooBig, unreadableOf2, warnedUnreadable, BOARDS_KIND, STATE_FILE4, state14, serial7, follower4;
|
|
297787
298142
|
var init_boards2 = __esm({
|
|
297788
298143
|
"src/core/replication/kinds/boards.ts"() {
|
|
297789
298144
|
"use strict";
|
|
@@ -297796,9 +298151,9 @@ var init_boards2 = __esm({
|
|
|
297796
298151
|
BOARDS_REMOVAL_FLOOR = 20;
|
|
297797
298152
|
BOARD_COPY_MAX_BYTES = 2 * 1024 * 1024;
|
|
297798
298153
|
TASK_ID_RE3 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
297799
|
-
boardsDir2 = () =>
|
|
298154
|
+
boardsDir2 = () => path266.join(WALNUT_HOME, "boards");
|
|
297800
298155
|
cache16 = /* @__PURE__ */ new Map();
|
|
297801
|
-
|
|
298156
|
+
hashOf8 = /* @__PURE__ */ new WeakMap();
|
|
297802
298157
|
warnedTooBig = /* @__PURE__ */ new Set();
|
|
297803
298158
|
unreadableOf2 = /* @__PURE__ */ new WeakMap();
|
|
297804
298159
|
warnedUnreadable = /* @__PURE__ */ new Set();
|
|
@@ -297806,7 +298161,7 @@ var init_boards2 = __esm({
|
|
|
297806
298161
|
kind: "boards",
|
|
297807
298162
|
schemaVersion: BOARDS_SCHEMA_VERSION,
|
|
297808
298163
|
key: (b8) => b8.task_id,
|
|
297809
|
-
hash: (b8) =>
|
|
298164
|
+
hash: (b8) => hashOf8.get(b8) ?? sha12(JSON.stringify(b8)),
|
|
297810
298165
|
ordered: false,
|
|
297811
298166
|
digest: false,
|
|
297812
298167
|
choice: "boards",
|
|
@@ -297826,16 +298181,16 @@ var init_boards2 = __esm({
|
|
|
297826
298181
|
};
|
|
297827
298182
|
}
|
|
297828
298183
|
};
|
|
297829
|
-
|
|
297830
|
-
|
|
297831
|
-
|
|
297832
|
-
|
|
298184
|
+
STATE_FILE4 = () => path266.join(WALNUT_HOME, "cache", "replica", "boards.json");
|
|
298185
|
+
state14 = null;
|
|
298186
|
+
serial7 = serialChain();
|
|
298187
|
+
follower4 = null;
|
|
297833
298188
|
}
|
|
297834
298189
|
});
|
|
297835
298190
|
|
|
297836
298191
|
// src/core/replication/kinds/inbox.ts
|
|
297837
|
-
import
|
|
297838
|
-
import
|
|
298192
|
+
import fsp144 from "fs/promises";
|
|
298193
|
+
import path267 from "path";
|
|
297839
298194
|
function watchLetters(soon) {
|
|
297840
298195
|
let stop2 = null;
|
|
297841
298196
|
let stopped2 = false;
|
|
@@ -297848,18 +298203,18 @@ function watchLetters(soon) {
|
|
|
297848
298203
|
};
|
|
297849
298204
|
}
|
|
297850
298205
|
async function leaderBodies(dir4 = bodiesDir()) {
|
|
297851
|
-
const names2 = (await
|
|
298206
|
+
const names2 = (await fsp144.readdir(dir4).catch(() => [])).filter((n6) => BODY_FILE_RE.test(n6)).sort();
|
|
297852
298207
|
const out = [];
|
|
297853
298208
|
const unreadable = [];
|
|
297854
298209
|
const seen2 = new Set(names2);
|
|
297855
298210
|
for (const name of names2) {
|
|
297856
|
-
const file =
|
|
298211
|
+
const file = path267.join(dir4, name);
|
|
297857
298212
|
try {
|
|
297858
|
-
const st2 = await
|
|
298213
|
+
const st2 = await fsp144.stat(file);
|
|
297859
298214
|
if (!st2.isFile() || st2.size > INBOX_BODY_COPY_MAX_BYTES) continue;
|
|
297860
298215
|
let c8 = bodyCache.get(name);
|
|
297861
298216
|
if (!c8 || c8.size !== st2.size || c8.mtimeMs !== st2.mtimeMs) {
|
|
297862
|
-
c8 = { size: st2.size, mtimeMs: st2.mtimeMs, hash: sha12(await
|
|
298217
|
+
c8 = { size: st2.size, mtimeMs: st2.mtimeMs, hash: sha12(await fsp144.readFile(file, "utf8")) };
|
|
297863
298218
|
bodyCache.set(name, c8);
|
|
297864
298219
|
}
|
|
297865
298220
|
const row = { name };
|
|
@@ -297878,21 +298233,21 @@ async function loadBody(b8) {
|
|
|
297878
298233
|
const file = bodyFiles.get(b8);
|
|
297879
298234
|
if (!file) return typeof b8.body === "string" ? b8 : void 0;
|
|
297880
298235
|
try {
|
|
297881
|
-
const body7 = await
|
|
298236
|
+
const body7 = await fsp144.readFile(file, "utf8");
|
|
297882
298237
|
return Buffer.byteLength(body7) > INBOX_BODY_COPY_MAX_BYTES ? void 0 : { name: b8.name, body: body7 };
|
|
297883
298238
|
} catch {
|
|
297884
298239
|
return void 0;
|
|
297885
298240
|
}
|
|
297886
298241
|
}
|
|
297887
298242
|
function stateIo(name) {
|
|
297888
|
-
const file = () =>
|
|
298243
|
+
const file = () => path267.join(WALNUT_HOME, "cache", "replica", `${name}.json`);
|
|
297889
298244
|
let state17 = null;
|
|
297890
298245
|
return {
|
|
297891
298246
|
load: async () => {
|
|
297892
298247
|
if (state17) return state17;
|
|
297893
298248
|
let s4 = { asOf: 0, at: 0, order: [], hashes: {} };
|
|
297894
298249
|
try {
|
|
297895
|
-
const raw = JSON.parse(await
|
|
298250
|
+
const raw = JSON.parse(await fsp144.readFile(file(), "utf8"));
|
|
297896
298251
|
if (raw?.v === 1 && raw.hashes && typeof raw.hashes === "object") {
|
|
297897
298252
|
s4 = { asOf: Number(raw.asOf) || 0, at: Number(raw.at) || 0, order: Array.isArray(raw.order) ? raw.order.map(String) : [], hashes: raw.hashes };
|
|
297898
298253
|
}
|
|
@@ -297911,7 +298266,7 @@ function stateIo(name) {
|
|
|
297911
298266
|
}
|
|
297912
298267
|
async function readIndex3() {
|
|
297913
298268
|
try {
|
|
297914
|
-
const raw = JSON.parse(await
|
|
298269
|
+
const raw = JSON.parse(await fsp144.readFile(indexFile3(), "utf8"));
|
|
297915
298270
|
return Array.isArray(raw?.letters) ? raw.letters.filter(isLetter) : [];
|
|
297916
298271
|
} catch {
|
|
297917
298272
|
return [];
|
|
@@ -297934,7 +298289,7 @@ function inboxFollower() {
|
|
|
297934
298289
|
removalFloor: INBOX_REMOVAL_FLOOR,
|
|
297935
298290
|
ordered: true,
|
|
297936
298291
|
digest: true,
|
|
297937
|
-
serial: (fn) =>
|
|
298292
|
+
serial: (fn) => serial8(fn),
|
|
297938
298293
|
refuse: refuse15,
|
|
297939
298294
|
load: () => indexIo.load(),
|
|
297940
298295
|
save: () => indexIo.save(),
|
|
@@ -297964,7 +298319,7 @@ function inboxFollower() {
|
|
|
297964
298319
|
},
|
|
297965
298320
|
purge: async () => {
|
|
297966
298321
|
const removed = (await readIndex3()).length;
|
|
297967
|
-
await
|
|
298322
|
+
await fsp144.rm(indexFile3(), { force: true });
|
|
297968
298323
|
await markCopyOff("inbox");
|
|
297969
298324
|
indexIo.reset();
|
|
297970
298325
|
return { removed };
|
|
@@ -297980,23 +298335,23 @@ function inboxBodiesFollower() {
|
|
|
297980
298335
|
log: log.notif,
|
|
297981
298336
|
removalFloor: INBOX_REMOVAL_FLOOR,
|
|
297982
298337
|
ordered: false,
|
|
297983
|
-
serial: (fn) =>
|
|
298338
|
+
serial: (fn) => serial8(fn),
|
|
297984
298339
|
refuse: refuse15,
|
|
297985
298340
|
load: () => bodiesIo.load(),
|
|
297986
298341
|
save: () => bodiesIo.save(),
|
|
297987
298342
|
isRow: isBody,
|
|
297988
298343
|
key: (b8) => b8.name,
|
|
297989
298344
|
hash: (b8) => sha12(b8.body),
|
|
297990
|
-
localKeys: async () => (await
|
|
298345
|
+
localKeys: async () => (await fsp144.readdir(bodiesDir()).catch(() => [])).filter((n6) => BODY_FILE_RE.test(n6)),
|
|
297991
298346
|
apply: async ({ rows, removeIds }) => {
|
|
297992
|
-
for (const name of removeIds ?? []) if (BODY_FILE_RE.test(name)) await
|
|
298347
|
+
for (const name of removeIds ?? []) if (BODY_FILE_RE.test(name)) await fsp144.rm(path267.join(bodiesDir(), name), { force: true });
|
|
297993
298348
|
const skipped = [];
|
|
297994
298349
|
for (const b8 of rows ?? []) {
|
|
297995
298350
|
if (Buffer.byteLength(b8.body) > INBOX_BODY_COPY_MAX_BYTES) {
|
|
297996
298351
|
skipped.push(b8.name);
|
|
297997
298352
|
continue;
|
|
297998
298353
|
}
|
|
297999
|
-
await writeCopyText(
|
|
298354
|
+
await writeCopyText(path267.join(bodiesDir(), b8.name), b8.body);
|
|
298000
298355
|
}
|
|
298001
298356
|
return { skipped };
|
|
298002
298357
|
},
|
|
@@ -298004,8 +298359,8 @@ function inboxBodiesFollower() {
|
|
|
298004
298359
|
changed: () => {
|
|
298005
298360
|
},
|
|
298006
298361
|
purge: async () => {
|
|
298007
|
-
const names2 = (await
|
|
298008
|
-
for (const name of names2) await
|
|
298362
|
+
const names2 = (await fsp144.readdir(bodiesDir()).catch(() => [])).filter((n6) => BODY_FILE_RE.test(n6));
|
|
298363
|
+
for (const name of names2) await fsp144.rm(path267.join(bodiesDir(), name), { force: true });
|
|
298009
298364
|
await markCopyOff("inbox-bodies");
|
|
298010
298365
|
bodiesIo.reset();
|
|
298011
298366
|
return { removed: names2.length };
|
|
@@ -298013,7 +298368,7 @@ function inboxBodiesFollower() {
|
|
|
298013
298368
|
});
|
|
298014
298369
|
return bodiesF;
|
|
298015
298370
|
}
|
|
298016
|
-
var INBOX_SCHEMA_VERSION, INBOX_REMOVAL_FLOOR, INBOX_BODY_COPY_MAX_BYTES, inboxDir, indexFile3, bodiesDir, letterHashes, INBOX_KIND, bodyCache, bodyHashes, bodyFiles, unreadableBodiesOf, INBOX_BODIES_KIND, refuse15, indexIo, bodiesIo,
|
|
298371
|
+
var INBOX_SCHEMA_VERSION, INBOX_REMOVAL_FLOOR, INBOX_BODY_COPY_MAX_BYTES, inboxDir, indexFile3, bodiesDir, letterHashes, INBOX_KIND, bodyCache, bodyHashes, bodyFiles, unreadableBodiesOf, INBOX_BODIES_KIND, refuse15, indexIo, bodiesIo, serial8, inboxF, bodiesF;
|
|
298017
298372
|
var init_inbox = __esm({
|
|
298018
298373
|
"src/core/replication/kinds/inbox.ts"() {
|
|
298019
298374
|
"use strict";
|
|
@@ -298026,9 +298381,9 @@ var init_inbox = __esm({
|
|
|
298026
298381
|
INBOX_SCHEMA_VERSION = 1;
|
|
298027
298382
|
INBOX_REMOVAL_FLOOR = 50;
|
|
298028
298383
|
INBOX_BODY_COPY_MAX_BYTES = 4 * 1024 * 1024;
|
|
298029
|
-
inboxDir = () =>
|
|
298030
|
-
indexFile3 = () =>
|
|
298031
|
-
bodiesDir = () =>
|
|
298384
|
+
inboxDir = () => path267.join(WALNUT_HOME, "human-inbox");
|
|
298385
|
+
indexFile3 = () => path267.join(inboxDir(), "index.json");
|
|
298386
|
+
bodiesDir = () => path267.join(inboxDir(), "bodies");
|
|
298032
298387
|
letterHashes = /* @__PURE__ */ new WeakMap();
|
|
298033
298388
|
INBOX_KIND = {
|
|
298034
298389
|
kind: "inbox",
|
|
@@ -298070,134 +298425,12 @@ var init_inbox = __esm({
|
|
|
298070
298425
|
refuse15 = copyRefusal;
|
|
298071
298426
|
indexIo = stateIo("inbox");
|
|
298072
298427
|
bodiesIo = stateIo("inbox-bodies");
|
|
298073
|
-
|
|
298428
|
+
serial8 = serialChain();
|
|
298074
298429
|
inboxF = null;
|
|
298075
298430
|
bodiesF = null;
|
|
298076
298431
|
}
|
|
298077
298432
|
});
|
|
298078
298433
|
|
|
298079
|
-
// src/core/replication/kinds/requests.ts
|
|
298080
|
-
import fsp144 from "fs/promises";
|
|
298081
|
-
import path267 from "path";
|
|
298082
|
-
function forwardRequest(local, incoming) {
|
|
298083
|
-
if (local && FINAL.has(local.status) && !FINAL.has(incoming.status)) return local;
|
|
298084
|
-
return incoming;
|
|
298085
|
-
}
|
|
298086
|
-
function hashOf7(row) {
|
|
298087
|
-
let h8 = hashes5.get(row);
|
|
298088
|
-
if (h8 === void 0) {
|
|
298089
|
-
h8 = sha12(JSON.stringify(row));
|
|
298090
|
-
hashes5.set(row, h8);
|
|
298091
|
-
}
|
|
298092
|
-
return h8;
|
|
298093
|
-
}
|
|
298094
|
-
async function load8() {
|
|
298095
|
-
if (state14) return state14;
|
|
298096
|
-
let s4 = { asOf: 0, at: 0, order: [], hashes: {} };
|
|
298097
|
-
try {
|
|
298098
|
-
const raw = JSON.parse(await fsp144.readFile(STATE_FILE4(), "utf8"));
|
|
298099
|
-
if (raw?.v === 1 && raw.hashes && typeof raw.hashes === "object") s4 = { asOf: Number(raw.asOf) || 0, at: Number(raw.at) || 0, order: [], hashes: raw.hashes };
|
|
298100
|
-
} catch {
|
|
298101
|
-
}
|
|
298102
|
-
state14 = s4;
|
|
298103
|
-
return s4;
|
|
298104
|
-
}
|
|
298105
|
-
async function save3() {
|
|
298106
|
-
if (state14) await writeCopyFile(STATE_FILE4(), { v: 1, asOf: state14.asOf, at: state14.at, hashes: state14.hashes });
|
|
298107
|
-
}
|
|
298108
|
-
async function readStore10() {
|
|
298109
|
-
try {
|
|
298110
|
-
const raw = JSON.parse(await fsp144.readFile(STORE_FILE(), "utf8"));
|
|
298111
|
-
return Array.isArray(raw?.requests) ? raw.requests.filter(isRow7) : [];
|
|
298112
|
-
} catch {
|
|
298113
|
-
return [];
|
|
298114
|
-
}
|
|
298115
|
-
}
|
|
298116
|
-
function isRow7(v3) {
|
|
298117
|
-
const r8 = v3;
|
|
298118
|
-
return !!r8 && typeof r8 === "object" && typeof r8.id === "string" && !!r8.id && typeof r8.fromSessionId === "string" && typeof r8.status === "string" && typeof r8.createdAt === "string";
|
|
298119
|
-
}
|
|
298120
|
-
function requestsFollower() {
|
|
298121
|
-
follower4 ??= createRowSetFollower({
|
|
298122
|
-
kind: "requests",
|
|
298123
|
-
schemaVersion: REQUESTS_SCHEMA_VERSION,
|
|
298124
|
-
label: "requests copy",
|
|
298125
|
-
log: log.session,
|
|
298126
|
-
removalFloor: REQUESTS_REMOVAL_FLOOR,
|
|
298127
|
-
ordered: false,
|
|
298128
|
-
serial: (fn) => serial8(fn),
|
|
298129
|
-
refuse: copyRefusal,
|
|
298130
|
-
load: load8,
|
|
298131
|
-
save: save3,
|
|
298132
|
-
isRow: isRow7,
|
|
298133
|
-
key: (r8) => r8.id,
|
|
298134
|
-
localKeys: async () => (await readStore10()).map((r8) => r8.id),
|
|
298135
|
-
apply: async ({ rows, removeIds }) => {
|
|
298136
|
-
const byId = new Map((await readStore10()).map((r8) => [r8.id, r8]));
|
|
298137
|
-
for (const id of removeIds ?? []) byId.delete(id);
|
|
298138
|
-
for (const r8 of rows ?? []) {
|
|
298139
|
-
const kept = forwardRequest(byId.get(r8.id), r8);
|
|
298140
|
-
if (kept !== r8) log.session.info("requests copy: kept a settled request the leader has not settled yet", { requestId: r8.id, local: kept.status, leader: r8.status });
|
|
298141
|
-
byId.set(r8.id, kept);
|
|
298142
|
-
}
|
|
298143
|
-
await writeCopyFile(STORE_FILE(), { requests: [...byId.values()] });
|
|
298144
|
-
return { skipped: [] };
|
|
298145
|
-
},
|
|
298146
|
-
held: async () => (await Promise.resolve().then(() => (init_journal_overlay(), journal_overlay_exports))).journalHeld("requests"),
|
|
298147
|
-
changed: () => {
|
|
298148
|
-
},
|
|
298149
|
-
purge: async () => {
|
|
298150
|
-
const removed = (await readStore10()).length;
|
|
298151
|
-
await fsp144.rm(STORE_FILE(), { force: true });
|
|
298152
|
-
await markCopyOff("requests");
|
|
298153
|
-
state14 = null;
|
|
298154
|
-
return { removed };
|
|
298155
|
-
}
|
|
298156
|
-
});
|
|
298157
|
-
return follower4;
|
|
298158
|
-
}
|
|
298159
|
-
var REQUESTS_SCHEMA_VERSION, REQUESTS_REMOVAL_FLOOR, FINAL, hashes5, REQUESTS_KIND, STATE_FILE4, STORE_FILE, state14, serial8, follower4;
|
|
298160
|
-
var init_requests = __esm({
|
|
298161
|
-
"src/core/replication/kinds/requests.ts"() {
|
|
298162
|
-
"use strict";
|
|
298163
|
-
init_constants();
|
|
298164
|
-
init_logging();
|
|
298165
|
-
init_kind();
|
|
298166
|
-
init_kind_follower();
|
|
298167
|
-
init_gate();
|
|
298168
|
-
REQUESTS_SCHEMA_VERSION = 1;
|
|
298169
|
-
REQUESTS_REMOVAL_FLOOR = 50;
|
|
298170
|
-
FINAL = /* @__PURE__ */ new Set(["replied", "notified", "expired"]);
|
|
298171
|
-
hashes5 = /* @__PURE__ */ new WeakMap();
|
|
298172
|
-
REQUESTS_KIND = {
|
|
298173
|
-
kind: "requests",
|
|
298174
|
-
schemaVersion: REQUESTS_SCHEMA_VERSION,
|
|
298175
|
-
key: (r8) => r8.id,
|
|
298176
|
-
hash: hashOf7,
|
|
298177
|
-
ordered: false,
|
|
298178
|
-
digest: false,
|
|
298179
|
-
choice: "requests",
|
|
298180
|
-
rows: async () => (await Promise.resolve().then(() => (init_session_requests(), session_requests_exports))).listAllSessionRequests(),
|
|
298181
|
-
watch: (soon) => {
|
|
298182
|
-
let stop2 = null;
|
|
298183
|
-
let stopped2 = false;
|
|
298184
|
-
void Promise.resolve().then(() => (init_session_requests(), session_requests_exports)).then(({ onSessionRequestsWritten: onSessionRequestsWritten2 }) => {
|
|
298185
|
-
if (!stopped2) stop2 = onSessionRequestsWritten2(soon);
|
|
298186
|
-
});
|
|
298187
|
-
return () => {
|
|
298188
|
-
stopped2 = true;
|
|
298189
|
-
stop2?.();
|
|
298190
|
-
};
|
|
298191
|
-
}
|
|
298192
|
-
};
|
|
298193
|
-
STATE_FILE4 = () => path267.join(WALNUT_HOME, "cache", "replica", "requests.json");
|
|
298194
|
-
STORE_FILE = () => path267.join(WALNUT_HOME, "session-requests.json");
|
|
298195
|
-
state14 = null;
|
|
298196
|
-
serial8 = serialChain();
|
|
298197
|
-
follower4 = null;
|
|
298198
|
-
}
|
|
298199
|
-
});
|
|
298200
|
-
|
|
298201
298434
|
// src/core/replication/kinds/sessions.ts
|
|
298202
298435
|
import fsp145 from "fs/promises";
|
|
298203
298436
|
import path268 from "path";
|
|
@@ -298228,11 +298461,11 @@ function projectedOf(row) {
|
|
|
298228
298461
|
}
|
|
298229
298462
|
return p6;
|
|
298230
298463
|
}
|
|
298231
|
-
function
|
|
298232
|
-
let h8 =
|
|
298464
|
+
function hashOf9(row) {
|
|
298465
|
+
let h8 = hashes7.get(row);
|
|
298233
298466
|
if (h8 === void 0) {
|
|
298234
298467
|
h8 = sessionCopyHash(row);
|
|
298235
|
-
|
|
298468
|
+
hashes7.set(row, h8);
|
|
298236
298469
|
}
|
|
298237
298470
|
return h8;
|
|
298238
298471
|
}
|
|
@@ -298252,7 +298485,7 @@ async function load9() {
|
|
|
298252
298485
|
async function save4() {
|
|
298253
298486
|
if (state15) await writeCopyFile(STATE_FILE5(), { v: 1, asOf: state15.asOf, at: state15.at, hashes: state15.hashes });
|
|
298254
298487
|
}
|
|
298255
|
-
function
|
|
298488
|
+
function isRow9(v3) {
|
|
298256
298489
|
const r8 = v3;
|
|
298257
298490
|
return !!r8 && typeof r8 === "object" && !Array.isArray(r8) && typeof r8.claudeSessionId === "string" && r8.claudeSessionId.length > 0 && r8.claudeSessionId.length <= 200;
|
|
298258
298491
|
}
|
|
@@ -298272,7 +298505,7 @@ function sessionsFollower() {
|
|
|
298272
298505
|
refuse: copyRefusal,
|
|
298273
298506
|
load: load9,
|
|
298274
298507
|
save: save4,
|
|
298275
|
-
isRow:
|
|
298508
|
+
isRow: isRow9,
|
|
298276
298509
|
key: (r8) => r8.claudeSessionId,
|
|
298277
298510
|
hash: sessionCopyHash,
|
|
298278
298511
|
localKeys: async () => (await Promise.resolve().then(() => (init_session_db(), session_db_exports))).sessionIdsInStore(),
|
|
@@ -298294,7 +298527,7 @@ function sessionsFollower() {
|
|
|
298294
298527
|
});
|
|
298295
298528
|
return follower5;
|
|
298296
298529
|
}
|
|
298297
|
-
var SESSIONS_SCHEMA_VERSION, SESSIONS_REMOVAL_FLOOR, PROCESS_FIELDS, PROCESS_SET, VOLATILE_SESSION_FIELDS, VOLATILE_SET, projected,
|
|
298530
|
+
var SESSIONS_SCHEMA_VERSION, SESSIONS_REMOVAL_FLOOR, PROCESS_FIELDS, PROCESS_SET, VOLATILE_SESSION_FIELDS, VOLATILE_SET, projected, hashes7, SESSIONS_KIND, STATE_FILE5, state15, serial9, follower5;
|
|
298298
298531
|
var init_sessions2 = __esm({
|
|
298299
298532
|
"src/core/replication/kinds/sessions.ts"() {
|
|
298300
298533
|
"use strict";
|
|
@@ -298331,12 +298564,12 @@ var init_sessions2 = __esm({
|
|
|
298331
298564
|
VOLATILE_SESSION_FIELDS = ["lastActiveAt", "activity", "contextTokens"];
|
|
298332
298565
|
VOLATILE_SET = new Set(VOLATILE_SESSION_FIELDS);
|
|
298333
298566
|
projected = /* @__PURE__ */ new WeakMap();
|
|
298334
|
-
|
|
298567
|
+
hashes7 = /* @__PURE__ */ new WeakMap();
|
|
298335
298568
|
SESSIONS_KIND = {
|
|
298336
298569
|
kind: "sessions",
|
|
298337
298570
|
schemaVersion: SESSIONS_SCHEMA_VERSION,
|
|
298338
298571
|
key: (s4) => s4.claudeSessionId,
|
|
298339
|
-
hash:
|
|
298572
|
+
hash: hashOf9,
|
|
298340
298573
|
ordered: false,
|
|
298341
298574
|
digest: true,
|
|
298342
298575
|
choice: "sessions",
|
|
@@ -298368,137 +298601,11 @@ var init_sessions2 = __esm({
|
|
|
298368
298601
|
}
|
|
298369
298602
|
});
|
|
298370
298603
|
|
|
298371
|
-
// src/core/replication/kinds/personas.ts
|
|
298372
|
-
var personas_exports = {};
|
|
298373
|
-
__export(personas_exports, {
|
|
298374
|
-
PERSONAS_KIND: () => PERSONAS_KIND,
|
|
298375
|
-
PERSONAS_REMOVAL_FLOOR: () => PERSONAS_REMOVAL_FLOOR,
|
|
298376
|
-
PERSONAS_SCHEMA_VERSION: () => PERSONAS_SCHEMA_VERSION,
|
|
298377
|
-
_resetPersonasCopyForTesting: () => _resetPersonasCopyForTesting,
|
|
298378
|
-
personasFollower: () => personasFollower,
|
|
298379
|
-
readPersonaCopy: () => readPersonaCopy
|
|
298380
|
-
});
|
|
298381
|
-
function tools(v3) {
|
|
298382
|
-
return Array.isArray(v3) && v3.length > 0 && v3.every((t3) => typeof t3 === "string" && TOOL_RE.test(t3)) ? [...v3] : void 0;
|
|
298383
|
-
}
|
|
298384
|
-
async function leaderRows3() {
|
|
298385
|
-
const [{ getConsoleAgents: getConsoleAgents2 }, { buildLaneProfile: buildLaneProfile2 }, { getConfig: getConfig2 }, { getAskWalnutLaunchPrefs: getAskWalnutLaunchPrefs2 }] = await Promise.all([
|
|
298386
|
-
Promise.resolve().then(() => (init_agent_registry(), agent_registry_exports)),
|
|
298387
|
-
Promise.resolve().then(() => (init_personal_ai_lane(), personal_ai_lane_exports)),
|
|
298388
|
-
Promise.resolve().then(() => (init_config_manager(), config_manager_exports)),
|
|
298389
|
-
Promise.resolve().then(() => (init_ask_walnut_launch(), ask_walnut_launch_exports))
|
|
298390
|
-
]);
|
|
298391
|
-
const config = await getConfig2();
|
|
298392
|
-
const launch = await getAskWalnutLaunchPrefs2().catch(() => ({}));
|
|
298393
|
-
const agents = [{ id: "general", name: "Walnut" }, ...(await getConsoleAgents2()).filter((a8) => a8.id !== "general").map((a8) => ({ id: a8.id, name: a8.name }))];
|
|
298394
|
-
const rows = [];
|
|
298395
|
-
for (const a8 of agents) {
|
|
298396
|
-
if (!ID_RE5.test(a8.id)) continue;
|
|
298397
|
-
try {
|
|
298398
|
-
const { profile, effort } = await buildLaneProfile2(config, a8.id);
|
|
298399
|
-
const prompt = profile.systemPrompt ?? "";
|
|
298400
|
-
if (!prompt || Buffer.byteLength(prompt, "utf8") > MAX_PROMPT_BYTES) continue;
|
|
298401
|
-
rows.push({
|
|
298402
|
-
key: a8.id,
|
|
298403
|
-
agentId: a8.id,
|
|
298404
|
-
name: String(a8.name ?? a8.id).slice(0, 120),
|
|
298405
|
-
systemPrompt: prompt,
|
|
298406
|
-
systemPromptMode: profile.systemPromptMode === "replace" ? "replace" : "append",
|
|
298407
|
-
...tools(profile.allowedTools) ? { allowedTools: tools(profile.allowedTools) } : {},
|
|
298408
|
-
...tools(profile.tools) ? { tools: tools(profile.tools) } : {},
|
|
298409
|
-
...effort ? { effort } : {},
|
|
298410
|
-
...launch.model ? { launchModel: launch.model } : {},
|
|
298411
|
-
...launch.effort ? { launchEffort: launch.effort } : {}
|
|
298412
|
-
});
|
|
298413
|
-
} catch (err2) {
|
|
298414
|
-
log.session.warn("copies: an agent persona was not rendered for the host", { agentId: a8.id, error: err2 instanceof Error ? err2.message : String(err2) });
|
|
298415
|
-
}
|
|
298416
|
-
}
|
|
298417
|
-
return rows;
|
|
298418
|
-
}
|
|
298419
|
-
function hashOf9(row) {
|
|
298420
|
-
let h8 = hashes7.get(row);
|
|
298421
|
-
if (h8 === void 0) {
|
|
298422
|
-
h8 = sha12(JSON.stringify(row));
|
|
298423
|
-
hashes7.set(row, h8);
|
|
298424
|
-
}
|
|
298425
|
-
return h8;
|
|
298426
|
-
}
|
|
298427
|
-
function isRow9(v3) {
|
|
298428
|
-
const r8 = v3;
|
|
298429
|
-
if (!r8 || typeof r8 !== "object" || Array.isArray(r8)) return false;
|
|
298430
|
-
if (Object.keys(r8).some((k8) => !ROW_KEYS.has(k8))) return false;
|
|
298431
|
-
if (typeof r8.key !== "string" || r8.key !== r8.agentId || !ID_RE5.test(r8.key) || typeof r8.name !== "string") return false;
|
|
298432
|
-
if (typeof r8.systemPrompt !== "string" || !r8.systemPrompt || Buffer.byteLength(r8.systemPrompt, "utf8") > MAX_PROMPT_BYTES) return false;
|
|
298433
|
-
if (r8.systemPromptMode !== "append" && r8.systemPromptMode !== "replace") return false;
|
|
298434
|
-
for (const k8 of ["allowedTools", "tools"]) if (r8[k8] !== void 0 && !tools(r8[k8])) return false;
|
|
298435
|
-
for (const k8 of ["effort", "launchModel", "launchEffort"]) if (r8[k8] !== void 0 && (typeof r8[k8] !== "string" || !/^[A-Za-z0-9._:[\]/-]{1,128}$/.test(r8[k8]))) return false;
|
|
298436
|
-
return true;
|
|
298437
|
-
}
|
|
298438
|
-
function admit2(r8) {
|
|
298439
|
-
return secretShapedValue(r8.systemPrompt) === null && secretShapedValue(r8.name) === null;
|
|
298440
|
-
}
|
|
298441
|
-
async function readPersonaCopy(agentId) {
|
|
298442
|
-
const rows = await copy4.read();
|
|
298443
|
-
return rows?.[agentId] ?? null;
|
|
298444
|
-
}
|
|
298445
|
-
function _resetPersonasCopyForTesting() {
|
|
298446
|
-
copy4.reset();
|
|
298447
|
-
}
|
|
298448
|
-
var PERSONAS_SCHEMA_VERSION, PERSONAS_REMOVAL_FLOOR, MAX_PROMPT_BYTES, ID_RE5, TOOL_RE, hashes7, PERSONAS_KIND, ROW_KEYS, copy4, personasFollower;
|
|
298449
|
-
var init_personas = __esm({
|
|
298450
|
-
"src/core/replication/kinds/personas.ts"() {
|
|
298451
|
-
"use strict";
|
|
298452
|
-
init_logging();
|
|
298453
|
-
init_config_allowlist();
|
|
298454
|
-
init_kind();
|
|
298455
|
-
init_file_copy();
|
|
298456
|
-
PERSONAS_SCHEMA_VERSION = 1;
|
|
298457
|
-
PERSONAS_REMOVAL_FLOOR = 0;
|
|
298458
|
-
MAX_PROMPT_BYTES = 120 * 1024;
|
|
298459
|
-
ID_RE5 = /^[A-Za-z0-9_-]{1,80}$/;
|
|
298460
|
-
TOOL_RE = /^[A-Za-z0-9_.:*()/ -]{1,200}$/;
|
|
298461
|
-
hashes7 = /* @__PURE__ */ new WeakMap();
|
|
298462
|
-
PERSONAS_KIND = {
|
|
298463
|
-
kind: "personas",
|
|
298464
|
-
schemaVersion: PERSONAS_SCHEMA_VERSION,
|
|
298465
|
-
key: (r8) => r8.key,
|
|
298466
|
-
hash: hashOf9,
|
|
298467
|
-
ordered: false,
|
|
298468
|
-
digest: false,
|
|
298469
|
-
choice: "personas",
|
|
298470
|
-
rows: leaderRows3,
|
|
298471
|
-
watch: (soon) => {
|
|
298472
|
-
let stop2 = null;
|
|
298473
|
-
let stopped2 = false;
|
|
298474
|
-
void Promise.resolve().then(() => (init_config_manager(), config_manager_exports)).then((cm) => {
|
|
298475
|
-
if (!stopped2) stop2 = cm.onConfigWritten(soon);
|
|
298476
|
-
});
|
|
298477
|
-
return () => {
|
|
298478
|
-
stopped2 = true;
|
|
298479
|
-
stop2?.();
|
|
298480
|
-
};
|
|
298481
|
-
}
|
|
298482
|
-
};
|
|
298483
|
-
ROW_KEYS = /* @__PURE__ */ new Set(["key", "agentId", "name", "systemPrompt", "systemPromptMode", "allowedTools", "tools", "effort", "launchModel", "launchEffort"]);
|
|
298484
|
-
copy4 = createFileCopy({
|
|
298485
|
-
kind: "personas",
|
|
298486
|
-
schemaVersion: PERSONAS_SCHEMA_VERSION,
|
|
298487
|
-
label: "personas copy",
|
|
298488
|
-
removalFloor: PERSONAS_REMOVAL_FLOOR,
|
|
298489
|
-
isRow: isRow9,
|
|
298490
|
-
key: (r8) => r8.key,
|
|
298491
|
-
admit: admit2
|
|
298492
|
-
});
|
|
298493
|
-
personasFollower = copy4.follower;
|
|
298494
|
-
}
|
|
298495
|
-
});
|
|
298496
|
-
|
|
298497
298604
|
// src/core/replication/kinds/index.ts
|
|
298498
298605
|
var kinds_exports = {};
|
|
298499
298606
|
__export(kinds_exports, {
|
|
298607
|
+
copyKeepersOnly: () => copyKeepersOnly,
|
|
298500
298608
|
copyKinds: () => copyKinds,
|
|
298501
|
-
hostReplicaOnly: () => hostReplicaOnly,
|
|
298502
298609
|
registerCopyFollowerKinds: () => registerCopyFollowerKinds,
|
|
298503
298610
|
startCopyKinds: () => startCopyKinds
|
|
298504
298611
|
});
|
|
@@ -298516,14 +298623,14 @@ function copyKinds() {
|
|
|
298516
298623
|
PERSONAS_KIND
|
|
298517
298624
|
];
|
|
298518
298625
|
}
|
|
298519
|
-
function
|
|
298626
|
+
function copyKeepersOnly(h8) {
|
|
298520
298627
|
return {
|
|
298521
298628
|
kind: h8.kind,
|
|
298522
|
-
// followerStep checks the version before the step: never `schema_newer`
|
|
298629
|
+
// followerStep checks the version before the step: never `schema_newer` where the kind is not kept.
|
|
298523
298630
|
get schemaVersion() {
|
|
298524
|
-
return keepsCopies() ? h8.schemaVersion : Number.MAX_SAFE_INTEGER;
|
|
298631
|
+
return keepsCopies(h8.kind) ? h8.schemaVersion : Number.MAX_SAFE_INTEGER;
|
|
298525
298632
|
},
|
|
298526
|
-
step: (op2, body7) => keepsCopies() ? h8.step(op2, body7) : { ok: false, status: 404, error: "unknown_kind" }
|
|
298633
|
+
step: (op2, body7) => keepsCopies(h8.kind) ? h8.step(op2, body7) : { ok: false, status: 404, error: "unknown_kind" }
|
|
298527
298634
|
};
|
|
298528
298635
|
}
|
|
298529
298636
|
function registerCopyFollowerKinds() {
|
|
@@ -298538,7 +298645,7 @@ function registerCopyFollowerKinds() {
|
|
|
298538
298645
|
prefsFollower(),
|
|
298539
298646
|
configFollower(),
|
|
298540
298647
|
personasFollower()
|
|
298541
|
-
].map((h8) => registerFollowerKind(
|
|
298648
|
+
].map((h8) => registerFollowerKind(copyKeepersOnly(h8)));
|
|
298542
298649
|
return () => {
|
|
298543
298650
|
for (const u3 of off) u3();
|
|
298544
298651
|
};
|