tesseract-agent 0.11.2 → 0.11.5

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.
@@ -3378,7 +3378,7 @@ var require_stream = __commonJS({
3378
3378
  };
3379
3379
  duplex._final = function(callback) {
3380
3380
  if (ws.readyState === ws.CONNECTING) {
3381
- ws.once("open", function open7() {
3381
+ ws.once("open", function open8() {
3382
3382
  duplex._final(callback);
3383
3383
  });
3384
3384
  return;
@@ -3399,7 +3399,7 @@ var require_stream = __commonJS({
3399
3399
  };
3400
3400
  duplex._write = function(chunk, encoding, callback) {
3401
3401
  if (ws.readyState === ws.CONNECTING) {
3402
- ws.once("open", function open7() {
3402
+ ws.once("open", function open8() {
3403
3403
  duplex._write(chunk, encoding, callback);
3404
3404
  });
3405
3405
  return;
@@ -4269,7 +4269,7 @@ function isPidAlive(pid) {
4269
4269
  function createSchedulerLock(lockDir, ownerId, now2 = () => Date.now()) {
4270
4270
  const lockFile = join5(lockDir, "scheduled_tasks.lock");
4271
4271
  let held = false;
4272
- const read = () => {
4272
+ const read2 = () => {
4273
4273
  try {
4274
4274
  const rec = JSON.parse(readFileSync4(lockFile, "utf-8"));
4275
4275
  if (rec && typeof rec.ownerId === "string" && typeof rec.pid === "number" && typeof rec.refreshedAt === "number")
@@ -4294,13 +4294,13 @@ function createSchedulerLock(lockDir, ownerId, now2 = () => Date.now()) {
4294
4294
  held = false;
4295
4295
  return false;
4296
4296
  }
4297
- const after = read();
4297
+ const after = read2();
4298
4298
  held = !!after && after.nonce === nonce2;
4299
4299
  return held;
4300
4300
  };
4301
4301
  return {
4302
4302
  isOwner() {
4303
- const existing = read();
4303
+ const existing = read2();
4304
4304
  if (!existing) {
4305
4305
  try {
4306
4306
  const fd = openSync(lockFile, "wx");
@@ -4312,7 +4312,7 @@ function createSchedulerLock(lockDir, ownerId, now2 = () => Date.now()) {
4312
4312
  held = true;
4313
4313
  return true;
4314
4314
  } catch {
4315
- const r = read();
4315
+ const r = read2();
4316
4316
  if (r && r.ownerId === ownerId)
4317
4317
  return writeLease();
4318
4318
  return false;
@@ -4329,7 +4329,7 @@ function createSchedulerLock(lockDir, ownerId, now2 = () => Date.now()) {
4329
4329
  release() {
4330
4330
  if (!held)
4331
4331
  return;
4332
- const r = read();
4332
+ const r = read2();
4333
4333
  if (r && r.ownerId === ownerId) {
4334
4334
  try {
4335
4335
  unlinkSync(lockFile);
@@ -24207,9 +24207,9 @@ function extractJsonObject(raw) {
24207
24207
  function extractJsonArray(raw) {
24208
24208
  return extractBalanced(raw, "[", "]");
24209
24209
  }
24210
- function extractBalanced(raw, open7, close) {
24210
+ function extractBalanced(raw, open8, close) {
24211
24211
  const s = raw.replace(/^```(?:json)?\s*/i, "").replace(/\s*```\s*$/i, "");
24212
- const start3 = s.indexOf(open7);
24212
+ const start3 = s.indexOf(open8);
24213
24213
  if (start3 < 0)
24214
24214
  return null;
24215
24215
  let depth = 0, inStr = false, esc3 = false;
@@ -24226,7 +24226,7 @@ function extractBalanced(raw, open7, close) {
24226
24226
  }
24227
24227
  if (c === '"')
24228
24228
  inStr = true;
24229
- else if (c === open7)
24229
+ else if (c === open8)
24230
24230
  depth++;
24231
24231
  else if (c === close) {
24232
24232
  depth--;
@@ -29167,17 +29167,17 @@ function markerPair(path6) {
29167
29167
  return { open: `// ${MARKER}:start`, close: `// ${MARKER}:end` };
29168
29168
  }
29169
29169
  function upsertMarkedBlock(path6, source, block2, anchor) {
29170
- const { open: open7, close } = markerPair(path6);
29171
- const start3 = source.indexOf(open7);
29170
+ const { open: open8, close } = markerPair(path6);
29171
+ const start3 = source.indexOf(open8);
29172
29172
  const end2 = source.indexOf(close);
29173
29173
  if (start3 !== -1 && end2 !== -1 && end2 > start3) {
29174
- const existing = source.slice(start3 + open7.length, end2);
29174
+ const existing = source.slice(start3 + open8.length, end2);
29175
29175
  const next = `
29176
29176
  ${block2}
29177
29177
  `;
29178
29178
  if (existing === next)
29179
29179
  return { ok: true, source, changed: false };
29180
- return { ok: true, source: source.slice(0, start3 + open7.length) + next + source.slice(end2), changed: true };
29180
+ return { ok: true, source: source.slice(0, start3 + open8.length) + next + source.slice(end2), changed: true };
29181
29181
  }
29182
29182
  if (start3 !== -1 || end2 !== -1) {
29183
29183
  return { ok: false, why: `found only one of the ${MARKER} markers \u2014 remove the stray one by hand and re-run` };
@@ -29189,7 +29189,7 @@ ${block2}
29189
29189
  return { ok: false, why: "could not find where to insert \u2014 the file does not look like the shape we expected" };
29190
29190
  const at = m.index + m[0].length;
29191
29191
  return { ok: true, source: `${source.slice(0, at)}
29192
- ${open7}
29192
+ ${open8}
29193
29193
  ${block2}
29194
29194
  ${close}${source.slice(at)}`, changed: true };
29195
29195
  }
@@ -30878,8 +30878,8 @@ ${err2 instanceof Error ? err2.message : String(err2)}
30878
30878
  const fd = openSync2(job.logPath, "r");
30879
30879
  try {
30880
30880
  const buf = Buffer.allocUnsafe(want);
30881
- const read = readSync(fd, buf, 0, want, size - want);
30882
- return buf.subarray(0, read).toString("utf8");
30881
+ const read2 = readSync(fd, buf, 0, want, size - want);
30882
+ return buf.subarray(0, read2).toString("utf8");
30883
30883
  } finally {
30884
30884
  closeSync2(fd);
30885
30885
  }
@@ -31045,6 +31045,19 @@ var init_work_ledger = __esm({
31045
31045
  * gone: what the barrier needs is the answer to "what happened to the thing I was waiting
31046
31046
  * for", asked after it stopped existing.
31047
31047
  */
31048
+ /**
31049
+ * Proof of life: the producer said something about this item (a progress frame, an
31050
+ * inventory that still lists it, a registry that still says running). Its deadline moves
31051
+ * out again, so a long-running job that keeps reporting is never mistaken for a hung one
31052
+ * and never swept while it is really working. Detached items have no deadline to move.
31053
+ */
31054
+ touch(id, now2) {
31055
+ const item = this.items.get(id);
31056
+ if (!item || item.disposition !== "awaited")
31057
+ return false;
31058
+ this.items.set(id, { ...item, deadline: now2 + DEFAULT_DEADLINE_MS[item.kind] });
31059
+ return true;
31060
+ }
31048
31061
  settle(id, outcome = "completed") {
31049
31062
  const had = this.items.delete(id);
31050
31063
  if (had) {
@@ -31123,6 +31136,10 @@ var init_work_ledger = __esm({
31123
31136
  for (const t of inv.tasks ?? []) {
31124
31137
  seen.add(t.id);
31125
31138
  const subagent = t.type === "subagent";
31139
+ if (this.items.has(t.id)) {
31140
+ this.touch(t.id, now2);
31141
+ continue;
31142
+ }
31126
31143
  this.register({
31127
31144
  id: t.id,
31128
31145
  kind: subagent ? "subagent" : "engine-task",
@@ -31165,7 +31182,7 @@ var init_work_ledger = __esm({
31165
31182
  else
31166
31183
  waiting.push(item);
31167
31184
  }
31168
- return { quiescent: waiting.length === 0, waiting, overdue, detached };
31185
+ return { quiescent: waiting.length === 0 && overdue.length === 0, waiting, overdue, detached };
31169
31186
  }
31170
31187
  /**
31171
31188
  * One line per item, for the grader and the closing report.
@@ -31254,10 +31271,10 @@ function wrapAsyncTool(def, opts) {
31254
31271
  return text9(raced.err instanceof Error ? raced.err.message : String(raced.err), true);
31255
31272
  }
31256
31273
  opts.learnedSlow?.add(t.name);
31257
- const job = opts.registry.start(t.name, describeArgs(t.name, args), async (write2) => {
31274
+ const job = opts.registry.start(t.name, describeArgs(t.name, args), async (write3) => {
31258
31275
  try {
31259
31276
  const out = await work;
31260
- write2(out);
31277
+ write3(out);
31261
31278
  } catch (err2) {
31262
31279
  throw err2 instanceof Error ? err2 : new Error(String(err2));
31263
31280
  }
@@ -37093,14 +37110,72 @@ var init_cost_ledger = __esm({
37093
37110
  }
37094
37111
  });
37095
37112
 
37113
+ // ../../packages/agent-core/dist/session-activity.js
37114
+ import { open as open3 } from "node:fs/promises";
37115
+ function lastTimestampIn(chunk) {
37116
+ let last = null;
37117
+ const re = /"timestamp":"([^"]{10,40})"/g;
37118
+ let m;
37119
+ while ((m = re.exec(chunk)) !== null) {
37120
+ const t = Date.parse(m[1]);
37121
+ if (Number.isFinite(t))
37122
+ last = t;
37123
+ }
37124
+ return last;
37125
+ }
37126
+ async function lastConversationTime(file2) {
37127
+ let fh;
37128
+ try {
37129
+ fh = await open3(file2, "r");
37130
+ } catch {
37131
+ return null;
37132
+ }
37133
+ try {
37134
+ const size = (await fh.stat()).size;
37135
+ if (size === 0)
37136
+ return null;
37137
+ let end2 = size;
37138
+ let scanned = 0;
37139
+ while (end2 > 0 && scanned < ACTIVITY_MAX_SCAN_BYTES) {
37140
+ const start3 = Math.max(0, end2 - ACTIVITY_WINDOW_BYTES);
37141
+ const len = end2 - start3;
37142
+ const buf = Buffer.alloc(len);
37143
+ const { bytesRead } = await fh.read(buf, 0, len, start3);
37144
+ const found = lastTimestampIn(buf.subarray(0, bytesRead).toString("utf8"));
37145
+ if (found !== null)
37146
+ return found;
37147
+ scanned += len;
37148
+ end2 = start3 + OVERLAP > start3 ? Math.max(0, start3 + OVERLAP) : start3;
37149
+ if (start3 === 0)
37150
+ break;
37151
+ }
37152
+ return null;
37153
+ } catch {
37154
+ return null;
37155
+ } finally {
37156
+ await fh.close().catch(() => {
37157
+ });
37158
+ }
37159
+ }
37160
+ var ACTIVITY_WINDOW_BYTES, ACTIVITY_MAX_SCAN_BYTES, OVERLAP;
37161
+ var init_session_activity = __esm({
37162
+ "../../packages/agent-core/dist/session-activity.js"() {
37163
+ "use strict";
37164
+ ACTIVITY_WINDOW_BYTES = 64 * 1024;
37165
+ ACTIVITY_MAX_SCAN_BYTES = 2 * 1024 * 1024;
37166
+ OVERLAP = 64;
37167
+ }
37168
+ });
37169
+
37096
37170
  // ../../packages/agent-core/dist/session-store.js
37097
37171
  import { readFile as readFile5, stat as stat2 } from "node:fs/promises";
37098
37172
  import { listSessions, getSessionMessages, getSubagentMessages as sdkGetSubagentMessages, forkSession } from "@anthropic-ai/claude-agent-sdk";
37099
- function toSessionInfo(s) {
37173
+ async function toSessionInfo(s) {
37100
37174
  const fromFirst = stripPromptPrefix(s.firstPrompt ?? "").slice(0, 80);
37101
37175
  const fromSummary = stripPromptPrefix(s.summary ?? "").slice(0, 80);
37102
37176
  const title = s.customTitle || fromFirst || fromSummary || `Session ${s.sessionId.slice(0, 8)}`;
37103
- return { id: s.sessionId, title, lastModified: s.lastModified, cwd: s.cwd };
37177
+ const spoken = s.cwd ? await lastConversationTime(sessionFile(s.cwd, s.sessionId)) : null;
37178
+ return { id: s.sessionId, title, lastModified: spoken ?? s.lastModified, cwd: s.cwd };
37104
37179
  }
37105
37180
  function transcriptMatches(raw, q) {
37106
37181
  for (const line of raw.split("\n")) {
@@ -37220,12 +37295,14 @@ ${input.command}
37220
37295
  }
37221
37296
  return blocks;
37222
37297
  }
37223
- var SEARCH_SCAN_LIMIT, SEARCH_RESULT_LIMIT, SEARCH_MAX_FILE_BYTES, FORK_RETRY_ATTEMPTS, FORK_RETRY_DELAY_MS, delay, SessionStore;
37298
+ var newestFirst, SEARCH_SCAN_LIMIT, SEARCH_RESULT_LIMIT, SEARCH_MAX_FILE_BYTES, FORK_RETRY_ATTEMPTS, FORK_RETRY_DELAY_MS, delay, SessionStore;
37224
37299
  var init_session_store = __esm({
37225
37300
  "../../packages/agent-core/dist/session-store.js"() {
37226
37301
  "use strict";
37227
37302
  init_session_transfer();
37228
37303
  init_history_slim();
37304
+ init_session_activity();
37305
+ newestFirst = (a, b) => b.lastModified - a.lastModified;
37229
37306
  SEARCH_SCAN_LIMIT = 200;
37230
37307
  SEARCH_RESULT_LIMIT = 50;
37231
37308
  SEARCH_MAX_FILE_BYTES = 8 * 1024 * 1024;
@@ -37239,7 +37316,7 @@ var init_session_store = __esm({
37239
37316
  async getSessions(projectDir) {
37240
37317
  try {
37241
37318
  const sessions3 = projectDir ? await listSessions({ dir: projectDir, limit: 50 }) : await listSessions({ limit: 50 });
37242
- return sessions3.map(toSessionInfo);
37319
+ return (await Promise.all(sessions3.map(toSessionInfo))).sort(newestFirst);
37243
37320
  } catch (err2) {
37244
37321
  return [];
37245
37322
  }
@@ -37260,7 +37337,7 @@ var init_session_store = __esm({
37260
37337
  }
37261
37338
  const out = [];
37262
37339
  for (const s of sessions3) {
37263
- const info = toSessionInfo(s);
37340
+ const info = await toSessionInfo(s);
37264
37341
  if (info.title.toLowerCase().includes(q)) {
37265
37342
  out.push(info);
37266
37343
  } else if (s.cwd) {
@@ -37278,7 +37355,7 @@ var init_session_store = __esm({
37278
37355
  if (out.length >= SEARCH_RESULT_LIMIT)
37279
37356
  break;
37280
37357
  }
37281
- return out;
37358
+ return out.sort(newestFirst);
37282
37359
  }
37283
37360
  async getSessionMessages(sessionId, projectDir) {
37284
37361
  try {
@@ -37308,6 +37385,7 @@ var init_session_store = __esm({
37308
37385
  rawToMessages(raw) {
37309
37386
  const messages = [];
37310
37387
  for (const entry of raw) {
37388
+ const ts = typeof entry.timestamp === "string" ? Date.parse(entry.timestamp) : NaN;
37311
37389
  const blocks = extractBlocks(entry.message);
37312
37390
  if (blocks.length === 0 && entry.type === "user")
37313
37391
  continue;
@@ -37323,7 +37401,8 @@ var init_session_store = __esm({
37323
37401
  blocks: entry.type === "assistant" ? blocks : void 0,
37324
37402
  // Thread the per-message SDK uuid so the renderer can pass it as
37325
37403
  // session:fork.upToMessageId ("fork from here").
37326
- uuid: typeof entry.uuid === "string" ? entry.uuid : void 0
37404
+ uuid: typeof entry.uuid === "string" ? entry.uuid : void 0,
37405
+ ...Number.isFinite(ts) ? { timestamp: ts } : {}
37327
37406
  });
37328
37407
  }
37329
37408
  return messages;
@@ -37920,6 +37999,12 @@ import { spawn as spawn2, execSync, execFileSync } from "node:child_process";
37920
37999
  function setBrowserExtensionProbe(fn) {
37921
38000
  browserExtensionConnected = fn;
37922
38001
  }
38002
+ function isTurnBearingFrame(type) {
38003
+ return type === "assistant" || type === "stream_event" || type === "user";
38004
+ }
38005
+ function turnStillOpening(openedAt, now2) {
38006
+ return openedAt !== void 0 && now2 - openedAt < TURN_OPENING_GRACE_MS;
38007
+ }
37923
38008
  function findUserInstalledClaude(binName) {
37924
38009
  const home = homedir3();
37925
38010
  const abs = [
@@ -38811,7 +38896,7 @@ ${next}` : next;
38811
38896
  function autoDecisionSubject(prompt2) {
38812
38897
  return prompt2.kind === "permission" ? prompt2.tool : void 0;
38813
38898
  }
38814
- var browserExtensionConnected, SLIM_KEEP_RECENT_TURNS, cachedClaudeExe, unsupportedCliOptions, rejectedCliArgs, CAPS_VERSION, capsLoaded, EFFORT_LADDER, cachedEfforts, modelEffortLevels, sharedSessionStore, monoNowMs, sessionCwdCache, cachedNodeExe, HUMAN_READABLE_FIELDS, SYSTEM_EVENT_CATEGORY, TOOL_RESULT_CAP, MAX_RESULT_IMAGES, MAX_IMAGE_BASE64, PERMISSION_MODES, EDIT_PREVIEW_CAP, AsyncMessagePump, IDLE_REAP_MS, EFFORT_SWAP_DEBOUNCE_MS, MODERATE_IDLE_MS, STEER_COALESCE_MS, AUTO_BACKGROUND_SECONDS, TASK_REGISTER_SECONDS, JOB_NOTICE_COALESCE_MS, JOB_NOTICE_WORK_ID, QUIESCENCE_MAX_MS, QUIESCENCE_POLL_MS, BATCH_WAIT_MS, INLINE_TOOL_NAMES, STOP_HARD_KILL_AFTER_MS, STREAM_STALL_MS, STREAM_FIRST_FRAME_MS, RV_TASK_MAX, OPTION_RATING_JSON_SCHEMA, AgentManager;
38899
+ var browserExtensionConnected, TURN_OPENING_GRACE_MS, SLIM_KEEP_RECENT_TURNS, cachedClaudeExe, unsupportedCliOptions, rejectedCliArgs, CAPS_VERSION, capsLoaded, EFFORT_LADDER, cachedEfforts, modelEffortLevels, sharedSessionStore, monoNowMs, sessionCwdCache, cachedNodeExe, HUMAN_READABLE_FIELDS, SYSTEM_EVENT_CATEGORY, TOOL_RESULT_CAP, MAX_RESULT_IMAGES, MAX_IMAGE_BASE64, PERMISSION_MODES, EDIT_PREVIEW_CAP, AsyncMessagePump, IDLE_REAP_MS, EFFORT_SWAP_DEBOUNCE_MS, MODERATE_IDLE_MS, STEER_COALESCE_MS, AUTO_BACKGROUND_SECONDS, TASK_REGISTER_SECONDS, JOB_NOTICE_COALESCE_MS, JOB_NOTICE_WORK_ID, QUIESCENCE_MAX_MS, QUIESCENCE_POLL_MS, BATCH_WAIT_MS, INLINE_TOOL_NAMES, STOP_HARD_KILL_AFTER_MS, STREAM_STALL_MS, STREAM_FIRST_FRAME_MS, RV_TASK_MAX, OPTION_RATING_JSON_SCHEMA, AgentManager;
38815
38900
  var init_agent_manager = __esm({
38816
38901
  "../../packages/agent-core/dist/agent-manager.js"() {
38817
38902
  "use strict";
@@ -38871,6 +38956,7 @@ var init_agent_manager = __esm({
38871
38956
  init_stream_stall();
38872
38957
  init_usage_limit();
38873
38958
  browserExtensionConnected = () => false;
38959
+ TURN_OPENING_GRACE_MS = 5 * 6e4;
38874
38960
  SLIM_KEEP_RECENT_TURNS = 3;
38875
38961
  unsupportedCliOptions = /* @__PURE__ */ new Set();
38876
38962
  rejectedCliArgs = /* @__PURE__ */ new Map();
@@ -38941,7 +39027,7 @@ var init_agent_manager = __esm({
38941
39027
  TASK_REGISTER_SECONDS = 3;
38942
39028
  JOB_NOTICE_COALESCE_MS = 400;
38943
39029
  JOB_NOTICE_WORK_ID = "pending-job-notices";
38944
- QUIESCENCE_MAX_MS = 20 * 6e4;
39030
+ QUIESCENCE_MAX_MS = 12 * 60 * 6e4;
38945
39031
  QUIESCENCE_POLL_MS = 500;
38946
39032
  BATCH_WAIT_MS = 6e4;
38947
39033
  INLINE_TOOL_NAMES = /* @__PURE__ */ new Set([
@@ -39980,50 +40066,77 @@ ${full.slice(-8e3)}`;
39980
40066
  let cappedOut = false;
39981
40067
  let narrated = false;
39982
40068
  const turn = live.turnSeq;
39983
- for (; ; ) {
39984
- if (live.rv !== rv) {
39985
- log(`[work] quiescence wait for ${live.sessionId} dropped \u2014 another run owns the session`);
39986
- this.clearWorkNarration(live, narrated);
39987
- return;
39988
- }
39989
- if (live.reaped) {
39990
- log(`[work] quiescence wait for ${live.sessionId} dropped \u2014 the session was torn down`);
39991
- this.clearWorkNarration(live, narrated);
39992
- return;
39993
- }
39994
- if (live.turnSeq !== turn) {
39995
- log(`[work] quiescence wait for ${live.sessionId} superseded by a new turn`);
39996
- this.clearWorkNarration(live, narrated);
39997
- return;
39998
- }
39999
- const v = live.ledger.verdict(Date.now());
40000
- if (v.quiescent)
40001
- break;
40002
- if (Date.now() - started2 >= QUIESCENCE_MAX_MS) {
40003
- cappedOut = true;
40004
- break;
40005
- }
40006
- if (!narrated && live.sessionId) {
40007
- narrated = true;
40008
- this.send({
40009
- type: "agent:narration",
40010
- sessionId: live.sessionId,
40011
- text: `Waiting for ${v.waiting.length} background ${v.waiting.length === 1 ? "task" : "tasks"} to finish\u2026`,
40012
- engineLabel: "Claude Code"
40013
- }, live.origin);
40069
+ live.gradePending = true;
40070
+ try {
40071
+ for (; ; ) {
40072
+ if (live.rv !== rv) {
40073
+ log(`[work] quiescence wait for ${live.sessionId} dropped \u2014 another run owns the session`);
40074
+ this.clearWorkNarration(live, narrated);
40075
+ return;
40076
+ }
40077
+ if (live.gone) {
40078
+ log(`[work] quiescence wait for ${live.sessionId} dropped \u2014 the session was torn down`);
40079
+ this.clearWorkNarration(live, narrated);
40080
+ return;
40081
+ }
40082
+ if (live.turnSeq !== turn) {
40083
+ log(`[work] quiescence wait for ${live.sessionId} superseded by a new turn`);
40084
+ this.clearWorkNarration(live, narrated);
40085
+ return;
40086
+ }
40087
+ const now2 = Date.now();
40088
+ live.ledger.sweep(now2);
40089
+ this.refreshLedgerFromRegistry(live, now2);
40090
+ const v = live.ledger.verdict(now2);
40091
+ if (v.quiescent)
40092
+ break;
40093
+ if (now2 - started2 >= QUIESCENCE_MAX_MS) {
40094
+ cappedOut = true;
40095
+ break;
40096
+ }
40097
+ if (!narrated && live.sessionId) {
40098
+ narrated = true;
40099
+ const running2 = v.waiting.length + v.overdue.length;
40100
+ this.send({
40101
+ type: "agent:narration",
40102
+ sessionId: live.sessionId,
40103
+ text: `Waiting for ${running2} background ${running2 === 1 ? "task" : "tasks"} to finish\u2026`,
40104
+ engineLabel: "Claude Code"
40105
+ }, live.origin);
40106
+ }
40107
+ await new Promise((res) => setTimeout(res, QUIESCENCE_POLL_MS));
40014
40108
  }
40015
- await new Promise((res) => setTimeout(res, QUIESCENCE_POLL_MS));
40109
+ this.clearWorkNarration(live, narrated);
40110
+ live.ledger.sweep(Date.now());
40111
+ const outstanding = live.ledger.summarize(Date.now());
40112
+ if (cappedOut)
40113
+ log(`[work] quiescence cap reached for ${live.sessionId}; grading anyway with: ${outstanding.join("; ") || "(nothing outstanding)"}`);
40114
+ else if (Date.now() - started2 > 1e3)
40115
+ log(`[work] ${live.sessionId} settled after ${Math.round((Date.now() - started2) / 1e3)}s \u2014 grading now`);
40116
+ if (!cappedOut && outstanding.length)
40117
+ log(`[work] grading with work still in flight: ${outstanding.join("; ")}`);
40118
+ await this.runVerification(live, finalText, didWork);
40119
+ } finally {
40120
+ live.gradePending = false;
40121
+ }
40122
+ }
40123
+ /**
40124
+ * Mark a turn the engine started on its own as busy — exactly what a send does.
40125
+ *
40126
+ * Bumping `turnSeq` is deliberate: a quiescence wait for the PREVIOUS turn must see itself
40127
+ * superseded, the same way it would by a turn we started, rather than grade the old final
40128
+ * text while the new turn runs.
40129
+ */
40130
+ adoptSelfStartedTurn(live) {
40131
+ log(`[turn] ${live.sessionId || "(pending)"} started a turn on its own \u2014 marking busy`);
40132
+ live.streaming = true;
40133
+ live.turnSeq++;
40134
+ live.turnOpeningAt = void 0;
40135
+ live.lastActivity = Date.now();
40136
+ if (live.idleTimer) {
40137
+ clearTimeout(live.idleTimer);
40138
+ live.idleTimer = void 0;
40016
40139
  }
40017
- this.clearWorkNarration(live, narrated);
40018
- live.ledger.sweep(Date.now());
40019
- const outstanding = live.ledger.summarize(Date.now());
40020
- if (cappedOut)
40021
- log(`[work] quiescence cap reached for ${live.sessionId}; grading anyway with: ${outstanding.join("; ") || "(nothing outstanding)"}`);
40022
- else if (Date.now() - started2 > 1e3)
40023
- log(`[work] ${live.sessionId} settled after ${Math.round((Date.now() - started2) / 1e3)}s \u2014 grading now`);
40024
- if (!cappedOut && outstanding.length)
40025
- log(`[work] grading with work still in flight: ${outstanding.join("; ")}`);
40026
- await this.runVerification(live, finalText, didWork);
40027
40140
  }
40028
40141
  /** Take down the "waiting on background work" strip, if we put one up. */
40029
40142
  clearWorkNarration(live, narrated) {
@@ -42557,6 +42670,10 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42557
42670
  }
42558
42671
  const sid = live.sessionId;
42559
42672
  const parentToolUseId = message.parent_tool_use_id ?? void 0;
42673
+ if (!live.streaming && !live.reaped && isTurnBearingFrame(message.type))
42674
+ this.adoptSelfStartedTurn(live);
42675
+ if (!live.streaming && !live.reaped && (live.turnsDone ?? 0) > 0 && message.type === "system" && message.subtype === "init")
42676
+ live.turnOpeningAt = Date.now();
42560
42677
  switch (message.type) {
42561
42678
  case "stream_event": {
42562
42679
  const event = message.event;
@@ -42699,6 +42816,8 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42699
42816
  }
42700
42817
  case "result": {
42701
42818
  this.emitLifecycle("Stop", { sessionId: sid, subtype: message.subtype ?? null });
42819
+ live.turnsDone = (live.turnsDone ?? 0) + 1;
42820
+ live.turnOpeningAt = void 0;
42702
42821
  flushPendingThinking();
42703
42822
  const r = message;
42704
42823
  const resultSid = r.session_id || "";
@@ -42908,6 +43027,7 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42908
43027
  const taskId = sstr(m.task_id);
42909
43028
  if (!taskId)
42910
43029
  break;
43030
+ live.ledger.touch(taskId, Date.now());
42911
43031
  const u = m.usage;
42912
43032
  emit2({
42913
43033
  type: "agent:task",
@@ -42946,6 +43066,8 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42946
43066
  if (status2 === "completed" || status2 === "failed" || status2 === "killed") {
42947
43067
  this.clearAutoBackground(live, taskId);
42948
43068
  live.taskIds.delete(taskId);
43069
+ } else {
43070
+ live.ledger.touch(taskId, Date.now());
42949
43071
  }
42950
43072
  break;
42951
43073
  }
@@ -42957,6 +43079,8 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42957
43079
  case "background_tasks_changed": {
42958
43080
  const listed = new Set((Array.isArray(m.tasks) ? m.tasks : []).map((t) => sstr(t?.task_id)).filter(Boolean));
42959
43081
  live.taskIds = listed;
43082
+ for (const id of listed)
43083
+ live.ledger.touch(id, Date.now());
42960
43084
  break;
42961
43085
  }
42962
43086
  case "task_notification": {
@@ -43314,6 +43438,7 @@ ${err2.stack}` : ""}` : String(err2);
43314
43438
  emit2({ type: "agent:status", sessionId: sid, status: "error" });
43315
43439
  }
43316
43440
  } finally {
43441
+ live.gone = true;
43317
43442
  if (live.idleTimer) {
43318
43443
  clearTimeout(live.idleTimer);
43319
43444
  live.idleTimer = void 0;
@@ -43498,7 +43623,7 @@ ${err2.stack}` : ""}` : String(err2);
43498
43623
  // Blocked on its own background work. A turn that dispatched a build emits nothing while
43499
43624
  // it waits, and that silence is the intended behaviour — not a dead stream. Reads the
43500
43625
  // ledger, so it goes false on its own once every awaited item has passed its deadline.
43501
- awaitingWork: live.ledger.verdict(Date.now()).waiting.length > 0,
43626
+ awaitingWork: !live.ledger.verdict(Date.now()).quiescent,
43502
43627
  idleMs: monoNowMs() - (live.lastFrameAt ?? 0),
43503
43628
  windowMs: live.stallWindowMs ?? STREAM_STALL_MS
43504
43629
  });
@@ -43522,6 +43647,7 @@ ${err2.stack}` : ""}` : String(err2);
43522
43647
  live.abort.abort();
43523
43648
  } catch {
43524
43649
  }
43650
+ live.gone = true;
43525
43651
  }
43526
43652
  /** M7 — stop ONE background task (vs interruptSession which aborts the whole
43527
43653
  * turn). Driver-only, same origin guard. No-op if the session/task is gone. */
@@ -43688,7 +43814,8 @@ ${err2.stack}` : ""}` : String(err2);
43688
43814
  for (const id of [...claimed])
43689
43815
  if (!live.ledger.has(id))
43690
43816
  claimed.delete(id);
43691
- const watched = live.ledger.verdict(started2).waiting.filter((i) => !claimed.has(i.id)).map((i) => ({ id: i.id, description: i.description, kind: i.kind }));
43817
+ const v0 = live.ledger.verdict(started2);
43818
+ const watched = [...v0.waiting, ...v0.overdue].filter((i) => !claimed.has(i.id)).map((i) => ({ id: i.id, description: i.description, kind: i.kind }));
43692
43819
  for (const w of watched)
43693
43820
  claimed.add(w.id);
43694
43821
  if (watched.length === 0)
@@ -43756,8 +43883,8 @@ ${lines.join("\n")}
43756
43883
  const fd = openSync5(path6, "r");
43757
43884
  try {
43758
43885
  const buf = Buffer.allocUnsafe(want);
43759
- const read = readSync4(fd, buf, 0, want, Math.max(0, size - want));
43760
- return buf.subarray(0, read).toString("utf8").slice(-maxChars);
43886
+ const read2 = readSync4(fd, buf, 0, want, Math.max(0, size - want));
43887
+ return buf.subarray(0, read2).toString("utf8").slice(-maxChars);
43761
43888
  } finally {
43762
43889
  closeSync5(fd);
43763
43890
  }
@@ -44247,12 +44374,65 @@ ${lines.join("\n")}
44247
44374
  /** Close an idle session's Query (→ child process + IPC freed via runConsumer's
44248
44375
  * finally), keeping the on-disk session resumable. Deletes from the live map
44249
44376
  * FIRST so a racing sendMessage misses it and cleanly re-creates with resume. */
44377
+ /**
44378
+ * Is this session, whatever `streaming` says, still in the middle of something?
44379
+ *
44380
+ * `streaming` only tracks turns WE started. A CLI running its own background monitor
44381
+ * starts turns by itself when events land, and between two of those — or during a long
44382
+ * tool call inside one — the session reads as idle here while the engine is hard at work.
44383
+ * The memory monitor's moderate-pressure reclaim reaped exactly such a session, 60 seconds
44384
+ * "idle" with a batch barrier that had just reported "1 still running": the CLI carried on
44385
+ * for another 69 minutes, un-mapped and ungradeable. Work the ledger is awaiting, a job
44386
+ * that is running, a wait inside `await_jobs`, or a turn-end grade still waiting for
44387
+ * quiescence — any of these means the session is busy.
44388
+ */
44389
+ hasWorkInFlight(live) {
44390
+ if (live.gradePending)
44391
+ return true;
44392
+ if (turnStillOpening(live.turnOpeningAt, Date.now()))
44393
+ return true;
44394
+ if ((live.awaitDepth ?? 0) > 0)
44395
+ return true;
44396
+ try {
44397
+ if (!live.ledger.verdict(Date.now()).quiescent)
44398
+ return true;
44399
+ } catch {
44400
+ }
44401
+ try {
44402
+ if (live.jobs?.list().some((j) => j.status === "running"))
44403
+ return true;
44404
+ } catch {
44405
+ }
44406
+ return false;
44407
+ }
44408
+ /** The job registry is the authority on daemon-owned jobs: anything it still reports as
44409
+ * running is alive, whatever the ledger's deadline says — touch it (or put it back if a
44410
+ * sweep already took it). */
44411
+ refreshLedgerFromRegistry(live, now2) {
44412
+ let jobs;
44413
+ try {
44414
+ jobs = live.jobs?.list() ?? [];
44415
+ } catch {
44416
+ return;
44417
+ }
44418
+ for (const j of jobs) {
44419
+ if (j.status !== "running")
44420
+ continue;
44421
+ if (!live.ledger.touch(j.id, now2)) {
44422
+ live.ledger.register({ id: j.id, kind: "tool-job", description: `${j.kind ?? "job"}: ${j.description ?? j.id}` }, now2);
44423
+ }
44424
+ }
44425
+ }
44250
44426
  reapIdleSession(sessionId, force = false) {
44251
44427
  const live = this.liveSessions.get(sessionId);
44252
44428
  if (!live || live.streaming || live.reaped)
44253
44429
  return false;
44254
44430
  if (this.isHeld(live) && !force)
44255
44431
  return false;
44432
+ if (!force && this.hasWorkInFlight(live)) {
44433
+ log(`[reap] ${sessionId} looks idle but has work in flight \u2014 left alone`);
44434
+ return false;
44435
+ }
44256
44436
  log("Reaping idle session:", sessionId);
44257
44437
  live.reaped = true;
44258
44438
  this.emitLifecycle("SessionEnd", { sessionId, reason: force ? "forced" : "idle-reap" });
@@ -44301,6 +44481,10 @@ ${lines.join("\n")}
44301
44481
  let n = 0;
44302
44482
  for (const live of [...this.liveSessions.values()]) {
44303
44483
  if (!live.streaming && !live.reaped) {
44484
+ if (this.hasWorkInFlight(live)) {
44485
+ log(`[reap] critical reclaim spared ${live.sessionId}: work in flight`);
44486
+ continue;
44487
+ }
44304
44488
  if (this.reapIdleSession(live.sessionId, true))
44305
44489
  n++;
44306
44490
  }
@@ -44325,6 +44509,7 @@ ${lines.join("\n")}
44325
44509
  if (live.reaped)
44326
44510
  continue;
44327
44511
  live.reaped = true;
44512
+ live.gone = true;
44328
44513
  if (live.idleTimer) {
44329
44514
  clearTimeout(live.idleTimer);
44330
44515
  live.idleTimer = void 0;
@@ -46172,9 +46357,9 @@ function wrapHostedAsyncTool(t, opts) {
46172
46357
  return text11(raced.err instanceof Error ? raced.err.message : String(raced.err), true);
46173
46358
  opts.learnedSlow?.add(t.name);
46174
46359
  const sessionId = ctx2?.sessionId;
46175
- const job = opts.registry.start(t.name, describeArgs2(t.name, args), async (write2) => {
46360
+ const job = opts.registry.start(t.name, describeArgs2(t.name, args), async (write3) => {
46176
46361
  try {
46177
- write2(await work);
46362
+ write3(await work);
46178
46363
  } catch (err2) {
46179
46364
  throw err2 instanceof Error ? err2 : new Error(String(err2));
46180
46365
  }
@@ -79502,7 +79687,7 @@ function alphabet(letters) {
79502
79687
  };
79503
79688
  }
79504
79689
  // @__NO_SIDE_EFFECTS__
79505
- function join67(separator = "") {
79690
+ function join68(separator = "") {
79506
79691
  astr("join", separator);
79507
79692
  return {
79508
79693
  encode: (from) => {
@@ -79707,7 +79892,7 @@ var init_esm = __esm({
79707
79892
  convertRadix2,
79708
79893
  radix,
79709
79894
  radix2,
79710
- join: join67,
79895
+ join: join68,
79711
79896
  padding
79712
79897
  };
79713
79898
  }
@@ -81254,8 +81439,8 @@ var mesh_ca_exports = {};
81254
81439
  __export(mesh_ca_exports, {
81255
81440
  netCaCommand: () => netCaCommand
81256
81441
  });
81257
- import { chmodSync as chmodSync8, existsSync as existsSync49, mkdirSync as mkdirSync45, readFileSync as readFileSync54, writeFileSync as writeFileSync46 } from "node:fs";
81258
- import { join as join87, resolve as resolve13 } from "node:path";
81442
+ import { chmodSync as chmodSync8, existsSync as existsSync50, mkdirSync as mkdirSync46, readFileSync as readFileSync55, writeFileSync as writeFileSync47 } from "node:fs";
81443
+ import { join as join88, resolve as resolve13 } from "node:path";
81259
81444
  import { createInterface as createInterface2 } from "node:readline";
81260
81445
  function die(msg) {
81261
81446
  console.error(msg);
@@ -81269,9 +81454,9 @@ async function readPassphrase(prompt2) {
81269
81454
  }
81270
81455
  const rl = createInterface2({ input: process.stdin, output: process.stdout, terminal: true });
81271
81456
  const out = process.stdout;
81272
- const write2 = out.write.bind(out);
81457
+ const write3 = out.write.bind(out);
81273
81458
  let muted = false;
81274
- out.write = (chunk) => muted ? true : write2(chunk);
81459
+ out.write = (chunk) => muted ? true : write3(chunk);
81275
81460
  process.stdout.write(prompt2);
81276
81461
  muted = true;
81277
81462
  try {
@@ -81281,33 +81466,33 @@ async function readPassphrase(prompt2) {
81281
81466
  }));
81282
81467
  } finally {
81283
81468
  muted = false;
81284
- out.write = write2;
81469
+ out.write = write3;
81285
81470
  process.stdout.write("\n");
81286
81471
  }
81287
81472
  }
81288
81473
  function writeSecretFile(p, bytes2) {
81289
- writeFileSync46(p, bytes2, { mode: 384 });
81474
+ writeFileSync47(p, bytes2, { mode: 384 });
81290
81475
  try {
81291
81476
  chmodSync8(p, 384);
81292
81477
  } catch {
81293
81478
  }
81294
81479
  }
81295
81480
  function ensureDir(p) {
81296
- mkdirSync45(p, { recursive: true, mode: 448 });
81481
+ mkdirSync46(p, { recursive: true, mode: 448 });
81297
81482
  try {
81298
81483
  chmodSync8(p, 448);
81299
81484
  } catch {
81300
81485
  }
81301
81486
  }
81302
81487
  async function openCa(dir2) {
81303
- const gPath = join87(dir2, "genesis.bin");
81304
- const sPath = join87(dir2, "ca.sealed");
81305
- if (!existsSync49(gPath) || !existsSync49(sPath)) {
81488
+ const gPath = join88(dir2, "genesis.bin");
81489
+ const sPath = join88(dir2, "ca.sealed");
81490
+ if (!existsSync50(gPath) || !existsSync50(sPath)) {
81306
81491
  die(`No mesh CA in ${dir2}. Run: tesseract-agent net init --org NAME --ca-dir ${dir2}`);
81307
81492
  }
81308
- const genesisBytes = new Uint8Array(readFileSync54(gPath));
81493
+ const genesisBytes = new Uint8Array(readFileSync55(gPath));
81309
81494
  const genesis = decodeGenesis(genesisBytes);
81310
- const sealed = decodeRecoveryBundle(new Uint8Array(readFileSync54(sPath)));
81495
+ const sealed = decodeRecoveryBundle(new Uint8Array(readFileSync55(sPath)));
81311
81496
  const pass = await readPassphrase("CA passphrase: ");
81312
81497
  let seed;
81313
81498
  try {
@@ -81323,7 +81508,7 @@ async function netCaCommand(rest, flags) {
81323
81508
  if (sub === "init") {
81324
81509
  const org = typeof flags.org === "string" ? flags.org.trim() : "";
81325
81510
  if (!org) die("Usage: tesseract-agent net init --org NAME [--ca-dir DIR]");
81326
- if (existsSync49(join87(caDir, "ca.sealed"))) {
81511
+ if (existsSync50(join88(caDir, "ca.sealed"))) {
81327
81512
  die(`A mesh CA already exists in ${caDir}. Refusing to overwrite it.`);
81328
81513
  }
81329
81514
  const pass = await readPassphrase("New CA passphrase: ");
@@ -81345,9 +81530,9 @@ async function netCaCommand(rest, flags) {
81345
81530
  const genesisBytes = encodeGenesis(genesis);
81346
81531
  const fp = await genesisFingerprint(genesis);
81347
81532
  ensureDir(caDir);
81348
- writeFileSync46(join87(caDir, "genesis.bin"), genesisBytes);
81349
- writeSecretFile(join87(caDir, "ca.sealed"), encodeRecoveryBundle(await sealCaKey(seed, pass, `${org} mesh CA`)));
81350
- writeSecretFile(join87(caDir, "disablement.secret"), hex3(disable.secret));
81533
+ writeFileSync47(join88(caDir, "genesis.bin"), genesisBytes);
81534
+ writeSecretFile(join88(caDir, "ca.sealed"), encodeRecoveryBundle(await sealCaKey(seed, pass, `${org} mesh CA`)));
81535
+ writeSecretFile(join88(caDir, "disablement.secret"), hex3(disable.secret));
81351
81536
  console.log(`
81352
81537
  Mesh created for "${org}".`);
81353
81538
  console.log(` fingerprint: ${hex3(fp)}`);
@@ -81362,7 +81547,7 @@ Mesh created for "${org}".`);
81362
81547
  console.log(` ${hex3(disable.secret)}`);
81363
81548
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
81364
81549
  console.log(`
81365
- A copy of the disablement secret is in ${join87(caDir, "disablement.secret")}.`);
81550
+ A copy of the disablement secret is in ${join88(caDir, "disablement.secret")}.`);
81366
81551
  console.log("Move it somewhere the CA directory is not \u2014 holding both in one place");
81367
81552
  console.log("defeats the point of having two.");
81368
81553
  const caFlag = caDir === resolve13("./mesh-ca") ? "" : ` --ca-dir ${caDir}`;
@@ -81415,14 +81600,14 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
81415
81600
  [{ keyIndex: 0, privateKey: ca.privateKey }]
81416
81601
  );
81417
81602
  ensureDir(outDir);
81418
- writeFileSync46(join87(outDir, "genesis.bin"), genesisBytes);
81419
- writeFileSync46(join87(outDir, "node.cert"), encodeCert(cert));
81420
- writeSecretFile(join87(outDir, "node.key"), await exportStaticPrivate(nodeKey));
81603
+ writeFileSync47(join88(outDir, "genesis.bin"), genesisBytes);
81604
+ writeFileSync47(join88(outDir, "node.cert"), encodeCert(cert));
81605
+ writeSecretFile(join88(outDir, "node.key"), await exportStaticPrivate(nodeKey));
81421
81606
  console.log(`Minted "${name}" at ${ip4}.`);
81422
81607
  console.log(` ${outDir}`);
81423
81608
  console.log("\nCopy that directory to the node and run there:");
81424
- console.log(` tesseract-agent net enroll --genesis ${join87(outDir, "genesis.bin")} \\`);
81425
- console.log(` --cert ${join87(outDir, "node.cert")} --key ${join87(outDir, "node.key")}`);
81609
+ console.log(` tesseract-agent net enroll --genesis ${join88(outDir, "genesis.bin")} \\`);
81610
+ console.log(` --cert ${join88(outDir, "node.cert")} --key ${join88(outDir, "node.key")}`);
81426
81611
  console.log("\nnode.key is the node's identity \u2014 send it over a channel you trust, and");
81427
81612
  console.log("delete this copy once the node has it.");
81428
81613
  return;
@@ -81458,8 +81643,8 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
81458
81643
  ip4Exceptions: []
81459
81644
  };
81460
81645
  const signed = await signBundle(bundle, [{ keyIndex: 0, privateKey: ca.privateKey }]);
81461
- const out = resolve13(typeof flags.out === "string" ? flags.out : join87(caDir, "bundle.bin"));
81462
- writeFileSync46(out, encodeSignedBundle(signed));
81646
+ const out = resolve13(typeof flags.out === "string" ? flags.out : join88(caDir, "bundle.bin"));
81647
+ writeFileSync47(out, encodeSignedBundle(signed));
81463
81648
  console.log(`Signed policy bundle (epoch ${epoch2}) \u2192 ${out}`);
81464
81649
  console.log("Every node must receive it; the relay distributes it, or copy it to");
81465
81650
  console.log(`each node's mesh directory as bundle.bin.`);
@@ -81481,17 +81666,43 @@ var init_mesh_ca = __esm({
81481
81666
 
81482
81667
  // src/cli.ts
81483
81668
  init_base_paths();
81484
- import { existsSync as existsSync50, mkdtempSync as mkdtempSync4, readFileSync as readFileSync56, rmSync as rmSync13 } from "node:fs";
81669
+ import { existsSync as existsSync51, mkdtempSync as mkdtempSync4, readFileSync as readFileSync57, rmSync as rmSync13 } from "node:fs";
81485
81670
  import { createHash as createHash9 } from "node:crypto";
81486
81671
  import { execFileSync as execFileSync6, spawn as spawn14 } from "node:child_process";
81487
81672
  import { fileURLToPath as fileURLToPath8 } from "node:url";
81488
81673
  import { tmpdir as tmpdir8 } from "node:os";
81489
- import { dirname as dirname40, join as join88, resolve as resolve15 } from "node:path";
81674
+ import { dirname as dirname41, join as join89, resolve as resolve15 } from "node:path";
81490
81675
  import { createInterface as createInterface3 } from "node:readline/promises";
81491
81676
 
81492
81677
  // ../../packages/host-core/dist/control-link.js
81493
81678
  import { hostname as hostname4 } from "node:os";
81494
81679
 
81680
+ // ../../packages/host-core/dist/hook-fanout.js
81681
+ function composeHooks(sets, onError) {
81682
+ return new Proxy({}, {
81683
+ get(_target, key2) {
81684
+ if (typeof key2 !== "string")
81685
+ return void 0;
81686
+ const fns = sets.map((s) => s[key2]).filter((f) => typeof f === "function");
81687
+ if (fns.length === 0)
81688
+ return void 0;
81689
+ const owners = sets.filter((s) => typeof s[key2] === "function");
81690
+ return (...args) => {
81691
+ for (let i = 0; i < fns.length; i++) {
81692
+ try {
81693
+ fns[i].apply(owners[i], args);
81694
+ } catch (err2) {
81695
+ onError?.(key2, err2);
81696
+ }
81697
+ }
81698
+ };
81699
+ },
81700
+ has(_target, key2) {
81701
+ return typeof key2 === "string" && sets.some((s) => typeof s[key2] === "function");
81702
+ }
81703
+ });
81704
+ }
81705
+
81495
81706
  // ../../packages/host-core/dist/engines/rewind-result.js
81496
81707
  var strings = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x.length > 0) : [];
81497
81708
  function toRewindOutcome(res, noHistory) {
@@ -81514,9 +81725,9 @@ function toRewindOutcome(res, noHistory) {
81514
81725
  }
81515
81726
 
81516
81727
  // ../../packages/host-core/dist/control-link.js
81517
- import { join as join60, basename as basename11 } from "node:path";
81518
- import { randomUUID as randomUUID24 } from "node:crypto";
81519
- import { mkdirSync as mkdirSync29 } from "node:fs";
81728
+ import { join as join61, basename as basename11 } from "node:path";
81729
+ import { randomUUID as randomUUID25 } from "node:crypto";
81730
+ import { mkdirSync as mkdirSync30 } from "node:fs";
81520
81731
 
81521
81732
  // ../../node_modules/ws/wrapper.mjs
81522
81733
  var import_stream = __toESM(require_stream(), 1);
@@ -84750,21 +84961,21 @@ function createMcpHealth(deps = {}) {
84750
84961
  let servers = {};
84751
84962
  const disabled2 = /* @__PURE__ */ new Set();
84752
84963
  const cache5 = /* @__PURE__ */ new Map();
84753
- const inflight = /* @__PURE__ */ new Map();
84964
+ const inflight2 = /* @__PURE__ */ new Map();
84754
84965
  async function probeCached(name, spec) {
84755
84966
  const hit = cache5.get(name);
84756
84967
  if (hit && now2() - hit.at < TTL_MS3)
84757
84968
  return hit.row;
84758
- const running2 = inflight.get(name);
84969
+ const running2 = inflight2.get(name);
84759
84970
  if (running2)
84760
84971
  return running2;
84761
84972
  const p = probe(name, spec).catch((e) => ({ name, status: "failed", error: e?.message ?? "probe failed" })).then((row) => {
84762
84973
  const full = { ...row, name };
84763
84974
  cache5.set(name, { at: now2(), row: full });
84764
- inflight.delete(name);
84975
+ inflight2.delete(name);
84765
84976
  return full;
84766
84977
  });
84767
- inflight.set(name, p);
84978
+ inflight2.set(name, p);
84768
84979
  return p;
84769
84980
  }
84770
84981
  return {
@@ -84784,7 +84995,7 @@ function createMcpHealth(deps = {}) {
84784
84995
  },
84785
84996
  async reconnect(name) {
84786
84997
  cache5.delete(name);
84787
- inflight.delete(name);
84998
+ inflight2.delete(name);
84788
84999
  if (servers[name] && !disabled2.has(name))
84789
85000
  await probeCached(name, servers[name]);
84790
85001
  },
@@ -84927,10 +85138,10 @@ function extractJson(text12) {
84927
85138
  }
84928
85139
  }
84929
85140
  for (let start3 = 0; start3 < text12.length; start3++) {
84930
- const open7 = text12[start3];
84931
- if (open7 !== "{" && open7 !== "[")
85141
+ const open8 = text12[start3];
85142
+ if (open8 !== "{" && open8 !== "[")
84932
85143
  continue;
84933
- const close = open7 === "{" ? "}" : "]";
85144
+ const close = open8 === "{" ? "}" : "]";
84934
85145
  let depth = 0;
84935
85146
  let inStr = false;
84936
85147
  let esc3 = false;
@@ -84949,7 +85160,7 @@ function extractJson(text12) {
84949
85160
  inStr = true;
84950
85161
  continue;
84951
85162
  }
84952
- if (ch === open7)
85163
+ if (ch === open8)
84953
85164
  depth++;
84954
85165
  else if (ch === close) {
84955
85166
  depth--;
@@ -89008,8 +89219,8 @@ ${text12}`;
89008
89219
  const t = await conn(threadCwd.get(sessionId) ?? spawnedCwd ?? projectDir ?? void 0);
89009
89220
  if (!t)
89010
89221
  return { ok: false, reason: `${label} is not reachable for this.` };
89011
- const read = await t.request("thread/read", { threadId: sessionId, includeTurns: true }).catch(() => null);
89012
- const turns2 = (read?.thread ?? {}).turns ?? [];
89222
+ const read2 = await t.request("thread/read", { threadId: sessionId, includeTurns: true }).catch(() => null);
89223
+ const turns2 = (read2?.thread ?? {}).turns ?? [];
89013
89224
  const at = turns2.findIndex((tn) => (tn.items ?? []).some((it) => it.id === uuid3));
89014
89225
  if (at < 0)
89015
89226
  return { ok: false, reason: `${label} no longer has that message.` };
@@ -90215,7 +90426,6 @@ var LAUNCH_MARKERS = [
90215
90426
  "CCB_FORCE_DAEMON_GUI",
90216
90427
  "CCB_HOST_DAEMON",
90217
90428
  "CCB_RDESK_ROLE",
90218
- "CCB_RDESK_SERVER",
90219
90429
  "CCB_RDESK_CLIENT",
90220
90430
  "CCB_RDESK_ONLY",
90221
90431
  "CCB_MESH_APP",
@@ -90230,7 +90440,7 @@ function mainAppChildEnv(env) {
90230
90440
  return out;
90231
90441
  }
90232
90442
  function ownBinaryIsMainApp(env) {
90233
- return !env.CCB_RDESK_ROLE && env.CCB_RDESK_SERVER !== "1" && env.CCB_RDESK_CLIENT !== "1" && env.CCB_MESH_APP !== "1";
90443
+ return !env.CCB_RDESK_ROLE && env.CCB_RDESK_CLIENT !== "1" && env.CCB_MESH_APP !== "1";
90234
90444
  }
90235
90445
 
90236
90446
  // ../../packages/host-core/dist/gui/dock-policy.js
@@ -91157,11 +91367,11 @@ var GUIDE_TOOLS = describedBy("tool.voice-guide", GUIDE_TOOL_SHAPES);
91157
91367
  var defaultGreeting = () => prompt("voice.greeting");
91158
91368
  function buildGuidePrompt(opts = {}) {
91159
91369
  const project = opts.projectName ? prompt("voice.guide.project-clause", { projectName: opts.projectName }) : "";
91160
- const open7 = (opts.sessions ?? []).map((s) => s.label?.trim()).filter((l) => !!l);
91161
- const openLine = open7.length > 0 ? prompt("voice.guide.open-sessions", {
91162
- count: open7.length,
91163
- plural: open7.length === 1 ? "" : "s",
91164
- labels: open7.map((l) => `"${l}"`).join(", "),
91370
+ const open8 = (opts.sessions ?? []).map((s) => s.label?.trim()).filter((l) => !!l);
91371
+ const openLine = open8.length > 0 ? prompt("voice.guide.open-sessions", {
91372
+ count: open8.length,
91373
+ plural: open8.length === 1 ? "" : "s",
91374
+ labels: open8.map((l) => `"${l}"`).join(", "),
91165
91375
  toolStatus: TOOL_STATUS
91166
91376
  }) : "";
91167
91377
  return [
@@ -95801,8 +96011,8 @@ async function falTopazEnhance(path6, spec, opts) {
95801
96011
  const dir2 = opts.outDir ?? workDir();
95802
96012
  mkdirSync22(dir2, { recursive: true });
95803
96013
  const outPath = join43(dir2, "enhanced.mp4");
95804
- const { writeFileSync: writeFileSync47 } = await import("node:fs");
95805
- writeFileSync47(outPath, Buffer.from(await dl.arrayBuffer()));
96014
+ const { writeFileSync: writeFileSync48 } = await import("node:fs");
96015
+ writeFileSync48(outPath, Buffer.from(await dl.arrayBuffer()));
95806
96016
  const out = await probeMedia(outPath).catch(() => null);
95807
96017
  opts.onProgress?.(100, "Enhance complete");
95808
96018
  return { path: outPath, mime: MIME, width: out?.width ?? null, height: out?.height ?? null, durationSec: out?.durationSec ?? p.durationSec, summary: `fal Topaz ${spec.model ?? "Proteus"} \xD7${spec.upscaleFactor ?? 2}` };
@@ -99105,9 +99315,9 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
99105
99315
  break;
99106
99316
  const len = Math.min(CHUNK2, f.size - offset);
99107
99317
  const buf = Buffer.alloc(len);
99108
- const read = readSync7(fd, buf, 0, len, offset);
99109
- send4({ type: "fs:transferChunk", transferId, toHost, fileIx, rel: f.rel, mode: f.mode, kind: "file", offset, base64: buf.subarray(0, read).toString("base64"), eof: offset + len >= f.size }, { hostId: toHost });
99110
- state3.sentBytes += read;
99318
+ const read2 = readSync7(fd, buf, 0, len, offset);
99319
+ send4({ type: "fs:transferChunk", transferId, toHost, fileIx, rel: f.rel, mode: f.mode, kind: "file", offset, base64: buf.subarray(0, read2).toString("base64"), eof: offset + len >= f.size }, { hostId: toHost });
99320
+ state3.sentBytes += read2;
99111
99321
  }
99112
99322
  }
99113
99323
  } catch (e) {
@@ -99916,22 +100126,70 @@ init_credentials();
99916
100126
  // ../../packages/host-core/dist/rdesk/machine-identity.js
99917
100127
  init_credentials();
99918
100128
  import { hostname as hostname3, platform } from "node:os";
100129
+ import { randomUUID as randomUUID24 } from "node:crypto";
100130
+ import { chmodSync as chmodSync3, existsSync as existsSync24, mkdirSync as mkdirSync27, readFileSync as readFileSync37, statSync as statSync14, unlinkSync as unlinkSync3, writeFileSync as writeFileSync25 } from "node:fs";
100131
+ import { join as join54 } from "node:path";
100132
+
100133
+ // ../../packages/host-core/dist/device-id.js
100134
+ init_base_paths();
100135
+ import { existsSync as existsSync23, mkdirSync as mkdirSync26, readFileSync as readFileSync36, writeFileSync as writeFileSync24 } from "node:fs";
100136
+ import { dirname as dirname24, join as join53 } from "node:path";
99919
100137
  import { randomUUID as randomUUID23 } from "node:crypto";
99920
- import { chmodSync as chmodSync3, existsSync as existsSync23, mkdirSync as mkdirSync26, readFileSync as readFileSync36, writeFileSync as writeFileSync24 } from "node:fs";
99921
- import { join as join53 } from "node:path";
99922
- var FILE = () => join53(daemonDir2(), "machine-identity.json");
100138
+ function deviceIdFile() {
100139
+ return join53(tesseractHome(), "device-id.json");
100140
+ }
100141
+ function read() {
100142
+ try {
100143
+ const raw = JSON.parse(readFileSync36(deviceIdFile(), "utf-8"));
100144
+ const deviceId3 = typeof raw.deviceId === "string" && raw.deviceId ? raw.deviceId : null;
100145
+ const aliases = Array.isArray(raw.aliases) ? raw.aliases.filter((a) => typeof a === "string" && !!a) : [];
100146
+ return { deviceId: deviceId3, aliases };
100147
+ } catch {
100148
+ return { deviceId: null, aliases: [] };
100149
+ }
100150
+ }
100151
+ function write(deviceId3, aliases) {
100152
+ try {
100153
+ const f = deviceIdFile();
100154
+ const dir2 = dirname24(f);
100155
+ if (!existsSync23(dir2))
100156
+ mkdirSync26(dir2, { recursive: true });
100157
+ writeFileSync24(f, JSON.stringify(aliases.length ? { deviceId: deviceId3, aliases } : { deviceId: deviceId3 }));
100158
+ } catch {
100159
+ }
100160
+ }
100161
+ function persistentDeviceId() {
100162
+ const cur = read();
100163
+ if (cur.deviceId)
100164
+ return cur.deviceId;
100165
+ const id = randomUUID23().slice(0, 8);
100166
+ write(id, cur.aliases);
100167
+ return id;
100168
+ }
100169
+ function addDeviceIdAlias(old) {
100170
+ if (!old)
100171
+ return;
100172
+ const cur = read();
100173
+ const deviceId3 = cur.deviceId ?? persistentDeviceId();
100174
+ if (old === deviceId3 || cur.aliases.includes(old))
100175
+ return;
100176
+ write(deviceId3, [...cur.aliases, old]);
100177
+ }
100178
+
100179
+ // ../../packages/host-core/dist/rdesk/machine-identity.js
100180
+ var FILE = () => join54(daemonDir2(), "machine-identity.json");
99923
100181
  function readMachineIdentity() {
99924
100182
  try {
99925
- const m = JSON.parse(readFileSync36(FILE(), "utf-8"));
100183
+ const m = JSON.parse(readFileSync37(FILE(), "utf-8"));
99926
100184
  return m?.deviceToken && m?.publicId ? m : null;
99927
100185
  } catch {
99928
100186
  return null;
99929
100187
  }
99930
100188
  }
99931
- function write(m) {
100189
+ function write2(m) {
99932
100190
  try {
99933
- mkdirSync26(daemonDir2(), { recursive: true, mode: 448 });
99934
- writeFileSync24(FILE(), JSON.stringify(m, null, 2), { mode: 384 });
100191
+ mkdirSync27(daemonDir2(), { recursive: true, mode: 448 });
100192
+ writeFileSync25(FILE(), JSON.stringify(m, null, 2), { mode: 384 });
99935
100193
  chmodSync3(FILE(), 384);
99936
100194
  } catch {
99937
100195
  }
@@ -99957,30 +100215,100 @@ function tokenUsable(m) {
99957
100215
  const ms = Date.parse(m.expiresAt);
99958
100216
  return Number.isFinite(ms) && ms - Date.now() > 24 * 60 * 60 * 1e3;
99959
100217
  }
100218
+ var inflight = null;
99960
100219
  async function ensureMachineIdentity(opts) {
100220
+ if (inflight)
100221
+ return inflight;
100222
+ inflight = ensureMachineIdentityOnce(opts).finally(() => {
100223
+ inflight = null;
100224
+ });
100225
+ return inflight;
100226
+ }
100227
+ var LOCK = () => join54(daemonDir2(), "machine-identity.lock");
100228
+ var LOCK_STALE_MS = 3e4;
100229
+ function tryRegistrationLock() {
100230
+ const f = LOCK();
100231
+ for (let attempt = 0; attempt < 2; attempt++) {
100232
+ try {
100233
+ mkdirSync27(daemonDir2(), { recursive: true, mode: 448 });
100234
+ writeFileSync25(f, String(process.pid), { flag: "wx" });
100235
+ return true;
100236
+ } catch {
100237
+ try {
100238
+ if (Date.now() - statSync14(f).mtimeMs < LOCK_STALE_MS)
100239
+ return false;
100240
+ unlinkSync3(f);
100241
+ } catch {
100242
+ return false;
100243
+ }
100244
+ }
100245
+ }
100246
+ return false;
100247
+ }
100248
+ function releaseRegistrationLock() {
100249
+ try {
100250
+ unlinkSync3(LOCK());
100251
+ } catch {
100252
+ }
100253
+ }
100254
+ async function waitForIdentity(ms) {
100255
+ const until = Date.now() + ms;
100256
+ while (Date.now() < until) {
100257
+ await new Promise((r) => setTimeout(r, 250));
100258
+ const m = readMachineIdentity();
100259
+ if (m)
100260
+ return m;
100261
+ }
100262
+ return null;
100263
+ }
100264
+ async function ensureMachineIdentityOnce(opts) {
99961
100265
  const { apiOrigin: apiOrigin2, backendOrigin: backendOrigin2, isAllowedOrigin: isAllowedOrigin3, log: log9 } = opts;
99962
100266
  if (!isAllowedOrigin3(apiOrigin2)) {
99963
100267
  log9?.(`machine identity: refusing a non-default server: ${apiOrigin2}`);
99964
100268
  return null;
99965
100269
  }
99966
100270
  let m = readMachineIdentity();
100271
+ if (m && opts.deviceId && m.deviceId !== opts.deviceId) {
100272
+ const old = m.deviceId;
100273
+ m = { ...m, deviceId: opts.deviceId };
100274
+ delete m.accessToken;
100275
+ delete m.expiresAt;
100276
+ write2(m);
100277
+ addDeviceIdAlias(old);
100278
+ log9?.(`machine identity: device id ${old} \u2192 ${opts.deviceId} (the id this computer uses whether signed in or not; ${old} kept as an alias)`);
100279
+ }
99967
100280
  try {
99968
100281
  if (!m) {
99969
- const reg = await postJson(`${apiOrigin2}/api/core/tesseract/identity/device`, { label: hostname3().slice(0, 120), platform: platform() });
99970
- m = {
99971
- deviceToken: reg.token,
99972
- publicId: reg.publicId,
99973
- deviceId: randomUUID23().slice(0, 8),
99974
- apiOrigin: apiOrigin2,
99975
- backendOrigin: backendOrigin2
99976
- };
99977
- write(m);
99978
- log9?.(`machine identity: registered \u2014 this machine can be reached as ${reg.publicId}`);
100282
+ if (!tryRegistrationLock()) {
100283
+ m = await waitForIdentity(1e4);
100284
+ if (!m) {
100285
+ log9?.("machine identity: another process is registering this machine \u2014 will use its identity on the next tick");
100286
+ return null;
100287
+ }
100288
+ } else {
100289
+ try {
100290
+ m = readMachineIdentity();
100291
+ if (!m) {
100292
+ const reg = await postJson(`${apiOrigin2}/api/core/tesseract/identity/device`, { label: hostname3().slice(0, 120), platform: platform() });
100293
+ m = {
100294
+ deviceToken: reg.token,
100295
+ publicId: reg.publicId,
100296
+ deviceId: opts.deviceId ?? randomUUID24().slice(0, 8),
100297
+ apiOrigin: apiOrigin2,
100298
+ backendOrigin: backendOrigin2
100299
+ };
100300
+ write2(m);
100301
+ log9?.(`machine identity: registered \u2014 this machine can be reached as ${reg.publicId}`);
100302
+ }
100303
+ } finally {
100304
+ releaseRegistrationLock();
100305
+ }
100306
+ }
99979
100307
  }
99980
100308
  if (!tokenUsable(m)) {
99981
100309
  const t = await postJson(`${apiOrigin2}/auth/device/relay-token`, { deviceToken: m.deviceToken, deviceId: m.deviceId });
99982
100310
  m = { ...m, accessToken: t.accessToken, expiresAt: t.expiresAt, publicId: t.publicId, apiOrigin: apiOrigin2, backendOrigin: backendOrigin2 };
99983
- write(m);
100311
+ write2(m);
99984
100312
  log9?.("machine identity: relay token minted");
99985
100313
  }
99986
100314
  return m;
@@ -100026,14 +100354,14 @@ function getMachinePublicId() {
100026
100354
 
100027
100355
  // ../../packages/host-core/dist/active-link/engine.js
100028
100356
  import { lstat as lstat7, readlink as readlink4, rm as rm4, mkdir as mkdir13, symlink as symlink2, rename as rename3, utimes as utimes2, writeFile as writeFile12 } from "node:fs/promises";
100029
- import { existsSync as existsSync25 } from "node:fs";
100030
- import { dirname as dirname27, join as join58, resolve as resolve11 } from "node:path";
100357
+ import { existsSync as existsSync26 } from "node:fs";
100358
+ import { dirname as dirname28, join as join59, resolve as resolve11 } from "node:path";
100031
100359
 
100032
100360
  // ../../packages/host-core/dist/active-link/blocks.js
100033
100361
  import { createHash as createHash5 } from "node:crypto";
100034
100362
  import { createReadStream as createReadStream2 } from "node:fs";
100035
- import { open as open3, mkdir as mkdir12, rename as rename2, chmod as chmod2, utimes, unlink } from "node:fs/promises";
100036
- import { dirname as dirname24 } from "node:path";
100363
+ import { open as open4, mkdir as mkdir12, rename as rename2, chmod as chmod2, utimes, unlink } from "node:fs/promises";
100364
+ import { dirname as dirname25 } from "node:path";
100037
100365
  var CHUNK3 = 1024 * 1024;
100038
100366
  var MAX_INFLIGHT2 = 8 * CHUNK3;
100039
100367
  var IDLE_MS2 = 6e4;
@@ -100161,8 +100489,8 @@ var StagingWriter = class {
100161
100489
  }
100162
100490
  async ensureOpen() {
100163
100491
  if (!this.fh) {
100164
- await mkdir12(dirname24(this.stagingPath), { recursive: true });
100165
- this.fh = await open3(this.stagingPath, "w");
100492
+ await mkdir12(dirname25(this.stagingPath), { recursive: true });
100493
+ this.fh = await open4(this.stagingPath, "w");
100166
100494
  }
100167
100495
  return this.fh;
100168
100496
  }
@@ -100191,7 +100519,7 @@ var StagingWriter = class {
100191
100519
  });
100192
100520
  await fh.close();
100193
100521
  this.fh = null;
100194
- await mkdir12(dirname24(dest), { recursive: true });
100522
+ await mkdir12(dirname25(dest), { recursive: true });
100195
100523
  await chmod2(this.stagingPath, mode & 511).catch(() => {
100196
100524
  });
100197
100525
  const secs = mtimeMs / 1e3;
@@ -100224,8 +100552,8 @@ var BlockAssembler = class {
100224
100552
  this.stagingPath = stagingPath;
100225
100553
  }
100226
100554
  async open() {
100227
- await mkdir12(dirname24(this.stagingPath), { recursive: true });
100228
- this.fh = await open3(this.stagingPath, "w");
100555
+ await mkdir12(dirname25(this.stagingPath), { recursive: true });
100556
+ this.fh = await open4(this.stagingPath, "w");
100229
100557
  }
100230
100558
  /** Write a received block at its byte offset (index * CHUNK). */
100231
100559
  async writeBlock(index, buf) {
@@ -100240,7 +100568,7 @@ var BlockAssembler = class {
100240
100568
  await this.open();
100241
100569
  let lf = null;
100242
100570
  try {
100243
- lf = await open3(localAbs, "r");
100571
+ lf = await open4(localAbs, "r");
100244
100572
  const buf = Buffer.alloc(len);
100245
100573
  const { bytesRead } = await lf.read(buf, 0, len, localOffset);
100246
100574
  if (bytesRead !== len)
@@ -100268,7 +100596,7 @@ var BlockAssembler = class {
100268
100596
  });
100269
100597
  return false;
100270
100598
  }
100271
- await mkdir12(dirname24(dest), { recursive: true });
100599
+ await mkdir12(dirname25(dest), { recursive: true });
100272
100600
  await chmod2(this.stagingPath, mode & 511).catch(() => {
100273
100601
  });
100274
100602
  const secs = mtimeMs / 1e3;
@@ -100291,8 +100619,8 @@ var BlockAssembler = class {
100291
100619
  };
100292
100620
 
100293
100621
  // ../../packages/host-core/dist/active-link/manifest.js
100294
- import { readFileSync as readFileSync37, writeFileSync as writeFileSync25, mkdirSync as mkdirSync27, existsSync as existsSync24, renameSync as renameSync8 } from "node:fs";
100295
- import { join as join54 } from "node:path";
100622
+ import { readFileSync as readFileSync38, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28, existsSync as existsSync25, renameSync as renameSync8 } from "node:fs";
100623
+ import { join as join55 } from "node:path";
100296
100624
 
100297
100625
  // ../../packages/host-core/dist/active-link/reconcile.js
100298
100626
  var ABSENT = { kind: "absent", t: -Infinity, hash: "" };
@@ -100328,11 +100656,11 @@ var LinkManifest = class {
100328
100656
  this.dir = dir2;
100329
100657
  }
100330
100658
  file() {
100331
- return join54(this.dir, "manifest.json");
100659
+ return join55(this.dir, "manifest.json");
100332
100660
  }
100333
100661
  load() {
100334
100662
  try {
100335
- const raw = JSON.parse(readFileSync37(this.file(), "utf-8"));
100663
+ const raw = JSON.parse(readFileSync38(this.file(), "utf-8"));
100336
100664
  this.records = new Map(Object.entries(raw.records ?? {}));
100337
100665
  this.tombstones = new Map(Object.entries(raw.tombstones ?? {}));
100338
100666
  } catch {
@@ -100413,14 +100741,14 @@ var LinkManifest = class {
100413
100741
  if (!this.dirty)
100414
100742
  return;
100415
100743
  try {
100416
- if (!existsSync24(this.dir))
100417
- mkdirSync27(this.dir, { recursive: true });
100744
+ if (!existsSync25(this.dir))
100745
+ mkdirSync28(this.dir, { recursive: true });
100418
100746
  const json3 = {
100419
100747
  records: Object.fromEntries(this.records),
100420
100748
  tombstones: Object.fromEntries(this.tombstones)
100421
100749
  };
100422
100750
  const tmp = `${this.file()}.tmp`;
100423
- writeFileSync25(tmp, JSON.stringify(json3));
100751
+ writeFileSync26(tmp, JSON.stringify(json3));
100424
100752
  renameSync8(tmp, this.file());
100425
100753
  this.dirty = false;
100426
100754
  } catch {
@@ -100430,7 +100758,7 @@ var LinkManifest = class {
100430
100758
 
100431
100759
  // ../../packages/host-core/dist/active-link/scanner.js
100432
100760
  import { readdir as readdir7, lstat as lstat3, readlink as readlink2 } from "node:fs/promises";
100433
- import { join as join55, sep as sep10 } from "node:path";
100761
+ import { join as join56, sep as sep10 } from "node:path";
100434
100762
  async function walkRels(root, extraIgnore) {
100435
100763
  const out = [];
100436
100764
  async function rec(dir2) {
@@ -100445,7 +100773,7 @@ async function walkRels(root, extraIgnore) {
100445
100773
  continue;
100446
100774
  if (e.isDirectory() && HEAVY_DIRS.has(e.name))
100447
100775
  continue;
100448
- const abs = join55(dir2, e.name);
100776
+ const abs = join56(dir2, e.name);
100449
100777
  if (extraIgnore?.(abs))
100450
100778
  continue;
100451
100779
  if (e.isDirectory())
@@ -100484,7 +100812,7 @@ async function scanTree(root, prior, allow, extraIgnore) {
100484
100812
  return { records };
100485
100813
  }
100486
100814
  function absOf(root, rel) {
100487
- return join55(root, rel.split("/").join(sep10));
100815
+ return join56(root, rel.split("/").join(sep10));
100488
100816
  }
100489
100817
 
100490
100818
  // ../../packages/host-core/dist/active-link/gitignore.js
@@ -100502,7 +100830,7 @@ async function gitSyncedFiles(root) {
100502
100830
 
100503
100831
  // ../../packages/host-core/dist/active-link/session.js
100504
100832
  import { createHash as createHash6 } from "node:crypto";
100505
- import { lstat as lstat4, readlink as readlink3, open as open4 } from "node:fs/promises";
100833
+ import { lstat as lstat4, readlink as readlink3, open as open5 } from "node:fs/promises";
100506
100834
  var OutboundSender = class {
100507
100835
  deps;
100508
100836
  queue = [];
@@ -100596,7 +100924,7 @@ var OutboundSender = class {
100596
100924
  const running2 = createHash6("sha256");
100597
100925
  let fh;
100598
100926
  try {
100599
- fh = await open4(abs, "r");
100927
+ fh = await open5(abs, "r");
100600
100928
  } catch {
100601
100929
  return;
100602
100930
  }
@@ -100667,7 +100995,7 @@ var OutboundSender = class {
100667
100995
  const mode = st.mode;
100668
100996
  let fh;
100669
100997
  try {
100670
- fh = await open4(abs, "r");
100998
+ fh = await open5(abs, "r");
100671
100999
  } catch {
100672
101000
  return;
100673
101001
  }
@@ -100928,7 +101256,7 @@ function readdirp(root, options = {}) {
100928
101256
 
100929
101257
  // ../../node_modules/chokidar/esm/handler.js
100930
101258
  import { watchFile, unwatchFile, watch as fs_watch } from "fs";
100931
- import { open as open5, stat as stat7, lstat as lstat6, realpath as fsrealpath } from "fs/promises";
101259
+ import { open as open6, stat as stat7, lstat as lstat6, realpath as fsrealpath } from "fs/promises";
100932
101260
  import * as sysPath from "path";
100933
101261
  import { type as osType } from "os";
100934
101262
  var STR_DATA = "data";
@@ -101312,7 +101640,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
101312
101640
  cont.watcherUnusable = true;
101313
101641
  if (isWindows2 && error51.code === "EPERM") {
101314
101642
  try {
101315
- const fd = await open5(path6, "r");
101643
+ const fd = await open6(path6, "r");
101316
101644
  await fd.close();
101317
101645
  broadcastErr(error51);
101318
101646
  } catch (err2) {
@@ -101430,9 +101758,9 @@ var NodeFsHandler = class {
101430
101758
  if (this.fsw.closed) {
101431
101759
  return;
101432
101760
  }
101433
- const dirname41 = sysPath.dirname(file2);
101761
+ const dirname42 = sysPath.dirname(file2);
101434
101762
  const basename14 = sysPath.basename(file2);
101435
- const parent = this.fsw._getWatchedDir(dirname41);
101763
+ const parent = this.fsw._getWatchedDir(dirname42);
101436
101764
  let prevStats = stats;
101437
101765
  if (parent.has(basename14))
101438
101766
  return;
@@ -101459,7 +101787,7 @@ var NodeFsHandler = class {
101459
101787
  prevStats = newStats2;
101460
101788
  }
101461
101789
  } catch (error51) {
101462
- this.fsw._remove(dirname41, basename14);
101790
+ this.fsw._remove(dirname42, basename14);
101463
101791
  }
101464
101792
  } else if (parent.has(basename14)) {
101465
101793
  const at = newStats.atimeMs;
@@ -102509,7 +102837,7 @@ var ActiveLinkEngine = class {
102509
102837
  }
102510
102838
  async start() {
102511
102839
  this.emit({ type: "status", linkId: this.opts.linkId, state: "scanning" });
102512
- await rm4(join58(this.stateDir, ".staging"), { recursive: true, force: true }).catch(() => {
102840
+ await rm4(join59(this.stateDir, ".staging"), { recursive: true, force: true }).catch(() => {
102513
102841
  });
102514
102842
  this.manifest.load();
102515
102843
  await this.reconcileScan();
@@ -102904,13 +103232,13 @@ var ActiveLinkEngine = class {
102904
103232
  * file so the path still exists — recorded as a FILE matching disk so the local
102905
103233
  * watcher doesn't churn. The target is containment-checked, never dereferenced. */
102906
103234
  async applySymlink(rel, dest, target, mtimeMs, mode) {
102907
- const resolved = resolve11(dirname27(dest), target);
103235
+ const resolved = resolve11(dirname28(dest), target);
102908
103236
  if (!isInsideRoot(resolved, this.opts.localRoot))
102909
103237
  return;
102910
103238
  const hash2 = hashString(target);
102911
103239
  const secs = mtimeMs / 1e3;
102912
103240
  try {
102913
- await mkdir13(dirname27(dest), { recursive: true });
103241
+ await mkdir13(dirname28(dest), { recursive: true });
102914
103242
  await rm4(dest, { force: true, recursive: true });
102915
103243
  try {
102916
103244
  await symlink2(target, dest);
@@ -102962,7 +103290,7 @@ var ActiveLinkEngine = class {
102962
103290
  return;
102963
103291
  if (fromRec && fromRec.kind === "file") {
102964
103292
  try {
102965
- await mkdir13(dirname27(toAbs2), { recursive: true });
103293
+ await mkdir13(dirname28(toAbs2), { recursive: true });
102966
103294
  await rename3(fromAbs, toAbs2);
102967
103295
  const secs = mtimeMs / 1e3;
102968
103296
  await utimes2(toAbs2, secs, secs).catch(() => {
@@ -102987,7 +103315,7 @@ var ActiveLinkEngine = class {
102987
103315
  await this.maybeRefreshAllow(rels);
102988
103316
  const state3 = /* @__PURE__ */ new Map();
102989
103317
  for (const rel of rels) {
102990
- if (existsSync25(absOf(this.opts.localRoot, rel)) && !this.isSynced(rel)) {
103318
+ if (existsSync26(absOf(this.opts.localRoot, rel)) && !this.isSynced(rel)) {
102991
103319
  this.manifest.dropRecord(rel);
102992
103320
  continue;
102993
103321
  }
@@ -103091,7 +103419,7 @@ var ActiveLinkEngine = class {
103091
103419
  for (const rel of this.manifest.recordRels()) {
103092
103420
  if (records.has(rel))
103093
103421
  continue;
103094
- if (existsSync25(absOf(this.opts.localRoot, rel)))
103422
+ if (existsSync26(absOf(this.opts.localRoot, rel)))
103095
103423
  this.manifest.dropRecord(rel);
103096
103424
  else
103097
103425
  this.manifest.setTombstone(rel, now2);
@@ -103137,7 +103465,7 @@ var ActiveLinkEngine = class {
103137
103465
  this.inboundWatchdog.clear();
103138
103466
  }
103139
103467
  stagingPath(rel, tag) {
103140
- return join58(this.stateDir, ".staging", `${hashString(rel)}.${tag}`);
103468
+ return join59(this.stateDir, ".staging", `${hashString(rel)}.${tag}`);
103141
103469
  }
103142
103470
  pruneSuppress() {
103143
103471
  const now2 = this.now();
@@ -103162,14 +103490,14 @@ var ActiveLinkEngine = class {
103162
103490
  };
103163
103491
 
103164
103492
  // ../../packages/host-core/dist/active-link/config.js
103165
- import { readFileSync as readFileSync38, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28, existsSync as existsSync26, renameSync as renameSync9, watch as watch3 } from "node:fs";
103166
- import { join as join59 } from "node:path";
103493
+ import { readFileSync as readFileSync39, writeFileSync as writeFileSync27, mkdirSync as mkdirSync29, existsSync as existsSync27, renameSync as renameSync9, watch as watch3 } from "node:fs";
103494
+ import { join as join60 } from "node:path";
103167
103495
  function configPath2() {
103168
- return join59(activeLinkRoot(), "links.json");
103496
+ return join60(activeLinkRoot(), "links.json");
103169
103497
  }
103170
103498
  function loadLinkConfigs() {
103171
103499
  try {
103172
- const raw = JSON.parse(readFileSync38(configPath2(), "utf-8"));
103500
+ const raw = JSON.parse(readFileSync39(configPath2(), "utf-8"));
103173
103501
  if (!Array.isArray(raw.links))
103174
103502
  return [];
103175
103503
  return raw.links.filter((c) => c && c.linkId && c.localRoot && c.peerHostId);
@@ -103180,10 +103508,10 @@ function loadLinkConfigs() {
103180
103508
  function writeAll(links) {
103181
103509
  try {
103182
103510
  const dir2 = activeLinkRoot();
103183
- if (!existsSync26(dir2))
103184
- mkdirSync28(dir2, { recursive: true });
103511
+ if (!existsSync27(dir2))
103512
+ mkdirSync29(dir2, { recursive: true });
103185
103513
  const tmp = `${configPath2()}.tmp`;
103186
- writeFileSync26(tmp, JSON.stringify({ links }, null, 2));
103514
+ writeFileSync27(tmp, JSON.stringify({ links }, null, 2));
103187
103515
  renameSync9(tmp, configPath2());
103188
103516
  } catch {
103189
103517
  }
@@ -103202,11 +103530,11 @@ function saveLinkConfig(cfg2) {
103202
103530
  writeAll(links);
103203
103531
  }
103204
103532
  function pendingPath() {
103205
- return join59(activeLinkRoot(), "pending-deprovisions.json");
103533
+ return join60(activeLinkRoot(), "pending-deprovisions.json");
103206
103534
  }
103207
103535
  function loadPendingDeprovisions() {
103208
103536
  try {
103209
- const raw = JSON.parse(readFileSync38(pendingPath(), "utf-8"));
103537
+ const raw = JSON.parse(readFileSync39(pendingPath(), "utf-8"));
103210
103538
  return Array.isArray(raw.pending) ? raw.pending.filter((p) => p && p.linkId && p.peerHostId) : [];
103211
103539
  } catch {
103212
103540
  return [];
@@ -103215,10 +103543,10 @@ function loadPendingDeprovisions() {
103215
103543
  function writePending(pending2) {
103216
103544
  try {
103217
103545
  const dir2 = activeLinkRoot();
103218
- if (!existsSync26(dir2))
103219
- mkdirSync28(dir2, { recursive: true });
103546
+ if (!existsSync27(dir2))
103547
+ mkdirSync29(dir2, { recursive: true });
103220
103548
  const tmp = `${pendingPath()}.tmp`;
103221
- writeFileSync26(tmp, JSON.stringify({ pending: pending2 }, null, 2));
103549
+ writeFileSync27(tmp, JSON.stringify({ pending: pending2 }, null, 2));
103222
103550
  renameSync9(tmp, pendingPath());
103223
103551
  } catch {
103224
103552
  }
@@ -103231,8 +103559,8 @@ function removeLinkConfig(linkId) {
103231
103559
  }
103232
103560
  function watchLinkConfigs(onChange) {
103233
103561
  const dir2 = activeLinkRoot();
103234
- if (!existsSync26(dir2))
103235
- mkdirSync28(dir2, { recursive: true });
103562
+ if (!existsSync27(dir2))
103563
+ mkdirSync29(dir2, { recursive: true });
103236
103564
  let timer2 = null;
103237
103565
  let watcher = null;
103238
103566
  try {
@@ -103377,7 +103705,7 @@ function routeInboundLinkFrame(frame) {
103377
103705
  init_dist5();
103378
103706
 
103379
103707
  // ../../packages/host-core/dist/pty-manager.js
103380
- import { existsSync as existsSync27 } from "node:fs";
103708
+ import { existsSync as existsSync28 } from "node:fs";
103381
103709
  import { homedir as homedir9 } from "node:os";
103382
103710
  init_safe_kill();
103383
103711
  var ptyPromise = null;
@@ -103532,7 +103860,7 @@ function listUnix() {
103532
103860
  const seen = /* @__PURE__ */ new Set();
103533
103861
  const loginShell = process.env.SHELL || "";
103534
103862
  const add2 = (id, path6) => {
103535
- if (!path6 || seen.has(path6) || !existsSync27(path6))
103863
+ if (!path6 || seen.has(path6) || !existsSync28(path6))
103536
103864
  return;
103537
103865
  seen.add(path6);
103538
103866
  out.push(mk(id, path6, path6 === loginShell));
@@ -103564,7 +103892,7 @@ function listWindows() {
103564
103892
  const gitBash = `${pf}\\Git\\bin\\bash.exe`;
103565
103893
  const pwsh7 = `${pf}\\PowerShell\\7\\pwsh.exe`;
103566
103894
  const add2 = (id, path6, label, isDefault = false) => {
103567
- if (path6 && existsSync27(path6))
103895
+ if (path6 && existsSync28(path6))
103568
103896
  out.push(mk(id, path6, isDefault, label));
103569
103897
  };
103570
103898
  add2("powershell", winPwsh, "Windows PowerShell", true);
@@ -103623,7 +103951,7 @@ function resolveCwd(cwd, hostRoot) {
103623
103951
  const fallback = hostRoot || homedir9();
103624
103952
  if (!cwd)
103625
103953
  return fallback;
103626
- if (!existsSync27(cwd))
103954
+ if (!existsSync28(cwd))
103627
103955
  return fallback;
103628
103956
  if (hostRoot && !isInsideRoot(cwd, hostRoot))
103629
103957
  return hostRoot;
@@ -103658,6 +103986,7 @@ function turnRekeyed(from, to) {
103658
103986
  var HOST_ROOT = resolveHostRoot();
103659
103987
  var HOST_CONTAIN = resolveContainmentRoot() ?? void 0;
103660
103988
  var hooks = null;
103989
+ var hookSets = [];
103661
103990
  var socket = null;
103662
103991
  var heartbeat = null;
103663
103992
  var reconnectTimer = null;
@@ -103855,6 +104184,16 @@ function listHosts() {
103855
104184
  function ownHost() {
103856
104185
  return ownHostId();
103857
104186
  }
104187
+ function setControlLinkDeviceId(id) {
104188
+ if (!id || id === deviceId)
104189
+ return;
104190
+ deviceId = id;
104191
+ if (cfg)
104192
+ cfg = { ...cfg, deviceId: id };
104193
+ lastOwnHostLog = null;
104194
+ hooks?.ownHostResolved(ownHostId());
104195
+ hooks?.pushHosts(presentedHosts());
104196
+ }
103858
104197
  function assertServerSelection() {
103859
104198
  if (!socket || socket.readyState !== 1)
103860
104199
  return;
@@ -104081,9 +104420,9 @@ function provisionActiveLinkMirror(payload) {
104081
104420
  const remoteSubfolder = typeof payload.remoteSubfolder === "string" ? payload.remoteSubfolder : void 0;
104082
104421
  let localRoot;
104083
104422
  if (remoteParent && remoteSubfolder) {
104084
- localRoot = join60(remoteParent, safeFolderName(remoteSubfolder));
104423
+ localRoot = join61(remoteParent, safeFolderName(remoteSubfolder));
104085
104424
  } else {
104086
- localRoot = join60(HOST_ROOT, "Tesseract Mirrors", safeFolderName(projectName));
104425
+ localRoot = join61(HOST_ROOT, "Tesseract Mirrors", safeFolderName(projectName));
104087
104426
  }
104088
104427
  if (loadLinkConfigs().some((c) => c.localRoot === localRoot && c.linkId !== linkId)) {
104089
104428
  localRoot = `${localRoot}-${linkId.slice(0, 6)}`;
@@ -104091,7 +104430,7 @@ function provisionActiveLinkMirror(payload) {
104091
104430
  if (!isInsideRoot(localRoot, HOST_ROOT))
104092
104431
  return;
104093
104432
  try {
104094
- mkdirSync29(localRoot, { recursive: true });
104433
+ mkdirSync30(localRoot, { recursive: true });
104095
104434
  } catch {
104096
104435
  }
104097
104436
  saveLinkConfig({
@@ -104399,7 +104738,7 @@ async function handleInboundAgent(msg, driverClientId) {
104399
104738
  send3("agent", {
104400
104739
  type: "agent:notice",
104401
104740
  sessionId: msg.sessionId,
104402
- noticeId: randomUUID24(),
104741
+ noticeId: randomUUID25(),
104403
104742
  category: "model",
104404
104743
  level: "warning",
104405
104744
  title: "That model is not available on this device",
@@ -105119,7 +105458,9 @@ function startControlLink(config2, h) {
105119
105458
  deviceId = config2.deviceId;
105120
105459
  backendOrigin = config2.tokenSource.backendOrigin;
105121
105460
  hostVersion = config2.version;
105122
- hooks = h;
105461
+ if (!hookSets.includes(h))
105462
+ hookSets.push(h);
105463
+ hooks = composeHooks(hookSets, (hook, err2) => console.warn(`[control-link] ${hook} listener failed:`, err2 instanceof Error ? err2.message : err2));
105123
105464
  stopped = false;
105124
105465
  if (config2.e2e && !hostSessions) {
105125
105466
  const e2e = config2.e2e;
@@ -105196,9 +105537,9 @@ init_gateway_plan2();
105196
105537
  init_base_paths();
105197
105538
  init_credentials();
105198
105539
  init_dist5();
105199
- import { mkdirSync as mkdirSync30, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
105200
- import { randomUUID as randomUUID25 } from "node:crypto";
105201
- import { dirname as dirname28 } from "node:path";
105540
+ import { mkdirSync as mkdirSync31, readFileSync as readFileSync40, writeFileSync as writeFileSync28 } from "node:fs";
105541
+ import { randomUUID as randomUUID26 } from "node:crypto";
105542
+ import { dirname as dirname29 } from "node:path";
105202
105543
  var REFRESH_MS = 24 * 60 * 60 * 1e3;
105203
105544
  var TIMEOUT_MS2 = 1e4;
105204
105545
  var CACHE = () => tessPath("bundled-model.json");
@@ -105208,22 +105549,22 @@ function deviceId2() {
105208
105549
  if (fromCredentials)
105209
105550
  return fromCredentials;
105210
105551
  try {
105211
- const raw = JSON.parse(readFileSync39(DEVICE_ID(), "utf8"));
105552
+ const raw = JSON.parse(readFileSync40(DEVICE_ID(), "utf8"));
105212
105553
  if (typeof raw?.deviceId === "string" && raw.deviceId)
105213
105554
  return raw.deviceId;
105214
105555
  } catch {
105215
105556
  }
105216
- const fresh = randomUUID25().slice(0, 8);
105557
+ const fresh = randomUUID26().slice(0, 8);
105217
105558
  try {
105218
- mkdirSync30(dirname28(DEVICE_ID()), { recursive: true });
105219
- writeFileSync27(DEVICE_ID(), JSON.stringify({ deviceId: fresh }), { mode: 384 });
105559
+ mkdirSync31(dirname29(DEVICE_ID()), { recursive: true });
105560
+ writeFileSync28(DEVICE_ID(), JSON.stringify({ deviceId: fresh }), { mode: 384 });
105220
105561
  } catch {
105221
105562
  }
105222
105563
  return fresh;
105223
105564
  }
105224
105565
  function readCache() {
105225
105566
  try {
105226
- const raw = JSON.parse(readFileSync39(CACHE(), "utf8"));
105567
+ const raw = JSON.parse(readFileSync40(CACHE(), "utf8"));
105227
105568
  if (typeof raw?.apiKey === "string" && typeof raw.baseUrl === "string" && raw.models?.low && raw.models.high) {
105228
105569
  return { ...raw, fetchedAt: raw.fetchedAt ?? 0 };
105229
105570
  }
@@ -105233,8 +105574,8 @@ function readCache() {
105233
105574
  }
105234
105575
  function writeCache(key2) {
105235
105576
  try {
105236
- mkdirSync30(dirname28(CACHE()), { recursive: true });
105237
- writeFileSync27(CACHE(), JSON.stringify({ ...key2, fetchedAt: Date.now() }, null, 2), { mode: 384 });
105577
+ mkdirSync31(dirname29(CACHE()), { recursive: true });
105578
+ writeFileSync28(CACHE(), JSON.stringify({ ...key2, fetchedAt: Date.now() }, null, 2), { mode: 384 });
105238
105579
  } catch (e) {
105239
105580
  log(`gateway key: could not cache (${e.message})`);
105240
105581
  }
@@ -105815,7 +106156,7 @@ Open System Settings \u2192 Privacy & Security \u2192 Screen Recording and switc
105815
106156
  }
105816
106157
 
105817
106158
  // ../../packages/host-core/dist/rdesk/publisher-window.js
105818
- import { join as join61 } from "node:path";
106159
+ import { join as join62 } from "node:path";
105819
106160
  var windows = /* @__PURE__ */ new Map();
105820
106161
  var ipcInstalled = false;
105821
106162
  function ensureIpc() {
@@ -105970,7 +106311,7 @@ var PublisherWindow = class {
105970
106311
  win3.setContentProtection(true);
105971
106312
  } catch {
105972
106313
  }
105973
- await win3.loadFile(join61(daemonUiDir(), "publisher.html"));
106314
+ await win3.loadFile(join62(daemonUiDir(), "publisher.html"));
105974
106315
  this.send("rdesk:pub:start", {
105975
106316
  sessionId: this.sessionId,
105976
106317
  sourceId,
@@ -106015,7 +106356,7 @@ var PublisherWindow = class {
106015
106356
  win3.setContentProtection(true);
106016
106357
  } catch {
106017
106358
  }
106018
- await win3.loadFile(join61(daemonUiDir(), "publisher.html"));
106359
+ await win3.loadFile(join62(daemonUiDir(), "publisher.html"));
106019
106360
  this.send("rdesk:pub:start", {
106020
106361
  sessionId: this.sessionId,
106021
106362
  mode: "canvas",
@@ -106615,10 +106956,10 @@ function setInProcConnector(fn) {
106615
106956
 
106616
106957
  // ../../packages/host-core/dist/rdesk/server-prefs.js
106617
106958
  init_credentials();
106618
- import { readFileSync as readFileSync40, writeFileSync as writeFileSync28 } from "node:fs";
106619
- import { join as join62 } from "node:path";
106959
+ import { readFileSync as readFileSync41, writeFileSync as writeFileSync29 } from "node:fs";
106960
+ import { join as join63 } from "node:path";
106620
106961
  function rdeskServerPrefsPath() {
106621
- return join62(daemonDir2(), "rdesk-server.json");
106962
+ return join63(daemonDir2(), "rdesk-server.json");
106622
106963
  }
106623
106964
  var DEFAULTS2 = {
106624
106965
  enabled: true,
@@ -106630,7 +106971,7 @@ var DEFAULTS2 = {
106630
106971
  };
106631
106972
  function readRdeskServerPrefs() {
106632
106973
  try {
106633
- const p = JSON.parse(readFileSync40(rdeskServerPrefsPath(), "utf8"));
106974
+ const p = JSON.parse(readFileSync41(rdeskServerPrefsPath(), "utf8"));
106634
106975
  return {
106635
106976
  // `!== false` (not `?? true`): only an explicit opt-out disables sharing, so a
106636
106977
  // partially-written or older prefs file never silently turns the machine off.
@@ -106648,7 +106989,7 @@ function readRdeskServerPrefs() {
106648
106989
  function writeRdeskServerPrefs(patch) {
106649
106990
  try {
106650
106991
  const next = { ...readRdeskServerPrefs(), ...patch };
106651
- writeFileSync28(rdeskServerPrefsPath(), JSON.stringify(next), { mode: 384 });
106992
+ writeFileSync29(rdeskServerPrefsPath(), JSON.stringify(next), { mode: 384 });
106652
106993
  } catch {
106653
106994
  }
106654
106995
  }
@@ -106663,13 +107004,13 @@ function rdeskSharingEnabled() {
106663
107004
  // ../../packages/host-core/dist/rdesk/password.js
106664
107005
  init_credentials();
106665
107006
  import { scryptSync, randomBytes as randomBytes5, timingSafeEqual as timingSafeEqual4, randomInt } from "node:crypto";
106666
- import { readFileSync as readFileSync41, writeFileSync as writeFileSync29, existsSync as existsSync28, unlinkSync as unlinkSync3 } from "node:fs";
106667
- import { join as join63 } from "node:path";
107007
+ import { readFileSync as readFileSync42, writeFileSync as writeFileSync30, existsSync as existsSync29, unlinkSync as unlinkSync4 } from "node:fs";
107008
+ import { join as join64 } from "node:path";
106668
107009
  function pwFile() {
106669
- return join63(daemonDir2(), "rdesk-password.json");
107010
+ return join64(daemonDir2(), "rdesk-password.json");
106670
107011
  }
106671
107012
  function pwPlainFile() {
106672
- return join63(daemonDir2(), "rdesk-password.enc");
107013
+ return join64(daemonDir2(), "rdesk-password.enc");
106673
107014
  }
106674
107015
  var PW_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789";
106675
107016
  var PW_LENGTH = 16;
@@ -106684,14 +107025,14 @@ function writePlain(password) {
106684
107025
  const safe2 = electronModule()?.safeStorage;
106685
107026
  if (!safe2?.isEncryptionAvailable())
106686
107027
  return;
106687
- writeFileSync29(pwPlainFile(), safe2.encryptString(password), { mode: 384 });
107028
+ writeFileSync30(pwPlainFile(), safe2.encryptString(password), { mode: 384 });
106688
107029
  } catch {
106689
107030
  }
106690
107031
  }
106691
107032
  function canRevealRdeskPassword() {
106692
107033
  try {
106693
107034
  const safe2 = electronModule()?.safeStorage;
106694
- return !!safe2?.isEncryptionAvailable() && existsSync28(pwPlainFile());
107035
+ return !!safe2?.isEncryptionAvailable() && existsSync29(pwPlainFile());
106695
107036
  } catch {
106696
107037
  return false;
106697
107038
  }
@@ -106701,7 +107042,7 @@ function readRdeskPasswordPlain() {
106701
107042
  const safe2 = electronModule()?.safeStorage;
106702
107043
  if (!safe2?.isEncryptionAvailable())
106703
107044
  return null;
106704
- return safe2.decryptString(readFileSync41(pwPlainFile()));
107045
+ return safe2.decryptString(readFileSync42(pwPlainFile()));
106705
107046
  } catch {
106706
107047
  return null;
106707
107048
  }
@@ -106709,18 +107050,18 @@ function readRdeskPasswordPlain() {
106709
107050
  function setRdeskPassword(password) {
106710
107051
  if (!password) {
106711
107052
  try {
106712
- unlinkSync3(pwFile());
107053
+ unlinkSync4(pwFile());
106713
107054
  } catch {
106714
107055
  }
106715
107056
  try {
106716
- unlinkSync3(pwPlainFile());
107057
+ unlinkSync4(pwPlainFile());
106717
107058
  } catch {
106718
107059
  }
106719
107060
  return;
106720
107061
  }
106721
107062
  const salt = randomBytes5(16);
106722
107063
  const hash2 = scryptSync(password, salt, 32);
106723
- writeFileSync29(pwFile(), JSON.stringify({ salt: salt.toString("hex"), hash: hash2.toString("hex") }), { mode: 384 });
107064
+ writeFileSync30(pwFile(), JSON.stringify({ salt: salt.toString("hex"), hash: hash2.toString("hex") }), { mode: 384 });
106724
107065
  writePlain(password);
106725
107066
  }
106726
107067
  function regenerateRdeskPassword() {
@@ -106734,7 +107075,7 @@ function ensureRdeskPassword() {
106734
107075
  return regenerateRdeskPassword();
106735
107076
  }
106736
107077
  function hasRdeskPassword() {
106737
- return !!process.env.CCB_RDESK_PASSWORD || existsSync28(pwFile());
107078
+ return !!process.env.CCB_RDESK_PASSWORD || existsSync29(pwFile());
106738
107079
  }
106739
107080
  function verifyRdeskPassword(password) {
106740
107081
  if (!password)
@@ -106743,7 +107084,7 @@ function verifyRdeskPassword(password) {
106743
107084
  if (override3)
106744
107085
  return password.length === override3.length && timingSafeEqual4(Buffer.from(password), Buffer.from(override3));
106745
107086
  try {
106746
- const { salt, hash: hash2 } = JSON.parse(readFileSync41(pwFile(), "utf8"));
107087
+ const { salt, hash: hash2 } = JSON.parse(readFileSync42(pwFile(), "utf8"));
106747
107088
  const got = scryptSync(password, Buffer.from(salt, "hex"), 32);
106748
107089
  const want = Buffer.from(hash2, "hex");
106749
107090
  return got.length === want.length && timingSafeEqual4(got, want);
@@ -107221,7 +107562,7 @@ function stopSystemEvents() {
107221
107562
  }
107222
107563
 
107223
107564
  // ../../packages/host-core/dist/local-server.js
107224
- import { randomUUID as randomUUID27 } from "node:crypto";
107565
+ import { randomUUID as randomUUID28 } from "node:crypto";
107225
107566
  init_daemon_settings();
107226
107567
 
107227
107568
  // ../../packages/host-core/dist/vault/manager.js
@@ -107309,8 +107650,8 @@ function createPasskeyRegistration(rpId) {
107309
107650
 
107310
107651
  // ../../packages/host-core/dist/vault/manager.js
107311
107652
  init_base_paths();
107312
- import { mkdirSync as mkdirSync33, readFileSync as readFileSync44, writeFileSync as writeFileSync32 } from "node:fs";
107313
- import { dirname as dirname30 } from "node:path";
107653
+ import { mkdirSync as mkdirSync34, readFileSync as readFileSync45, writeFileSync as writeFileSync33 } from "node:fs";
107654
+ import { dirname as dirname31 } from "node:path";
107314
107655
 
107315
107656
  // ../../packages/vault-core/dist/crypto.js
107316
107657
  init_argon2();
@@ -107404,7 +107745,7 @@ async function seal(key2, plaintext, aad) {
107404
107745
  const ct = await aesSeal(key2, nonce2, plaintext, aad);
107405
107746
  return `${ENVELOPE}:${b64u(nonce2)}:${b64u(ct)}`;
107406
107747
  }
107407
- async function open6(key2, envelope2, aad) {
107748
+ async function open7(key2, envelope2, aad) {
107408
107749
  const parts = envelope2.split(":");
107409
107750
  if (parts.length !== 3 || parts[0] !== ENVELOPE)
107410
107751
  throw new Error("malformed vault envelope");
@@ -107417,7 +107758,7 @@ async function wrapVaultKey(masterKey, vaultKey) {
107417
107758
  return seal(await wrappingKey(masterKey), vaultKey, WRAP_AAD);
107418
107759
  }
107419
107760
  async function unwrapVaultKey(masterKey, wrapped) {
107420
- return open6(await wrappingKey(masterKey), wrapped, WRAP_AAD);
107761
+ return open7(await wrappingKey(masterKey), wrapped, WRAP_AAD);
107421
107762
  }
107422
107763
  async function createVault(masterPassword, kdf2 = defaultKdfParams()) {
107423
107764
  const masterKey = deriveMasterKey(masterPassword, kdf2);
@@ -107450,7 +107791,7 @@ async function recoverWithKey(recoveryKey, meta4) {
107450
107791
  throw new Error("no recovery key is set for this vault");
107451
107792
  const kek = await importAesKey(parseRecoveryKey(recoveryKey));
107452
107793
  try {
107453
- return await open6(kek, meta4.recoveryWrappedVaultKey, RECOVERY_AAD);
107794
+ return await open7(kek, meta4.recoveryWrappedVaultKey, RECOVERY_AAD);
107454
107795
  } catch {
107455
107796
  throw new Error("Incorrect recovery key");
107456
107797
  }
@@ -107471,7 +107812,7 @@ async function encryptItem(vaultKey, item) {
107471
107812
  }
107472
107813
  async function decryptItem(vaultKey, enc) {
107473
107814
  const key2 = await importAesKey(vaultKey);
107474
- return JSON.parse(fromUtf8(await open6(key2, enc.ciphertext, itemAad(enc.id))));
107815
+ return JSON.parse(fromUtf8(await open7(key2, enc.ciphertext, itemAad(enc.id))));
107475
107816
  }
107476
107817
  function tombstone(id, updatedAt) {
107477
107818
  return { id, ciphertext: "", updatedAt, deleted: true };
@@ -107817,7 +108158,7 @@ var XJSON_AAD = utf8("tesseract-vault-encrypted-json-v1");
107817
108158
  init_credentials();
107818
108159
 
107819
108160
  // ../../packages/host-core/dist/vault/store.js
107820
- import { randomUUID as randomUUID26 } from "node:crypto";
108161
+ import { randomUUID as randomUUID27 } from "node:crypto";
107821
108162
  var b64 = (u) => Buffer.from(u).toString("base64");
107822
108163
  var u82 = (s) => new Uint8Array(Buffer.from(s, "base64"));
107823
108164
  var isServerRecoverableMeta = (m) => !m.wrappedVaultKey;
@@ -108119,7 +108460,7 @@ var VaultStore = class {
108119
108460
  const existing = input.id ? items.get(input.id) : void 0;
108120
108461
  const { id: _drop, name, folderId, favorite, reprompt, notes, tags, ...content } = input;
108121
108462
  const item = {
108122
- id: input.id ?? randomUUID26(),
108463
+ id: input.id ?? randomUUID27(),
108123
108464
  name,
108124
108465
  folderId,
108125
108466
  favorite,
@@ -108148,7 +108489,7 @@ var VaultStore = class {
108148
108489
  const now2 = this.now();
108149
108490
  for (const d of drafts) {
108150
108491
  const { name, notes, favorite, tags, ...content } = d;
108151
- const item = { id: randomUUID26(), name, notes, favorite, tags, createdAt: now2, updatedAt: now2, ...content };
108492
+ const item = { id: randomUUID27(), name, notes, favorite, tags, createdAt: now2, updatedAt: now2, ...content };
108152
108493
  items.set(item.id, item);
108153
108494
  this.enc.set(item.id, await encryptItem(key2, item));
108154
108495
  this.dirty.add(item.id);
@@ -108334,8 +108675,8 @@ function makeDaemonVaultApi(getOrigin, getToken2) {
108334
108675
 
108335
108676
  // ../../packages/host-core/dist/vault/persistence.js
108336
108677
  init_base_paths();
108337
- import { existsSync as existsSync29, mkdirSync as mkdirSync31, readFileSync as readFileSync42, writeFileSync as writeFileSync30, unlinkSync as unlinkSync4 } from "node:fs";
108338
- import { dirname as dirname29 } from "node:path";
108678
+ import { existsSync as existsSync30, mkdirSync as mkdirSync32, readFileSync as readFileSync43, writeFileSync as writeFileSync31, unlinkSync as unlinkSync5 } from "node:fs";
108679
+ import { dirname as dirname30 } from "node:path";
108339
108680
  function vaultStoreFile() {
108340
108681
  return homePath(".tesseract", "vault", "vault.json");
108341
108682
  }
@@ -108346,9 +108687,9 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
108346
108687
  return {
108347
108688
  load() {
108348
108689
  try {
108349
- if (!existsSync29(file2()))
108690
+ if (!existsSync30(file2()))
108350
108691
  return null;
108351
- const parsed = JSON.parse(readFileSync42(file2(), "utf8"));
108692
+ const parsed = JSON.parse(readFileSync43(file2(), "utf8"));
108352
108693
  if (!parsed || typeof parsed !== "object")
108353
108694
  return null;
108354
108695
  return { meta: parsed.meta ?? null, items: Array.isArray(parsed.items) ? parsed.items : [] };
@@ -108358,29 +108699,29 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
108358
108699
  },
108359
108700
  save(state3) {
108360
108701
  try {
108361
- mkdirSync31(dirname29(file2()), { recursive: true, mode: 448 });
108362
- writeFileSync30(file2(), JSON.stringify(state3), { mode: 384 });
108702
+ mkdirSync32(dirname30(file2()), { recursive: true, mode: 448 });
108703
+ writeFileSync31(file2(), JSON.stringify(state3), { mode: 384 });
108363
108704
  } catch {
108364
108705
  }
108365
108706
  },
108366
108707
  loadDeviceKey() {
108367
108708
  try {
108368
- return existsSync29(deviceKeyFile()) ? readFileSync42(deviceKeyFile(), "utf8").trim() || null : null;
108709
+ return existsSync30(deviceKeyFile()) ? readFileSync43(deviceKeyFile(), "utf8").trim() || null : null;
108369
108710
  } catch {
108370
108711
  return null;
108371
108712
  }
108372
108713
  },
108373
108714
  saveDeviceKey(base64Key) {
108374
108715
  try {
108375
- mkdirSync31(dirname29(deviceKeyFile()), { recursive: true, mode: 448 });
108376
- writeFileSync30(deviceKeyFile(), base64Key, { mode: 384 });
108716
+ mkdirSync32(dirname30(deviceKeyFile()), { recursive: true, mode: 448 });
108717
+ writeFileSync31(deviceKeyFile(), base64Key, { mode: 384 });
108377
108718
  } catch {
108378
108719
  }
108379
108720
  },
108380
108721
  clearDeviceKey() {
108381
108722
  try {
108382
- if (existsSync29(deviceKeyFile()))
108383
- unlinkSync4(deviceKeyFile());
108723
+ if (existsSync30(deviceKeyFile()))
108724
+ unlinkSync5(deviceKeyFile());
108384
108725
  } catch {
108385
108726
  }
108386
108727
  }
@@ -108389,8 +108730,8 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
108389
108730
 
108390
108731
  // ../../packages/host-core/dist/vault/biometric.js
108391
108732
  init_base_paths();
108392
- import { existsSync as existsSync30, mkdirSync as mkdirSync32, readFileSync as readFileSync43, rmSync as rmSync6, writeFileSync as writeFileSync31 } from "node:fs";
108393
- import { join as join64 } from "node:path";
108733
+ import { existsSync as existsSync31, mkdirSync as mkdirSync33, readFileSync as readFileSync44, rmSync as rmSync6, writeFileSync as writeFileSync32 } from "node:fs";
108734
+ import { join as join65 } from "node:path";
108394
108735
  async function electronBio() {
108395
108736
  if (!electronModule())
108396
108737
  return null;
@@ -108407,11 +108748,11 @@ async function electronBio() {
108407
108748
  }
108408
108749
  function bioDir() {
108409
108750
  const d = homePath(".tesseract", "vault-bio");
108410
- mkdirSync32(d, { recursive: true, mode: 448 });
108751
+ mkdirSync33(d, { recursive: true, mode: 448 });
108411
108752
  return d;
108412
108753
  }
108413
108754
  function bioFile(id) {
108414
- return join64(bioDir(), `${String(id).replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 64)}.enc`);
108755
+ return join65(bioDir(), `${String(id).replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 64)}.enc`);
108415
108756
  }
108416
108757
  async function biometricAvailable() {
108417
108758
  if (process.platform !== "darwin")
@@ -108426,24 +108767,24 @@ async function biometricAvailable() {
108426
108767
  }
108427
108768
  }
108428
108769
  function biometricEnrolled(id) {
108429
- return existsSync30(bioFile(id));
108770
+ return existsSync31(bioFile(id));
108430
108771
  }
108431
108772
  async function biometricEnroll(id, base64Key) {
108432
108773
  const bio = await electronBio();
108433
108774
  if (!bio)
108434
108775
  throw new Error("Touch ID is not available on this device.");
108435
108776
  await bio.systemPreferences.promptTouchID("enable Touch ID for your vault");
108436
- writeFileSync31(bioFile(id), bio.safeStorage.encryptString(base64Key), { mode: 384 });
108777
+ writeFileSync32(bioFile(id), bio.safeStorage.encryptString(base64Key), { mode: 384 });
108437
108778
  }
108438
108779
  async function biometricUnlock(id) {
108439
108780
  const f = bioFile(id);
108440
- if (!existsSync30(f))
108781
+ if (!existsSync31(f))
108441
108782
  throw new Error("Touch ID is not set up for this vault.");
108442
108783
  const bio = await electronBio();
108443
108784
  if (!bio)
108444
108785
  throw new Error("Touch ID is not available on this device.");
108445
108786
  await bio.systemPreferences.promptTouchID("unlock your vault");
108446
- return bio.safeStorage.decryptString(readFileSync43(f));
108787
+ return bio.safeStorage.decryptString(readFileSync44(f));
108447
108788
  }
108448
108789
  function biometricDisable(id) {
108449
108790
  try {
@@ -108473,7 +108814,7 @@ var VaultManager = class {
108473
108814
  // ── auto-lock ────────────────────────────────────────────────────────────────────
108474
108815
  loadAutoLock() {
108475
108816
  try {
108476
- const raw = JSON.parse(readFileSync44(settingsFile(), "utf8"));
108817
+ const raw = JSON.parse(readFileSync45(settingsFile(), "utf8"));
108477
108818
  return Number.isFinite(raw.autoLockMinutes) ? Math.max(0, raw.autoLockMinutes) : 0;
108478
108819
  } catch {
108479
108820
  return 0;
@@ -108481,8 +108822,8 @@ var VaultManager = class {
108481
108822
  }
108482
108823
  saveAutoLock() {
108483
108824
  try {
108484
- mkdirSync33(dirname30(settingsFile()), { recursive: true, mode: 448 });
108485
- writeFileSync32(settingsFile(), JSON.stringify({ autoLockMinutes: this.autoLockMinutes }), { mode: 384 });
108825
+ mkdirSync34(dirname31(settingsFile()), { recursive: true, mode: 448 });
108826
+ writeFileSync33(settingsFile(), JSON.stringify({ autoLockMinutes: this.autoLockMinutes }), { mode: 384 });
108486
108827
  } catch {
108487
108828
  }
108488
108829
  }
@@ -109179,7 +109520,7 @@ async function startLocalServer(opts) {
109179
109520
  send4("agent", {
109180
109521
  type: "agent:notice",
109181
109522
  sessionId: msg.sessionId,
109182
- noticeId: randomUUID27(),
109523
+ noticeId: randomUUID28(),
109183
109524
  category: "model",
109184
109525
  level: "warning",
109185
109526
  title: "That model is not available on this device",
@@ -109557,22 +109898,22 @@ async function startLocalServer(opts) {
109557
109898
 
109558
109899
  // ../../packages/host-core/dist/daemon-runtime.js
109559
109900
  init_base_paths();
109560
- import { readFileSync as readFileSync49, writeFileSync as writeFileSync40, existsSync as existsSync39, mkdirSync as mkdirSync41, unlinkSync as unlinkSync6, chmodSync as chmodSync7, statSync as statSync14 } from "node:fs";
109901
+ import { readFileSync as readFileSync50, writeFileSync as writeFileSync41, existsSync as existsSync40, mkdirSync as mkdirSync42, unlinkSync as unlinkSync7, chmodSync as chmodSync7, statSync as statSync15 } from "node:fs";
109561
109902
  import { execFileSync as execFileSync5 } from "node:child_process";
109562
- import { join as join77 } from "node:path";
109903
+ import { join as join78 } from "node:path";
109563
109904
  import { randomBytes as randomBytes10 } from "node:crypto";
109564
109905
  import { hostname as hostname5 } from "node:os";
109565
109906
 
109566
109907
  // ../../packages/shared/dist/daemon-registry.js
109567
109908
  init_base_paths();
109568
109909
  import { execFileSync as execFileSync3 } from "node:child_process";
109569
- import { existsSync as existsSync31, mkdirSync as mkdirSync34, readdirSync as readdirSync11, readFileSync as readFileSync45, readlinkSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync33 } from "node:fs";
109570
- import { join as join65 } from "node:path";
109910
+ import { existsSync as existsSync32, mkdirSync as mkdirSync35, readdirSync as readdirSync11, readFileSync as readFileSync46, readlinkSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync34 } from "node:fs";
109911
+ import { join as join66 } from "node:path";
109571
109912
  var SUPERVISOR_PID = Number(process.env.CCB_DAEMON_SUPERVISOR_PID ?? 0) || 0;
109572
109913
  delete process.env.CCB_DAEMON_SUPERVISOR_PID;
109573
109914
  var PS_ENV = { ...process.env, LC_ALL: "C", LANG: "C" };
109574
- var registryDir = () => join65(daemonDir(), "daemons");
109575
- var recordPath = (pid) => join65(registryDir(), `${pid}.json`);
109915
+ var registryDir = () => join66(daemonDir(), "daemons");
109916
+ var recordPath = (pid) => join66(registryDir(), `${pid}.json`);
109576
109917
  function isPidAlive2(pid) {
109577
109918
  try {
109578
109919
  process.kill(pid, 0);
@@ -109624,7 +109965,7 @@ function pidStillMatches(pid, rec) {
109624
109965
  }
109625
109966
  function registerSelfAsDaemon(version2) {
109626
109967
  try {
109627
- mkdirSync34(registryDir(), { recursive: true, mode: 448 });
109968
+ mkdirSync35(registryDir(), { recursive: true, mode: 448 });
109628
109969
  const rec = {
109629
109970
  pid: process.pid,
109630
109971
  startedAt: procStartedAt(process.pid),
@@ -109636,7 +109977,7 @@ function registerSelfAsDaemon(version2) {
109636
109977
  ...process.env.CCB_RDESK_ONLY === "1" || process.env.CCB_MESH_ONLY === "1" ? { rdeskOnly: true } : {},
109637
109978
  ...SUPERVISOR_PID ? { supervisorPid: SUPERVISOR_PID, supervisorStartedAt: procStartedAt(SUPERVISOR_PID) } : {}
109638
109979
  };
109639
- writeFileSync33(recordPath(process.pid), JSON.stringify(rec), { mode: 384 });
109980
+ writeFileSync34(recordPath(process.pid), JSON.stringify(rec), { mode: 384 });
109640
109981
  invalidateSupervisorCache();
109641
109982
  try {
109642
109983
  registeredDaemons(process.pid);
@@ -109647,7 +109988,7 @@ function registerSelfAsDaemon(version2) {
109647
109988
  }
109648
109989
  function forgetDaemon(pid) {
109649
109990
  try {
109650
- unlinkSync5(recordPath(pid));
109991
+ unlinkSync6(recordPath(pid));
109651
109992
  } catch {
109652
109993
  }
109653
109994
  invalidateSupervisorCache();
@@ -109657,7 +109998,7 @@ function unregisterSelfAsDaemon() {
109657
109998
  }
109658
109999
  function readRecord(pid) {
109659
110000
  try {
109660
- return JSON.parse(readFileSync45(recordPath(pid), "utf-8"));
110001
+ return JSON.parse(readFileSync46(recordPath(pid), "utf-8"));
109661
110002
  } catch {
109662
110003
  return null;
109663
110004
  }
@@ -109671,7 +110012,7 @@ function allRegisteredPids() {
109671
110012
  }
109672
110013
  function registeredDaemons(selfPid) {
109673
110014
  const out = [];
109674
- if (!existsSync31(registryDir()))
110015
+ if (!existsSync32(registryDir()))
109675
110016
  return out;
109676
110017
  for (const pid of allRegisteredPids()) {
109677
110018
  if (pid === selfPid)
@@ -109700,18 +110041,18 @@ function liveDaemons() {
109700
110041
  }
109701
110042
 
109702
110043
  // ../../packages/host-core/dist/device-identity.js
109703
- import { join as join66 } from "node:path";
109704
- import { readFileSync as readFileSync46, writeFileSync as writeFileSync34, existsSync as existsSync32, mkdirSync as mkdirSync35, renameSync as renameSync10, chmodSync as chmodSync4 } from "node:fs";
110044
+ import { join as join67 } from "node:path";
110045
+ import { readFileSync as readFileSync47, writeFileSync as writeFileSync35, existsSync as existsSync33, mkdirSync as mkdirSync36, renameSync as renameSync10, chmodSync as chmodSync4 } from "node:fs";
109705
110046
  init_credentials();
109706
110047
  var cached3 = null;
109707
110048
  function identityPath() {
109708
- return join66(daemonDir2(), "identity.json");
110049
+ return join67(daemonDir2(), "identity.json");
109709
110050
  }
109710
110051
  async function loadOrCreateDeviceIdentity() {
109711
110052
  if (cached3)
109712
110053
  return cached3;
109713
110054
  try {
109714
- const stored = JSON.parse(readFileSync46(identityPath(), "utf-8"));
110055
+ const stored = JSON.parse(readFileSync47(identityPath(), "utf-8"));
109715
110056
  if (stored?.privateJwk) {
109716
110057
  cached3 = await importIdentity(stored.privateJwk);
109717
110058
  return cached3;
@@ -109721,10 +110062,10 @@ async function loadOrCreateDeviceIdentity() {
109721
110062
  const kp = await generateIdentityKeyPair(true);
109722
110063
  const { privateJwk, publicRaw } = await exportIdentity(kp);
109723
110064
  const dir2 = daemonDir2();
109724
- if (!existsSync32(dir2))
109725
- mkdirSync35(dir2, { recursive: true, mode: 448 });
110065
+ if (!existsSync33(dir2))
110066
+ mkdirSync36(dir2, { recursive: true, mode: 448 });
109726
110067
  const tmp = `${identityPath()}.tmp`;
109727
- writeFileSync34(tmp, JSON.stringify({ privateJwk, publicRaw, alg: "P256-ECDSA" }, null, 2), { mode: 384 });
110068
+ writeFileSync35(tmp, JSON.stringify({ privateJwk, publicRaw, alg: "P256-ECDSA" }, null, 2), { mode: 384 });
109728
110069
  renameSync10(tmp, identityPath());
109729
110070
  try {
109730
110071
  chmodSync4(identityPath(), 384);
@@ -109735,7 +110076,7 @@ async function loadOrCreateDeviceIdentity() {
109735
110076
  }
109736
110077
  var sealingCached = null;
109737
110078
  function sealingPath() {
109738
- return join66(daemonDir2(), "sealing.json");
110079
+ return join67(daemonDir2(), "sealing.json");
109739
110080
  }
109740
110081
  var EC_DH = { name: "ECDH", namedCurve: "P-256" };
109741
110082
  async function loadOrCreateSealingKey() {
@@ -109743,7 +110084,7 @@ async function loadOrCreateSealingKey() {
109743
110084
  return sealingCached;
109744
110085
  const { subtle: subtle5 } = globalThis.crypto;
109745
110086
  try {
109746
- const stored = JSON.parse(readFileSync46(sealingPath(), "utf-8"));
110087
+ const stored = JSON.parse(readFileSync47(sealingPath(), "utf-8"));
109747
110088
  if (stored?.privateJwk && stored.publicRaw) {
109748
110089
  const privateKey = await subtle5.importKey("jwk", stored.privateJwk, EC_DH, true, ["deriveBits"]);
109749
110090
  sealingCached = { privateKey, publicRaw: unb64u(stored.publicRaw) };
@@ -109755,10 +110096,10 @@ async function loadOrCreateSealingKey() {
109755
110096
  const publicRaw = new Uint8Array(await subtle5.exportKey("raw", kp.publicKey));
109756
110097
  const privateJwk = await subtle5.exportKey("jwk", kp.privateKey);
109757
110098
  const dir2 = daemonDir2();
109758
- if (!existsSync32(dir2))
109759
- mkdirSync35(dir2, { recursive: true, mode: 448 });
110099
+ if (!existsSync33(dir2))
110100
+ mkdirSync36(dir2, { recursive: true, mode: 448 });
109760
110101
  const tmp = `${sealingPath()}.tmp`;
109761
- writeFileSync34(tmp, JSON.stringify({ privateJwk, publicRaw: b64u(publicRaw), alg: "P256-ECDH" }, null, 2), { mode: 384 });
110102
+ writeFileSync35(tmp, JSON.stringify({ privateJwk, publicRaw: b64u(publicRaw), alg: "P256-ECDH" }, null, 2), { mode: 384 });
109762
110103
  renameSync10(tmp, sealingPath());
109763
110104
  try {
109764
110105
  chmodSync4(sealingPath(), 384);
@@ -109855,6 +110196,7 @@ var BundleOfferLedger = class {
109855
110196
  init_dist6();
109856
110197
 
109857
110198
  // ../../packages/host-core/dist/mesh/netd-client.js
110199
+ import { existsSync as existsSync34, readdirSync as readdirSync12 } from "node:fs";
109858
110200
  import { connect as connect2 } from "node:net";
109859
110201
  import { platform as platform3 } from "node:process";
109860
110202
  var NETD_WIRE_VERSION = 2;
@@ -109867,6 +110209,17 @@ function netdEndpoint() {
109867
110209
  return "/var/run/tesseract-netd.sock";
109868
110210
  return "/run/tesseract-netd.sock";
109869
110211
  }
110212
+ function netdListening() {
110213
+ const ep = endpointOverride() ?? netdEndpoint();
110214
+ if (process.platform !== "win32")
110215
+ return existsSync34(ep);
110216
+ try {
110217
+ const name = ep.replace(/^\\\\\.\\pipe\\/, "");
110218
+ return readdirSync12("\\\\.\\pipe\\").includes(name);
110219
+ } catch {
110220
+ return false;
110221
+ }
110222
+ }
109870
110223
  function endpointOverride() {
109871
110224
  return process.env.CCB_NETD_SOCKET ?? null;
109872
110225
  }
@@ -110149,7 +110502,7 @@ var NetdEngine = class {
110149
110502
  p.relayed = p.relayed || relayed;
110150
110503
  this.#pendingEndpoints.set(k, p);
110151
110504
  }
110152
- startHandshake(staticPub, _nowMs) {
110505
+ #flushHint(staticPub) {
110153
110506
  const k = staticPub.toString("hex");
110154
110507
  const p = this.#pendingEndpoints.get(k) ?? { endpoints: [], relayed: false };
110155
110508
  this.#pendingEndpoints.delete(k);
@@ -110158,6 +110511,12 @@ var NetdEngine = class {
110158
110511
  this.#lastError = `hint: ${r.detail}`;
110159
110512
  });
110160
110513
  }
110514
+ startHandshake(staticPub, _nowMs) {
110515
+ this.#flushHint(staticPub);
110516
+ }
110517
+ ensureHandshake(staticPub, _nowMs) {
110518
+ this.#flushHint(staticPub);
110519
+ }
110161
110520
  /** No UDP here — netd owns the socket. Never called in practice; kept for the interface. */
110162
110521
  injectUdp(_pkt, _from, _nowMs) {
110163
110522
  }
@@ -110222,9 +110581,6 @@ var NetdEngine = class {
110222
110581
  }
110223
110582
  };
110224
110583
 
110225
- // ../../packages/host-core/dist/mesh/node.js
110226
- import { existsSync as existsSync34 } from "node:fs";
110227
-
110228
110584
  // ../../packages/host-core/dist/mesh/bundle-refresh.js
110229
110585
  init_dist6();
110230
110586
  var CONTEXT = "tsr-bundle-fetch-v1";
@@ -110261,13 +110617,13 @@ ${ts}`);
110261
110617
 
110262
110618
  // ../../packages/host-core/dist/mesh/config.js
110263
110619
  init_credentials();
110264
- import { chmodSync as chmodSync5, existsSync as existsSync33, mkdirSync as mkdirSync36, readdirSync as readdirSync12, readFileSync as readFileSync47, renameSync as renameSync11, rmSync as rmSync7, writeFileSync as writeFileSync35 } from "node:fs";
110265
- import { dirname as dirname31, join as join68 } from "node:path";
110620
+ import { chmodSync as chmodSync5, existsSync as existsSync35, mkdirSync as mkdirSync37, readdirSync as readdirSync13, readFileSync as readFileSync48, renameSync as renameSync11, rmSync as rmSync7, writeFileSync as writeFileSync36 } from "node:fs";
110621
+ import { dirname as dirname32, join as join69 } from "node:path";
110266
110622
  function meshDir() {
110267
- return join68(daemonDir2(), "mesh");
110623
+ return join69(daemonDir2(), "mesh");
110268
110624
  }
110269
110625
  function meshesDir() {
110270
- return join68(meshDir(), "meshes");
110626
+ return join69(meshDir(), "meshes");
110271
110627
  }
110272
110628
  var MESH_DIR_NAME_BYTES = 8;
110273
110629
  function meshDirName(genesisFp) {
@@ -110285,7 +110641,7 @@ function oneMeshDir(meshId) {
110285
110641
  if (!isMeshId(meshId)) {
110286
110642
  throw new Error(`not a mesh id: ${JSON.stringify(meshId.slice(0, 64))}`);
110287
110643
  }
110288
- return join68(meshesDir(), meshId);
110644
+ return join69(meshesDir(), meshId);
110289
110645
  }
110290
110646
  var LEGACY_MESH_ID = "legacy";
110291
110647
  var CERT_GENESIS_FP_OFFSET = 19;
@@ -110303,29 +110659,29 @@ var FILES = {
110303
110659
  local: "local.json"
110304
110660
  };
110305
110661
  function readIfPresent(name, dir2 = meshDir()) {
110306
- const p = join68(dir2, name);
110662
+ const p = join69(dir2, name);
110307
110663
  try {
110308
- return existsSync33(p) ? new Uint8Array(readFileSync47(p)) : void 0;
110664
+ return existsSync35(p) ? new Uint8Array(readFileSync48(p)) : void 0;
110309
110665
  } catch {
110310
110666
  return void 0;
110311
110667
  }
110312
110668
  }
110313
110669
  function migrateSingleMesh() {
110314
- const legacyGenesis = join68(meshDir(), FILES.genesis);
110315
- if (!existsSync33(legacyGenesis))
110670
+ const legacyGenesis = join69(meshDir(), FILES.genesis);
110671
+ if (!existsSync35(legacyGenesis))
110316
110672
  return null;
110317
110673
  const id = meshIdFromCert(readIfPresent(FILES.cert)) ?? LEGACY_MESH_ID;
110318
110674
  const dest = oneMeshDir(id);
110319
110675
  try {
110320
- mkdirSync36(dest, { recursive: true, mode: 448 });
110676
+ mkdirSync37(dest, { recursive: true, mode: 448 });
110321
110677
  chmodSync5(dest, 448);
110322
110678
  for (const f of Object.values(FILES)) {
110323
- const from = join68(meshDir(), f);
110324
- if (existsSync33(from))
110325
- renameSync11(from, join68(dest, f));
110679
+ const from = join69(meshDir(), f);
110680
+ if (existsSync35(from))
110681
+ renameSync11(from, join69(dest, f));
110326
110682
  }
110327
- const key2 = join68(dest, FILES.key);
110328
- if (existsSync33(key2))
110683
+ const key2 = join69(dest, FILES.key);
110684
+ if (existsSync35(key2))
110329
110685
  chmodSync5(key2, 384);
110330
110686
  } catch {
110331
110687
  return null;
@@ -110336,7 +110692,7 @@ function listMeshIds() {
110336
110692
  migrateSingleMesh();
110337
110693
  let names;
110338
110694
  try {
110339
- names = readdirSync12(meshesDir(), { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
110695
+ names = readdirSync13(meshesDir(), { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
110340
110696
  } catch {
110341
110697
  return [];
110342
110698
  }
@@ -110348,15 +110704,15 @@ function listMeshIds() {
110348
110704
  }
110349
110705
  function readLocal(meshId) {
110350
110706
  try {
110351
- return JSON.parse(readFileSync47(join68(oneMeshDir(meshId), FILES.local), "utf8"));
110707
+ return JSON.parse(readFileSync48(join69(oneMeshDir(meshId), FILES.local), "utf8"));
110352
110708
  } catch {
110353
110709
  return null;
110354
110710
  }
110355
110711
  }
110356
110712
  function writeLocal(meshId, state3) {
110357
110713
  try {
110358
- mkdirSync36(oneMeshDir(meshId), { recursive: true, mode: 448 });
110359
- writeFileSync35(join68(oneMeshDir(meshId), FILES.local), JSON.stringify(state3, null, 2), { mode: 384 });
110714
+ mkdirSync37(oneMeshDir(meshId), { recursive: true, mode: 448 });
110715
+ writeFileSync36(join69(oneMeshDir(meshId), FILES.local), JSON.stringify(state3, null, 2), { mode: 384 });
110360
110716
  } catch {
110361
110717
  }
110362
110718
  }
@@ -110389,8 +110745,8 @@ function loadMeshIdentity() {
110389
110745
  return first === void 0 ? null : loadMesh(first);
110390
110746
  }
110391
110747
  function writeSecret(name, bytes2, dir2 = meshDir()) {
110392
- const p = join68(dir2, name);
110393
- writeFileSync35(p, bytes2, { mode: 384 });
110748
+ const p = join69(dir2, name);
110749
+ writeFileSync36(p, bytes2, { mode: 384 });
110394
110750
  try {
110395
110751
  chmodSync5(p, 384);
110396
110752
  } catch {
@@ -110402,20 +110758,20 @@ function saveMeshIdentity(id) {
110402
110758
  saveMesh(meshId, id);
110403
110759
  return;
110404
110760
  }
110405
- mkdirSync36(meshDir(), { recursive: true, mode: 448 });
110761
+ mkdirSync37(meshDir(), { recursive: true, mode: 448 });
110406
110762
  try {
110407
110763
  chmodSync5(meshDir(), 448);
110408
110764
  } catch {
110409
110765
  }
110410
- writeFileSync35(join68(meshDir(), FILES.genesis), id.genesis);
110411
- writeFileSync35(join68(meshDir(), FILES.cert), id.cert);
110766
+ writeFileSync36(join69(meshDir(), FILES.genesis), id.genesis);
110767
+ writeFileSync36(join69(meshDir(), FILES.cert), id.cert);
110412
110768
  writeSecret(FILES.key, id.staticPrivate);
110413
110769
  if (id.bundle)
110414
- writeFileSync35(join68(meshDir(), FILES.bundle), id.bundle);
110770
+ writeFileSync36(join69(meshDir(), FILES.bundle), id.bundle);
110415
110771
  }
110416
110772
  function saveMesh(meshId, id) {
110417
110773
  const dir2 = oneMeshDir(meshId);
110418
- mkdirSync36(dir2, { recursive: true, mode: 448 });
110774
+ mkdirSync37(dir2, { recursive: true, mode: 448 });
110419
110775
  try {
110420
110776
  chmodSync5(meshDir(), 448);
110421
110777
  } catch {
@@ -110428,13 +110784,13 @@ function saveMesh(meshId, id) {
110428
110784
  chmodSync5(dir2, 448);
110429
110785
  } catch {
110430
110786
  }
110431
- writeFileSync35(join68(dir2, FILES.genesis), id.genesis);
110432
- writeFileSync35(join68(dir2, FILES.cert), id.cert);
110787
+ writeFileSync36(join69(dir2, FILES.genesis), id.genesis);
110788
+ writeFileSync36(join69(dir2, FILES.cert), id.cert);
110433
110789
  writeSecret(FILES.key, id.staticPrivate, dir2);
110434
110790
  if (id.sigPrivate)
110435
110791
  writeSecret(FILES.sigKey, id.sigPrivate, dir2);
110436
110792
  if (id.bundle)
110437
- writeFileSync35(join68(dir2, FILES.bundle), id.bundle);
110793
+ writeFileSync36(join69(dir2, FILES.bundle), id.bundle);
110438
110794
  if (readLocal(meshId) === null)
110439
110795
  writeLocal(meshId, { joinedAt: Date.now() });
110440
110796
  }
@@ -110444,13 +110800,13 @@ function removeMesh(meshId) {
110444
110800
  var STATUS_REFRESH_MS = 5e3;
110445
110801
  var STATUS_STALE_MS = 2e4;
110446
110802
  function statusPath(meshId) {
110447
- return meshId === void 0 ? join68(meshDir(), "status.json") : join68(oneMeshDir(meshId), "status.json");
110803
+ return meshId === void 0 ? join69(meshDir(), "status.json") : join69(oneMeshDir(meshId), "status.json");
110448
110804
  }
110449
110805
  function writeStatus(status2, meshId) {
110450
110806
  try {
110451
110807
  const p = statusPath(meshId);
110452
- mkdirSync36(dirname31(p), { recursive: true, mode: 448 });
110453
- writeFileSync35(p, JSON.stringify({ ...status2, at: Date.now() }, null, 2));
110808
+ mkdirSync37(dirname32(p), { recursive: true, mode: 448 });
110809
+ writeFileSync36(p, JSON.stringify({ ...status2, at: Date.now() }, null, 2));
110454
110810
  } catch {
110455
110811
  }
110456
110812
  }
@@ -110462,7 +110818,7 @@ function clearStatus(meshId) {
110462
110818
  }
110463
110819
  function readStatus(meshId) {
110464
110820
  try {
110465
- const raw = JSON.parse(readFileSync47(statusPath(meshId), "utf8"));
110821
+ const raw = JSON.parse(readFileSync48(statusPath(meshId), "utf8"));
110466
110822
  if (typeof raw.at !== "number")
110467
110823
  return null;
110468
110824
  return { ...raw, at: raw.at, stale: Date.now() - raw.at > STATUS_STALE_MS };
@@ -110474,8 +110830,8 @@ function cacheBundle(bundle, meshId) {
110474
110830
  try {
110475
110831
  const id = meshId ?? listMeshIds()[0];
110476
110832
  const dir2 = id === void 0 ? meshDir() : oneMeshDir(id);
110477
- mkdirSync36(dir2, { recursive: true, mode: 448 });
110478
- writeFileSync35(join68(dir2, FILES.bundle), bundle);
110833
+ mkdirSync37(dir2, { recursive: true, mode: 448 });
110834
+ writeFileSync36(join69(dir2, FILES.bundle), bundle);
110479
110835
  } catch {
110480
110836
  }
110481
110837
  }
@@ -110631,7 +110987,7 @@ function loadMeshCore() {
110631
110987
  }
110632
110988
  var meshCore = loadMeshCore();
110633
110989
  function meshEngineStatus() {
110634
- if (process.env.CCB_MESH_IN_DAEMON !== "1" && existsSync34(netdEndpoint())) {
110990
+ if (process.env.CCB_MESH_IN_DAEMON !== "1" && netdListening()) {
110635
110991
  return { available: true, reason: null };
110636
110992
  }
110637
110993
  return { available: meshCore.available === true, reason: meshCore.loadError ?? null };
@@ -110861,7 +111217,14 @@ var MeshNode = class {
110861
111217
  reason: "this machine was removed from the network \u2014 ask an admin for a new invitation"
110862
111218
  };
110863
111219
  }
110864
- const inNetd = process.env.CCB_MESH_IN_DAEMON !== "1" && existsSync34(netdEndpoint());
111220
+ const forcedInDaemon = process.env.CCB_MESH_IN_DAEMON === "1";
111221
+ const inNetd = !forcedInDaemon && netdListening();
111222
+ if (!inNetd && !forcedInDaemon) {
111223
+ return {
111224
+ ok: false,
111225
+ reason: "the network helper is not running, so nothing can open the tunnel \u2014 install it with `tesseract-agent net helper install`"
111226
+ };
111227
+ }
110865
111228
  if (!inNetd && !meshCore.available) {
110866
111229
  return { ok: false, reason: `mesh engine unavailable: ${meshCore.loadError ?? "no prebuilt"}` };
110867
111230
  }
@@ -111066,7 +111429,7 @@ var MeshNode = class {
111066
111429
  this.#peers.set(hex6, staticPub);
111067
111430
  }
111068
111431
  engine.addPath(staticPub, `${address}:${port}`, false);
111069
- engine.startHandshake(staticPub, Date.now());
111432
+ engine.ensureHandshake(staticPub, Date.now());
111070
111433
  this.#drain();
111071
111434
  } catch (e) {
111072
111435
  this.#lastError = e instanceof Error ? e.message : String(e);
@@ -111151,7 +111514,7 @@ var MeshNode = class {
111151
111514
  } catch {
111152
111515
  }
111153
111516
  }
111154
- engine.startHandshake(pk, Date.now());
111517
+ engine.ensureHandshake(pk, Date.now());
111155
111518
  break;
111156
111519
  }
111157
111520
  case "mesh:gone": {
@@ -111295,7 +111658,7 @@ var MeshNode = class {
111295
111658
  for (const e of p.endpoints)
111296
111659
  engine.addPath(pk, `${p.observedIp}:${e.port}`, false);
111297
111660
  }
111298
- engine.startHandshake(pk, Date.now());
111661
+ engine.ensureHandshake(pk, Date.now());
111299
111662
  const meshId = this.#engine?.meshId();
111300
111663
  try {
111301
111664
  if (meshId)
@@ -111610,7 +111973,7 @@ function startNodes(log9) {
111610
111973
  }
111611
111974
 
111612
111975
  // ../../packages/host-core/dist/drops/receive-ui.js
111613
- import { basename as basename12, dirname as dirname32 } from "node:path";
111976
+ import { basename as basename12, dirname as dirname33 } from "node:path";
111614
111977
  var log5 = (...a) => console.log("[drops]", ...a);
111615
111978
  function formatBytes(n) {
111616
111979
  if (!Number.isFinite(n) || n <= 0)
@@ -111675,7 +112038,7 @@ function initDropReceiveUi(deps = {}) {
111675
112038
  log5("reveal failed:", err2 instanceof Error ? err2.message : String(err2));
111676
112039
  }
111677
112040
  };
111678
- const open7 = () => {
112041
+ const open8 = () => {
111679
112042
  const el2 = electronModule();
111680
112043
  if (!el2)
111681
112044
  return;
@@ -111686,7 +112049,7 @@ function initDropReceiveUi(deps = {}) {
111686
112049
  title: "Files received",
111687
112050
  body: `${describe3(e)} \xB7 ${formatBytes(e.bytesDone)}`,
111688
112051
  actions: [{ id: "reveal", label: "Show in Finder" }, { id: "open", label: "Open" }],
111689
- onAction: (id) => id === "open" ? open7() : reveal(),
112052
+ onAction: (id) => id === "open" ? open8() : reveal(),
111690
112053
  // Clicking the banner body is the only reliable action on macOS (buttons need
111691
112054
  // an expanded banner and are suppressed under Focus), so make it do the useful
111692
112055
  // thing rather than nothing.
@@ -111704,7 +112067,7 @@ import { basename as basename13 } from "node:path";
111704
112067
  // ../../packages/host-core/dist/drops/paths.js
111705
112068
  init_base_paths();
111706
112069
  import { mkdir as mkdir14 } from "node:fs/promises";
111707
- import { join as join69 } from "node:path";
112070
+ import { join as join70 } from "node:path";
111708
112071
 
111709
112072
  // ../../packages/host-core/dist/drops/names.js
111710
112073
  var WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
@@ -111793,7 +112156,7 @@ function basenameOf(p) {
111793
112156
  function resolveDropsRoot() {
111794
112157
  const root = resolveHostRoot();
111795
112158
  const preferred = dropsDir();
111796
- return isInsideRoot(preferred, root) ? preferred : join69(root, "Drops");
112159
+ return isInsideRoot(preferred, root) ? preferred : join70(root, "Drops");
111797
112160
  }
111798
112161
  async function ensureDropsRoot() {
111799
112162
  const dir2 = resolveDropsRoot();
@@ -111809,7 +112172,7 @@ async function ensureDropDir(opts) {
111809
112172
  parts.push(sanitizeDropName(opts.sender, "Unknown sender"));
111810
112173
  if (!opts.singleItem && opts.label)
111811
112174
  parts.push(sanitizeDropName(opts.label, "Files"));
111812
- const dir2 = join69(...parts);
112175
+ const dir2 = join70(...parts);
111813
112176
  await mkdir14(dir2, { recursive: true });
111814
112177
  return dir2;
111815
112178
  }
@@ -111952,7 +112315,7 @@ function createDropHandler(deps) {
111952
112315
  // ../../packages/host-core/dist/drops/blob-fetch.js
111953
112316
  import { createWriteStream as createWriteStream2 } from "node:fs";
111954
112317
  import { mkdir as mkdir15, rm as rm5, chmod as chmod3 } from "node:fs/promises";
111955
- import { dirname as dirname33, join as join70 } from "node:path";
112318
+ import { dirname as dirname34, join as join71 } from "node:path";
111956
112319
  import { Readable as Readable2 } from "node:stream";
111957
112320
  import { pipeline } from "node:stream/promises";
111958
112321
 
@@ -112110,8 +112473,8 @@ async function fetchBlobDrop(opts) {
112110
112473
  if (opts.sealedKey) {
112111
112474
  if (!opts.sealingPrivate)
112112
112475
  throw new Error("This device has no sealing key, so it cannot open the transfer.");
112113
- const open7 = opts.openSeal ?? openFromPrivateKey;
112114
- contentKey = await open7(await opts.sealingPrivate(), opts.sealedKey, new TextEncoder().encode(opts.dropId));
112476
+ const open8 = opts.openSeal ?? openFromPrivateKey;
112477
+ contentKey = await open8(await opts.sealingPrivate(), opts.sealedKey, new TextEncoder().encode(opts.dropId));
112115
112478
  }
112116
112479
  const totalBytes = opts.items.reduce((n, i) => n + (i.kind === "file" ? i.size : 0), 0);
112117
112480
  let bytesDone = 0;
@@ -112124,7 +112487,7 @@ async function fetchBlobDrop(opts) {
112124
112487
  log7(`drop ${opts.dropId}: refusing directory "${item.rel}"`);
112125
112488
  continue;
112126
112489
  }
112127
- const abs = join70(opts.destDir, rel);
112490
+ const abs = join71(opts.destDir, rel);
112128
112491
  if (!isInsideRoot(abs, opts.destDir)) {
112129
112492
  log7(`drop ${opts.dropId}: refusing directory outside the destination`);
112130
112493
  continue;
@@ -112145,12 +112508,12 @@ async function fetchBlobDrop(opts) {
112145
112508
  log7(`drop ${opts.dropId}: refusing "${item.rel}"`);
112146
112509
  continue;
112147
112510
  }
112148
- let abs = join70(opts.destDir, rel);
112511
+ let abs = join71(opts.destDir, rel);
112149
112512
  if (!isInsideRoot(abs, opts.destDir)) {
112150
112513
  log7(`drop ${opts.dropId}: refusing a path outside the destination`);
112151
112514
  continue;
112152
112515
  }
112153
- await mkdir15(dirname33(abs), { recursive: true });
112516
+ await mkdir15(dirname34(abs), { recursive: true });
112154
112517
  abs = await uniqueDropPath(abs);
112155
112518
  const res = await fetchFn(new URL(item.url, opts.apiOrigin).toString(), { signal: opts.signal });
112156
112519
  if (!res.ok || !res.body)
@@ -112182,7 +112545,7 @@ async function fetchBlobDrop(opts) {
112182
112545
  }
112183
112546
 
112184
112547
  // ../../packages/host-core/dist/chat-agent.js
112185
- import { randomUUID as randomUUID28 } from "node:crypto";
112548
+ import { randomUUID as randomUUID29 } from "node:crypto";
112186
112549
  init_prompts();
112187
112550
  var TURN_TIMEOUT_MS = 4 * 6e4;
112188
112551
  var PARTIAL_INTERVAL_MS = 700;
@@ -112211,7 +112574,7 @@ function createChatAgentRunner(deps) {
112211
112574
  }
112212
112575
  async function runTurn(prompt2, onPartial) {
112213
112576
  const backend2 = await getSharedBackend();
112214
- const clientRequestId = `chat-agent-${randomUUID28()}`;
112577
+ const clientRequestId = `chat-agent-${randomUUID29()}`;
112215
112578
  return new Promise((resolve16, reject) => {
112216
112579
  let text12 = "";
112217
112580
  let settled = false;
@@ -112420,13 +112783,13 @@ var RdeskServerChannel = class {
112420
112783
  };
112421
112784
 
112422
112785
  // ../../packages/host-core/dist/rdesk/channel-client.js
112423
- import { readFileSync as readFileSync48 } from "node:fs";
112424
- import { join as join71 } from "node:path";
112786
+ import { readFileSync as readFileSync49 } from "node:fs";
112787
+ import { join as join72 } from "node:path";
112425
112788
  var RECONNECT_MS = 2e3;
112426
112789
  var CLAIM_RETRY_MS = 5e3;
112427
112790
  function readEndpoint(dir2, selfPid) {
112428
112791
  try {
112429
- const s = JSON.parse(readFileSync48(join71(dir2, "status.json"), "utf8"));
112792
+ const s = JSON.parse(readFileSync49(join72(dir2, "status.json"), "utf8"));
112430
112793
  if (selfPid && s.pid === selfPid)
112431
112794
  return null;
112432
112795
  return s.localPort && s.localToken ? `ws://127.0.0.1:${s.localPort}/?token=${s.localToken}` : null;
@@ -112871,10 +113234,10 @@ function registerRdpEngine() {
112871
113234
  // ../../packages/host-core/dist/rdesk/audit.js
112872
113235
  init_credentials();
112873
113236
  import { appendFile, stat as stat9, rename as rename4 } from "node:fs/promises";
112874
- import { join as join72 } from "node:path";
113237
+ import { join as join73 } from "node:path";
112875
113238
  var MAX_BYTES2 = 2 * 1024 * 1024;
112876
113239
  function rdeskAuditPath() {
112877
- return join72(daemonDir2(), "rdesk-audit.jsonl");
113240
+ return join73(daemonDir2(), "rdesk-audit.jsonl");
112878
113241
  }
112879
113242
  var queue = [];
112880
113243
  var draining = false;
@@ -112916,13 +113279,13 @@ function appendRdeskAudit(e) {
112916
113279
 
112917
113280
  // ../../packages/host-core/dist/fileprovider-bridge.js
112918
113281
  init_managed_spawn();
112919
- import { writeFileSync as writeFileSync36, mkdirSync as mkdirSync37, rmSync as rmSync8, existsSync as existsSync35 } from "node:fs";
113282
+ import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync38, rmSync as rmSync8, existsSync as existsSync36 } from "node:fs";
112920
113283
  import { homedir as homedir10 } from "node:os";
112921
- import { join as join73 } from "node:path";
113284
+ import { join as join74 } from "node:path";
112922
113285
  init_safe_kill();
112923
113286
  var APPEX_BUNDLE_ID = "dev.tesseract.FileProvider";
112924
113287
  function appexBridgeInfoPath() {
112925
- return join73(homedir10(), "Library", "Containers", APPEX_BUNDLE_ID, "Data", "Library", "Application Support", "tesseract-bridge.json");
113288
+ return join74(homedir10(), "Library", "Containers", APPEX_BUNDLE_ID, "Data", "Library", "Application Support", "tesseract-bridge.json");
112926
113289
  }
112927
113290
  function clearBridgeInfo() {
112928
113291
  if (process.platform !== "darwin")
@@ -113087,9 +113450,9 @@ function stopFileProviderBridge() {
113087
113450
 
113088
113451
  // ../../packages/host-core/dist/vault/autofill-bridge.js
113089
113452
  import { randomBytes as randomBytes9 } from "node:crypto";
113090
- import { existsSync as existsSync36, mkdirSync as mkdirSync38, writeFileSync as writeFileSync37, rmSync as rmSync9 } from "node:fs";
113453
+ import { existsSync as existsSync37, mkdirSync as mkdirSync39, writeFileSync as writeFileSync38, rmSync as rmSync9 } from "node:fs";
113091
113454
  import { homedir as homedir11 } from "node:os";
113092
- import { join as join74 } from "node:path";
113455
+ import { join as join75 } from "node:path";
113093
113456
 
113094
113457
  // ../../packages/host-core/dist/vault/peer-verify.js
113095
113458
  import { execFile as execFile9 } from "node:child_process";
@@ -113151,10 +113514,10 @@ async function isTrustedAutofillPeer(remotePort) {
113151
113514
  var APPEX_BUNDLE_ID2 = "dev.tesseract.AutoFill";
113152
113515
  var BRIDGE_PORTS2 = [17872, 17873, 17874, 17875];
113153
113516
  function appexContainerData() {
113154
- return join74(homedir11(), "Library", "Containers", APPEX_BUNDLE_ID2, "Data");
113517
+ return join75(homedir11(), "Library", "Containers", APPEX_BUNDLE_ID2, "Data");
113155
113518
  }
113156
113519
  function bridgeInfoPath() {
113157
- return join74(appexContainerData(), "Library", "Application Support", "tesseract-autofill-bridge.json");
113520
+ return join75(appexContainerData(), "Library", "Application Support", "tesseract-autofill-bridge.json");
113158
113521
  }
113159
113522
  var infoLoggedOnce = false;
113160
113523
  function writeBridgeInfo(port, token3, log9) {
@@ -113162,16 +113525,16 @@ function writeBridgeInfo(port, token3, log9) {
113162
113525
  return;
113163
113526
  const containerData = appexContainerData();
113164
113527
  try {
113165
- if (!existsSync36(containerData)) {
113528
+ if (!existsSync37(containerData)) {
113166
113529
  if (!infoLoggedOnce) {
113167
113530
  infoLoggedOnce = true;
113168
113531
  log9("autofill bridge-info SKIP: no appex container yet at", containerData);
113169
113532
  }
113170
113533
  return;
113171
113534
  }
113172
- const dir2 = join74(containerData, "Library", "Application Support");
113173
- mkdirSync38(dir2, { recursive: true });
113174
- writeFileSync37(bridgeInfoPath(), JSON.stringify({ port, token: token3, pid: process.pid, ts: Date.now() }), { mode: 384 });
113535
+ const dir2 = join75(containerData, "Library", "Application Support");
113536
+ mkdirSync39(dir2, { recursive: true });
113537
+ writeFileSync38(bridgeInfoPath(), JSON.stringify({ port, token: token3, pid: process.pid, ts: Date.now() }), { mode: 384 });
113175
113538
  if (!infoLoggedOnce) {
113176
113539
  infoLoggedOnce = true;
113177
113540
  log9("autofill bridge-info WROTE", port, "\u2192", dir2);
@@ -113411,9 +113774,9 @@ function createNodePowerController() {
113411
113774
 
113412
113775
  // ../../packages/host-core/dist/native-host.js
113413
113776
  import { execFileSync as execFileSync4 } from "node:child_process";
113414
- import { chmodSync as chmodSync6, existsSync as existsSync37, mkdirSync as mkdirSync39, writeFileSync as writeFileSync38 } from "node:fs";
113777
+ import { chmodSync as chmodSync6, existsSync as existsSync38, mkdirSync as mkdirSync40, writeFileSync as writeFileSync39 } from "node:fs";
113415
113778
  import { homedir as homedir12, platform as platform5 } from "node:os";
113416
- import { dirname as dirname34, join as join75, resolve as resolve12 } from "node:path";
113779
+ import { dirname as dirname35, join as join76, resolve as resolve12 } from "node:path";
113417
113780
  import { fileURLToPath as fileURLToPath6 } from "node:url";
113418
113781
  var HOST_NAME = "com.tesseract.companion";
113419
113782
  var EXTENSION_IDS = ["icpnghhpcmaonjckkpilpajblfehpplo", "giolfpookdhjfafcchaflhmigghaeffn"];
@@ -113422,41 +113785,41 @@ function browserProfileDirs() {
113422
113785
  const home = homedir12();
113423
113786
  const p = platform5();
113424
113787
  if (p === "darwin") {
113425
- const base = join75(home, "Library/Application Support");
113426
- return ["Google/Chrome", "Google/Chrome Beta", "Google/Chrome Dev", "Google/Chrome Canary", "Chromium", "Microsoft Edge", "BraveSoftware/Brave-Browser", "Vivaldi", "Arc"].map((b) => join75(base, b));
113788
+ const base = join76(home, "Library/Application Support");
113789
+ return ["Google/Chrome", "Google/Chrome Beta", "Google/Chrome Dev", "Google/Chrome Canary", "Chromium", "Microsoft Edge", "BraveSoftware/Brave-Browser", "Vivaldi", "Arc"].map((b) => join76(base, b));
113427
113790
  }
113428
113791
  if (p === "win32")
113429
113792
  return [];
113430
- const cfg2 = join75(home, ".config");
113431
- return ["google-chrome", "google-chrome-beta", "chromium", "microsoft-edge", "BraveSoftware/Brave-Browser", "vivaldi"].map((b) => join75(cfg2, b));
113793
+ const cfg2 = join76(home, ".config");
113794
+ return ["google-chrome", "google-chrome-beta", "chromium", "microsoft-edge", "BraveSoftware/Brave-Browser", "vivaldi"].map((b) => join76(cfg2, b));
113432
113795
  }
113433
113796
  function resolveBridge(log9) {
113434
113797
  const candidates = [
113435
113798
  process.env.CCB_COMPANION_HOST_JS,
113436
- process.resourcesPath ? join75(process.resourcesPath, "companion-host", BRIDGE_BASENAME) : void 0
113799
+ process.resourcesPath ? join76(process.resourcesPath, "companion-host", BRIDGE_BASENAME) : void 0
113437
113800
  ];
113438
113801
  try {
113439
- const here = dirname34(fileURLToPath6(import.meta.url));
113802
+ const here = dirname35(fileURLToPath6(import.meta.url));
113440
113803
  candidates.push(resolve12(here, "../../../apps/companion-host/dist", BRIDGE_BASENAME));
113441
113804
  candidates.push(resolve12(here, "../../apps/companion-host/dist", BRIDGE_BASENAME));
113442
113805
  } catch {
113443
113806
  }
113444
113807
  for (const c of candidates)
113445
- if (c && existsSync37(c))
113808
+ if (c && existsSync38(c))
113446
113809
  return c;
113447
113810
  log9("companion native-host: bridge not found; skipping registration (looked in", candidates.filter(Boolean).join(" , "), ")");
113448
113811
  return null;
113449
113812
  }
113450
113813
  function writeLauncher(daemonDir3, bridge, runtime) {
113451
113814
  const isWin = platform5() === "win32";
113452
- const launcher = join75(daemonDir3, isWin ? "companion-host.cmd" : "companion-host.sh");
113815
+ const launcher = join76(daemonDir3, isWin ? "companion-host.cmd" : "companion-host.sh");
113453
113816
  if (isWin) {
113454
- writeFileSync38(launcher, `@echo off\r
113817
+ writeFileSync39(launcher, `@echo off\r
113455
113818
  set ELECTRON_RUN_AS_NODE=1\r
113456
113819
  "${runtime}" "${bridge}" %*\r
113457
113820
  `);
113458
113821
  } else {
113459
- writeFileSync38(launcher, `#!/bin/sh
113822
+ writeFileSync39(launcher, `#!/bin/sh
113460
113823
  # Tesseract Companion native-messaging launcher (auto-written by the daemon).
113461
113824
  ELECTRON_RUN_AS_NODE=1 exec "${runtime}" "${bridge}" "$@"
113462
113825
  `);
@@ -113471,7 +113834,7 @@ function registerNativeHost(opts) {
113471
113834
  if (!bridge)
113472
113835
  return;
113473
113836
  const runtime = opts.runtime ?? process.execPath;
113474
- mkdirSync39(opts.daemonDir, { recursive: true });
113837
+ mkdirSync40(opts.daemonDir, { recursive: true });
113475
113838
  const launcher = writeLauncher(opts.daemonDir, bridge, runtime);
113476
113839
  const manifestJson = JSON.stringify({
113477
113840
  name: HOST_NAME,
@@ -113484,12 +113847,12 @@ function registerNativeHost(opts) {
113484
113847
  return registerWindows(opts.daemonDir, manifestJson, log9);
113485
113848
  let wrote = 0;
113486
113849
  for (const profile of browserProfileDirs()) {
113487
- if (!existsSync37(profile))
113850
+ if (!existsSync38(profile))
113488
113851
  continue;
113489
113852
  try {
113490
- const dir2 = join75(profile, "NativeMessagingHosts");
113491
- mkdirSync39(dir2, { recursive: true });
113492
- writeFileSync38(join75(dir2, `${HOST_NAME}.json`), manifestJson);
113853
+ const dir2 = join76(profile, "NativeMessagingHosts");
113854
+ mkdirSync40(dir2, { recursive: true });
113855
+ writeFileSync39(join76(dir2, `${HOST_NAME}.json`), manifestJson);
113493
113856
  wrote++;
113494
113857
  } catch {
113495
113858
  }
@@ -113501,8 +113864,8 @@ function registerNativeHost(opts) {
113501
113864
  }
113502
113865
  function registerWindows(daemonDir3, manifestJson, log9) {
113503
113866
  try {
113504
- const manifestPath = join75(daemonDir3, `${HOST_NAME}.json`);
113505
- writeFileSync38(manifestPath, manifestJson);
113867
+ const manifestPath = join76(daemonDir3, `${HOST_NAME}.json`);
113868
+ writeFileSync39(manifestPath, manifestJson);
113506
113869
  for (const root of ["Software\\Google\\Chrome", "Software\\Microsoft\\Edge", "Software\\BraveSoftware\\Brave-Browser"]) {
113507
113870
  try {
113508
113871
  execFileSync4("reg", ["add", `HKCU\\${root}\\NativeMessagingHosts\\${HOST_NAME}`, "/ve", "/t", "REG_SZ", "/d", manifestPath, "/f"], { stdio: "ignore" });
@@ -113520,10 +113883,10 @@ init_daemon_settings();
113520
113883
 
113521
113884
  // ../../packages/host-core/dist/activity/activity-tracker.js
113522
113885
  init_credentials();
113523
- import { promises as fsp, writeFileSync as writeFileSync39, mkdirSync as mkdirSync40, existsSync as existsSync38 } from "node:fs";
113524
- import { join as join76 } from "node:path";
113886
+ import { promises as fsp, writeFileSync as writeFileSync40, mkdirSync as mkdirSync41, existsSync as existsSync39 } from "node:fs";
113887
+ import { join as join77 } from "node:path";
113525
113888
  function activityProfilePath() {
113526
- return join76(daemonDir2(), "activity-profile.json");
113889
+ return join77(daemonDir2(), "activity-profile.json");
113527
113890
  }
113528
113891
  var MAX_APPS = 300;
113529
113892
  var MAX_AGE_DAYS = 120;
@@ -113598,7 +113961,7 @@ function createActivityTracker(opts = {}) {
113598
113961
  return;
113599
113962
  const key2 = front.bundleId || front.name;
113600
113963
  await ensureLoaded();
113601
- if (profile && Object.keys(profile.apps).length && !existsSync38(activityProfilePath())) {
113964
+ if (profile && Object.keys(profile.apps).length && !existsSync39(activityProfilePath())) {
113602
113965
  log9("activity profile cleared externally \u2014 resetting in-memory");
113603
113966
  profile = { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), apps: {} };
113604
113967
  }
@@ -113634,8 +113997,8 @@ function createActivityTracker(opts = {}) {
113634
113997
  if (profile) {
113635
113998
  pruneProfile(profile);
113636
113999
  profile.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
113637
- mkdirSync40(daemonDir2(), { recursive: true, mode: 448 });
113638
- writeFileSync39(activityProfilePath(), JSON.stringify(profile), { mode: 384 });
114000
+ mkdirSync41(daemonDir2(), { recursive: true, mode: 448 });
114001
+ writeFileSync40(activityProfilePath(), JSON.stringify(profile), { mode: 384 });
113639
114002
  dirty = 0;
113640
114003
  }
113641
114004
  } catch (e) {
@@ -113690,7 +114053,7 @@ init_credentials();
113690
114053
  // ../../packages/host-core/dist/error-report.js
113691
114054
  init_dist2();
113692
114055
  init_credentials();
113693
- import { randomUUID as randomUUID29 } from "node:crypto";
114056
+ import { randomUUID as randomUUID30 } from "node:crypto";
113694
114057
  import { release as osRelease, arch as osArch } from "node:os";
113695
114058
  var MAX_QUEUE = 100;
113696
114059
  var FLUSH_INTERVAL_MS = 3e4;
@@ -113742,7 +114105,7 @@ function captureDaemonError(error51, opts = {}) {
113742
114105
  return;
113743
114106
  const creds3 = readCredentials();
113744
114107
  const report = {
113745
- reportId: randomUUID29(),
114108
+ reportId: randomUUID30(),
113746
114109
  occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
113747
114110
  schemaVersion: 1,
113748
114111
  surface,
@@ -113839,8 +114202,8 @@ async function runDaemon(opts = {}) {
113839
114202
  log9("paths", JSON.stringify(sealBasePaths()));
113840
114203
  const OUR_STARTED_AT = procStartedAt(process.pid);
113841
114204
  let ownsMachine = false;
113842
- const pidfile = () => join77(daemonDir2(), "daemon.lock");
113843
- const statusFile = () => join77(daemonDir2(), "status.json");
114205
+ const pidfile = () => join78(daemonDir2(), "daemon.lock");
114206
+ const statusFile = () => join78(daemonDir2(), "status.json");
113844
114207
  const isAlive2 = (pid) => {
113845
114208
  if (!Number.isFinite(pid) || pid <= 0)
113846
114209
  return false;
@@ -113853,7 +114216,7 @@ async function runDaemon(opts = {}) {
113853
114216
  };
113854
114217
  const lockHeldByAnother = () => {
113855
114218
  try {
113856
- const pid = Number(readFileSync49(pidfile(), "utf-8").trim());
114219
+ const pid = Number(readFileSync50(pidfile(), "utf-8").trim());
113857
114220
  return Number.isFinite(pid) && pid > 0 && pid !== process.pid && isAlive2(pid);
113858
114221
  } catch {
113859
114222
  return false;
@@ -113861,7 +114224,7 @@ async function runDaemon(opts = {}) {
113861
114224
  };
113862
114225
  const lockHeldByYieldingSubset = () => {
113863
114226
  try {
113864
- const pid = Number(readFileSync49(pidfile(), "utf-8").trim());
114227
+ const pid = Number(readFileSync50(pidfile(), "utf-8").trim());
113865
114228
  if (!Number.isFinite(pid) || pid <= 0 || pid === process.pid || !isAlive2(pid))
113866
114229
  return false;
113867
114230
  return liveDaemons().some((d) => d.pid === pid && d.rdeskOnly === true);
@@ -113872,22 +114235,22 @@ async function runDaemon(opts = {}) {
113872
114235
  function acquireLock2() {
113873
114236
  const f = pidfile();
113874
114237
  try {
113875
- if (!existsSync39(daemonDir2()))
113876
- mkdirSync41(daemonDir2(), { recursive: true, mode: 448 });
114238
+ if (!existsSync40(daemonDir2()))
114239
+ mkdirSync42(daemonDir2(), { recursive: true, mode: 448 });
113877
114240
  } catch {
113878
114241
  }
113879
114242
  for (let attempt = 0; attempt < 2; attempt++) {
113880
114243
  try {
113881
- writeFileSync40(f, String(process.pid), { flag: "wx" });
114244
+ writeFileSync41(f, String(process.pid), { flag: "wx" });
113882
114245
  return true;
113883
114246
  } catch {
113884
114247
  try {
113885
- const prev = Number(readFileSync49(f, "utf-8").trim());
114248
+ const prev = Number(readFileSync50(f, "utf-8").trim());
113886
114249
  if (!prev)
113887
114250
  return false;
113888
114251
  if (prev !== process.pid && isAlive2(prev))
113889
114252
  return false;
113890
- unlinkSync6(f);
114253
+ unlinkSync7(f);
113891
114254
  } catch {
113892
114255
  return false;
113893
114256
  }
@@ -113898,8 +114261,8 @@ async function runDaemon(opts = {}) {
113898
114261
  function releaseLock() {
113899
114262
  try {
113900
114263
  const f = pidfile();
113901
- if (existsSync39(f) && Number(readFileSync49(f, "utf-8").trim()) === process.pid)
113902
- unlinkSync6(f);
114264
+ if (existsSync40(f) && Number(readFileSync50(f, "utf-8").trim()) === process.pid)
114265
+ unlinkSync7(f);
113903
114266
  } catch {
113904
114267
  }
113905
114268
  }
@@ -113908,7 +114271,7 @@ async function runDaemon(opts = {}) {
113908
114271
  if (!ownsMachine)
113909
114272
  return;
113910
114273
  try {
113911
- writeFileSync40(statusFile(), JSON.stringify({ pid: process.pid, startedAt: OUR_STARTED_AT, role: process.env.CCB_RDESK_ROLE ?? "host", version: VERSION3, execPath: process.env.CCB_DAEMON_EXECPATH ?? process.execPath, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), gui: daemonGuiTrayActive(), ...localInfo ?? {}, ...s }));
114274
+ writeFileSync41(statusFile(), JSON.stringify({ pid: process.pid, startedAt: OUR_STARTED_AT, role: process.env.CCB_RDESK_ROLE ?? "host", version: VERSION3, execPath: process.env.CCB_DAEMON_EXECPATH ?? process.execPath, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), gui: daemonGuiTrayActive(), ...localInfo ?? {}, ...s }));
113912
114275
  chmodSync7(statusFile(), 384);
113913
114276
  } catch {
113914
114277
  }
@@ -113966,6 +114329,7 @@ async function runDaemon(opts = {}) {
113966
114329
  apiOrigin: apiOriginForMachine(),
113967
114330
  backendOrigin: backendOriginForMachine(),
113968
114331
  isAllowedOrigin: isAllowedApiOrigin,
114332
+ deviceId: persistentDeviceId(),
113969
114333
  log: (msg) => log9(msg)
113970
114334
  });
113971
114335
  machine = m;
@@ -114417,6 +114781,7 @@ async function runDaemon(opts = {}) {
114417
114781
  apiOrigin: c.apiOrigin,
114418
114782
  backendOrigin: c.backendOrigin,
114419
114783
  isAllowedOrigin: isAllowedApiOrigin,
114784
+ deviceId: persistentDeviceId(),
114420
114785
  log: (m) => log9(m)
114421
114786
  });
114422
114787
  if (!next?.accessToken) {
@@ -114443,7 +114808,7 @@ async function runDaemon(opts = {}) {
114443
114808
  if (r.status === 401) {
114444
114809
  log9("device token no longer valid \u2014 dropping to local-only on restart");
114445
114810
  try {
114446
- unlinkSync6(join77(daemonDir2(), "credentials.json"));
114811
+ unlinkSync7(join78(daemonDir2(), "credentials.json"));
114447
114812
  } catch {
114448
114813
  }
114449
114814
  shutdown(0, "token-revoked-401");
@@ -114472,6 +114837,7 @@ async function runDaemon(opts = {}) {
114472
114837
  c = fresh;
114473
114838
  accessToken = fresh.accessToken;
114474
114839
  log9(`signed in as ${fresh.userId} \u2014 re-homing the control link to the account`);
114840
+ setControlLinkDeviceId(fresh.deviceId);
114475
114841
  refreshControlLink();
114476
114842
  return;
114477
114843
  }
@@ -114479,6 +114845,7 @@ async function runDaemon(opts = {}) {
114479
114845
  apiOrigin: c.apiOrigin,
114480
114846
  backendOrigin: c.backendOrigin,
114481
114847
  isAllowedOrigin: isAllowedApiOrigin,
114848
+ deviceId: persistentDeviceId(),
114482
114849
  log: (msg) => log9(msg)
114483
114850
  });
114484
114851
  if (!m?.accessToken) {
@@ -114489,6 +114856,7 @@ async function runDaemon(opts = {}) {
114489
114856
  c = { ...c, accessToken: m.accessToken, refreshSecret: "", dtid: "", userId: "", deviceId: m.deviceId, publicId: m.publicId, expiresAt: m.expiresAt ?? c.expiresAt };
114490
114857
  accessToken = m.accessToken;
114491
114858
  log9("signed out \u2014 this machine speaks for itself again");
114859
+ setControlLinkDeviceId(m.deviceId);
114492
114860
  refreshControlLink();
114493
114861
  });
114494
114862
  registerTesseractEngine({ getIceServers: () => fetchIceServers() });
@@ -114741,7 +115109,7 @@ async function runDaemon(opts = {}) {
114741
115109
  let freeTicks = 0;
114742
115110
  const lockHolder = () => {
114743
115111
  try {
114744
- return Number(readFileSync49(pidfile(), "utf-8").trim()) || 0;
115112
+ return Number(readFileSync50(pidfile(), "utf-8").trim()) || 0;
114745
115113
  } catch {
114746
115114
  return 0;
114747
115115
  }
@@ -114818,7 +115186,7 @@ async function runDaemon(opts = {}) {
114818
115186
  // open. getRdeskClientWebContents() is null for the SERVER / full-app daemon (no client
114819
115187
  // window) → those sends are no-ops, so this is inert outside the rdesk-client role.
114820
115188
  pushHosts: (hosts) => {
114821
- writeStatus2({ deviceId: c.deviceId, connected: true });
115189
+ writeStatus2({ deviceId: c.deviceId, ownHostId: ownHost(), connected: true });
114822
115190
  getRdeskClientWebContents()?.send("hostlink:hosts", hosts);
114823
115191
  },
114824
115192
  ownHostResolved: (own2) => {
@@ -114950,7 +115318,7 @@ async function runDaemon(opts = {}) {
114950
115318
  if (appPid > 0 && appPid !== process.pid) {
114951
115319
  const quitMarker = () => {
114952
115320
  try {
114953
- return Number(readFileSync49(join77(daemonDir2(), "app-quit.marker"), "utf-8").trim()) || 0;
115321
+ return Number(readFileSync50(join78(daemonDir2(), "app-quit.marker"), "utf-8").trim()) || 0;
114954
115322
  } catch {
114955
115323
  return 0;
114956
115324
  }
@@ -114975,7 +115343,7 @@ async function runDaemon(opts = {}) {
114975
115343
  log9(`desktop app (pid ${appPid}) is gone with NO clean-quit marker \u2014 reporting`);
114976
115344
  const tail3 = (name) => {
114977
115345
  try {
114978
- const buf = readFileSync49(join77(daemonDir2(), name), "utf-8");
115346
+ const buf = readFileSync50(join78(daemonDir2(), name), "utf-8");
114979
115347
  return buf.length > 4096 ? buf.slice(-4096) : buf;
114980
115348
  } catch {
114981
115349
  return void 0;
@@ -115006,14 +115374,14 @@ async function runDaemon(opts = {}) {
115006
115374
  }
115007
115375
  try {
115008
115376
  const DAEMON_LOG_CAP = 2 * 1024 * 1024;
115009
- const daemonLogFile = join77(daemonDir2(), "daemon.log");
115377
+ const daemonLogFile = join78(daemonDir2(), "daemon.log");
115010
115378
  const capTimer = setInterval(() => {
115011
115379
  try {
115012
- if (existsSync39(daemonLogFile) && statSync14(daemonLogFile).size > DAEMON_LOG_CAP) {
115013
- const buf = readFileSync49(daemonLogFile, "utf-8");
115380
+ if (existsSync40(daemonLogFile) && statSync15(daemonLogFile).size > DAEMON_LOG_CAP) {
115381
+ const buf = readFileSync50(daemonLogFile, "utf-8");
115014
115382
  const kept = `\u2026[daemon.log capped at ${(/* @__PURE__ */ new Date()).toISOString()}]\u2026
115015
115383
  ` + buf.slice(-DAEMON_LOG_CAP / 2);
115016
- writeFileSync40(daemonLogFile, kept);
115384
+ writeFileSync41(daemonLogFile, kept);
115017
115385
  }
115018
115386
  } catch {
115019
115387
  }
@@ -115323,15 +115691,15 @@ init_credentials();
115323
115691
 
115324
115692
  // ../../packages/host-core/dist/net-service/ensure-installed.js
115325
115693
  import { execFile as execFile14 } from "node:child_process";
115326
- import { existsSync as existsSync43 } from "node:fs";
115327
- import { dirname as dirname36, join as join81 } from "node:path";
115694
+ import { existsSync as existsSync44 } from "node:fs";
115695
+ import { dirname as dirname37, join as join82 } from "node:path";
115328
115696
  import { promisify as promisify10 } from "node:util";
115329
115697
 
115330
115698
  // ../../packages/host-core/dist/net-service/launchd-system.js
115331
115699
  import { spawn as spawn9 } from "node:child_process";
115332
- import { existsSync as existsSync40, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync41, rmSync as rmSync10, readFileSync as readFileSync50 } from "node:fs";
115700
+ import { existsSync as existsSync41, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync42, rmSync as rmSync10, readFileSync as readFileSync51 } from "node:fs";
115333
115701
  import { tmpdir as tmpdir6 } from "node:os";
115334
- import { join as join78 } from "node:path";
115702
+ import { join as join79 } from "node:path";
115335
115703
 
115336
115704
  // ../../packages/host-core/dist/net-service/owner-uid.js
115337
115705
  function installOwnerUid(env = process.env, self2 = typeof process.getuid === "function" ? process.getuid() : 0) {
@@ -115423,9 +115791,9 @@ ${args}
115423
115791
  <key>ProcessType</key>
115424
115792
  <string>Interactive</string>
115425
115793
  <key>StandardErrorPath</key>
115426
- <string>${xml(join78(spec.stateDir, "netd.log"))}</string>
115794
+ <string>${xml(join79(spec.stateDir, "netd.log"))}</string>
115427
115795
  <key>StandardOutPath</key>
115428
- <string>${xml(join78(spec.stateDir, "netd.log"))}</string>
115796
+ <string>${xml(join79(spec.stateDir, "netd.log"))}</string>
115429
115797
  </dict>
115430
115798
  </plist>
115431
115799
  `;
@@ -115438,10 +115806,10 @@ function runForCode(cmd, args) {
115438
115806
  });
115439
115807
  }
115440
115808
  async function elevate(script) {
115441
- const dir2 = mkdtempSync2(join78(tmpdir6(), "tesseract-netd-"));
115442
- const path6 = join78(dir2, "install.sh");
115809
+ const dir2 = mkdtempSync2(join79(tmpdir6(), "tesseract-netd-"));
115810
+ const path6 = join79(dir2, "install.sh");
115443
115811
  try {
115444
- writeFileSync41(path6, script, { mode: 384 });
115812
+ writeFileSync42(path6, script, { mode: 384 });
115445
115813
  if (await alreadyElevated()) {
115446
115814
  return { code: await runForCode("/bin/sh", [path6]), declined: false };
115447
115815
  }
@@ -115500,9 +115868,9 @@ ${plist}TESSERACT_PLIST_EOF`,
115500
115868
  };
115501
115869
  },
115502
115870
  async state() {
115503
- if (!existsSync40(PLIST))
115871
+ if (!existsSync41(PLIST))
115504
115872
  return { installed: false, running: false };
115505
- const owner = parseOwnerUid(readFileSync50(PLIST, "utf8"));
115873
+ const owner = parseOwnerUid(readFileSync51(PLIST, "utf8"));
115506
115874
  const running2 = await netdAvailable();
115507
115875
  return {
115508
115876
  installed: true,
@@ -115520,7 +115888,7 @@ ${plist}TESSERACT_PLIST_EOF`,
115520
115888
 
115521
115889
  // ../../packages/host-core/dist/net-service/systemd-system.js
115522
115890
  import { spawn as spawn11 } from "node:child_process";
115523
- import { existsSync as existsSync41, readFileSync as readFileSync51 } from "node:fs";
115891
+ import { existsSync as existsSync42, readFileSync as readFileSync52 } from "node:fs";
115524
115892
 
115525
115893
  // ../../packages/host-core/dist/service/exec.js
115526
115894
  import { execFile as execFile11, spawn as spawn10 } from "node:child_process";
@@ -115556,6 +115924,8 @@ async function elevated(script) {
115556
115924
  }
115557
115925
  var UNIT = "tesseract-netd.service";
115558
115926
  var UNIT_PATH = `/etc/systemd/system/${UNIT}`;
115927
+ var SYSTEM_EXEC_DIR = "/usr/local/libexec/tesseract-netd";
115928
+ var SYSTEM_EXEC = `${SYSTEM_EXEC_DIR}/tesseract-netd`;
115559
115929
  function unitVal(v) {
115560
115930
  return v.replace(/%/g, "%%");
115561
115931
  }
@@ -115627,8 +115997,12 @@ WantedBy=multi-user.target
115627
115997
  function buildInstallScript(spec) {
115628
115998
  return [
115629
115999
  `install -d -m 0700 ${sh2(spec.stateDir)}`,
116000
+ // Copy the helper to the root-owned system path and run it from there — see SYSTEM_EXEC.
116001
+ // BEFORE the unit is written and started, so the ExecStart it names already exists.
116002
+ `install -d -m 0755 ${sh2(SYSTEM_EXEC_DIR)}`,
116003
+ `install -m 0755 ${sh2(spec.exec)} ${sh2(SYSTEM_EXEC)}`,
115630
116004
  `cat > ${sh2(UNIT_PATH)} <<'TESSERACT_UNIT_EOF'
115631
- ${buildUnit(spec)}TESSERACT_UNIT_EOF`,
116005
+ ${buildUnit({ ...spec, exec: SYSTEM_EXEC })}TESSERACT_UNIT_EOF`,
115632
116006
  "systemctl daemon-reload",
115633
116007
  `systemctl enable ${UNIT}`,
115634
116008
  // RESTART, not `enable --now`. `--now` only STARTS, so on a REINSTALL it leaves the
@@ -115657,15 +116031,19 @@ function makeSystemdSystem() {
115657
116031
  const script = [
115658
116032
  `systemctl disable --now ${UNIT} || true`,
115659
116033
  `rm -f ${sh2(UNIT_PATH)}`,
116034
+ // The copied binary too — see SYSTEM_EXEC. Leaving a root-owned setuid-adjacent
116035
+ // binary behind after an uninstall is exactly the kind of thing a security review
116036
+ // flags, and it is ours to clean up.
116037
+ `rm -rf ${sh2(SYSTEM_EXEC_DIR)}`,
115660
116038
  "systemctl daemon-reload"
115661
116039
  ].join("\n");
115662
116040
  const code = await elevated(script);
115663
116041
  return code === 0 ? { ok: true } : { ok: false, detail: `removing the helper failed (exit ${code})` };
115664
116042
  },
115665
116043
  async state() {
115666
- if (!existsSync41(UNIT_PATH))
116044
+ if (!existsSync42(UNIT_PATH))
115667
116045
  return { installed: false, running: false };
115668
- const owner = parseOwnerUid(readFileSync51(UNIT_PATH, "utf8"));
116046
+ const owner = parseOwnerUid(readFileSync52(UNIT_PATH, "utf8"));
115669
116047
  const active = await tryRun("systemctl", ["is-active", UNIT]);
115670
116048
  const running2 = active.stdout.trim() === "active";
115671
116049
  const own2 = owner === void 0 ? {} : { ownerUid: owner };
@@ -115690,9 +116068,9 @@ function sh2(s) {
115690
116068
 
115691
116069
  // ../../packages/host-core/dist/net-service/windows-service.js
115692
116070
  import { execFile as execFile12, spawn as spawn12 } from "node:child_process";
115693
- import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync42, rmSync as rmSync11 } from "node:fs";
116071
+ import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync43, rmSync as rmSync11 } from "node:fs";
115694
116072
  import { tmpdir as tmpdir7 } from "node:os";
115695
- import { join as join79 } from "node:path";
116073
+ import { join as join80 } from "node:path";
115696
116074
  import { promisify as promisify8 } from "node:util";
115697
116075
  var run6 = promisify8(execFile12);
115698
116076
  var SERVICE = "TesseractNetd";
@@ -115720,9 +116098,9 @@ function buildBinaryPath(spec) {
115720
116098
  return parts.map((p) => `"${p}"`).join(" ");
115721
116099
  }
115722
116100
  async function elevatePowerShell(script) {
115723
- const dir2 = mkdtempSync3(join79(tmpdir7(), "tesseract-netd-"));
115724
- const inner = join79(dir2, "install.ps1");
115725
- writeFileSync42(inner, script, { encoding: "utf8" });
116101
+ const dir2 = mkdtempSync3(join80(tmpdir7(), "tesseract-netd-"));
116102
+ const inner = join80(dir2, "install.ps1");
116103
+ writeFileSync43(inner, script, { encoding: "utf8" });
115726
116104
  if (await alreadyElevated()) {
115727
116105
  return new Promise((resolve16) => {
115728
116106
  const p = spawn12("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", inner], { stdio: "inherit" });
@@ -115737,8 +116115,8 @@ async function elevatePowerShell(script) {
115737
116115
  p.on("close", (code) => finish(code ?? 1));
115738
116116
  });
115739
116117
  }
115740
- const outer = join79(dir2, "elevate.ps1");
115741
- writeFileSync42(outer, [
116118
+ const outer = join80(dir2, "elevate.ps1");
116119
+ writeFileSync43(outer, [
115742
116120
  '$ErrorActionPreference = "Stop"',
115743
116121
  "try {",
115744
116122
  ` $p = Start-Process -FilePath "powershell.exe" -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File",${ps(inner)}) -Verb RunAs -Wait -PassThru`,
@@ -115926,15 +116304,15 @@ function makeNetService() {
115926
116304
  }
115927
116305
 
115928
116306
  // ../../packages/host-core/dist/net-service/netd-binary.js
115929
- import { existsSync as existsSync42 } from "node:fs";
115930
- import { dirname as dirname35, join as join80 } from "node:path";
116307
+ import { existsSync as existsSync43 } from "node:fs";
116308
+ import { dirname as dirname36, join as join81 } from "node:path";
115931
116309
  import { fileURLToPath as fileURLToPath7 } from "node:url";
115932
116310
  function netdBinaryName() {
115933
116311
  return process.platform === "win32" ? "tesseract-netd.exe" : "tesseract-netd";
115934
116312
  }
115935
116313
  function override2() {
115936
116314
  const p = process.env.CCB_NETD_BIN;
115937
- return p && existsSync42(p) ? p : null;
116315
+ return p && existsSync43(p) ? p : null;
115938
116316
  }
115939
116317
  function netdBinaryPath() {
115940
116318
  const fromEnv = override2();
@@ -115944,24 +116322,24 @@ function netdBinaryPath() {
115944
116322
  const candidates = [];
115945
116323
  const resources = process.resourcesPath;
115946
116324
  if (resources)
115947
- candidates.push(join80(resources, "netd", name));
116325
+ candidates.push(join81(resources, "netd", name));
115948
116326
  try {
115949
- const here = dirname35(fileURLToPath7(import.meta.url));
115950
- candidates.push(join80(here, "..", "..", "netd", name));
115951
- candidates.push(join80(here, "..", "..", "..", "netd", name));
116327
+ const here = dirname36(fileURLToPath7(import.meta.url));
116328
+ candidates.push(join81(here, "..", "..", "netd", name));
116329
+ candidates.push(join81(here, "..", "..", "..", "netd", name));
115952
116330
  const triple = `${process.platform}-${process.arch}`;
115953
- for (const root of [here, join80(here, ".."), join80(here, "..", "..")]) {
115954
- candidates.push(join80(root, "mesh-core", "prebuilds", triple, "netd", name));
116331
+ for (const root of [here, join81(here, ".."), join81(here, "..", "..")]) {
116332
+ candidates.push(join81(root, "mesh-core", "prebuilds", triple, "netd", name));
115955
116333
  }
115956
116334
  } catch {
115957
116335
  }
115958
116336
  if (process.env.CCB_REPO_ROOT) {
115959
- candidates.push(join80(process.env.CCB_REPO_ROOT, "crates", "target", "release", name));
116337
+ candidates.push(join81(process.env.CCB_REPO_ROOT, "crates", "target", "release", name));
115960
116338
  }
115961
- candidates.push(join80(process.cwd(), "crates", "target", "release", name));
116339
+ candidates.push(join81(process.cwd(), "crates", "target", "release", name));
115962
116340
  for (const c of candidates) {
115963
116341
  try {
115964
- if (existsSync42(c))
116342
+ if (existsSync43(c))
115965
116343
  return c;
115966
116344
  } catch {
115967
116345
  }
@@ -116003,7 +116381,7 @@ async function ensureNetHelperInstalled() {
116003
116381
  if (st.installed && !mismatched)
116004
116382
  return { ok: true, already: true };
116005
116383
  const exec2 = netdBinaryPath();
116006
- if (exec2 && process.platform === "win32" && !existsSync43(join81(dirname36(exec2), "wintun.dll"))) {
116384
+ if (exec2 && process.platform === "win32" && !existsSync44(join82(dirname37(exec2), "wintun.dll"))) {
116007
116385
  return {
116008
116386
  ok: false,
116009
116387
  reason: "no-binary",
@@ -116055,8 +116433,8 @@ import { platform as platform6 } from "node:os";
116055
116433
 
116056
116434
  // ../../packages/host-core/dist/service/launchd.js
116057
116435
  init_credentials();
116058
- import { writeFileSync as writeFileSync43, existsSync as existsSync44, mkdirSync as mkdirSync42, unlinkSync as unlinkSync7 } from "node:fs";
116059
- import { dirname as dirname37, join as join82 } from "node:path";
116436
+ import { writeFileSync as writeFileSync44, existsSync as existsSync45, mkdirSync as mkdirSync43, unlinkSync as unlinkSync8 } from "node:fs";
116437
+ import { dirname as dirname38, join as join83 } from "node:path";
116060
116438
  import { homedir as homedir13, userInfo as userInfo2 } from "node:os";
116061
116439
  function xml2(s) {
116062
116440
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -116064,10 +116442,10 @@ function xml2(s) {
116064
116442
  function makeLaunchd(instanceId) {
116065
116443
  const suffix = instanceSuffix(instanceId);
116066
116444
  const label = SERVICE_LABEL_BASE + (suffix ? `.${suffix}` : "");
116067
- const plistPath = () => join82(homedir13(), "Library", "LaunchAgents", `${label}.plist`);
116445
+ const plistPath = () => join83(homedir13(), "Library", "LaunchAgents", `${label}.plist`);
116068
116446
  const domainTarget = () => `gui/${userInfo2().uid}`;
116069
116447
  const serviceTarget = () => `${domainTarget()}/${label}`;
116070
- const logFile = () => join82(daemonDir2(), "daemon.log");
116448
+ const logFile = () => join83(daemonDir2(), "daemon.log");
116071
116449
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
116072
116450
  function buildPlist2(spec) {
116073
116451
  const args = [spec.exec, ...spec.args].map((a) => ` <string>${xml2(a)}</string>`).join("\n");
@@ -116142,10 +116520,10 @@ ${env}
116142
116520
  };
116143
116521
  return {
116144
116522
  async install(spec) {
116145
- mkdirSync42(workDirOf(spec), { recursive: true });
116146
- mkdirSync42(dirname37(plistPath()), { recursive: true });
116147
- mkdirSync42(dirname37(spec.logPath), { recursive: true });
116148
- writeFileSync43(plistPath(), buildPlist2(spec));
116523
+ mkdirSync43(workDirOf(spec), { recursive: true });
116524
+ mkdirSync43(dirname38(plistPath()), { recursive: true });
116525
+ mkdirSync43(dirname38(spec.logPath), { recursive: true });
116526
+ writeFileSync44(plistPath(), buildPlist2(spec));
116149
116527
  await run5("launchctl", ["bootout", serviceTarget()]).catch(() => {
116150
116528
  });
116151
116529
  await untilGone();
@@ -116161,9 +116539,9 @@ ${env}
116161
116539
  async uninstall() {
116162
116540
  await run5("launchctl", ["bootout", serviceTarget()]).catch(() => {
116163
116541
  });
116164
- if (existsSync44(plistPath())) {
116542
+ if (existsSync45(plistPath())) {
116165
116543
  try {
116166
- unlinkSync7(plistPath());
116544
+ unlinkSync8(plistPath());
116167
116545
  } catch {
116168
116546
  }
116169
116547
  }
@@ -116172,7 +116550,7 @@ ${env}
116172
116550
  await this.install(spec);
116173
116551
  },
116174
116552
  async isInstalled() {
116175
- return existsSync44(plistPath());
116553
+ return existsSync45(plistPath());
116176
116554
  },
116177
116555
  async start() {
116178
116556
  await run5("launchctl", ["bootstrap", domainTarget(), plistPath()]).catch(() => {
@@ -116189,7 +116567,7 @@ ${env}
116189
116567
  },
116190
116568
  async logs(follow) {
116191
116569
  const f = logFile();
116192
- if (!existsSync44(f)) {
116570
+ if (!existsSync45(f)) {
116193
116571
  console.log(`No log yet at ${f} \u2014 has the service started?`);
116194
116572
  return;
116195
116573
  }
@@ -116200,8 +116578,8 @@ ${env}
116200
116578
 
116201
116579
  // ../../packages/host-core/dist/service/systemd.js
116202
116580
  init_credentials();
116203
- import { writeFileSync as writeFileSync44, existsSync as existsSync45, mkdirSync as mkdirSync43, unlinkSync as unlinkSync8 } from "node:fs";
116204
- import { dirname as dirname38, join as join83 } from "node:path";
116581
+ import { writeFileSync as writeFileSync45, existsSync as existsSync46, mkdirSync as mkdirSync44, unlinkSync as unlinkSync9 } from "node:fs";
116582
+ import { dirname as dirname39, join as join84 } from "node:path";
116205
116583
  import { homedir as homedir14, userInfo as userInfo3 } from "node:os";
116206
116584
  function unitVal2(v) {
116207
116585
  return v.replace(/%/g, "%%");
@@ -116213,8 +116591,8 @@ function makeSystemd(instanceId) {
116213
116591
  const suffix = instanceSuffix(instanceId);
116214
116592
  const unit = `tesseract-host${suffix ? `-${suffix}` : ""}.service`;
116215
116593
  const unitPath = () => {
116216
- const base = process.env.XDG_CONFIG_HOME || join83(homedir14(), ".config");
116217
- return join83(base, "systemd", "user", unit);
116594
+ const base = process.env.XDG_CONFIG_HOME || join84(homedir14(), ".config");
116595
+ return join84(base, "systemd", "user", unit);
116218
116596
  };
116219
116597
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
116220
116598
  function buildUnit2(spec) {
@@ -116241,10 +116619,10 @@ WantedBy=default.target
116241
116619
  }
116242
116620
  return {
116243
116621
  async install(spec) {
116244
- mkdirSync43(workDirOf(spec), { recursive: true });
116245
- mkdirSync43(dirname38(unitPath()), { recursive: true });
116246
- mkdirSync43(dirname38(spec.logPath), { recursive: true });
116247
- writeFileSync44(unitPath(), buildUnit2(spec));
116622
+ mkdirSync44(workDirOf(spec), { recursive: true });
116623
+ mkdirSync44(dirname39(unitPath()), { recursive: true });
116624
+ mkdirSync44(dirname39(spec.logPath), { recursive: true });
116625
+ writeFileSync45(unitPath(), buildUnit2(spec));
116248
116626
  await run5("loginctl", ["enable-linger", userInfo3().username]).catch(() => {
116249
116627
  });
116250
116628
  await run5("systemctl", ["--user", "daemon-reload"]).catch(() => {
@@ -116256,9 +116634,9 @@ WantedBy=default.target
116256
116634
  async uninstall() {
116257
116635
  await run5("systemctl", ["--user", "disable", "--now", unit]).catch(() => {
116258
116636
  });
116259
- if (existsSync45(unitPath())) {
116637
+ if (existsSync46(unitPath())) {
116260
116638
  try {
116261
- unlinkSync8(unitPath());
116639
+ unlinkSync9(unitPath());
116262
116640
  } catch {
116263
116641
  }
116264
116642
  }
@@ -116269,7 +116647,7 @@ WantedBy=default.target
116269
116647
  await this.install(spec);
116270
116648
  },
116271
116649
  async isInstalled() {
116272
- return existsSync45(unitPath());
116650
+ return existsSync46(unitPath());
116273
116651
  },
116274
116652
  async start() {
116275
116653
  await run5("systemctl", ["--user", "start", unit]);
@@ -116281,8 +116659,8 @@ WantedBy=default.target
116281
116659
  await runInherit("systemctl", ["--user", "status", unit, "--no-pager"]);
116282
116660
  },
116283
116661
  async logs(follow) {
116284
- const f = join83(daemonDir2(), "daemon.log");
116285
- if (existsSync45(f)) {
116662
+ const f = join84(daemonDir2(), "daemon.log");
116663
+ if (existsSync46(f)) {
116286
116664
  await runInherit("tail", follow ? ["-f", f] : ["-n", "200", f]);
116287
116665
  return;
116288
116666
  }
@@ -116294,12 +116672,12 @@ WantedBy=default.target
116294
116672
 
116295
116673
  // ../../packages/host-core/dist/service/windows.js
116296
116674
  init_credentials();
116297
- import { writeFileSync as writeFileSync45, existsSync as existsSync46, mkdirSync as mkdirSync44, unlinkSync as unlinkSync9, readFileSync as readFileSync52 } from "node:fs";
116298
- import { dirname as dirname39, join as join84 } from "node:path";
116675
+ import { writeFileSync as writeFileSync46, existsSync as existsSync47, mkdirSync as mkdirSync45, unlinkSync as unlinkSync10, readFileSync as readFileSync53 } from "node:fs";
116676
+ import { dirname as dirname40, join as join85 } from "node:path";
116299
116677
  function publishedDaemonPid(dir2) {
116300
116678
  for (const f of ["status.json", "daemon.lock"]) {
116301
116679
  try {
116302
- const raw = readFileSync52(join84(dir2, f), "utf-8");
116680
+ const raw = readFileSync53(join85(dir2, f), "utf-8");
116303
116681
  const pid = f === "status.json" ? Number(JSON.parse(raw).pid) : Number(raw.trim());
116304
116682
  if (Number.isInteger(pid) && pid > 0)
116305
116683
  return pid;
@@ -116311,8 +116689,8 @@ function publishedDaemonPid(dir2) {
116311
116689
  function makeWindowsTask(instanceId) {
116312
116690
  const suffix = instanceSuffix(instanceId);
116313
116691
  const task = `Fineguide\\TesseractHost${suffix ? `-${suffix}` : ""}`;
116314
- const wrapperPath = () => join84(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
116315
- const logFile = () => join84(daemonDir2(), "daemon.log");
116692
+ const wrapperPath = () => join85(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
116693
+ const logFile = () => join85(daemonDir2(), "daemon.log");
116316
116694
  const oneLine2 = (s) => s.replace(/[\r\n]+/g, " ");
116317
116695
  const envVal = (v) => oneLine2(v).replace(/%/g, "%%").replace(/"/g, "");
116318
116696
  const cmdArg = (a) => `"${oneLine2(a).replace(/"/g, "")}"`;
@@ -116328,10 +116706,10 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
116328
116706
  }
116329
116707
  return {
116330
116708
  async install(spec) {
116331
- mkdirSync44(spec.workingDirectory ?? daemonDir2(), { recursive: true });
116332
- mkdirSync44(dirname39(spec.logPath), { recursive: true });
116333
- mkdirSync44(dirname39(wrapperPath()), { recursive: true });
116334
- writeFileSync45(wrapperPath(), buildWrapper(spec));
116709
+ mkdirSync45(spec.workingDirectory ?? daemonDir2(), { recursive: true });
116710
+ mkdirSync45(dirname40(spec.logPath), { recursive: true });
116711
+ mkdirSync45(dirname40(wrapperPath()), { recursive: true });
116712
+ writeFileSync46(wrapperPath(), buildWrapper(spec));
116335
116713
  await run5("schtasks", ["/Create", "/TN", task, "/SC", "ONLOGON", "/RL", "LIMITED", "/F", "/TR", `"${wrapperPath()}"`]);
116336
116714
  await run5("schtasks", ["/Run", "/TN", task]).catch(() => {
116337
116715
  });
@@ -116339,9 +116717,9 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
116339
116717
  async uninstall() {
116340
116718
  await run5("schtasks", ["/Delete", "/TN", task, "/F"]).catch(() => {
116341
116719
  });
116342
- if (existsSync46(wrapperPath())) {
116720
+ if (existsSync47(wrapperPath())) {
116343
116721
  try {
116344
- unlinkSync9(wrapperPath());
116722
+ unlinkSync10(wrapperPath());
116345
116723
  } catch {
116346
116724
  }
116347
116725
  }
@@ -116413,7 +116791,7 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
116413
116791
  },
116414
116792
  async logs(follow) {
116415
116793
  const f = logFile();
116416
- if (!existsSync46(f)) {
116794
+ if (!existsSync47(f)) {
116417
116795
  console.log(`No log yet at ${f} \u2014 has the task run?`);
116418
116796
  return;
116419
116797
  }
@@ -116444,9 +116822,9 @@ init_safe_kill();
116444
116822
 
116445
116823
  // src/auth.ts
116446
116824
  var import_qrcode_terminal = __toESM(require_main(), 1);
116447
- import { randomUUID as randomUUID30 } from "node:crypto";
116448
- import { existsSync as existsSync47, rmSync as rmSync12 } from "node:fs";
116449
- import { join as join85 } from "node:path";
116825
+ import { randomUUID as randomUUID31 } from "node:crypto";
116826
+ import { existsSync as existsSync48, rmSync as rmSync12 } from "node:fs";
116827
+ import { join as join86 } from "node:path";
116450
116828
 
116451
116829
  // src/config.ts
116452
116830
  import { hostname as hostname6 } from "node:os";
@@ -116586,7 +116964,7 @@ async function login(opts) {
116586
116964
  process.exit(1);
116587
116965
  }
116588
116966
  }
116589
- const deviceId3 = readCredentials()?.deviceId ?? process.env.CCB_DEVICE_ID ?? randomUUID30().slice(0, 8);
116967
+ const deviceId3 = readCredentials()?.deviceId ?? process.env.CCB_DEVICE_ID ?? randomUUID31().slice(0, 8);
116590
116968
  const label = opts.name ?? defaultLabel();
116591
116969
  if (opts.token) {
116592
116970
  const dt = await fetchJson(`${api}/auth/device-token`, {
@@ -116647,8 +117025,8 @@ async function logout() {
116647
117025
  }
116648
117026
  for (const f of ["credentials.json", "status.json", "daemon.lock"]) {
116649
117027
  try {
116650
- const p = join85(daemonDir2(), f);
116651
- if (existsSync47(p)) rmSync12(p);
117028
+ const p = join86(daemonDir2(), f);
117029
+ if (existsSync48(p)) rmSync12(p);
116652
117030
  } catch {
116653
117031
  }
116654
117032
  }
@@ -116806,9 +117184,9 @@ function startSelfUpdater(current) {
116806
117184
  }
116807
117185
 
116808
117186
  // src/service.ts
116809
- import { join as join86 } from "node:path";
117187
+ import { join as join87 } from "node:path";
116810
117188
  import { platform as platform7 } from "node:os";
116811
- import { existsSync as existsSync48, readFileSync as readFileSync53 } from "node:fs";
117189
+ import { existsSync as existsSync49, readFileSync as readFileSync54 } from "node:fs";
116812
117190
  function controller(instanceId) {
116813
117191
  const c = getServiceController(instanceId);
116814
117192
  if (!c) {
@@ -116821,7 +117199,7 @@ function buildSpec(cliEntry) {
116821
117199
  exec: process.execPath,
116822
117200
  args: [cliEntry, "run"],
116823
117201
  env: { CCB_DAEMON_DIR: daemonDir2() },
116824
- logPath: join86(daemonDir2(), "daemon.log")
117202
+ logPath: join87(daemonDir2(), "daemon.log")
116825
117203
  };
116826
117204
  }
116827
117205
  var isAlive = (pid) => {
@@ -116833,10 +117211,10 @@ var isAlive = (pid) => {
116833
117211
  }
116834
117212
  };
116835
117213
  function runningDaemonInfo() {
116836
- const lock = join86(daemonDir2(), "daemon.lock");
117214
+ const lock = join87(daemonDir2(), "daemon.lock");
116837
117215
  try {
116838
- if (!existsSync48(lock)) return null;
116839
- const pid = Number(readFileSync53(lock, "utf-8").trim());
117216
+ if (!existsSync49(lock)) return null;
117217
+ const pid = Number(readFileSync54(lock, "utf-8").trim());
116840
117218
  if (!pid || !isAlive(pid)) return null;
116841
117219
  return { pid, device: readCredentials()?.deviceId };
116842
117220
  } catch {
@@ -116870,7 +117248,7 @@ async function logs(instanceId, follow) {
116870
117248
  }
116871
117249
 
116872
117250
  // src/net.ts
116873
- import { readFileSync as readFileSync55 } from "node:fs";
117251
+ import { readFileSync as readFileSync56 } from "node:fs";
116874
117252
  import { randomBytes as randomBytes11 } from "node:crypto";
116875
117253
  import { hostname as hostname7 } from "node:os";
116876
117254
  import { resolve as resolve14 } from "node:path";
@@ -116935,7 +117313,7 @@ function readOrDie(label, p) {
116935
117313
  process.exit(1);
116936
117314
  }
116937
117315
  try {
116938
- return new Uint8Array(readFileSync55(resolve14(p)));
117316
+ return new Uint8Array(readFileSync56(resolve14(p)));
116939
117317
  } catch (e) {
116940
117318
  console.error(`net enroll: could not read --${label} ${p}: ${e instanceof Error ? e.message : e}`);
116941
117319
  process.exit(1);
@@ -117488,8 +117866,8 @@ async function netCommand(rest, flags) {
117488
117866
  // src/cli.ts
117489
117867
  function pkgVersion() {
117490
117868
  try {
117491
- const p = join88(dirname40(fileURLToPath8(import.meta.url)), "..", "package.json");
117492
- return JSON.parse(readFileSync56(p, "utf8")).version ?? "0.0.0";
117869
+ const p = join89(dirname41(fileURLToPath8(import.meta.url)), "..", "package.json");
117870
+ return JSON.parse(readFileSync57(p, "utf8")).version ?? "0.0.0";
117493
117871
  } catch {
117494
117872
  return "0.0.0";
117495
117873
  }
@@ -117717,7 +118095,7 @@ async function linkCommand(rest, flags) {
117717
118095
  process.exit(1);
117718
118096
  }
117719
118097
  async function captureClaudeSubscription(flags) {
117720
- const home = mkdtempSync4(join88(tmpdir8(), "tesseract-claude-login-"));
118098
+ const home = mkdtempSync4(join89(tmpdir8(), "tesseract-claude-login-"));
117721
118099
  const binary = typeof flags["claude-path"] === "string" ? flags["claude-path"] : process.env.CCB_ENGINE_PATH_CLAUDE_CODE || "claude";
117722
118100
  const args = ["auth", "login", "--claudeai"];
117723
118101
  if (typeof flags.email === "string") args.push("--email", flags.email);
@@ -117734,8 +118112,8 @@ async function captureClaudeSubscription(flags) {
117734
118112
  child.once("close", (exitCode, signal) => resolveCode(signal ? 1 : exitCode ?? 1));
117735
118113
  });
117736
118114
  if (code !== 0) throw new Error(`Claude sign-in did not complete (exit ${code}).`);
117737
- const file2 = join88(home, ".credentials.json");
117738
- if (existsSync50(file2)) return readFileSync56(file2, "utf8");
118115
+ const file2 = join89(home, ".credentials.json");
118116
+ if (existsSync51(file2)) return readFileSync57(file2, "utf8");
117739
118117
  if (process.platform === "darwin") {
117740
118118
  const value = execFileSync6("security", [
117741
118119
  "find-generic-password",
@@ -117817,7 +118195,7 @@ async function runnerCommand(rest, flags) {
117817
118195
  process.exit(1);
117818
118196
  }
117819
118197
  const oauthFilePath = typeof flags["oauth-file"] === "string" ? resolve15(flags["oauth-file"]) : void 0;
117820
- const oauthAuthFile = oauthFilePath ? readFileSync56(oauthFilePath, "utf8") : void 0;
118198
+ const oauthAuthFile = oauthFilePath ? readFileSync57(oauthFilePath, "utf8") : void 0;
117821
118199
  if (oauthAuthFile) {
117822
118200
  try {
117823
118201
  JSON.parse(oauthAuthFile);