tesseract-agent 0.11.3 → 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;
@@ -37923,6 +38002,9 @@ function setBrowserExtensionProbe(fn) {
37923
38002
  function isTurnBearingFrame(type) {
37924
38003
  return type === "assistant" || type === "stream_event" || type === "user";
37925
38004
  }
38005
+ function turnStillOpening(openedAt, now2) {
38006
+ return openedAt !== void 0 && now2 - openedAt < TURN_OPENING_GRACE_MS;
38007
+ }
37926
38008
  function findUserInstalledClaude(binName) {
37927
38009
  const home = homedir3();
37928
38010
  const abs = [
@@ -38814,7 +38896,7 @@ ${next}` : next;
38814
38896
  function autoDecisionSubject(prompt2) {
38815
38897
  return prompt2.kind === "permission" ? prompt2.tool : void 0;
38816
38898
  }
38817
- 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;
38818
38900
  var init_agent_manager = __esm({
38819
38901
  "../../packages/agent-core/dist/agent-manager.js"() {
38820
38902
  "use strict";
@@ -38874,6 +38956,7 @@ var init_agent_manager = __esm({
38874
38956
  init_stream_stall();
38875
38957
  init_usage_limit();
38876
38958
  browserExtensionConnected = () => false;
38959
+ TURN_OPENING_GRACE_MS = 5 * 6e4;
38877
38960
  SLIM_KEEP_RECENT_TURNS = 3;
38878
38961
  unsupportedCliOptions = /* @__PURE__ */ new Set();
38879
38962
  rejectedCliArgs = /* @__PURE__ */ new Map();
@@ -38944,7 +39027,7 @@ var init_agent_manager = __esm({
38944
39027
  TASK_REGISTER_SECONDS = 3;
38945
39028
  JOB_NOTICE_COALESCE_MS = 400;
38946
39029
  JOB_NOTICE_WORK_ID = "pending-job-notices";
38947
- QUIESCENCE_MAX_MS = 20 * 6e4;
39030
+ QUIESCENCE_MAX_MS = 12 * 60 * 6e4;
38948
39031
  QUIESCENCE_POLL_MS = 500;
38949
39032
  BATCH_WAIT_MS = 6e4;
38950
39033
  INLINE_TOOL_NAMES = /* @__PURE__ */ new Set([
@@ -40001,19 +40084,23 @@ ${full.slice(-8e3)}`;
40001
40084
  this.clearWorkNarration(live, narrated);
40002
40085
  return;
40003
40086
  }
40004
- const v = live.ledger.verdict(Date.now());
40087
+ const now2 = Date.now();
40088
+ live.ledger.sweep(now2);
40089
+ this.refreshLedgerFromRegistry(live, now2);
40090
+ const v = live.ledger.verdict(now2);
40005
40091
  if (v.quiescent)
40006
40092
  break;
40007
- if (Date.now() - started2 >= QUIESCENCE_MAX_MS) {
40093
+ if (now2 - started2 >= QUIESCENCE_MAX_MS) {
40008
40094
  cappedOut = true;
40009
40095
  break;
40010
40096
  }
40011
40097
  if (!narrated && live.sessionId) {
40012
40098
  narrated = true;
40099
+ const running2 = v.waiting.length + v.overdue.length;
40013
40100
  this.send({
40014
40101
  type: "agent:narration",
40015
40102
  sessionId: live.sessionId,
40016
- text: `Waiting for ${v.waiting.length} background ${v.waiting.length === 1 ? "task" : "tasks"} to finish\u2026`,
40103
+ text: `Waiting for ${running2} background ${running2 === 1 ? "task" : "tasks"} to finish\u2026`,
40017
40104
  engineLabel: "Claude Code"
40018
40105
  }, live.origin);
40019
40106
  }
@@ -40044,6 +40131,7 @@ ${full.slice(-8e3)}`;
40044
40131
  log(`[turn] ${live.sessionId || "(pending)"} started a turn on its own \u2014 marking busy`);
40045
40132
  live.streaming = true;
40046
40133
  live.turnSeq++;
40134
+ live.turnOpeningAt = void 0;
40047
40135
  live.lastActivity = Date.now();
40048
40136
  if (live.idleTimer) {
40049
40137
  clearTimeout(live.idleTimer);
@@ -42584,6 +42672,8 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42584
42672
  const parentToolUseId = message.parent_tool_use_id ?? void 0;
42585
42673
  if (!live.streaming && !live.reaped && isTurnBearingFrame(message.type))
42586
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();
42587
42677
  switch (message.type) {
42588
42678
  case "stream_event": {
42589
42679
  const event = message.event;
@@ -42726,6 +42816,8 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42726
42816
  }
42727
42817
  case "result": {
42728
42818
  this.emitLifecycle("Stop", { sessionId: sid, subtype: message.subtype ?? null });
42819
+ live.turnsDone = (live.turnsDone ?? 0) + 1;
42820
+ live.turnOpeningAt = void 0;
42729
42821
  flushPendingThinking();
42730
42822
  const r = message;
42731
42823
  const resultSid = r.session_id || "";
@@ -42935,6 +43027,7 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42935
43027
  const taskId = sstr(m.task_id);
42936
43028
  if (!taskId)
42937
43029
  break;
43030
+ live.ledger.touch(taskId, Date.now());
42938
43031
  const u = m.usage;
42939
43032
  emit2({
42940
43033
  type: "agent:task",
@@ -42973,6 +43066,8 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42973
43066
  if (status2 === "completed" || status2 === "failed" || status2 === "killed") {
42974
43067
  this.clearAutoBackground(live, taskId);
42975
43068
  live.taskIds.delete(taskId);
43069
+ } else {
43070
+ live.ledger.touch(taskId, Date.now());
42976
43071
  }
42977
43072
  break;
42978
43073
  }
@@ -42984,6 +43079,8 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
42984
43079
  case "background_tasks_changed": {
42985
43080
  const listed = new Set((Array.isArray(m.tasks) ? m.tasks : []).map((t) => sstr(t?.task_id)).filter(Boolean));
42986
43081
  live.taskIds = listed;
43082
+ for (const id of listed)
43083
+ live.ledger.touch(id, Date.now());
42987
43084
  break;
42988
43085
  }
42989
43086
  case "task_notification": {
@@ -43526,7 +43623,7 @@ ${err2.stack}` : ""}` : String(err2);
43526
43623
  // Blocked on its own background work. A turn that dispatched a build emits nothing while
43527
43624
  // it waits, and that silence is the intended behaviour — not a dead stream. Reads the
43528
43625
  // ledger, so it goes false on its own once every awaited item has passed its deadline.
43529
- awaitingWork: live.ledger.verdict(Date.now()).waiting.length > 0,
43626
+ awaitingWork: !live.ledger.verdict(Date.now()).quiescent,
43530
43627
  idleMs: monoNowMs() - (live.lastFrameAt ?? 0),
43531
43628
  windowMs: live.stallWindowMs ?? STREAM_STALL_MS
43532
43629
  });
@@ -43717,7 +43814,8 @@ ${err2.stack}` : ""}` : String(err2);
43717
43814
  for (const id of [...claimed])
43718
43815
  if (!live.ledger.has(id))
43719
43816
  claimed.delete(id);
43720
- 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 }));
43721
43819
  for (const w of watched)
43722
43820
  claimed.add(w.id);
43723
43821
  if (watched.length === 0)
@@ -43785,8 +43883,8 @@ ${lines.join("\n")}
43785
43883
  const fd = openSync5(path6, "r");
43786
43884
  try {
43787
43885
  const buf = Buffer.allocUnsafe(want);
43788
- const read = readSync4(fd, buf, 0, want, Math.max(0, size - want));
43789
- 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);
43790
43888
  } finally {
43791
43889
  closeSync5(fd);
43792
43890
  }
@@ -44291,10 +44389,12 @@ ${lines.join("\n")}
44291
44389
  hasWorkInFlight(live) {
44292
44390
  if (live.gradePending)
44293
44391
  return true;
44392
+ if (turnStillOpening(live.turnOpeningAt, Date.now()))
44393
+ return true;
44294
44394
  if ((live.awaitDepth ?? 0) > 0)
44295
44395
  return true;
44296
44396
  try {
44297
- if (live.ledger.verdict(Date.now()).waiting.length > 0)
44397
+ if (!live.ledger.verdict(Date.now()).quiescent)
44298
44398
  return true;
44299
44399
  } catch {
44300
44400
  }
@@ -44305,6 +44405,24 @@ ${lines.join("\n")}
44305
44405
  }
44306
44406
  return false;
44307
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
+ }
44308
44426
  reapIdleSession(sessionId, force = false) {
44309
44427
  const live = this.liveSessions.get(sessionId);
44310
44428
  if (!live || live.streaming || live.reaped)
@@ -46239,9 +46357,9 @@ function wrapHostedAsyncTool(t, opts) {
46239
46357
  return text11(raced.err instanceof Error ? raced.err.message : String(raced.err), true);
46240
46358
  opts.learnedSlow?.add(t.name);
46241
46359
  const sessionId = ctx2?.sessionId;
46242
- 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) => {
46243
46361
  try {
46244
- write2(await work);
46362
+ write3(await work);
46245
46363
  } catch (err2) {
46246
46364
  throw err2 instanceof Error ? err2 : new Error(String(err2));
46247
46365
  }
@@ -79569,7 +79687,7 @@ function alphabet(letters) {
79569
79687
  };
79570
79688
  }
79571
79689
  // @__NO_SIDE_EFFECTS__
79572
- function join67(separator = "") {
79690
+ function join68(separator = "") {
79573
79691
  astr("join", separator);
79574
79692
  return {
79575
79693
  encode: (from) => {
@@ -79774,7 +79892,7 @@ var init_esm = __esm({
79774
79892
  convertRadix2,
79775
79893
  radix,
79776
79894
  radix2,
79777
- join: join67,
79895
+ join: join68,
79778
79896
  padding
79779
79897
  };
79780
79898
  }
@@ -81321,8 +81439,8 @@ var mesh_ca_exports = {};
81321
81439
  __export(mesh_ca_exports, {
81322
81440
  netCaCommand: () => netCaCommand
81323
81441
  });
81324
- import { chmodSync as chmodSync8, existsSync as existsSync49, mkdirSync as mkdirSync45, readFileSync as readFileSync54, writeFileSync as writeFileSync46 } from "node:fs";
81325
- 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";
81326
81444
  import { createInterface as createInterface2 } from "node:readline";
81327
81445
  function die(msg) {
81328
81446
  console.error(msg);
@@ -81336,9 +81454,9 @@ async function readPassphrase(prompt2) {
81336
81454
  }
81337
81455
  const rl = createInterface2({ input: process.stdin, output: process.stdout, terminal: true });
81338
81456
  const out = process.stdout;
81339
- const write2 = out.write.bind(out);
81457
+ const write3 = out.write.bind(out);
81340
81458
  let muted = false;
81341
- out.write = (chunk) => muted ? true : write2(chunk);
81459
+ out.write = (chunk) => muted ? true : write3(chunk);
81342
81460
  process.stdout.write(prompt2);
81343
81461
  muted = true;
81344
81462
  try {
@@ -81348,33 +81466,33 @@ async function readPassphrase(prompt2) {
81348
81466
  }));
81349
81467
  } finally {
81350
81468
  muted = false;
81351
- out.write = write2;
81469
+ out.write = write3;
81352
81470
  process.stdout.write("\n");
81353
81471
  }
81354
81472
  }
81355
81473
  function writeSecretFile(p, bytes2) {
81356
- writeFileSync46(p, bytes2, { mode: 384 });
81474
+ writeFileSync47(p, bytes2, { mode: 384 });
81357
81475
  try {
81358
81476
  chmodSync8(p, 384);
81359
81477
  } catch {
81360
81478
  }
81361
81479
  }
81362
81480
  function ensureDir(p) {
81363
- mkdirSync45(p, { recursive: true, mode: 448 });
81481
+ mkdirSync46(p, { recursive: true, mode: 448 });
81364
81482
  try {
81365
81483
  chmodSync8(p, 448);
81366
81484
  } catch {
81367
81485
  }
81368
81486
  }
81369
81487
  async function openCa(dir2) {
81370
- const gPath = join87(dir2, "genesis.bin");
81371
- const sPath = join87(dir2, "ca.sealed");
81372
- 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)) {
81373
81491
  die(`No mesh CA in ${dir2}. Run: tesseract-agent net init --org NAME --ca-dir ${dir2}`);
81374
81492
  }
81375
- const genesisBytes = new Uint8Array(readFileSync54(gPath));
81493
+ const genesisBytes = new Uint8Array(readFileSync55(gPath));
81376
81494
  const genesis = decodeGenesis(genesisBytes);
81377
- const sealed = decodeRecoveryBundle(new Uint8Array(readFileSync54(sPath)));
81495
+ const sealed = decodeRecoveryBundle(new Uint8Array(readFileSync55(sPath)));
81378
81496
  const pass = await readPassphrase("CA passphrase: ");
81379
81497
  let seed;
81380
81498
  try {
@@ -81390,7 +81508,7 @@ async function netCaCommand(rest, flags) {
81390
81508
  if (sub === "init") {
81391
81509
  const org = typeof flags.org === "string" ? flags.org.trim() : "";
81392
81510
  if (!org) die("Usage: tesseract-agent net init --org NAME [--ca-dir DIR]");
81393
- if (existsSync49(join87(caDir, "ca.sealed"))) {
81511
+ if (existsSync50(join88(caDir, "ca.sealed"))) {
81394
81512
  die(`A mesh CA already exists in ${caDir}. Refusing to overwrite it.`);
81395
81513
  }
81396
81514
  const pass = await readPassphrase("New CA passphrase: ");
@@ -81412,9 +81530,9 @@ async function netCaCommand(rest, flags) {
81412
81530
  const genesisBytes = encodeGenesis(genesis);
81413
81531
  const fp = await genesisFingerprint(genesis);
81414
81532
  ensureDir(caDir);
81415
- writeFileSync46(join87(caDir, "genesis.bin"), genesisBytes);
81416
- writeSecretFile(join87(caDir, "ca.sealed"), encodeRecoveryBundle(await sealCaKey(seed, pass, `${org} mesh CA`)));
81417
- 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));
81418
81536
  console.log(`
81419
81537
  Mesh created for "${org}".`);
81420
81538
  console.log(` fingerprint: ${hex3(fp)}`);
@@ -81429,7 +81547,7 @@ Mesh created for "${org}".`);
81429
81547
  console.log(` ${hex3(disable.secret)}`);
81430
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");
81431
81549
  console.log(`
81432
- 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")}.`);
81433
81551
  console.log("Move it somewhere the CA directory is not \u2014 holding both in one place");
81434
81552
  console.log("defeats the point of having two.");
81435
81553
  const caFlag = caDir === resolve13("./mesh-ca") ? "" : ` --ca-dir ${caDir}`;
@@ -81482,14 +81600,14 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
81482
81600
  [{ keyIndex: 0, privateKey: ca.privateKey }]
81483
81601
  );
81484
81602
  ensureDir(outDir);
81485
- writeFileSync46(join87(outDir, "genesis.bin"), genesisBytes);
81486
- writeFileSync46(join87(outDir, "node.cert"), encodeCert(cert));
81487
- 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));
81488
81606
  console.log(`Minted "${name}" at ${ip4}.`);
81489
81607
  console.log(` ${outDir}`);
81490
81608
  console.log("\nCopy that directory to the node and run there:");
81491
- console.log(` tesseract-agent net enroll --genesis ${join87(outDir, "genesis.bin")} \\`);
81492
- 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")}`);
81493
81611
  console.log("\nnode.key is the node's identity \u2014 send it over a channel you trust, and");
81494
81612
  console.log("delete this copy once the node has it.");
81495
81613
  return;
@@ -81525,8 +81643,8 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
81525
81643
  ip4Exceptions: []
81526
81644
  };
81527
81645
  const signed = await signBundle(bundle, [{ keyIndex: 0, privateKey: ca.privateKey }]);
81528
- const out = resolve13(typeof flags.out === "string" ? flags.out : join87(caDir, "bundle.bin"));
81529
- writeFileSync46(out, encodeSignedBundle(signed));
81646
+ const out = resolve13(typeof flags.out === "string" ? flags.out : join88(caDir, "bundle.bin"));
81647
+ writeFileSync47(out, encodeSignedBundle(signed));
81530
81648
  console.log(`Signed policy bundle (epoch ${epoch2}) \u2192 ${out}`);
81531
81649
  console.log("Every node must receive it; the relay distributes it, or copy it to");
81532
81650
  console.log(`each node's mesh directory as bundle.bin.`);
@@ -81548,17 +81666,43 @@ var init_mesh_ca = __esm({
81548
81666
 
81549
81667
  // src/cli.ts
81550
81668
  init_base_paths();
81551
- 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";
81552
81670
  import { createHash as createHash9 } from "node:crypto";
81553
81671
  import { execFileSync as execFileSync6, spawn as spawn14 } from "node:child_process";
81554
81672
  import { fileURLToPath as fileURLToPath8 } from "node:url";
81555
81673
  import { tmpdir as tmpdir8 } from "node:os";
81556
- 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";
81557
81675
  import { createInterface as createInterface3 } from "node:readline/promises";
81558
81676
 
81559
81677
  // ../../packages/host-core/dist/control-link.js
81560
81678
  import { hostname as hostname4 } from "node:os";
81561
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
+
81562
81706
  // ../../packages/host-core/dist/engines/rewind-result.js
81563
81707
  var strings = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x.length > 0) : [];
81564
81708
  function toRewindOutcome(res, noHistory) {
@@ -81581,9 +81725,9 @@ function toRewindOutcome(res, noHistory) {
81581
81725
  }
81582
81726
 
81583
81727
  // ../../packages/host-core/dist/control-link.js
81584
- import { join as join60, basename as basename11 } from "node:path";
81585
- import { randomUUID as randomUUID24 } from "node:crypto";
81586
- 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";
81587
81731
 
81588
81732
  // ../../node_modules/ws/wrapper.mjs
81589
81733
  var import_stream = __toESM(require_stream(), 1);
@@ -84817,21 +84961,21 @@ function createMcpHealth(deps = {}) {
84817
84961
  let servers = {};
84818
84962
  const disabled2 = /* @__PURE__ */ new Set();
84819
84963
  const cache5 = /* @__PURE__ */ new Map();
84820
- const inflight = /* @__PURE__ */ new Map();
84964
+ const inflight2 = /* @__PURE__ */ new Map();
84821
84965
  async function probeCached(name, spec) {
84822
84966
  const hit = cache5.get(name);
84823
84967
  if (hit && now2() - hit.at < TTL_MS3)
84824
84968
  return hit.row;
84825
- const running2 = inflight.get(name);
84969
+ const running2 = inflight2.get(name);
84826
84970
  if (running2)
84827
84971
  return running2;
84828
84972
  const p = probe(name, spec).catch((e) => ({ name, status: "failed", error: e?.message ?? "probe failed" })).then((row) => {
84829
84973
  const full = { ...row, name };
84830
84974
  cache5.set(name, { at: now2(), row: full });
84831
- inflight.delete(name);
84975
+ inflight2.delete(name);
84832
84976
  return full;
84833
84977
  });
84834
- inflight.set(name, p);
84978
+ inflight2.set(name, p);
84835
84979
  return p;
84836
84980
  }
84837
84981
  return {
@@ -84851,7 +84995,7 @@ function createMcpHealth(deps = {}) {
84851
84995
  },
84852
84996
  async reconnect(name) {
84853
84997
  cache5.delete(name);
84854
- inflight.delete(name);
84998
+ inflight2.delete(name);
84855
84999
  if (servers[name] && !disabled2.has(name))
84856
85000
  await probeCached(name, servers[name]);
84857
85001
  },
@@ -84994,10 +85138,10 @@ function extractJson(text12) {
84994
85138
  }
84995
85139
  }
84996
85140
  for (let start3 = 0; start3 < text12.length; start3++) {
84997
- const open7 = text12[start3];
84998
- if (open7 !== "{" && open7 !== "[")
85141
+ const open8 = text12[start3];
85142
+ if (open8 !== "{" && open8 !== "[")
84999
85143
  continue;
85000
- const close = open7 === "{" ? "}" : "]";
85144
+ const close = open8 === "{" ? "}" : "]";
85001
85145
  let depth = 0;
85002
85146
  let inStr = false;
85003
85147
  let esc3 = false;
@@ -85016,7 +85160,7 @@ function extractJson(text12) {
85016
85160
  inStr = true;
85017
85161
  continue;
85018
85162
  }
85019
- if (ch === open7)
85163
+ if (ch === open8)
85020
85164
  depth++;
85021
85165
  else if (ch === close) {
85022
85166
  depth--;
@@ -89075,8 +89219,8 @@ ${text12}`;
89075
89219
  const t = await conn(threadCwd.get(sessionId) ?? spawnedCwd ?? projectDir ?? void 0);
89076
89220
  if (!t)
89077
89221
  return { ok: false, reason: `${label} is not reachable for this.` };
89078
- const read = await t.request("thread/read", { threadId: sessionId, includeTurns: true }).catch(() => null);
89079
- 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 ?? [];
89080
89224
  const at = turns2.findIndex((tn) => (tn.items ?? []).some((it) => it.id === uuid3));
89081
89225
  if (at < 0)
89082
89226
  return { ok: false, reason: `${label} no longer has that message.` };
@@ -90282,7 +90426,6 @@ var LAUNCH_MARKERS = [
90282
90426
  "CCB_FORCE_DAEMON_GUI",
90283
90427
  "CCB_HOST_DAEMON",
90284
90428
  "CCB_RDESK_ROLE",
90285
- "CCB_RDESK_SERVER",
90286
90429
  "CCB_RDESK_CLIENT",
90287
90430
  "CCB_RDESK_ONLY",
90288
90431
  "CCB_MESH_APP",
@@ -90297,7 +90440,7 @@ function mainAppChildEnv(env) {
90297
90440
  return out;
90298
90441
  }
90299
90442
  function ownBinaryIsMainApp(env) {
90300
- 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";
90301
90444
  }
90302
90445
 
90303
90446
  // ../../packages/host-core/dist/gui/dock-policy.js
@@ -91224,11 +91367,11 @@ var GUIDE_TOOLS = describedBy("tool.voice-guide", GUIDE_TOOL_SHAPES);
91224
91367
  var defaultGreeting = () => prompt("voice.greeting");
91225
91368
  function buildGuidePrompt(opts = {}) {
91226
91369
  const project = opts.projectName ? prompt("voice.guide.project-clause", { projectName: opts.projectName }) : "";
91227
- const open7 = (opts.sessions ?? []).map((s) => s.label?.trim()).filter((l) => !!l);
91228
- const openLine = open7.length > 0 ? prompt("voice.guide.open-sessions", {
91229
- count: open7.length,
91230
- plural: open7.length === 1 ? "" : "s",
91231
- 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(", "),
91232
91375
  toolStatus: TOOL_STATUS
91233
91376
  }) : "";
91234
91377
  return [
@@ -95868,8 +96011,8 @@ async function falTopazEnhance(path6, spec, opts) {
95868
96011
  const dir2 = opts.outDir ?? workDir();
95869
96012
  mkdirSync22(dir2, { recursive: true });
95870
96013
  const outPath = join43(dir2, "enhanced.mp4");
95871
- const { writeFileSync: writeFileSync47 } = await import("node:fs");
95872
- writeFileSync47(outPath, Buffer.from(await dl.arrayBuffer()));
96014
+ const { writeFileSync: writeFileSync48 } = await import("node:fs");
96015
+ writeFileSync48(outPath, Buffer.from(await dl.arrayBuffer()));
95873
96016
  const out = await probeMedia(outPath).catch(() => null);
95874
96017
  opts.onProgress?.(100, "Enhance complete");
95875
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}` };
@@ -99172,9 +99315,9 @@ async function startOutboundTransfer(msg, controllerClientId, ownHostId2, hostRo
99172
99315
  break;
99173
99316
  const len = Math.min(CHUNK2, f.size - offset);
99174
99317
  const buf = Buffer.alloc(len);
99175
- const read = readSync7(fd, buf, 0, len, offset);
99176
- 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 });
99177
- 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;
99178
99321
  }
99179
99322
  }
99180
99323
  } catch (e) {
@@ -99983,22 +100126,70 @@ init_credentials();
99983
100126
  // ../../packages/host-core/dist/rdesk/machine-identity.js
99984
100127
  init_credentials();
99985
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";
99986
100137
  import { randomUUID as randomUUID23 } from "node:crypto";
99987
- import { chmodSync as chmodSync3, existsSync as existsSync23, mkdirSync as mkdirSync26, readFileSync as readFileSync36, writeFileSync as writeFileSync24 } from "node:fs";
99988
- import { join as join53 } from "node:path";
99989
- 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");
99990
100181
  function readMachineIdentity() {
99991
100182
  try {
99992
- const m = JSON.parse(readFileSync36(FILE(), "utf-8"));
100183
+ const m = JSON.parse(readFileSync37(FILE(), "utf-8"));
99993
100184
  return m?.deviceToken && m?.publicId ? m : null;
99994
100185
  } catch {
99995
100186
  return null;
99996
100187
  }
99997
100188
  }
99998
- function write(m) {
100189
+ function write2(m) {
99999
100190
  try {
100000
- mkdirSync26(daemonDir2(), { recursive: true, mode: 448 });
100001
- 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 });
100002
100193
  chmodSync3(FILE(), 384);
100003
100194
  } catch {
100004
100195
  }
@@ -100024,30 +100215,100 @@ function tokenUsable(m) {
100024
100215
  const ms = Date.parse(m.expiresAt);
100025
100216
  return Number.isFinite(ms) && ms - Date.now() > 24 * 60 * 60 * 1e3;
100026
100217
  }
100218
+ var inflight = null;
100027
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) {
100028
100265
  const { apiOrigin: apiOrigin2, backendOrigin: backendOrigin2, isAllowedOrigin: isAllowedOrigin3, log: log9 } = opts;
100029
100266
  if (!isAllowedOrigin3(apiOrigin2)) {
100030
100267
  log9?.(`machine identity: refusing a non-default server: ${apiOrigin2}`);
100031
100268
  return null;
100032
100269
  }
100033
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
+ }
100034
100280
  try {
100035
100281
  if (!m) {
100036
- const reg = await postJson(`${apiOrigin2}/api/core/tesseract/identity/device`, { label: hostname3().slice(0, 120), platform: platform() });
100037
- m = {
100038
- deviceToken: reg.token,
100039
- publicId: reg.publicId,
100040
- deviceId: randomUUID23().slice(0, 8),
100041
- apiOrigin: apiOrigin2,
100042
- backendOrigin: backendOrigin2
100043
- };
100044
- write(m);
100045
- 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
+ }
100046
100307
  }
100047
100308
  if (!tokenUsable(m)) {
100048
100309
  const t = await postJson(`${apiOrigin2}/auth/device/relay-token`, { deviceToken: m.deviceToken, deviceId: m.deviceId });
100049
100310
  m = { ...m, accessToken: t.accessToken, expiresAt: t.expiresAt, publicId: t.publicId, apiOrigin: apiOrigin2, backendOrigin: backendOrigin2 };
100050
- write(m);
100311
+ write2(m);
100051
100312
  log9?.("machine identity: relay token minted");
100052
100313
  }
100053
100314
  return m;
@@ -100093,14 +100354,14 @@ function getMachinePublicId() {
100093
100354
 
100094
100355
  // ../../packages/host-core/dist/active-link/engine.js
100095
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";
100096
- import { existsSync as existsSync25 } from "node:fs";
100097
- 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";
100098
100359
 
100099
100360
  // ../../packages/host-core/dist/active-link/blocks.js
100100
100361
  import { createHash as createHash5 } from "node:crypto";
100101
100362
  import { createReadStream as createReadStream2 } from "node:fs";
100102
- import { open as open3, mkdir as mkdir12, rename as rename2, chmod as chmod2, utimes, unlink } from "node:fs/promises";
100103
- 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";
100104
100365
  var CHUNK3 = 1024 * 1024;
100105
100366
  var MAX_INFLIGHT2 = 8 * CHUNK3;
100106
100367
  var IDLE_MS2 = 6e4;
@@ -100228,8 +100489,8 @@ var StagingWriter = class {
100228
100489
  }
100229
100490
  async ensureOpen() {
100230
100491
  if (!this.fh) {
100231
- await mkdir12(dirname24(this.stagingPath), { recursive: true });
100232
- this.fh = await open3(this.stagingPath, "w");
100492
+ await mkdir12(dirname25(this.stagingPath), { recursive: true });
100493
+ this.fh = await open4(this.stagingPath, "w");
100233
100494
  }
100234
100495
  return this.fh;
100235
100496
  }
@@ -100258,7 +100519,7 @@ var StagingWriter = class {
100258
100519
  });
100259
100520
  await fh.close();
100260
100521
  this.fh = null;
100261
- await mkdir12(dirname24(dest), { recursive: true });
100522
+ await mkdir12(dirname25(dest), { recursive: true });
100262
100523
  await chmod2(this.stagingPath, mode & 511).catch(() => {
100263
100524
  });
100264
100525
  const secs = mtimeMs / 1e3;
@@ -100291,8 +100552,8 @@ var BlockAssembler = class {
100291
100552
  this.stagingPath = stagingPath;
100292
100553
  }
100293
100554
  async open() {
100294
- await mkdir12(dirname24(this.stagingPath), { recursive: true });
100295
- this.fh = await open3(this.stagingPath, "w");
100555
+ await mkdir12(dirname25(this.stagingPath), { recursive: true });
100556
+ this.fh = await open4(this.stagingPath, "w");
100296
100557
  }
100297
100558
  /** Write a received block at its byte offset (index * CHUNK). */
100298
100559
  async writeBlock(index, buf) {
@@ -100307,7 +100568,7 @@ var BlockAssembler = class {
100307
100568
  await this.open();
100308
100569
  let lf = null;
100309
100570
  try {
100310
- lf = await open3(localAbs, "r");
100571
+ lf = await open4(localAbs, "r");
100311
100572
  const buf = Buffer.alloc(len);
100312
100573
  const { bytesRead } = await lf.read(buf, 0, len, localOffset);
100313
100574
  if (bytesRead !== len)
@@ -100335,7 +100596,7 @@ var BlockAssembler = class {
100335
100596
  });
100336
100597
  return false;
100337
100598
  }
100338
- await mkdir12(dirname24(dest), { recursive: true });
100599
+ await mkdir12(dirname25(dest), { recursive: true });
100339
100600
  await chmod2(this.stagingPath, mode & 511).catch(() => {
100340
100601
  });
100341
100602
  const secs = mtimeMs / 1e3;
@@ -100358,8 +100619,8 @@ var BlockAssembler = class {
100358
100619
  };
100359
100620
 
100360
100621
  // ../../packages/host-core/dist/active-link/manifest.js
100361
- import { readFileSync as readFileSync37, writeFileSync as writeFileSync25, mkdirSync as mkdirSync27, existsSync as existsSync24, renameSync as renameSync8 } from "node:fs";
100362
- 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";
100363
100624
 
100364
100625
  // ../../packages/host-core/dist/active-link/reconcile.js
100365
100626
  var ABSENT = { kind: "absent", t: -Infinity, hash: "" };
@@ -100395,11 +100656,11 @@ var LinkManifest = class {
100395
100656
  this.dir = dir2;
100396
100657
  }
100397
100658
  file() {
100398
- return join54(this.dir, "manifest.json");
100659
+ return join55(this.dir, "manifest.json");
100399
100660
  }
100400
100661
  load() {
100401
100662
  try {
100402
- const raw = JSON.parse(readFileSync37(this.file(), "utf-8"));
100663
+ const raw = JSON.parse(readFileSync38(this.file(), "utf-8"));
100403
100664
  this.records = new Map(Object.entries(raw.records ?? {}));
100404
100665
  this.tombstones = new Map(Object.entries(raw.tombstones ?? {}));
100405
100666
  } catch {
@@ -100480,14 +100741,14 @@ var LinkManifest = class {
100480
100741
  if (!this.dirty)
100481
100742
  return;
100482
100743
  try {
100483
- if (!existsSync24(this.dir))
100484
- mkdirSync27(this.dir, { recursive: true });
100744
+ if (!existsSync25(this.dir))
100745
+ mkdirSync28(this.dir, { recursive: true });
100485
100746
  const json3 = {
100486
100747
  records: Object.fromEntries(this.records),
100487
100748
  tombstones: Object.fromEntries(this.tombstones)
100488
100749
  };
100489
100750
  const tmp = `${this.file()}.tmp`;
100490
- writeFileSync25(tmp, JSON.stringify(json3));
100751
+ writeFileSync26(tmp, JSON.stringify(json3));
100491
100752
  renameSync8(tmp, this.file());
100492
100753
  this.dirty = false;
100493
100754
  } catch {
@@ -100497,7 +100758,7 @@ var LinkManifest = class {
100497
100758
 
100498
100759
  // ../../packages/host-core/dist/active-link/scanner.js
100499
100760
  import { readdir as readdir7, lstat as lstat3, readlink as readlink2 } from "node:fs/promises";
100500
- import { join as join55, sep as sep10 } from "node:path";
100761
+ import { join as join56, sep as sep10 } from "node:path";
100501
100762
  async function walkRels(root, extraIgnore) {
100502
100763
  const out = [];
100503
100764
  async function rec(dir2) {
@@ -100512,7 +100773,7 @@ async function walkRels(root, extraIgnore) {
100512
100773
  continue;
100513
100774
  if (e.isDirectory() && HEAVY_DIRS.has(e.name))
100514
100775
  continue;
100515
- const abs = join55(dir2, e.name);
100776
+ const abs = join56(dir2, e.name);
100516
100777
  if (extraIgnore?.(abs))
100517
100778
  continue;
100518
100779
  if (e.isDirectory())
@@ -100551,7 +100812,7 @@ async function scanTree(root, prior, allow, extraIgnore) {
100551
100812
  return { records };
100552
100813
  }
100553
100814
  function absOf(root, rel) {
100554
- return join55(root, rel.split("/").join(sep10));
100815
+ return join56(root, rel.split("/").join(sep10));
100555
100816
  }
100556
100817
 
100557
100818
  // ../../packages/host-core/dist/active-link/gitignore.js
@@ -100569,7 +100830,7 @@ async function gitSyncedFiles(root) {
100569
100830
 
100570
100831
  // ../../packages/host-core/dist/active-link/session.js
100571
100832
  import { createHash as createHash6 } from "node:crypto";
100572
- 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";
100573
100834
  var OutboundSender = class {
100574
100835
  deps;
100575
100836
  queue = [];
@@ -100663,7 +100924,7 @@ var OutboundSender = class {
100663
100924
  const running2 = createHash6("sha256");
100664
100925
  let fh;
100665
100926
  try {
100666
- fh = await open4(abs, "r");
100927
+ fh = await open5(abs, "r");
100667
100928
  } catch {
100668
100929
  return;
100669
100930
  }
@@ -100734,7 +100995,7 @@ var OutboundSender = class {
100734
100995
  const mode = st.mode;
100735
100996
  let fh;
100736
100997
  try {
100737
- fh = await open4(abs, "r");
100998
+ fh = await open5(abs, "r");
100738
100999
  } catch {
100739
101000
  return;
100740
101001
  }
@@ -100995,7 +101256,7 @@ function readdirp(root, options = {}) {
100995
101256
 
100996
101257
  // ../../node_modules/chokidar/esm/handler.js
100997
101258
  import { watchFile, unwatchFile, watch as fs_watch } from "fs";
100998
- 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";
100999
101260
  import * as sysPath from "path";
101000
101261
  import { type as osType } from "os";
101001
101262
  var STR_DATA = "data";
@@ -101379,7 +101640,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
101379
101640
  cont.watcherUnusable = true;
101380
101641
  if (isWindows2 && error51.code === "EPERM") {
101381
101642
  try {
101382
- const fd = await open5(path6, "r");
101643
+ const fd = await open6(path6, "r");
101383
101644
  await fd.close();
101384
101645
  broadcastErr(error51);
101385
101646
  } catch (err2) {
@@ -101497,9 +101758,9 @@ var NodeFsHandler = class {
101497
101758
  if (this.fsw.closed) {
101498
101759
  return;
101499
101760
  }
101500
- const dirname41 = sysPath.dirname(file2);
101761
+ const dirname42 = sysPath.dirname(file2);
101501
101762
  const basename14 = sysPath.basename(file2);
101502
- const parent = this.fsw._getWatchedDir(dirname41);
101763
+ const parent = this.fsw._getWatchedDir(dirname42);
101503
101764
  let prevStats = stats;
101504
101765
  if (parent.has(basename14))
101505
101766
  return;
@@ -101526,7 +101787,7 @@ var NodeFsHandler = class {
101526
101787
  prevStats = newStats2;
101527
101788
  }
101528
101789
  } catch (error51) {
101529
- this.fsw._remove(dirname41, basename14);
101790
+ this.fsw._remove(dirname42, basename14);
101530
101791
  }
101531
101792
  } else if (parent.has(basename14)) {
101532
101793
  const at = newStats.atimeMs;
@@ -102576,7 +102837,7 @@ var ActiveLinkEngine = class {
102576
102837
  }
102577
102838
  async start() {
102578
102839
  this.emit({ type: "status", linkId: this.opts.linkId, state: "scanning" });
102579
- await rm4(join58(this.stateDir, ".staging"), { recursive: true, force: true }).catch(() => {
102840
+ await rm4(join59(this.stateDir, ".staging"), { recursive: true, force: true }).catch(() => {
102580
102841
  });
102581
102842
  this.manifest.load();
102582
102843
  await this.reconcileScan();
@@ -102971,13 +103232,13 @@ var ActiveLinkEngine = class {
102971
103232
  * file so the path still exists — recorded as a FILE matching disk so the local
102972
103233
  * watcher doesn't churn. The target is containment-checked, never dereferenced. */
102973
103234
  async applySymlink(rel, dest, target, mtimeMs, mode) {
102974
- const resolved = resolve11(dirname27(dest), target);
103235
+ const resolved = resolve11(dirname28(dest), target);
102975
103236
  if (!isInsideRoot(resolved, this.opts.localRoot))
102976
103237
  return;
102977
103238
  const hash2 = hashString(target);
102978
103239
  const secs = mtimeMs / 1e3;
102979
103240
  try {
102980
- await mkdir13(dirname27(dest), { recursive: true });
103241
+ await mkdir13(dirname28(dest), { recursive: true });
102981
103242
  await rm4(dest, { force: true, recursive: true });
102982
103243
  try {
102983
103244
  await symlink2(target, dest);
@@ -103029,7 +103290,7 @@ var ActiveLinkEngine = class {
103029
103290
  return;
103030
103291
  if (fromRec && fromRec.kind === "file") {
103031
103292
  try {
103032
- await mkdir13(dirname27(toAbs2), { recursive: true });
103293
+ await mkdir13(dirname28(toAbs2), { recursive: true });
103033
103294
  await rename3(fromAbs, toAbs2);
103034
103295
  const secs = mtimeMs / 1e3;
103035
103296
  await utimes2(toAbs2, secs, secs).catch(() => {
@@ -103054,7 +103315,7 @@ var ActiveLinkEngine = class {
103054
103315
  await this.maybeRefreshAllow(rels);
103055
103316
  const state3 = /* @__PURE__ */ new Map();
103056
103317
  for (const rel of rels) {
103057
- if (existsSync25(absOf(this.opts.localRoot, rel)) && !this.isSynced(rel)) {
103318
+ if (existsSync26(absOf(this.opts.localRoot, rel)) && !this.isSynced(rel)) {
103058
103319
  this.manifest.dropRecord(rel);
103059
103320
  continue;
103060
103321
  }
@@ -103158,7 +103419,7 @@ var ActiveLinkEngine = class {
103158
103419
  for (const rel of this.manifest.recordRels()) {
103159
103420
  if (records.has(rel))
103160
103421
  continue;
103161
- if (existsSync25(absOf(this.opts.localRoot, rel)))
103422
+ if (existsSync26(absOf(this.opts.localRoot, rel)))
103162
103423
  this.manifest.dropRecord(rel);
103163
103424
  else
103164
103425
  this.manifest.setTombstone(rel, now2);
@@ -103204,7 +103465,7 @@ var ActiveLinkEngine = class {
103204
103465
  this.inboundWatchdog.clear();
103205
103466
  }
103206
103467
  stagingPath(rel, tag) {
103207
- return join58(this.stateDir, ".staging", `${hashString(rel)}.${tag}`);
103468
+ return join59(this.stateDir, ".staging", `${hashString(rel)}.${tag}`);
103208
103469
  }
103209
103470
  pruneSuppress() {
103210
103471
  const now2 = this.now();
@@ -103229,14 +103490,14 @@ var ActiveLinkEngine = class {
103229
103490
  };
103230
103491
 
103231
103492
  // ../../packages/host-core/dist/active-link/config.js
103232
- import { readFileSync as readFileSync38, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28, existsSync as existsSync26, renameSync as renameSync9, watch as watch3 } from "node:fs";
103233
- 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";
103234
103495
  function configPath2() {
103235
- return join59(activeLinkRoot(), "links.json");
103496
+ return join60(activeLinkRoot(), "links.json");
103236
103497
  }
103237
103498
  function loadLinkConfigs() {
103238
103499
  try {
103239
- const raw = JSON.parse(readFileSync38(configPath2(), "utf-8"));
103500
+ const raw = JSON.parse(readFileSync39(configPath2(), "utf-8"));
103240
103501
  if (!Array.isArray(raw.links))
103241
103502
  return [];
103242
103503
  return raw.links.filter((c) => c && c.linkId && c.localRoot && c.peerHostId);
@@ -103247,10 +103508,10 @@ function loadLinkConfigs() {
103247
103508
  function writeAll(links) {
103248
103509
  try {
103249
103510
  const dir2 = activeLinkRoot();
103250
- if (!existsSync26(dir2))
103251
- mkdirSync28(dir2, { recursive: true });
103511
+ if (!existsSync27(dir2))
103512
+ mkdirSync29(dir2, { recursive: true });
103252
103513
  const tmp = `${configPath2()}.tmp`;
103253
- writeFileSync26(tmp, JSON.stringify({ links }, null, 2));
103514
+ writeFileSync27(tmp, JSON.stringify({ links }, null, 2));
103254
103515
  renameSync9(tmp, configPath2());
103255
103516
  } catch {
103256
103517
  }
@@ -103269,11 +103530,11 @@ function saveLinkConfig(cfg2) {
103269
103530
  writeAll(links);
103270
103531
  }
103271
103532
  function pendingPath() {
103272
- return join59(activeLinkRoot(), "pending-deprovisions.json");
103533
+ return join60(activeLinkRoot(), "pending-deprovisions.json");
103273
103534
  }
103274
103535
  function loadPendingDeprovisions() {
103275
103536
  try {
103276
- const raw = JSON.parse(readFileSync38(pendingPath(), "utf-8"));
103537
+ const raw = JSON.parse(readFileSync39(pendingPath(), "utf-8"));
103277
103538
  return Array.isArray(raw.pending) ? raw.pending.filter((p) => p && p.linkId && p.peerHostId) : [];
103278
103539
  } catch {
103279
103540
  return [];
@@ -103282,10 +103543,10 @@ function loadPendingDeprovisions() {
103282
103543
  function writePending(pending2) {
103283
103544
  try {
103284
103545
  const dir2 = activeLinkRoot();
103285
- if (!existsSync26(dir2))
103286
- mkdirSync28(dir2, { recursive: true });
103546
+ if (!existsSync27(dir2))
103547
+ mkdirSync29(dir2, { recursive: true });
103287
103548
  const tmp = `${pendingPath()}.tmp`;
103288
- writeFileSync26(tmp, JSON.stringify({ pending: pending2 }, null, 2));
103549
+ writeFileSync27(tmp, JSON.stringify({ pending: pending2 }, null, 2));
103289
103550
  renameSync9(tmp, pendingPath());
103290
103551
  } catch {
103291
103552
  }
@@ -103298,8 +103559,8 @@ function removeLinkConfig(linkId) {
103298
103559
  }
103299
103560
  function watchLinkConfigs(onChange) {
103300
103561
  const dir2 = activeLinkRoot();
103301
- if (!existsSync26(dir2))
103302
- mkdirSync28(dir2, { recursive: true });
103562
+ if (!existsSync27(dir2))
103563
+ mkdirSync29(dir2, { recursive: true });
103303
103564
  let timer2 = null;
103304
103565
  let watcher = null;
103305
103566
  try {
@@ -103444,7 +103705,7 @@ function routeInboundLinkFrame(frame) {
103444
103705
  init_dist5();
103445
103706
 
103446
103707
  // ../../packages/host-core/dist/pty-manager.js
103447
- import { existsSync as existsSync27 } from "node:fs";
103708
+ import { existsSync as existsSync28 } from "node:fs";
103448
103709
  import { homedir as homedir9 } from "node:os";
103449
103710
  init_safe_kill();
103450
103711
  var ptyPromise = null;
@@ -103599,7 +103860,7 @@ function listUnix() {
103599
103860
  const seen = /* @__PURE__ */ new Set();
103600
103861
  const loginShell = process.env.SHELL || "";
103601
103862
  const add2 = (id, path6) => {
103602
- if (!path6 || seen.has(path6) || !existsSync27(path6))
103863
+ if (!path6 || seen.has(path6) || !existsSync28(path6))
103603
103864
  return;
103604
103865
  seen.add(path6);
103605
103866
  out.push(mk(id, path6, path6 === loginShell));
@@ -103631,7 +103892,7 @@ function listWindows() {
103631
103892
  const gitBash = `${pf}\\Git\\bin\\bash.exe`;
103632
103893
  const pwsh7 = `${pf}\\PowerShell\\7\\pwsh.exe`;
103633
103894
  const add2 = (id, path6, label, isDefault = false) => {
103634
- if (path6 && existsSync27(path6))
103895
+ if (path6 && existsSync28(path6))
103635
103896
  out.push(mk(id, path6, isDefault, label));
103636
103897
  };
103637
103898
  add2("powershell", winPwsh, "Windows PowerShell", true);
@@ -103690,7 +103951,7 @@ function resolveCwd(cwd, hostRoot) {
103690
103951
  const fallback = hostRoot || homedir9();
103691
103952
  if (!cwd)
103692
103953
  return fallback;
103693
- if (!existsSync27(cwd))
103954
+ if (!existsSync28(cwd))
103694
103955
  return fallback;
103695
103956
  if (hostRoot && !isInsideRoot(cwd, hostRoot))
103696
103957
  return hostRoot;
@@ -103725,6 +103986,7 @@ function turnRekeyed(from, to) {
103725
103986
  var HOST_ROOT = resolveHostRoot();
103726
103987
  var HOST_CONTAIN = resolveContainmentRoot() ?? void 0;
103727
103988
  var hooks = null;
103989
+ var hookSets = [];
103728
103990
  var socket = null;
103729
103991
  var heartbeat = null;
103730
103992
  var reconnectTimer = null;
@@ -103922,6 +104184,16 @@ function listHosts() {
103922
104184
  function ownHost() {
103923
104185
  return ownHostId();
103924
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
+ }
103925
104197
  function assertServerSelection() {
103926
104198
  if (!socket || socket.readyState !== 1)
103927
104199
  return;
@@ -104148,9 +104420,9 @@ function provisionActiveLinkMirror(payload) {
104148
104420
  const remoteSubfolder = typeof payload.remoteSubfolder === "string" ? payload.remoteSubfolder : void 0;
104149
104421
  let localRoot;
104150
104422
  if (remoteParent && remoteSubfolder) {
104151
- localRoot = join60(remoteParent, safeFolderName(remoteSubfolder));
104423
+ localRoot = join61(remoteParent, safeFolderName(remoteSubfolder));
104152
104424
  } else {
104153
- localRoot = join60(HOST_ROOT, "Tesseract Mirrors", safeFolderName(projectName));
104425
+ localRoot = join61(HOST_ROOT, "Tesseract Mirrors", safeFolderName(projectName));
104154
104426
  }
104155
104427
  if (loadLinkConfigs().some((c) => c.localRoot === localRoot && c.linkId !== linkId)) {
104156
104428
  localRoot = `${localRoot}-${linkId.slice(0, 6)}`;
@@ -104158,7 +104430,7 @@ function provisionActiveLinkMirror(payload) {
104158
104430
  if (!isInsideRoot(localRoot, HOST_ROOT))
104159
104431
  return;
104160
104432
  try {
104161
- mkdirSync29(localRoot, { recursive: true });
104433
+ mkdirSync30(localRoot, { recursive: true });
104162
104434
  } catch {
104163
104435
  }
104164
104436
  saveLinkConfig({
@@ -104466,7 +104738,7 @@ async function handleInboundAgent(msg, driverClientId) {
104466
104738
  send3("agent", {
104467
104739
  type: "agent:notice",
104468
104740
  sessionId: msg.sessionId,
104469
- noticeId: randomUUID24(),
104741
+ noticeId: randomUUID25(),
104470
104742
  category: "model",
104471
104743
  level: "warning",
104472
104744
  title: "That model is not available on this device",
@@ -105186,7 +105458,9 @@ function startControlLink(config2, h) {
105186
105458
  deviceId = config2.deviceId;
105187
105459
  backendOrigin = config2.tokenSource.backendOrigin;
105188
105460
  hostVersion = config2.version;
105189
- 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));
105190
105464
  stopped = false;
105191
105465
  if (config2.e2e && !hostSessions) {
105192
105466
  const e2e = config2.e2e;
@@ -105263,9 +105537,9 @@ init_gateway_plan2();
105263
105537
  init_base_paths();
105264
105538
  init_credentials();
105265
105539
  init_dist5();
105266
- import { mkdirSync as mkdirSync30, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
105267
- import { randomUUID as randomUUID25 } from "node:crypto";
105268
- 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";
105269
105543
  var REFRESH_MS = 24 * 60 * 60 * 1e3;
105270
105544
  var TIMEOUT_MS2 = 1e4;
105271
105545
  var CACHE = () => tessPath("bundled-model.json");
@@ -105275,22 +105549,22 @@ function deviceId2() {
105275
105549
  if (fromCredentials)
105276
105550
  return fromCredentials;
105277
105551
  try {
105278
- const raw = JSON.parse(readFileSync39(DEVICE_ID(), "utf8"));
105552
+ const raw = JSON.parse(readFileSync40(DEVICE_ID(), "utf8"));
105279
105553
  if (typeof raw?.deviceId === "string" && raw.deviceId)
105280
105554
  return raw.deviceId;
105281
105555
  } catch {
105282
105556
  }
105283
- const fresh = randomUUID25().slice(0, 8);
105557
+ const fresh = randomUUID26().slice(0, 8);
105284
105558
  try {
105285
- mkdirSync30(dirname28(DEVICE_ID()), { recursive: true });
105286
- 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 });
105287
105561
  } catch {
105288
105562
  }
105289
105563
  return fresh;
105290
105564
  }
105291
105565
  function readCache() {
105292
105566
  try {
105293
- const raw = JSON.parse(readFileSync39(CACHE(), "utf8"));
105567
+ const raw = JSON.parse(readFileSync40(CACHE(), "utf8"));
105294
105568
  if (typeof raw?.apiKey === "string" && typeof raw.baseUrl === "string" && raw.models?.low && raw.models.high) {
105295
105569
  return { ...raw, fetchedAt: raw.fetchedAt ?? 0 };
105296
105570
  }
@@ -105300,8 +105574,8 @@ function readCache() {
105300
105574
  }
105301
105575
  function writeCache(key2) {
105302
105576
  try {
105303
- mkdirSync30(dirname28(CACHE()), { recursive: true });
105304
- 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 });
105305
105579
  } catch (e) {
105306
105580
  log(`gateway key: could not cache (${e.message})`);
105307
105581
  }
@@ -105882,7 +106156,7 @@ Open System Settings \u2192 Privacy & Security \u2192 Screen Recording and switc
105882
106156
  }
105883
106157
 
105884
106158
  // ../../packages/host-core/dist/rdesk/publisher-window.js
105885
- import { join as join61 } from "node:path";
106159
+ import { join as join62 } from "node:path";
105886
106160
  var windows = /* @__PURE__ */ new Map();
105887
106161
  var ipcInstalled = false;
105888
106162
  function ensureIpc() {
@@ -106037,7 +106311,7 @@ var PublisherWindow = class {
106037
106311
  win3.setContentProtection(true);
106038
106312
  } catch {
106039
106313
  }
106040
- await win3.loadFile(join61(daemonUiDir(), "publisher.html"));
106314
+ await win3.loadFile(join62(daemonUiDir(), "publisher.html"));
106041
106315
  this.send("rdesk:pub:start", {
106042
106316
  sessionId: this.sessionId,
106043
106317
  sourceId,
@@ -106082,7 +106356,7 @@ var PublisherWindow = class {
106082
106356
  win3.setContentProtection(true);
106083
106357
  } catch {
106084
106358
  }
106085
- await win3.loadFile(join61(daemonUiDir(), "publisher.html"));
106359
+ await win3.loadFile(join62(daemonUiDir(), "publisher.html"));
106086
106360
  this.send("rdesk:pub:start", {
106087
106361
  sessionId: this.sessionId,
106088
106362
  mode: "canvas",
@@ -106682,10 +106956,10 @@ function setInProcConnector(fn) {
106682
106956
 
106683
106957
  // ../../packages/host-core/dist/rdesk/server-prefs.js
106684
106958
  init_credentials();
106685
- import { readFileSync as readFileSync40, writeFileSync as writeFileSync28 } from "node:fs";
106686
- 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";
106687
106961
  function rdeskServerPrefsPath() {
106688
- return join62(daemonDir2(), "rdesk-server.json");
106962
+ return join63(daemonDir2(), "rdesk-server.json");
106689
106963
  }
106690
106964
  var DEFAULTS2 = {
106691
106965
  enabled: true,
@@ -106697,7 +106971,7 @@ var DEFAULTS2 = {
106697
106971
  };
106698
106972
  function readRdeskServerPrefs() {
106699
106973
  try {
106700
- const p = JSON.parse(readFileSync40(rdeskServerPrefsPath(), "utf8"));
106974
+ const p = JSON.parse(readFileSync41(rdeskServerPrefsPath(), "utf8"));
106701
106975
  return {
106702
106976
  // `!== false` (not `?? true`): only an explicit opt-out disables sharing, so a
106703
106977
  // partially-written or older prefs file never silently turns the machine off.
@@ -106715,7 +106989,7 @@ function readRdeskServerPrefs() {
106715
106989
  function writeRdeskServerPrefs(patch) {
106716
106990
  try {
106717
106991
  const next = { ...readRdeskServerPrefs(), ...patch };
106718
- writeFileSync28(rdeskServerPrefsPath(), JSON.stringify(next), { mode: 384 });
106992
+ writeFileSync29(rdeskServerPrefsPath(), JSON.stringify(next), { mode: 384 });
106719
106993
  } catch {
106720
106994
  }
106721
106995
  }
@@ -106730,13 +107004,13 @@ function rdeskSharingEnabled() {
106730
107004
  // ../../packages/host-core/dist/rdesk/password.js
106731
107005
  init_credentials();
106732
107006
  import { scryptSync, randomBytes as randomBytes5, timingSafeEqual as timingSafeEqual4, randomInt } from "node:crypto";
106733
- import { readFileSync as readFileSync41, writeFileSync as writeFileSync29, existsSync as existsSync28, unlinkSync as unlinkSync3 } from "node:fs";
106734
- 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";
106735
107009
  function pwFile() {
106736
- return join63(daemonDir2(), "rdesk-password.json");
107010
+ return join64(daemonDir2(), "rdesk-password.json");
106737
107011
  }
106738
107012
  function pwPlainFile() {
106739
- return join63(daemonDir2(), "rdesk-password.enc");
107013
+ return join64(daemonDir2(), "rdesk-password.enc");
106740
107014
  }
106741
107015
  var PW_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789";
106742
107016
  var PW_LENGTH = 16;
@@ -106751,14 +107025,14 @@ function writePlain(password) {
106751
107025
  const safe2 = electronModule()?.safeStorage;
106752
107026
  if (!safe2?.isEncryptionAvailable())
106753
107027
  return;
106754
- writeFileSync29(pwPlainFile(), safe2.encryptString(password), { mode: 384 });
107028
+ writeFileSync30(pwPlainFile(), safe2.encryptString(password), { mode: 384 });
106755
107029
  } catch {
106756
107030
  }
106757
107031
  }
106758
107032
  function canRevealRdeskPassword() {
106759
107033
  try {
106760
107034
  const safe2 = electronModule()?.safeStorage;
106761
- return !!safe2?.isEncryptionAvailable() && existsSync28(pwPlainFile());
107035
+ return !!safe2?.isEncryptionAvailable() && existsSync29(pwPlainFile());
106762
107036
  } catch {
106763
107037
  return false;
106764
107038
  }
@@ -106768,7 +107042,7 @@ function readRdeskPasswordPlain() {
106768
107042
  const safe2 = electronModule()?.safeStorage;
106769
107043
  if (!safe2?.isEncryptionAvailable())
106770
107044
  return null;
106771
- return safe2.decryptString(readFileSync41(pwPlainFile()));
107045
+ return safe2.decryptString(readFileSync42(pwPlainFile()));
106772
107046
  } catch {
106773
107047
  return null;
106774
107048
  }
@@ -106776,18 +107050,18 @@ function readRdeskPasswordPlain() {
106776
107050
  function setRdeskPassword(password) {
106777
107051
  if (!password) {
106778
107052
  try {
106779
- unlinkSync3(pwFile());
107053
+ unlinkSync4(pwFile());
106780
107054
  } catch {
106781
107055
  }
106782
107056
  try {
106783
- unlinkSync3(pwPlainFile());
107057
+ unlinkSync4(pwPlainFile());
106784
107058
  } catch {
106785
107059
  }
106786
107060
  return;
106787
107061
  }
106788
107062
  const salt = randomBytes5(16);
106789
107063
  const hash2 = scryptSync(password, salt, 32);
106790
- 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 });
106791
107065
  writePlain(password);
106792
107066
  }
106793
107067
  function regenerateRdeskPassword() {
@@ -106801,7 +107075,7 @@ function ensureRdeskPassword() {
106801
107075
  return regenerateRdeskPassword();
106802
107076
  }
106803
107077
  function hasRdeskPassword() {
106804
- return !!process.env.CCB_RDESK_PASSWORD || existsSync28(pwFile());
107078
+ return !!process.env.CCB_RDESK_PASSWORD || existsSync29(pwFile());
106805
107079
  }
106806
107080
  function verifyRdeskPassword(password) {
106807
107081
  if (!password)
@@ -106810,7 +107084,7 @@ function verifyRdeskPassword(password) {
106810
107084
  if (override3)
106811
107085
  return password.length === override3.length && timingSafeEqual4(Buffer.from(password), Buffer.from(override3));
106812
107086
  try {
106813
- const { salt, hash: hash2 } = JSON.parse(readFileSync41(pwFile(), "utf8"));
107087
+ const { salt, hash: hash2 } = JSON.parse(readFileSync42(pwFile(), "utf8"));
106814
107088
  const got = scryptSync(password, Buffer.from(salt, "hex"), 32);
106815
107089
  const want = Buffer.from(hash2, "hex");
106816
107090
  return got.length === want.length && timingSafeEqual4(got, want);
@@ -107288,7 +107562,7 @@ function stopSystemEvents() {
107288
107562
  }
107289
107563
 
107290
107564
  // ../../packages/host-core/dist/local-server.js
107291
- import { randomUUID as randomUUID27 } from "node:crypto";
107565
+ import { randomUUID as randomUUID28 } from "node:crypto";
107292
107566
  init_daemon_settings();
107293
107567
 
107294
107568
  // ../../packages/host-core/dist/vault/manager.js
@@ -107376,8 +107650,8 @@ function createPasskeyRegistration(rpId) {
107376
107650
 
107377
107651
  // ../../packages/host-core/dist/vault/manager.js
107378
107652
  init_base_paths();
107379
- import { mkdirSync as mkdirSync33, readFileSync as readFileSync44, writeFileSync as writeFileSync32 } from "node:fs";
107380
- 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";
107381
107655
 
107382
107656
  // ../../packages/vault-core/dist/crypto.js
107383
107657
  init_argon2();
@@ -107471,7 +107745,7 @@ async function seal(key2, plaintext, aad) {
107471
107745
  const ct = await aesSeal(key2, nonce2, plaintext, aad);
107472
107746
  return `${ENVELOPE}:${b64u(nonce2)}:${b64u(ct)}`;
107473
107747
  }
107474
- async function open6(key2, envelope2, aad) {
107748
+ async function open7(key2, envelope2, aad) {
107475
107749
  const parts = envelope2.split(":");
107476
107750
  if (parts.length !== 3 || parts[0] !== ENVELOPE)
107477
107751
  throw new Error("malformed vault envelope");
@@ -107484,7 +107758,7 @@ async function wrapVaultKey(masterKey, vaultKey) {
107484
107758
  return seal(await wrappingKey(masterKey), vaultKey, WRAP_AAD);
107485
107759
  }
107486
107760
  async function unwrapVaultKey(masterKey, wrapped) {
107487
- return open6(await wrappingKey(masterKey), wrapped, WRAP_AAD);
107761
+ return open7(await wrappingKey(masterKey), wrapped, WRAP_AAD);
107488
107762
  }
107489
107763
  async function createVault(masterPassword, kdf2 = defaultKdfParams()) {
107490
107764
  const masterKey = deriveMasterKey(masterPassword, kdf2);
@@ -107517,7 +107791,7 @@ async function recoverWithKey(recoveryKey, meta4) {
107517
107791
  throw new Error("no recovery key is set for this vault");
107518
107792
  const kek = await importAesKey(parseRecoveryKey(recoveryKey));
107519
107793
  try {
107520
- return await open6(kek, meta4.recoveryWrappedVaultKey, RECOVERY_AAD);
107794
+ return await open7(kek, meta4.recoveryWrappedVaultKey, RECOVERY_AAD);
107521
107795
  } catch {
107522
107796
  throw new Error("Incorrect recovery key");
107523
107797
  }
@@ -107538,7 +107812,7 @@ async function encryptItem(vaultKey, item) {
107538
107812
  }
107539
107813
  async function decryptItem(vaultKey, enc) {
107540
107814
  const key2 = await importAesKey(vaultKey);
107541
- 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))));
107542
107816
  }
107543
107817
  function tombstone(id, updatedAt) {
107544
107818
  return { id, ciphertext: "", updatedAt, deleted: true };
@@ -107884,7 +108158,7 @@ var XJSON_AAD = utf8("tesseract-vault-encrypted-json-v1");
107884
108158
  init_credentials();
107885
108159
 
107886
108160
  // ../../packages/host-core/dist/vault/store.js
107887
- import { randomUUID as randomUUID26 } from "node:crypto";
108161
+ import { randomUUID as randomUUID27 } from "node:crypto";
107888
108162
  var b64 = (u) => Buffer.from(u).toString("base64");
107889
108163
  var u82 = (s) => new Uint8Array(Buffer.from(s, "base64"));
107890
108164
  var isServerRecoverableMeta = (m) => !m.wrappedVaultKey;
@@ -108186,7 +108460,7 @@ var VaultStore = class {
108186
108460
  const existing = input.id ? items.get(input.id) : void 0;
108187
108461
  const { id: _drop, name, folderId, favorite, reprompt, notes, tags, ...content } = input;
108188
108462
  const item = {
108189
- id: input.id ?? randomUUID26(),
108463
+ id: input.id ?? randomUUID27(),
108190
108464
  name,
108191
108465
  folderId,
108192
108466
  favorite,
@@ -108215,7 +108489,7 @@ var VaultStore = class {
108215
108489
  const now2 = this.now();
108216
108490
  for (const d of drafts) {
108217
108491
  const { name, notes, favorite, tags, ...content } = d;
108218
- 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 };
108219
108493
  items.set(item.id, item);
108220
108494
  this.enc.set(item.id, await encryptItem(key2, item));
108221
108495
  this.dirty.add(item.id);
@@ -108401,8 +108675,8 @@ function makeDaemonVaultApi(getOrigin, getToken2) {
108401
108675
 
108402
108676
  // ../../packages/host-core/dist/vault/persistence.js
108403
108677
  init_base_paths();
108404
- import { existsSync as existsSync29, mkdirSync as mkdirSync31, readFileSync as readFileSync42, writeFileSync as writeFileSync30, unlinkSync as unlinkSync4 } from "node:fs";
108405
- 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";
108406
108680
  function vaultStoreFile() {
108407
108681
  return homePath(".tesseract", "vault", "vault.json");
108408
108682
  }
@@ -108413,9 +108687,9 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
108413
108687
  return {
108414
108688
  load() {
108415
108689
  try {
108416
- if (!existsSync29(file2()))
108690
+ if (!existsSync30(file2()))
108417
108691
  return null;
108418
- const parsed = JSON.parse(readFileSync42(file2(), "utf8"));
108692
+ const parsed = JSON.parse(readFileSync43(file2(), "utf8"));
108419
108693
  if (!parsed || typeof parsed !== "object")
108420
108694
  return null;
108421
108695
  return { meta: parsed.meta ?? null, items: Array.isArray(parsed.items) ? parsed.items : [] };
@@ -108425,29 +108699,29 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
108425
108699
  },
108426
108700
  save(state3) {
108427
108701
  try {
108428
- mkdirSync31(dirname29(file2()), { recursive: true, mode: 448 });
108429
- writeFileSync30(file2(), JSON.stringify(state3), { mode: 384 });
108702
+ mkdirSync32(dirname30(file2()), { recursive: true, mode: 448 });
108703
+ writeFileSync31(file2(), JSON.stringify(state3), { mode: 384 });
108430
108704
  } catch {
108431
108705
  }
108432
108706
  },
108433
108707
  loadDeviceKey() {
108434
108708
  try {
108435
- return existsSync29(deviceKeyFile()) ? readFileSync42(deviceKeyFile(), "utf8").trim() || null : null;
108709
+ return existsSync30(deviceKeyFile()) ? readFileSync43(deviceKeyFile(), "utf8").trim() || null : null;
108436
108710
  } catch {
108437
108711
  return null;
108438
108712
  }
108439
108713
  },
108440
108714
  saveDeviceKey(base64Key) {
108441
108715
  try {
108442
- mkdirSync31(dirname29(deviceKeyFile()), { recursive: true, mode: 448 });
108443
- writeFileSync30(deviceKeyFile(), base64Key, { mode: 384 });
108716
+ mkdirSync32(dirname30(deviceKeyFile()), { recursive: true, mode: 448 });
108717
+ writeFileSync31(deviceKeyFile(), base64Key, { mode: 384 });
108444
108718
  } catch {
108445
108719
  }
108446
108720
  },
108447
108721
  clearDeviceKey() {
108448
108722
  try {
108449
- if (existsSync29(deviceKeyFile()))
108450
- unlinkSync4(deviceKeyFile());
108723
+ if (existsSync30(deviceKeyFile()))
108724
+ unlinkSync5(deviceKeyFile());
108451
108725
  } catch {
108452
108726
  }
108453
108727
  }
@@ -108456,8 +108730,8 @@ function makeVaultPersistence(file2 = vaultStoreFile, deviceKeyFile = vaultDevic
108456
108730
 
108457
108731
  // ../../packages/host-core/dist/vault/biometric.js
108458
108732
  init_base_paths();
108459
- import { existsSync as existsSync30, mkdirSync as mkdirSync32, readFileSync as readFileSync43, rmSync as rmSync6, writeFileSync as writeFileSync31 } from "node:fs";
108460
- 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";
108461
108735
  async function electronBio() {
108462
108736
  if (!electronModule())
108463
108737
  return null;
@@ -108474,11 +108748,11 @@ async function electronBio() {
108474
108748
  }
108475
108749
  function bioDir() {
108476
108750
  const d = homePath(".tesseract", "vault-bio");
108477
- mkdirSync32(d, { recursive: true, mode: 448 });
108751
+ mkdirSync33(d, { recursive: true, mode: 448 });
108478
108752
  return d;
108479
108753
  }
108480
108754
  function bioFile(id) {
108481
- 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`);
108482
108756
  }
108483
108757
  async function biometricAvailable() {
108484
108758
  if (process.platform !== "darwin")
@@ -108493,24 +108767,24 @@ async function biometricAvailable() {
108493
108767
  }
108494
108768
  }
108495
108769
  function biometricEnrolled(id) {
108496
- return existsSync30(bioFile(id));
108770
+ return existsSync31(bioFile(id));
108497
108771
  }
108498
108772
  async function biometricEnroll(id, base64Key) {
108499
108773
  const bio = await electronBio();
108500
108774
  if (!bio)
108501
108775
  throw new Error("Touch ID is not available on this device.");
108502
108776
  await bio.systemPreferences.promptTouchID("enable Touch ID for your vault");
108503
- writeFileSync31(bioFile(id), bio.safeStorage.encryptString(base64Key), { mode: 384 });
108777
+ writeFileSync32(bioFile(id), bio.safeStorage.encryptString(base64Key), { mode: 384 });
108504
108778
  }
108505
108779
  async function biometricUnlock(id) {
108506
108780
  const f = bioFile(id);
108507
- if (!existsSync30(f))
108781
+ if (!existsSync31(f))
108508
108782
  throw new Error("Touch ID is not set up for this vault.");
108509
108783
  const bio = await electronBio();
108510
108784
  if (!bio)
108511
108785
  throw new Error("Touch ID is not available on this device.");
108512
108786
  await bio.systemPreferences.promptTouchID("unlock your vault");
108513
- return bio.safeStorage.decryptString(readFileSync43(f));
108787
+ return bio.safeStorage.decryptString(readFileSync44(f));
108514
108788
  }
108515
108789
  function biometricDisable(id) {
108516
108790
  try {
@@ -108540,7 +108814,7 @@ var VaultManager = class {
108540
108814
  // ── auto-lock ────────────────────────────────────────────────────────────────────
108541
108815
  loadAutoLock() {
108542
108816
  try {
108543
- const raw = JSON.parse(readFileSync44(settingsFile(), "utf8"));
108817
+ const raw = JSON.parse(readFileSync45(settingsFile(), "utf8"));
108544
108818
  return Number.isFinite(raw.autoLockMinutes) ? Math.max(0, raw.autoLockMinutes) : 0;
108545
108819
  } catch {
108546
108820
  return 0;
@@ -108548,8 +108822,8 @@ var VaultManager = class {
108548
108822
  }
108549
108823
  saveAutoLock() {
108550
108824
  try {
108551
- mkdirSync33(dirname30(settingsFile()), { recursive: true, mode: 448 });
108552
- 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 });
108553
108827
  } catch {
108554
108828
  }
108555
108829
  }
@@ -109246,7 +109520,7 @@ async function startLocalServer(opts) {
109246
109520
  send4("agent", {
109247
109521
  type: "agent:notice",
109248
109522
  sessionId: msg.sessionId,
109249
- noticeId: randomUUID27(),
109523
+ noticeId: randomUUID28(),
109250
109524
  category: "model",
109251
109525
  level: "warning",
109252
109526
  title: "That model is not available on this device",
@@ -109624,22 +109898,22 @@ async function startLocalServer(opts) {
109624
109898
 
109625
109899
  // ../../packages/host-core/dist/daemon-runtime.js
109626
109900
  init_base_paths();
109627
- 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";
109628
109902
  import { execFileSync as execFileSync5 } from "node:child_process";
109629
- import { join as join77 } from "node:path";
109903
+ import { join as join78 } from "node:path";
109630
109904
  import { randomBytes as randomBytes10 } from "node:crypto";
109631
109905
  import { hostname as hostname5 } from "node:os";
109632
109906
 
109633
109907
  // ../../packages/shared/dist/daemon-registry.js
109634
109908
  init_base_paths();
109635
109909
  import { execFileSync as execFileSync3 } from "node:child_process";
109636
- import { existsSync as existsSync31, mkdirSync as mkdirSync34, readdirSync as readdirSync11, readFileSync as readFileSync45, readlinkSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync33 } from "node:fs";
109637
- 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";
109638
109912
  var SUPERVISOR_PID = Number(process.env.CCB_DAEMON_SUPERVISOR_PID ?? 0) || 0;
109639
109913
  delete process.env.CCB_DAEMON_SUPERVISOR_PID;
109640
109914
  var PS_ENV = { ...process.env, LC_ALL: "C", LANG: "C" };
109641
- var registryDir = () => join65(daemonDir(), "daemons");
109642
- var recordPath = (pid) => join65(registryDir(), `${pid}.json`);
109915
+ var registryDir = () => join66(daemonDir(), "daemons");
109916
+ var recordPath = (pid) => join66(registryDir(), `${pid}.json`);
109643
109917
  function isPidAlive2(pid) {
109644
109918
  try {
109645
109919
  process.kill(pid, 0);
@@ -109691,7 +109965,7 @@ function pidStillMatches(pid, rec) {
109691
109965
  }
109692
109966
  function registerSelfAsDaemon(version2) {
109693
109967
  try {
109694
- mkdirSync34(registryDir(), { recursive: true, mode: 448 });
109968
+ mkdirSync35(registryDir(), { recursive: true, mode: 448 });
109695
109969
  const rec = {
109696
109970
  pid: process.pid,
109697
109971
  startedAt: procStartedAt(process.pid),
@@ -109703,7 +109977,7 @@ function registerSelfAsDaemon(version2) {
109703
109977
  ...process.env.CCB_RDESK_ONLY === "1" || process.env.CCB_MESH_ONLY === "1" ? { rdeskOnly: true } : {},
109704
109978
  ...SUPERVISOR_PID ? { supervisorPid: SUPERVISOR_PID, supervisorStartedAt: procStartedAt(SUPERVISOR_PID) } : {}
109705
109979
  };
109706
- writeFileSync33(recordPath(process.pid), JSON.stringify(rec), { mode: 384 });
109980
+ writeFileSync34(recordPath(process.pid), JSON.stringify(rec), { mode: 384 });
109707
109981
  invalidateSupervisorCache();
109708
109982
  try {
109709
109983
  registeredDaemons(process.pid);
@@ -109714,7 +109988,7 @@ function registerSelfAsDaemon(version2) {
109714
109988
  }
109715
109989
  function forgetDaemon(pid) {
109716
109990
  try {
109717
- unlinkSync5(recordPath(pid));
109991
+ unlinkSync6(recordPath(pid));
109718
109992
  } catch {
109719
109993
  }
109720
109994
  invalidateSupervisorCache();
@@ -109724,7 +109998,7 @@ function unregisterSelfAsDaemon() {
109724
109998
  }
109725
109999
  function readRecord(pid) {
109726
110000
  try {
109727
- return JSON.parse(readFileSync45(recordPath(pid), "utf-8"));
110001
+ return JSON.parse(readFileSync46(recordPath(pid), "utf-8"));
109728
110002
  } catch {
109729
110003
  return null;
109730
110004
  }
@@ -109738,7 +110012,7 @@ function allRegisteredPids() {
109738
110012
  }
109739
110013
  function registeredDaemons(selfPid) {
109740
110014
  const out = [];
109741
- if (!existsSync31(registryDir()))
110015
+ if (!existsSync32(registryDir()))
109742
110016
  return out;
109743
110017
  for (const pid of allRegisteredPids()) {
109744
110018
  if (pid === selfPid)
@@ -109767,18 +110041,18 @@ function liveDaemons() {
109767
110041
  }
109768
110042
 
109769
110043
  // ../../packages/host-core/dist/device-identity.js
109770
- import { join as join66 } from "node:path";
109771
- 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";
109772
110046
  init_credentials();
109773
110047
  var cached3 = null;
109774
110048
  function identityPath() {
109775
- return join66(daemonDir2(), "identity.json");
110049
+ return join67(daemonDir2(), "identity.json");
109776
110050
  }
109777
110051
  async function loadOrCreateDeviceIdentity() {
109778
110052
  if (cached3)
109779
110053
  return cached3;
109780
110054
  try {
109781
- const stored = JSON.parse(readFileSync46(identityPath(), "utf-8"));
110055
+ const stored = JSON.parse(readFileSync47(identityPath(), "utf-8"));
109782
110056
  if (stored?.privateJwk) {
109783
110057
  cached3 = await importIdentity(stored.privateJwk);
109784
110058
  return cached3;
@@ -109788,10 +110062,10 @@ async function loadOrCreateDeviceIdentity() {
109788
110062
  const kp = await generateIdentityKeyPair(true);
109789
110063
  const { privateJwk, publicRaw } = await exportIdentity(kp);
109790
110064
  const dir2 = daemonDir2();
109791
- if (!existsSync32(dir2))
109792
- mkdirSync35(dir2, { recursive: true, mode: 448 });
110065
+ if (!existsSync33(dir2))
110066
+ mkdirSync36(dir2, { recursive: true, mode: 448 });
109793
110067
  const tmp = `${identityPath()}.tmp`;
109794
- 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 });
109795
110069
  renameSync10(tmp, identityPath());
109796
110070
  try {
109797
110071
  chmodSync4(identityPath(), 384);
@@ -109802,7 +110076,7 @@ async function loadOrCreateDeviceIdentity() {
109802
110076
  }
109803
110077
  var sealingCached = null;
109804
110078
  function sealingPath() {
109805
- return join66(daemonDir2(), "sealing.json");
110079
+ return join67(daemonDir2(), "sealing.json");
109806
110080
  }
109807
110081
  var EC_DH = { name: "ECDH", namedCurve: "P-256" };
109808
110082
  async function loadOrCreateSealingKey() {
@@ -109810,7 +110084,7 @@ async function loadOrCreateSealingKey() {
109810
110084
  return sealingCached;
109811
110085
  const { subtle: subtle5 } = globalThis.crypto;
109812
110086
  try {
109813
- const stored = JSON.parse(readFileSync46(sealingPath(), "utf-8"));
110087
+ const stored = JSON.parse(readFileSync47(sealingPath(), "utf-8"));
109814
110088
  if (stored?.privateJwk && stored.publicRaw) {
109815
110089
  const privateKey = await subtle5.importKey("jwk", stored.privateJwk, EC_DH, true, ["deriveBits"]);
109816
110090
  sealingCached = { privateKey, publicRaw: unb64u(stored.publicRaw) };
@@ -109822,10 +110096,10 @@ async function loadOrCreateSealingKey() {
109822
110096
  const publicRaw = new Uint8Array(await subtle5.exportKey("raw", kp.publicKey));
109823
110097
  const privateJwk = await subtle5.exportKey("jwk", kp.privateKey);
109824
110098
  const dir2 = daemonDir2();
109825
- if (!existsSync32(dir2))
109826
- mkdirSync35(dir2, { recursive: true, mode: 448 });
110099
+ if (!existsSync33(dir2))
110100
+ mkdirSync36(dir2, { recursive: true, mode: 448 });
109827
110101
  const tmp = `${sealingPath()}.tmp`;
109828
- 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 });
109829
110103
  renameSync10(tmp, sealingPath());
109830
110104
  try {
109831
110105
  chmodSync4(sealingPath(), 384);
@@ -109922,6 +110196,7 @@ var BundleOfferLedger = class {
109922
110196
  init_dist6();
109923
110197
 
109924
110198
  // ../../packages/host-core/dist/mesh/netd-client.js
110199
+ import { existsSync as existsSync34, readdirSync as readdirSync12 } from "node:fs";
109925
110200
  import { connect as connect2 } from "node:net";
109926
110201
  import { platform as platform3 } from "node:process";
109927
110202
  var NETD_WIRE_VERSION = 2;
@@ -109934,6 +110209,17 @@ function netdEndpoint() {
109934
110209
  return "/var/run/tesseract-netd.sock";
109935
110210
  return "/run/tesseract-netd.sock";
109936
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
+ }
109937
110223
  function endpointOverride() {
109938
110224
  return process.env.CCB_NETD_SOCKET ?? null;
109939
110225
  }
@@ -110295,9 +110581,6 @@ var NetdEngine = class {
110295
110581
  }
110296
110582
  };
110297
110583
 
110298
- // ../../packages/host-core/dist/mesh/node.js
110299
- import { existsSync as existsSync34 } from "node:fs";
110300
-
110301
110584
  // ../../packages/host-core/dist/mesh/bundle-refresh.js
110302
110585
  init_dist6();
110303
110586
  var CONTEXT = "tsr-bundle-fetch-v1";
@@ -110334,13 +110617,13 @@ ${ts}`);
110334
110617
 
110335
110618
  // ../../packages/host-core/dist/mesh/config.js
110336
110619
  init_credentials();
110337
- 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";
110338
- 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";
110339
110622
  function meshDir() {
110340
- return join68(daemonDir2(), "mesh");
110623
+ return join69(daemonDir2(), "mesh");
110341
110624
  }
110342
110625
  function meshesDir() {
110343
- return join68(meshDir(), "meshes");
110626
+ return join69(meshDir(), "meshes");
110344
110627
  }
110345
110628
  var MESH_DIR_NAME_BYTES = 8;
110346
110629
  function meshDirName(genesisFp) {
@@ -110358,7 +110641,7 @@ function oneMeshDir(meshId) {
110358
110641
  if (!isMeshId(meshId)) {
110359
110642
  throw new Error(`not a mesh id: ${JSON.stringify(meshId.slice(0, 64))}`);
110360
110643
  }
110361
- return join68(meshesDir(), meshId);
110644
+ return join69(meshesDir(), meshId);
110362
110645
  }
110363
110646
  var LEGACY_MESH_ID = "legacy";
110364
110647
  var CERT_GENESIS_FP_OFFSET = 19;
@@ -110376,29 +110659,29 @@ var FILES = {
110376
110659
  local: "local.json"
110377
110660
  };
110378
110661
  function readIfPresent(name, dir2 = meshDir()) {
110379
- const p = join68(dir2, name);
110662
+ const p = join69(dir2, name);
110380
110663
  try {
110381
- return existsSync33(p) ? new Uint8Array(readFileSync47(p)) : void 0;
110664
+ return existsSync35(p) ? new Uint8Array(readFileSync48(p)) : void 0;
110382
110665
  } catch {
110383
110666
  return void 0;
110384
110667
  }
110385
110668
  }
110386
110669
  function migrateSingleMesh() {
110387
- const legacyGenesis = join68(meshDir(), FILES.genesis);
110388
- if (!existsSync33(legacyGenesis))
110670
+ const legacyGenesis = join69(meshDir(), FILES.genesis);
110671
+ if (!existsSync35(legacyGenesis))
110389
110672
  return null;
110390
110673
  const id = meshIdFromCert(readIfPresent(FILES.cert)) ?? LEGACY_MESH_ID;
110391
110674
  const dest = oneMeshDir(id);
110392
110675
  try {
110393
- mkdirSync36(dest, { recursive: true, mode: 448 });
110676
+ mkdirSync37(dest, { recursive: true, mode: 448 });
110394
110677
  chmodSync5(dest, 448);
110395
110678
  for (const f of Object.values(FILES)) {
110396
- const from = join68(meshDir(), f);
110397
- if (existsSync33(from))
110398
- renameSync11(from, join68(dest, f));
110679
+ const from = join69(meshDir(), f);
110680
+ if (existsSync35(from))
110681
+ renameSync11(from, join69(dest, f));
110399
110682
  }
110400
- const key2 = join68(dest, FILES.key);
110401
- if (existsSync33(key2))
110683
+ const key2 = join69(dest, FILES.key);
110684
+ if (existsSync35(key2))
110402
110685
  chmodSync5(key2, 384);
110403
110686
  } catch {
110404
110687
  return null;
@@ -110409,7 +110692,7 @@ function listMeshIds() {
110409
110692
  migrateSingleMesh();
110410
110693
  let names;
110411
110694
  try {
110412
- 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);
110413
110696
  } catch {
110414
110697
  return [];
110415
110698
  }
@@ -110421,15 +110704,15 @@ function listMeshIds() {
110421
110704
  }
110422
110705
  function readLocal(meshId) {
110423
110706
  try {
110424
- return JSON.parse(readFileSync47(join68(oneMeshDir(meshId), FILES.local), "utf8"));
110707
+ return JSON.parse(readFileSync48(join69(oneMeshDir(meshId), FILES.local), "utf8"));
110425
110708
  } catch {
110426
110709
  return null;
110427
110710
  }
110428
110711
  }
110429
110712
  function writeLocal(meshId, state3) {
110430
110713
  try {
110431
- mkdirSync36(oneMeshDir(meshId), { recursive: true, mode: 448 });
110432
- 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 });
110433
110716
  } catch {
110434
110717
  }
110435
110718
  }
@@ -110462,8 +110745,8 @@ function loadMeshIdentity() {
110462
110745
  return first === void 0 ? null : loadMesh(first);
110463
110746
  }
110464
110747
  function writeSecret(name, bytes2, dir2 = meshDir()) {
110465
- const p = join68(dir2, name);
110466
- writeFileSync35(p, bytes2, { mode: 384 });
110748
+ const p = join69(dir2, name);
110749
+ writeFileSync36(p, bytes2, { mode: 384 });
110467
110750
  try {
110468
110751
  chmodSync5(p, 384);
110469
110752
  } catch {
@@ -110475,20 +110758,20 @@ function saveMeshIdentity(id) {
110475
110758
  saveMesh(meshId, id);
110476
110759
  return;
110477
110760
  }
110478
- mkdirSync36(meshDir(), { recursive: true, mode: 448 });
110761
+ mkdirSync37(meshDir(), { recursive: true, mode: 448 });
110479
110762
  try {
110480
110763
  chmodSync5(meshDir(), 448);
110481
110764
  } catch {
110482
110765
  }
110483
- writeFileSync35(join68(meshDir(), FILES.genesis), id.genesis);
110484
- writeFileSync35(join68(meshDir(), FILES.cert), id.cert);
110766
+ writeFileSync36(join69(meshDir(), FILES.genesis), id.genesis);
110767
+ writeFileSync36(join69(meshDir(), FILES.cert), id.cert);
110485
110768
  writeSecret(FILES.key, id.staticPrivate);
110486
110769
  if (id.bundle)
110487
- writeFileSync35(join68(meshDir(), FILES.bundle), id.bundle);
110770
+ writeFileSync36(join69(meshDir(), FILES.bundle), id.bundle);
110488
110771
  }
110489
110772
  function saveMesh(meshId, id) {
110490
110773
  const dir2 = oneMeshDir(meshId);
110491
- mkdirSync36(dir2, { recursive: true, mode: 448 });
110774
+ mkdirSync37(dir2, { recursive: true, mode: 448 });
110492
110775
  try {
110493
110776
  chmodSync5(meshDir(), 448);
110494
110777
  } catch {
@@ -110501,13 +110784,13 @@ function saveMesh(meshId, id) {
110501
110784
  chmodSync5(dir2, 448);
110502
110785
  } catch {
110503
110786
  }
110504
- writeFileSync35(join68(dir2, FILES.genesis), id.genesis);
110505
- writeFileSync35(join68(dir2, FILES.cert), id.cert);
110787
+ writeFileSync36(join69(dir2, FILES.genesis), id.genesis);
110788
+ writeFileSync36(join69(dir2, FILES.cert), id.cert);
110506
110789
  writeSecret(FILES.key, id.staticPrivate, dir2);
110507
110790
  if (id.sigPrivate)
110508
110791
  writeSecret(FILES.sigKey, id.sigPrivate, dir2);
110509
110792
  if (id.bundle)
110510
- writeFileSync35(join68(dir2, FILES.bundle), id.bundle);
110793
+ writeFileSync36(join69(dir2, FILES.bundle), id.bundle);
110511
110794
  if (readLocal(meshId) === null)
110512
110795
  writeLocal(meshId, { joinedAt: Date.now() });
110513
110796
  }
@@ -110517,13 +110800,13 @@ function removeMesh(meshId) {
110517
110800
  var STATUS_REFRESH_MS = 5e3;
110518
110801
  var STATUS_STALE_MS = 2e4;
110519
110802
  function statusPath(meshId) {
110520
- 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");
110521
110804
  }
110522
110805
  function writeStatus(status2, meshId) {
110523
110806
  try {
110524
110807
  const p = statusPath(meshId);
110525
- mkdirSync36(dirname31(p), { recursive: true, mode: 448 });
110526
- 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));
110527
110810
  } catch {
110528
110811
  }
110529
110812
  }
@@ -110535,7 +110818,7 @@ function clearStatus(meshId) {
110535
110818
  }
110536
110819
  function readStatus(meshId) {
110537
110820
  try {
110538
- const raw = JSON.parse(readFileSync47(statusPath(meshId), "utf8"));
110821
+ const raw = JSON.parse(readFileSync48(statusPath(meshId), "utf8"));
110539
110822
  if (typeof raw.at !== "number")
110540
110823
  return null;
110541
110824
  return { ...raw, at: raw.at, stale: Date.now() - raw.at > STATUS_STALE_MS };
@@ -110547,8 +110830,8 @@ function cacheBundle(bundle, meshId) {
110547
110830
  try {
110548
110831
  const id = meshId ?? listMeshIds()[0];
110549
110832
  const dir2 = id === void 0 ? meshDir() : oneMeshDir(id);
110550
- mkdirSync36(dir2, { recursive: true, mode: 448 });
110551
- writeFileSync35(join68(dir2, FILES.bundle), bundle);
110833
+ mkdirSync37(dir2, { recursive: true, mode: 448 });
110834
+ writeFileSync36(join69(dir2, FILES.bundle), bundle);
110552
110835
  } catch {
110553
110836
  }
110554
110837
  }
@@ -110704,7 +110987,7 @@ function loadMeshCore() {
110704
110987
  }
110705
110988
  var meshCore = loadMeshCore();
110706
110989
  function meshEngineStatus() {
110707
- if (process.env.CCB_MESH_IN_DAEMON !== "1" && existsSync34(netdEndpoint())) {
110990
+ if (process.env.CCB_MESH_IN_DAEMON !== "1" && netdListening()) {
110708
110991
  return { available: true, reason: null };
110709
110992
  }
110710
110993
  return { available: meshCore.available === true, reason: meshCore.loadError ?? null };
@@ -110934,7 +111217,14 @@ var MeshNode = class {
110934
111217
  reason: "this machine was removed from the network \u2014 ask an admin for a new invitation"
110935
111218
  };
110936
111219
  }
110937
- 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
+ }
110938
111228
  if (!inNetd && !meshCore.available) {
110939
111229
  return { ok: false, reason: `mesh engine unavailable: ${meshCore.loadError ?? "no prebuilt"}` };
110940
111230
  }
@@ -111683,7 +111973,7 @@ function startNodes(log9) {
111683
111973
  }
111684
111974
 
111685
111975
  // ../../packages/host-core/dist/drops/receive-ui.js
111686
- import { basename as basename12, dirname as dirname32 } from "node:path";
111976
+ import { basename as basename12, dirname as dirname33 } from "node:path";
111687
111977
  var log5 = (...a) => console.log("[drops]", ...a);
111688
111978
  function formatBytes(n) {
111689
111979
  if (!Number.isFinite(n) || n <= 0)
@@ -111748,7 +112038,7 @@ function initDropReceiveUi(deps = {}) {
111748
112038
  log5("reveal failed:", err2 instanceof Error ? err2.message : String(err2));
111749
112039
  }
111750
112040
  };
111751
- const open7 = () => {
112041
+ const open8 = () => {
111752
112042
  const el2 = electronModule();
111753
112043
  if (!el2)
111754
112044
  return;
@@ -111759,7 +112049,7 @@ function initDropReceiveUi(deps = {}) {
111759
112049
  title: "Files received",
111760
112050
  body: `${describe3(e)} \xB7 ${formatBytes(e.bytesDone)}`,
111761
112051
  actions: [{ id: "reveal", label: "Show in Finder" }, { id: "open", label: "Open" }],
111762
- onAction: (id) => id === "open" ? open7() : reveal(),
112052
+ onAction: (id) => id === "open" ? open8() : reveal(),
111763
112053
  // Clicking the banner body is the only reliable action on macOS (buttons need
111764
112054
  // an expanded banner and are suppressed under Focus), so make it do the useful
111765
112055
  // thing rather than nothing.
@@ -111777,7 +112067,7 @@ import { basename as basename13 } from "node:path";
111777
112067
  // ../../packages/host-core/dist/drops/paths.js
111778
112068
  init_base_paths();
111779
112069
  import { mkdir as mkdir14 } from "node:fs/promises";
111780
- import { join as join69 } from "node:path";
112070
+ import { join as join70 } from "node:path";
111781
112071
 
111782
112072
  // ../../packages/host-core/dist/drops/names.js
111783
112073
  var WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
@@ -111866,7 +112156,7 @@ function basenameOf(p) {
111866
112156
  function resolveDropsRoot() {
111867
112157
  const root = resolveHostRoot();
111868
112158
  const preferred = dropsDir();
111869
- return isInsideRoot(preferred, root) ? preferred : join69(root, "Drops");
112159
+ return isInsideRoot(preferred, root) ? preferred : join70(root, "Drops");
111870
112160
  }
111871
112161
  async function ensureDropsRoot() {
111872
112162
  const dir2 = resolveDropsRoot();
@@ -111882,7 +112172,7 @@ async function ensureDropDir(opts) {
111882
112172
  parts.push(sanitizeDropName(opts.sender, "Unknown sender"));
111883
112173
  if (!opts.singleItem && opts.label)
111884
112174
  parts.push(sanitizeDropName(opts.label, "Files"));
111885
- const dir2 = join69(...parts);
112175
+ const dir2 = join70(...parts);
111886
112176
  await mkdir14(dir2, { recursive: true });
111887
112177
  return dir2;
111888
112178
  }
@@ -112025,7 +112315,7 @@ function createDropHandler(deps) {
112025
112315
  // ../../packages/host-core/dist/drops/blob-fetch.js
112026
112316
  import { createWriteStream as createWriteStream2 } from "node:fs";
112027
112317
  import { mkdir as mkdir15, rm as rm5, chmod as chmod3 } from "node:fs/promises";
112028
- import { dirname as dirname33, join as join70 } from "node:path";
112318
+ import { dirname as dirname34, join as join71 } from "node:path";
112029
112319
  import { Readable as Readable2 } from "node:stream";
112030
112320
  import { pipeline } from "node:stream/promises";
112031
112321
 
@@ -112183,8 +112473,8 @@ async function fetchBlobDrop(opts) {
112183
112473
  if (opts.sealedKey) {
112184
112474
  if (!opts.sealingPrivate)
112185
112475
  throw new Error("This device has no sealing key, so it cannot open the transfer.");
112186
- const open7 = opts.openSeal ?? openFromPrivateKey;
112187
- 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));
112188
112478
  }
112189
112479
  const totalBytes = opts.items.reduce((n, i) => n + (i.kind === "file" ? i.size : 0), 0);
112190
112480
  let bytesDone = 0;
@@ -112197,7 +112487,7 @@ async function fetchBlobDrop(opts) {
112197
112487
  log7(`drop ${opts.dropId}: refusing directory "${item.rel}"`);
112198
112488
  continue;
112199
112489
  }
112200
- const abs = join70(opts.destDir, rel);
112490
+ const abs = join71(opts.destDir, rel);
112201
112491
  if (!isInsideRoot(abs, opts.destDir)) {
112202
112492
  log7(`drop ${opts.dropId}: refusing directory outside the destination`);
112203
112493
  continue;
@@ -112218,12 +112508,12 @@ async function fetchBlobDrop(opts) {
112218
112508
  log7(`drop ${opts.dropId}: refusing "${item.rel}"`);
112219
112509
  continue;
112220
112510
  }
112221
- let abs = join70(opts.destDir, rel);
112511
+ let abs = join71(opts.destDir, rel);
112222
112512
  if (!isInsideRoot(abs, opts.destDir)) {
112223
112513
  log7(`drop ${opts.dropId}: refusing a path outside the destination`);
112224
112514
  continue;
112225
112515
  }
112226
- await mkdir15(dirname33(abs), { recursive: true });
112516
+ await mkdir15(dirname34(abs), { recursive: true });
112227
112517
  abs = await uniqueDropPath(abs);
112228
112518
  const res = await fetchFn(new URL(item.url, opts.apiOrigin).toString(), { signal: opts.signal });
112229
112519
  if (!res.ok || !res.body)
@@ -112255,7 +112545,7 @@ async function fetchBlobDrop(opts) {
112255
112545
  }
112256
112546
 
112257
112547
  // ../../packages/host-core/dist/chat-agent.js
112258
- import { randomUUID as randomUUID28 } from "node:crypto";
112548
+ import { randomUUID as randomUUID29 } from "node:crypto";
112259
112549
  init_prompts();
112260
112550
  var TURN_TIMEOUT_MS = 4 * 6e4;
112261
112551
  var PARTIAL_INTERVAL_MS = 700;
@@ -112284,7 +112574,7 @@ function createChatAgentRunner(deps) {
112284
112574
  }
112285
112575
  async function runTurn(prompt2, onPartial) {
112286
112576
  const backend2 = await getSharedBackend();
112287
- const clientRequestId = `chat-agent-${randomUUID28()}`;
112577
+ const clientRequestId = `chat-agent-${randomUUID29()}`;
112288
112578
  return new Promise((resolve16, reject) => {
112289
112579
  let text12 = "";
112290
112580
  let settled = false;
@@ -112493,13 +112783,13 @@ var RdeskServerChannel = class {
112493
112783
  };
112494
112784
 
112495
112785
  // ../../packages/host-core/dist/rdesk/channel-client.js
112496
- import { readFileSync as readFileSync48 } from "node:fs";
112497
- import { join as join71 } from "node:path";
112786
+ import { readFileSync as readFileSync49 } from "node:fs";
112787
+ import { join as join72 } from "node:path";
112498
112788
  var RECONNECT_MS = 2e3;
112499
112789
  var CLAIM_RETRY_MS = 5e3;
112500
112790
  function readEndpoint(dir2, selfPid) {
112501
112791
  try {
112502
- const s = JSON.parse(readFileSync48(join71(dir2, "status.json"), "utf8"));
112792
+ const s = JSON.parse(readFileSync49(join72(dir2, "status.json"), "utf8"));
112503
112793
  if (selfPid && s.pid === selfPid)
112504
112794
  return null;
112505
112795
  return s.localPort && s.localToken ? `ws://127.0.0.1:${s.localPort}/?token=${s.localToken}` : null;
@@ -112944,10 +113234,10 @@ function registerRdpEngine() {
112944
113234
  // ../../packages/host-core/dist/rdesk/audit.js
112945
113235
  init_credentials();
112946
113236
  import { appendFile, stat as stat9, rename as rename4 } from "node:fs/promises";
112947
- import { join as join72 } from "node:path";
113237
+ import { join as join73 } from "node:path";
112948
113238
  var MAX_BYTES2 = 2 * 1024 * 1024;
112949
113239
  function rdeskAuditPath() {
112950
- return join72(daemonDir2(), "rdesk-audit.jsonl");
113240
+ return join73(daemonDir2(), "rdesk-audit.jsonl");
112951
113241
  }
112952
113242
  var queue = [];
112953
113243
  var draining = false;
@@ -112989,13 +113279,13 @@ function appendRdeskAudit(e) {
112989
113279
 
112990
113280
  // ../../packages/host-core/dist/fileprovider-bridge.js
112991
113281
  init_managed_spawn();
112992
- 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";
112993
113283
  import { homedir as homedir10 } from "node:os";
112994
- import { join as join73 } from "node:path";
113284
+ import { join as join74 } from "node:path";
112995
113285
  init_safe_kill();
112996
113286
  var APPEX_BUNDLE_ID = "dev.tesseract.FileProvider";
112997
113287
  function appexBridgeInfoPath() {
112998
- 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");
112999
113289
  }
113000
113290
  function clearBridgeInfo() {
113001
113291
  if (process.platform !== "darwin")
@@ -113160,9 +113450,9 @@ function stopFileProviderBridge() {
113160
113450
 
113161
113451
  // ../../packages/host-core/dist/vault/autofill-bridge.js
113162
113452
  import { randomBytes as randomBytes9 } from "node:crypto";
113163
- 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";
113164
113454
  import { homedir as homedir11 } from "node:os";
113165
- import { join as join74 } from "node:path";
113455
+ import { join as join75 } from "node:path";
113166
113456
 
113167
113457
  // ../../packages/host-core/dist/vault/peer-verify.js
113168
113458
  import { execFile as execFile9 } from "node:child_process";
@@ -113224,10 +113514,10 @@ async function isTrustedAutofillPeer(remotePort) {
113224
113514
  var APPEX_BUNDLE_ID2 = "dev.tesseract.AutoFill";
113225
113515
  var BRIDGE_PORTS2 = [17872, 17873, 17874, 17875];
113226
113516
  function appexContainerData() {
113227
- return join74(homedir11(), "Library", "Containers", APPEX_BUNDLE_ID2, "Data");
113517
+ return join75(homedir11(), "Library", "Containers", APPEX_BUNDLE_ID2, "Data");
113228
113518
  }
113229
113519
  function bridgeInfoPath() {
113230
- return join74(appexContainerData(), "Library", "Application Support", "tesseract-autofill-bridge.json");
113520
+ return join75(appexContainerData(), "Library", "Application Support", "tesseract-autofill-bridge.json");
113231
113521
  }
113232
113522
  var infoLoggedOnce = false;
113233
113523
  function writeBridgeInfo(port, token3, log9) {
@@ -113235,16 +113525,16 @@ function writeBridgeInfo(port, token3, log9) {
113235
113525
  return;
113236
113526
  const containerData = appexContainerData();
113237
113527
  try {
113238
- if (!existsSync36(containerData)) {
113528
+ if (!existsSync37(containerData)) {
113239
113529
  if (!infoLoggedOnce) {
113240
113530
  infoLoggedOnce = true;
113241
113531
  log9("autofill bridge-info SKIP: no appex container yet at", containerData);
113242
113532
  }
113243
113533
  return;
113244
113534
  }
113245
- const dir2 = join74(containerData, "Library", "Application Support");
113246
- mkdirSync38(dir2, { recursive: true });
113247
- 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 });
113248
113538
  if (!infoLoggedOnce) {
113249
113539
  infoLoggedOnce = true;
113250
113540
  log9("autofill bridge-info WROTE", port, "\u2192", dir2);
@@ -113484,9 +113774,9 @@ function createNodePowerController() {
113484
113774
 
113485
113775
  // ../../packages/host-core/dist/native-host.js
113486
113776
  import { execFileSync as execFileSync4 } from "node:child_process";
113487
- 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";
113488
113778
  import { homedir as homedir12, platform as platform5 } from "node:os";
113489
- 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";
113490
113780
  import { fileURLToPath as fileURLToPath6 } from "node:url";
113491
113781
  var HOST_NAME = "com.tesseract.companion";
113492
113782
  var EXTENSION_IDS = ["icpnghhpcmaonjckkpilpajblfehpplo", "giolfpookdhjfafcchaflhmigghaeffn"];
@@ -113495,41 +113785,41 @@ function browserProfileDirs() {
113495
113785
  const home = homedir12();
113496
113786
  const p = platform5();
113497
113787
  if (p === "darwin") {
113498
- const base = join75(home, "Library/Application Support");
113499
- 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));
113500
113790
  }
113501
113791
  if (p === "win32")
113502
113792
  return [];
113503
- const cfg2 = join75(home, ".config");
113504
- 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));
113505
113795
  }
113506
113796
  function resolveBridge(log9) {
113507
113797
  const candidates = [
113508
113798
  process.env.CCB_COMPANION_HOST_JS,
113509
- process.resourcesPath ? join75(process.resourcesPath, "companion-host", BRIDGE_BASENAME) : void 0
113799
+ process.resourcesPath ? join76(process.resourcesPath, "companion-host", BRIDGE_BASENAME) : void 0
113510
113800
  ];
113511
113801
  try {
113512
- const here = dirname34(fileURLToPath6(import.meta.url));
113802
+ const here = dirname35(fileURLToPath6(import.meta.url));
113513
113803
  candidates.push(resolve12(here, "../../../apps/companion-host/dist", BRIDGE_BASENAME));
113514
113804
  candidates.push(resolve12(here, "../../apps/companion-host/dist", BRIDGE_BASENAME));
113515
113805
  } catch {
113516
113806
  }
113517
113807
  for (const c of candidates)
113518
- if (c && existsSync37(c))
113808
+ if (c && existsSync38(c))
113519
113809
  return c;
113520
113810
  log9("companion native-host: bridge not found; skipping registration (looked in", candidates.filter(Boolean).join(" , "), ")");
113521
113811
  return null;
113522
113812
  }
113523
113813
  function writeLauncher(daemonDir3, bridge, runtime) {
113524
113814
  const isWin = platform5() === "win32";
113525
- const launcher = join75(daemonDir3, isWin ? "companion-host.cmd" : "companion-host.sh");
113815
+ const launcher = join76(daemonDir3, isWin ? "companion-host.cmd" : "companion-host.sh");
113526
113816
  if (isWin) {
113527
- writeFileSync38(launcher, `@echo off\r
113817
+ writeFileSync39(launcher, `@echo off\r
113528
113818
  set ELECTRON_RUN_AS_NODE=1\r
113529
113819
  "${runtime}" "${bridge}" %*\r
113530
113820
  `);
113531
113821
  } else {
113532
- writeFileSync38(launcher, `#!/bin/sh
113822
+ writeFileSync39(launcher, `#!/bin/sh
113533
113823
  # Tesseract Companion native-messaging launcher (auto-written by the daemon).
113534
113824
  ELECTRON_RUN_AS_NODE=1 exec "${runtime}" "${bridge}" "$@"
113535
113825
  `);
@@ -113544,7 +113834,7 @@ function registerNativeHost(opts) {
113544
113834
  if (!bridge)
113545
113835
  return;
113546
113836
  const runtime = opts.runtime ?? process.execPath;
113547
- mkdirSync39(opts.daemonDir, { recursive: true });
113837
+ mkdirSync40(opts.daemonDir, { recursive: true });
113548
113838
  const launcher = writeLauncher(opts.daemonDir, bridge, runtime);
113549
113839
  const manifestJson = JSON.stringify({
113550
113840
  name: HOST_NAME,
@@ -113557,12 +113847,12 @@ function registerNativeHost(opts) {
113557
113847
  return registerWindows(opts.daemonDir, manifestJson, log9);
113558
113848
  let wrote = 0;
113559
113849
  for (const profile of browserProfileDirs()) {
113560
- if (!existsSync37(profile))
113850
+ if (!existsSync38(profile))
113561
113851
  continue;
113562
113852
  try {
113563
- const dir2 = join75(profile, "NativeMessagingHosts");
113564
- mkdirSync39(dir2, { recursive: true });
113565
- 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);
113566
113856
  wrote++;
113567
113857
  } catch {
113568
113858
  }
@@ -113574,8 +113864,8 @@ function registerNativeHost(opts) {
113574
113864
  }
113575
113865
  function registerWindows(daemonDir3, manifestJson, log9) {
113576
113866
  try {
113577
- const manifestPath = join75(daemonDir3, `${HOST_NAME}.json`);
113578
- writeFileSync38(manifestPath, manifestJson);
113867
+ const manifestPath = join76(daemonDir3, `${HOST_NAME}.json`);
113868
+ writeFileSync39(manifestPath, manifestJson);
113579
113869
  for (const root of ["Software\\Google\\Chrome", "Software\\Microsoft\\Edge", "Software\\BraveSoftware\\Brave-Browser"]) {
113580
113870
  try {
113581
113871
  execFileSync4("reg", ["add", `HKCU\\${root}\\NativeMessagingHosts\\${HOST_NAME}`, "/ve", "/t", "REG_SZ", "/d", manifestPath, "/f"], { stdio: "ignore" });
@@ -113593,10 +113883,10 @@ init_daemon_settings();
113593
113883
 
113594
113884
  // ../../packages/host-core/dist/activity/activity-tracker.js
113595
113885
  init_credentials();
113596
- import { promises as fsp, writeFileSync as writeFileSync39, mkdirSync as mkdirSync40, existsSync as existsSync38 } from "node:fs";
113597
- 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";
113598
113888
  function activityProfilePath() {
113599
- return join76(daemonDir2(), "activity-profile.json");
113889
+ return join77(daemonDir2(), "activity-profile.json");
113600
113890
  }
113601
113891
  var MAX_APPS = 300;
113602
113892
  var MAX_AGE_DAYS = 120;
@@ -113671,7 +113961,7 @@ function createActivityTracker(opts = {}) {
113671
113961
  return;
113672
113962
  const key2 = front.bundleId || front.name;
113673
113963
  await ensureLoaded();
113674
- if (profile && Object.keys(profile.apps).length && !existsSync38(activityProfilePath())) {
113964
+ if (profile && Object.keys(profile.apps).length && !existsSync39(activityProfilePath())) {
113675
113965
  log9("activity profile cleared externally \u2014 resetting in-memory");
113676
113966
  profile = { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), apps: {} };
113677
113967
  }
@@ -113707,8 +113997,8 @@ function createActivityTracker(opts = {}) {
113707
113997
  if (profile) {
113708
113998
  pruneProfile(profile);
113709
113999
  profile.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
113710
- mkdirSync40(daemonDir2(), { recursive: true, mode: 448 });
113711
- writeFileSync39(activityProfilePath(), JSON.stringify(profile), { mode: 384 });
114000
+ mkdirSync41(daemonDir2(), { recursive: true, mode: 448 });
114001
+ writeFileSync40(activityProfilePath(), JSON.stringify(profile), { mode: 384 });
113712
114002
  dirty = 0;
113713
114003
  }
113714
114004
  } catch (e) {
@@ -113763,7 +114053,7 @@ init_credentials();
113763
114053
  // ../../packages/host-core/dist/error-report.js
113764
114054
  init_dist2();
113765
114055
  init_credentials();
113766
- import { randomUUID as randomUUID29 } from "node:crypto";
114056
+ import { randomUUID as randomUUID30 } from "node:crypto";
113767
114057
  import { release as osRelease, arch as osArch } from "node:os";
113768
114058
  var MAX_QUEUE = 100;
113769
114059
  var FLUSH_INTERVAL_MS = 3e4;
@@ -113815,7 +114105,7 @@ function captureDaemonError(error51, opts = {}) {
113815
114105
  return;
113816
114106
  const creds3 = readCredentials();
113817
114107
  const report = {
113818
- reportId: randomUUID29(),
114108
+ reportId: randomUUID30(),
113819
114109
  occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
113820
114110
  schemaVersion: 1,
113821
114111
  surface,
@@ -113912,8 +114202,8 @@ async function runDaemon(opts = {}) {
113912
114202
  log9("paths", JSON.stringify(sealBasePaths()));
113913
114203
  const OUR_STARTED_AT = procStartedAt(process.pid);
113914
114204
  let ownsMachine = false;
113915
- const pidfile = () => join77(daemonDir2(), "daemon.lock");
113916
- const statusFile = () => join77(daemonDir2(), "status.json");
114205
+ const pidfile = () => join78(daemonDir2(), "daemon.lock");
114206
+ const statusFile = () => join78(daemonDir2(), "status.json");
113917
114207
  const isAlive2 = (pid) => {
113918
114208
  if (!Number.isFinite(pid) || pid <= 0)
113919
114209
  return false;
@@ -113926,7 +114216,7 @@ async function runDaemon(opts = {}) {
113926
114216
  };
113927
114217
  const lockHeldByAnother = () => {
113928
114218
  try {
113929
- const pid = Number(readFileSync49(pidfile(), "utf-8").trim());
114219
+ const pid = Number(readFileSync50(pidfile(), "utf-8").trim());
113930
114220
  return Number.isFinite(pid) && pid > 0 && pid !== process.pid && isAlive2(pid);
113931
114221
  } catch {
113932
114222
  return false;
@@ -113934,7 +114224,7 @@ async function runDaemon(opts = {}) {
113934
114224
  };
113935
114225
  const lockHeldByYieldingSubset = () => {
113936
114226
  try {
113937
- const pid = Number(readFileSync49(pidfile(), "utf-8").trim());
114227
+ const pid = Number(readFileSync50(pidfile(), "utf-8").trim());
113938
114228
  if (!Number.isFinite(pid) || pid <= 0 || pid === process.pid || !isAlive2(pid))
113939
114229
  return false;
113940
114230
  return liveDaemons().some((d) => d.pid === pid && d.rdeskOnly === true);
@@ -113945,22 +114235,22 @@ async function runDaemon(opts = {}) {
113945
114235
  function acquireLock2() {
113946
114236
  const f = pidfile();
113947
114237
  try {
113948
- if (!existsSync39(daemonDir2()))
113949
- mkdirSync41(daemonDir2(), { recursive: true, mode: 448 });
114238
+ if (!existsSync40(daemonDir2()))
114239
+ mkdirSync42(daemonDir2(), { recursive: true, mode: 448 });
113950
114240
  } catch {
113951
114241
  }
113952
114242
  for (let attempt = 0; attempt < 2; attempt++) {
113953
114243
  try {
113954
- writeFileSync40(f, String(process.pid), { flag: "wx" });
114244
+ writeFileSync41(f, String(process.pid), { flag: "wx" });
113955
114245
  return true;
113956
114246
  } catch {
113957
114247
  try {
113958
- const prev = Number(readFileSync49(f, "utf-8").trim());
114248
+ const prev = Number(readFileSync50(f, "utf-8").trim());
113959
114249
  if (!prev)
113960
114250
  return false;
113961
114251
  if (prev !== process.pid && isAlive2(prev))
113962
114252
  return false;
113963
- unlinkSync6(f);
114253
+ unlinkSync7(f);
113964
114254
  } catch {
113965
114255
  return false;
113966
114256
  }
@@ -113971,8 +114261,8 @@ async function runDaemon(opts = {}) {
113971
114261
  function releaseLock() {
113972
114262
  try {
113973
114263
  const f = pidfile();
113974
- if (existsSync39(f) && Number(readFileSync49(f, "utf-8").trim()) === process.pid)
113975
- unlinkSync6(f);
114264
+ if (existsSync40(f) && Number(readFileSync50(f, "utf-8").trim()) === process.pid)
114265
+ unlinkSync7(f);
113976
114266
  } catch {
113977
114267
  }
113978
114268
  }
@@ -113981,7 +114271,7 @@ async function runDaemon(opts = {}) {
113981
114271
  if (!ownsMachine)
113982
114272
  return;
113983
114273
  try {
113984
- 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 }));
113985
114275
  chmodSync7(statusFile(), 384);
113986
114276
  } catch {
113987
114277
  }
@@ -114039,6 +114329,7 @@ async function runDaemon(opts = {}) {
114039
114329
  apiOrigin: apiOriginForMachine(),
114040
114330
  backendOrigin: backendOriginForMachine(),
114041
114331
  isAllowedOrigin: isAllowedApiOrigin,
114332
+ deviceId: persistentDeviceId(),
114042
114333
  log: (msg) => log9(msg)
114043
114334
  });
114044
114335
  machine = m;
@@ -114490,6 +114781,7 @@ async function runDaemon(opts = {}) {
114490
114781
  apiOrigin: c.apiOrigin,
114491
114782
  backendOrigin: c.backendOrigin,
114492
114783
  isAllowedOrigin: isAllowedApiOrigin,
114784
+ deviceId: persistentDeviceId(),
114493
114785
  log: (m) => log9(m)
114494
114786
  });
114495
114787
  if (!next?.accessToken) {
@@ -114516,7 +114808,7 @@ async function runDaemon(opts = {}) {
114516
114808
  if (r.status === 401) {
114517
114809
  log9("device token no longer valid \u2014 dropping to local-only on restart");
114518
114810
  try {
114519
- unlinkSync6(join77(daemonDir2(), "credentials.json"));
114811
+ unlinkSync7(join78(daemonDir2(), "credentials.json"));
114520
114812
  } catch {
114521
114813
  }
114522
114814
  shutdown(0, "token-revoked-401");
@@ -114545,6 +114837,7 @@ async function runDaemon(opts = {}) {
114545
114837
  c = fresh;
114546
114838
  accessToken = fresh.accessToken;
114547
114839
  log9(`signed in as ${fresh.userId} \u2014 re-homing the control link to the account`);
114840
+ setControlLinkDeviceId(fresh.deviceId);
114548
114841
  refreshControlLink();
114549
114842
  return;
114550
114843
  }
@@ -114552,6 +114845,7 @@ async function runDaemon(opts = {}) {
114552
114845
  apiOrigin: c.apiOrigin,
114553
114846
  backendOrigin: c.backendOrigin,
114554
114847
  isAllowedOrigin: isAllowedApiOrigin,
114848
+ deviceId: persistentDeviceId(),
114555
114849
  log: (msg) => log9(msg)
114556
114850
  });
114557
114851
  if (!m?.accessToken) {
@@ -114562,6 +114856,7 @@ async function runDaemon(opts = {}) {
114562
114856
  c = { ...c, accessToken: m.accessToken, refreshSecret: "", dtid: "", userId: "", deviceId: m.deviceId, publicId: m.publicId, expiresAt: m.expiresAt ?? c.expiresAt };
114563
114857
  accessToken = m.accessToken;
114564
114858
  log9("signed out \u2014 this machine speaks for itself again");
114859
+ setControlLinkDeviceId(m.deviceId);
114565
114860
  refreshControlLink();
114566
114861
  });
114567
114862
  registerTesseractEngine({ getIceServers: () => fetchIceServers() });
@@ -114814,7 +115109,7 @@ async function runDaemon(opts = {}) {
114814
115109
  let freeTicks = 0;
114815
115110
  const lockHolder = () => {
114816
115111
  try {
114817
- return Number(readFileSync49(pidfile(), "utf-8").trim()) || 0;
115112
+ return Number(readFileSync50(pidfile(), "utf-8").trim()) || 0;
114818
115113
  } catch {
114819
115114
  return 0;
114820
115115
  }
@@ -114891,7 +115186,7 @@ async function runDaemon(opts = {}) {
114891
115186
  // open. getRdeskClientWebContents() is null for the SERVER / full-app daemon (no client
114892
115187
  // window) → those sends are no-ops, so this is inert outside the rdesk-client role.
114893
115188
  pushHosts: (hosts) => {
114894
- writeStatus2({ deviceId: c.deviceId, connected: true });
115189
+ writeStatus2({ deviceId: c.deviceId, ownHostId: ownHost(), connected: true });
114895
115190
  getRdeskClientWebContents()?.send("hostlink:hosts", hosts);
114896
115191
  },
114897
115192
  ownHostResolved: (own2) => {
@@ -115023,7 +115318,7 @@ async function runDaemon(opts = {}) {
115023
115318
  if (appPid > 0 && appPid !== process.pid) {
115024
115319
  const quitMarker = () => {
115025
115320
  try {
115026
- 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;
115027
115322
  } catch {
115028
115323
  return 0;
115029
115324
  }
@@ -115048,7 +115343,7 @@ async function runDaemon(opts = {}) {
115048
115343
  log9(`desktop app (pid ${appPid}) is gone with NO clean-quit marker \u2014 reporting`);
115049
115344
  const tail3 = (name) => {
115050
115345
  try {
115051
- const buf = readFileSync49(join77(daemonDir2(), name), "utf-8");
115346
+ const buf = readFileSync50(join78(daemonDir2(), name), "utf-8");
115052
115347
  return buf.length > 4096 ? buf.slice(-4096) : buf;
115053
115348
  } catch {
115054
115349
  return void 0;
@@ -115079,14 +115374,14 @@ async function runDaemon(opts = {}) {
115079
115374
  }
115080
115375
  try {
115081
115376
  const DAEMON_LOG_CAP = 2 * 1024 * 1024;
115082
- const daemonLogFile = join77(daemonDir2(), "daemon.log");
115377
+ const daemonLogFile = join78(daemonDir2(), "daemon.log");
115083
115378
  const capTimer = setInterval(() => {
115084
115379
  try {
115085
- if (existsSync39(daemonLogFile) && statSync14(daemonLogFile).size > DAEMON_LOG_CAP) {
115086
- const buf = readFileSync49(daemonLogFile, "utf-8");
115380
+ if (existsSync40(daemonLogFile) && statSync15(daemonLogFile).size > DAEMON_LOG_CAP) {
115381
+ const buf = readFileSync50(daemonLogFile, "utf-8");
115087
115382
  const kept = `\u2026[daemon.log capped at ${(/* @__PURE__ */ new Date()).toISOString()}]\u2026
115088
115383
  ` + buf.slice(-DAEMON_LOG_CAP / 2);
115089
- writeFileSync40(daemonLogFile, kept);
115384
+ writeFileSync41(daemonLogFile, kept);
115090
115385
  }
115091
115386
  } catch {
115092
115387
  }
@@ -115396,15 +115691,15 @@ init_credentials();
115396
115691
 
115397
115692
  // ../../packages/host-core/dist/net-service/ensure-installed.js
115398
115693
  import { execFile as execFile14 } from "node:child_process";
115399
- import { existsSync as existsSync43 } from "node:fs";
115400
- 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";
115401
115696
  import { promisify as promisify10 } from "node:util";
115402
115697
 
115403
115698
  // ../../packages/host-core/dist/net-service/launchd-system.js
115404
115699
  import { spawn as spawn9 } from "node:child_process";
115405
- 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";
115406
115701
  import { tmpdir as tmpdir6 } from "node:os";
115407
- import { join as join78 } from "node:path";
115702
+ import { join as join79 } from "node:path";
115408
115703
 
115409
115704
  // ../../packages/host-core/dist/net-service/owner-uid.js
115410
115705
  function installOwnerUid(env = process.env, self2 = typeof process.getuid === "function" ? process.getuid() : 0) {
@@ -115496,9 +115791,9 @@ ${args}
115496
115791
  <key>ProcessType</key>
115497
115792
  <string>Interactive</string>
115498
115793
  <key>StandardErrorPath</key>
115499
- <string>${xml(join78(spec.stateDir, "netd.log"))}</string>
115794
+ <string>${xml(join79(spec.stateDir, "netd.log"))}</string>
115500
115795
  <key>StandardOutPath</key>
115501
- <string>${xml(join78(spec.stateDir, "netd.log"))}</string>
115796
+ <string>${xml(join79(spec.stateDir, "netd.log"))}</string>
115502
115797
  </dict>
115503
115798
  </plist>
115504
115799
  `;
@@ -115511,10 +115806,10 @@ function runForCode(cmd, args) {
115511
115806
  });
115512
115807
  }
115513
115808
  async function elevate(script) {
115514
- const dir2 = mkdtempSync2(join78(tmpdir6(), "tesseract-netd-"));
115515
- const path6 = join78(dir2, "install.sh");
115809
+ const dir2 = mkdtempSync2(join79(tmpdir6(), "tesseract-netd-"));
115810
+ const path6 = join79(dir2, "install.sh");
115516
115811
  try {
115517
- writeFileSync41(path6, script, { mode: 384 });
115812
+ writeFileSync42(path6, script, { mode: 384 });
115518
115813
  if (await alreadyElevated()) {
115519
115814
  return { code: await runForCode("/bin/sh", [path6]), declined: false };
115520
115815
  }
@@ -115573,9 +115868,9 @@ ${plist}TESSERACT_PLIST_EOF`,
115573
115868
  };
115574
115869
  },
115575
115870
  async state() {
115576
- if (!existsSync40(PLIST))
115871
+ if (!existsSync41(PLIST))
115577
115872
  return { installed: false, running: false };
115578
- const owner = parseOwnerUid(readFileSync50(PLIST, "utf8"));
115873
+ const owner = parseOwnerUid(readFileSync51(PLIST, "utf8"));
115579
115874
  const running2 = await netdAvailable();
115580
115875
  return {
115581
115876
  installed: true,
@@ -115593,7 +115888,7 @@ ${plist}TESSERACT_PLIST_EOF`,
115593
115888
 
115594
115889
  // ../../packages/host-core/dist/net-service/systemd-system.js
115595
115890
  import { spawn as spawn11 } from "node:child_process";
115596
- import { existsSync as existsSync41, readFileSync as readFileSync51 } from "node:fs";
115891
+ import { existsSync as existsSync42, readFileSync as readFileSync52 } from "node:fs";
115597
115892
 
115598
115893
  // ../../packages/host-core/dist/service/exec.js
115599
115894
  import { execFile as execFile11, spawn as spawn10 } from "node:child_process";
@@ -115629,6 +115924,8 @@ async function elevated(script) {
115629
115924
  }
115630
115925
  var UNIT = "tesseract-netd.service";
115631
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`;
115632
115929
  function unitVal(v) {
115633
115930
  return v.replace(/%/g, "%%");
115634
115931
  }
@@ -115700,8 +115997,12 @@ WantedBy=multi-user.target
115700
115997
  function buildInstallScript(spec) {
115701
115998
  return [
115702
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)}`,
115703
116004
  `cat > ${sh2(UNIT_PATH)} <<'TESSERACT_UNIT_EOF'
115704
- ${buildUnit(spec)}TESSERACT_UNIT_EOF`,
116005
+ ${buildUnit({ ...spec, exec: SYSTEM_EXEC })}TESSERACT_UNIT_EOF`,
115705
116006
  "systemctl daemon-reload",
115706
116007
  `systemctl enable ${UNIT}`,
115707
116008
  // RESTART, not `enable --now`. `--now` only STARTS, so on a REINSTALL it leaves the
@@ -115730,15 +116031,19 @@ function makeSystemdSystem() {
115730
116031
  const script = [
115731
116032
  `systemctl disable --now ${UNIT} || true`,
115732
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)}`,
115733
116038
  "systemctl daemon-reload"
115734
116039
  ].join("\n");
115735
116040
  const code = await elevated(script);
115736
116041
  return code === 0 ? { ok: true } : { ok: false, detail: `removing the helper failed (exit ${code})` };
115737
116042
  },
115738
116043
  async state() {
115739
- if (!existsSync41(UNIT_PATH))
116044
+ if (!existsSync42(UNIT_PATH))
115740
116045
  return { installed: false, running: false };
115741
- const owner = parseOwnerUid(readFileSync51(UNIT_PATH, "utf8"));
116046
+ const owner = parseOwnerUid(readFileSync52(UNIT_PATH, "utf8"));
115742
116047
  const active = await tryRun("systemctl", ["is-active", UNIT]);
115743
116048
  const running2 = active.stdout.trim() === "active";
115744
116049
  const own2 = owner === void 0 ? {} : { ownerUid: owner };
@@ -115763,9 +116068,9 @@ function sh2(s) {
115763
116068
 
115764
116069
  // ../../packages/host-core/dist/net-service/windows-service.js
115765
116070
  import { execFile as execFile12, spawn as spawn12 } from "node:child_process";
115766
- 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";
115767
116072
  import { tmpdir as tmpdir7 } from "node:os";
115768
- import { join as join79 } from "node:path";
116073
+ import { join as join80 } from "node:path";
115769
116074
  import { promisify as promisify8 } from "node:util";
115770
116075
  var run6 = promisify8(execFile12);
115771
116076
  var SERVICE = "TesseractNetd";
@@ -115793,9 +116098,9 @@ function buildBinaryPath(spec) {
115793
116098
  return parts.map((p) => `"${p}"`).join(" ");
115794
116099
  }
115795
116100
  async function elevatePowerShell(script) {
115796
- const dir2 = mkdtempSync3(join79(tmpdir7(), "tesseract-netd-"));
115797
- const inner = join79(dir2, "install.ps1");
115798
- 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" });
115799
116104
  if (await alreadyElevated()) {
115800
116105
  return new Promise((resolve16) => {
115801
116106
  const p = spawn12("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", inner], { stdio: "inherit" });
@@ -115810,8 +116115,8 @@ async function elevatePowerShell(script) {
115810
116115
  p.on("close", (code) => finish(code ?? 1));
115811
116116
  });
115812
116117
  }
115813
- const outer = join79(dir2, "elevate.ps1");
115814
- writeFileSync42(outer, [
116118
+ const outer = join80(dir2, "elevate.ps1");
116119
+ writeFileSync43(outer, [
115815
116120
  '$ErrorActionPreference = "Stop"',
115816
116121
  "try {",
115817
116122
  ` $p = Start-Process -FilePath "powershell.exe" -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File",${ps(inner)}) -Verb RunAs -Wait -PassThru`,
@@ -115999,15 +116304,15 @@ function makeNetService() {
115999
116304
  }
116000
116305
 
116001
116306
  // ../../packages/host-core/dist/net-service/netd-binary.js
116002
- import { existsSync as existsSync42 } from "node:fs";
116003
- 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";
116004
116309
  import { fileURLToPath as fileURLToPath7 } from "node:url";
116005
116310
  function netdBinaryName() {
116006
116311
  return process.platform === "win32" ? "tesseract-netd.exe" : "tesseract-netd";
116007
116312
  }
116008
116313
  function override2() {
116009
116314
  const p = process.env.CCB_NETD_BIN;
116010
- return p && existsSync42(p) ? p : null;
116315
+ return p && existsSync43(p) ? p : null;
116011
116316
  }
116012
116317
  function netdBinaryPath() {
116013
116318
  const fromEnv = override2();
@@ -116017,24 +116322,24 @@ function netdBinaryPath() {
116017
116322
  const candidates = [];
116018
116323
  const resources = process.resourcesPath;
116019
116324
  if (resources)
116020
- candidates.push(join80(resources, "netd", name));
116325
+ candidates.push(join81(resources, "netd", name));
116021
116326
  try {
116022
- const here = dirname35(fileURLToPath7(import.meta.url));
116023
- candidates.push(join80(here, "..", "..", "netd", name));
116024
- 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));
116025
116330
  const triple = `${process.platform}-${process.arch}`;
116026
- for (const root of [here, join80(here, ".."), join80(here, "..", "..")]) {
116027
- 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));
116028
116333
  }
116029
116334
  } catch {
116030
116335
  }
116031
116336
  if (process.env.CCB_REPO_ROOT) {
116032
- 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));
116033
116338
  }
116034
- candidates.push(join80(process.cwd(), "crates", "target", "release", name));
116339
+ candidates.push(join81(process.cwd(), "crates", "target", "release", name));
116035
116340
  for (const c of candidates) {
116036
116341
  try {
116037
- if (existsSync42(c))
116342
+ if (existsSync43(c))
116038
116343
  return c;
116039
116344
  } catch {
116040
116345
  }
@@ -116076,7 +116381,7 @@ async function ensureNetHelperInstalled() {
116076
116381
  if (st.installed && !mismatched)
116077
116382
  return { ok: true, already: true };
116078
116383
  const exec2 = netdBinaryPath();
116079
- if (exec2 && process.platform === "win32" && !existsSync43(join81(dirname36(exec2), "wintun.dll"))) {
116384
+ if (exec2 && process.platform === "win32" && !existsSync44(join82(dirname37(exec2), "wintun.dll"))) {
116080
116385
  return {
116081
116386
  ok: false,
116082
116387
  reason: "no-binary",
@@ -116128,8 +116433,8 @@ import { platform as platform6 } from "node:os";
116128
116433
 
116129
116434
  // ../../packages/host-core/dist/service/launchd.js
116130
116435
  init_credentials();
116131
- import { writeFileSync as writeFileSync43, existsSync as existsSync44, mkdirSync as mkdirSync42, unlinkSync as unlinkSync7 } from "node:fs";
116132
- 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";
116133
116438
  import { homedir as homedir13, userInfo as userInfo2 } from "node:os";
116134
116439
  function xml2(s) {
116135
116440
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -116137,10 +116442,10 @@ function xml2(s) {
116137
116442
  function makeLaunchd(instanceId) {
116138
116443
  const suffix = instanceSuffix(instanceId);
116139
116444
  const label = SERVICE_LABEL_BASE + (suffix ? `.${suffix}` : "");
116140
- const plistPath = () => join82(homedir13(), "Library", "LaunchAgents", `${label}.plist`);
116445
+ const plistPath = () => join83(homedir13(), "Library", "LaunchAgents", `${label}.plist`);
116141
116446
  const domainTarget = () => `gui/${userInfo2().uid}`;
116142
116447
  const serviceTarget = () => `${domainTarget()}/${label}`;
116143
- const logFile = () => join82(daemonDir2(), "daemon.log");
116448
+ const logFile = () => join83(daemonDir2(), "daemon.log");
116144
116449
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
116145
116450
  function buildPlist2(spec) {
116146
116451
  const args = [spec.exec, ...spec.args].map((a) => ` <string>${xml2(a)}</string>`).join("\n");
@@ -116215,10 +116520,10 @@ ${env}
116215
116520
  };
116216
116521
  return {
116217
116522
  async install(spec) {
116218
- mkdirSync42(workDirOf(spec), { recursive: true });
116219
- mkdirSync42(dirname37(plistPath()), { recursive: true });
116220
- mkdirSync42(dirname37(spec.logPath), { recursive: true });
116221
- 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));
116222
116527
  await run5("launchctl", ["bootout", serviceTarget()]).catch(() => {
116223
116528
  });
116224
116529
  await untilGone();
@@ -116234,9 +116539,9 @@ ${env}
116234
116539
  async uninstall() {
116235
116540
  await run5("launchctl", ["bootout", serviceTarget()]).catch(() => {
116236
116541
  });
116237
- if (existsSync44(plistPath())) {
116542
+ if (existsSync45(plistPath())) {
116238
116543
  try {
116239
- unlinkSync7(plistPath());
116544
+ unlinkSync8(plistPath());
116240
116545
  } catch {
116241
116546
  }
116242
116547
  }
@@ -116245,7 +116550,7 @@ ${env}
116245
116550
  await this.install(spec);
116246
116551
  },
116247
116552
  async isInstalled() {
116248
- return existsSync44(plistPath());
116553
+ return existsSync45(plistPath());
116249
116554
  },
116250
116555
  async start() {
116251
116556
  await run5("launchctl", ["bootstrap", domainTarget(), plistPath()]).catch(() => {
@@ -116262,7 +116567,7 @@ ${env}
116262
116567
  },
116263
116568
  async logs(follow) {
116264
116569
  const f = logFile();
116265
- if (!existsSync44(f)) {
116570
+ if (!existsSync45(f)) {
116266
116571
  console.log(`No log yet at ${f} \u2014 has the service started?`);
116267
116572
  return;
116268
116573
  }
@@ -116273,8 +116578,8 @@ ${env}
116273
116578
 
116274
116579
  // ../../packages/host-core/dist/service/systemd.js
116275
116580
  init_credentials();
116276
- import { writeFileSync as writeFileSync44, existsSync as existsSync45, mkdirSync as mkdirSync43, unlinkSync as unlinkSync8 } from "node:fs";
116277
- 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";
116278
116583
  import { homedir as homedir14, userInfo as userInfo3 } from "node:os";
116279
116584
  function unitVal2(v) {
116280
116585
  return v.replace(/%/g, "%%");
@@ -116286,8 +116591,8 @@ function makeSystemd(instanceId) {
116286
116591
  const suffix = instanceSuffix(instanceId);
116287
116592
  const unit = `tesseract-host${suffix ? `-${suffix}` : ""}.service`;
116288
116593
  const unitPath = () => {
116289
- const base = process.env.XDG_CONFIG_HOME || join83(homedir14(), ".config");
116290
- return join83(base, "systemd", "user", unit);
116594
+ const base = process.env.XDG_CONFIG_HOME || join84(homedir14(), ".config");
116595
+ return join84(base, "systemd", "user", unit);
116291
116596
  };
116292
116597
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
116293
116598
  function buildUnit2(spec) {
@@ -116314,10 +116619,10 @@ WantedBy=default.target
116314
116619
  }
116315
116620
  return {
116316
116621
  async install(spec) {
116317
- mkdirSync43(workDirOf(spec), { recursive: true });
116318
- mkdirSync43(dirname38(unitPath()), { recursive: true });
116319
- mkdirSync43(dirname38(spec.logPath), { recursive: true });
116320
- 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));
116321
116626
  await run5("loginctl", ["enable-linger", userInfo3().username]).catch(() => {
116322
116627
  });
116323
116628
  await run5("systemctl", ["--user", "daemon-reload"]).catch(() => {
@@ -116329,9 +116634,9 @@ WantedBy=default.target
116329
116634
  async uninstall() {
116330
116635
  await run5("systemctl", ["--user", "disable", "--now", unit]).catch(() => {
116331
116636
  });
116332
- if (existsSync45(unitPath())) {
116637
+ if (existsSync46(unitPath())) {
116333
116638
  try {
116334
- unlinkSync8(unitPath());
116639
+ unlinkSync9(unitPath());
116335
116640
  } catch {
116336
116641
  }
116337
116642
  }
@@ -116342,7 +116647,7 @@ WantedBy=default.target
116342
116647
  await this.install(spec);
116343
116648
  },
116344
116649
  async isInstalled() {
116345
- return existsSync45(unitPath());
116650
+ return existsSync46(unitPath());
116346
116651
  },
116347
116652
  async start() {
116348
116653
  await run5("systemctl", ["--user", "start", unit]);
@@ -116354,8 +116659,8 @@ WantedBy=default.target
116354
116659
  await runInherit("systemctl", ["--user", "status", unit, "--no-pager"]);
116355
116660
  },
116356
116661
  async logs(follow) {
116357
- const f = join83(daemonDir2(), "daemon.log");
116358
- if (existsSync45(f)) {
116662
+ const f = join84(daemonDir2(), "daemon.log");
116663
+ if (existsSync46(f)) {
116359
116664
  await runInherit("tail", follow ? ["-f", f] : ["-n", "200", f]);
116360
116665
  return;
116361
116666
  }
@@ -116367,12 +116672,12 @@ WantedBy=default.target
116367
116672
 
116368
116673
  // ../../packages/host-core/dist/service/windows.js
116369
116674
  init_credentials();
116370
- import { writeFileSync as writeFileSync45, existsSync as existsSync46, mkdirSync as mkdirSync44, unlinkSync as unlinkSync9, readFileSync as readFileSync52 } from "node:fs";
116371
- 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";
116372
116677
  function publishedDaemonPid(dir2) {
116373
116678
  for (const f of ["status.json", "daemon.lock"]) {
116374
116679
  try {
116375
- const raw = readFileSync52(join84(dir2, f), "utf-8");
116680
+ const raw = readFileSync53(join85(dir2, f), "utf-8");
116376
116681
  const pid = f === "status.json" ? Number(JSON.parse(raw).pid) : Number(raw.trim());
116377
116682
  if (Number.isInteger(pid) && pid > 0)
116378
116683
  return pid;
@@ -116384,8 +116689,8 @@ function publishedDaemonPid(dir2) {
116384
116689
  function makeWindowsTask(instanceId) {
116385
116690
  const suffix = instanceSuffix(instanceId);
116386
116691
  const task = `Fineguide\\TesseractHost${suffix ? `-${suffix}` : ""}`;
116387
- const wrapperPath = () => join84(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
116388
- const logFile = () => join84(daemonDir2(), "daemon.log");
116692
+ const wrapperPath = () => join85(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
116693
+ const logFile = () => join85(daemonDir2(), "daemon.log");
116389
116694
  const oneLine2 = (s) => s.replace(/[\r\n]+/g, " ");
116390
116695
  const envVal = (v) => oneLine2(v).replace(/%/g, "%%").replace(/"/g, "");
116391
116696
  const cmdArg = (a) => `"${oneLine2(a).replace(/"/g, "")}"`;
@@ -116401,10 +116706,10 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
116401
116706
  }
116402
116707
  return {
116403
116708
  async install(spec) {
116404
- mkdirSync44(spec.workingDirectory ?? daemonDir2(), { recursive: true });
116405
- mkdirSync44(dirname39(spec.logPath), { recursive: true });
116406
- mkdirSync44(dirname39(wrapperPath()), { recursive: true });
116407
- 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));
116408
116713
  await run5("schtasks", ["/Create", "/TN", task, "/SC", "ONLOGON", "/RL", "LIMITED", "/F", "/TR", `"${wrapperPath()}"`]);
116409
116714
  await run5("schtasks", ["/Run", "/TN", task]).catch(() => {
116410
116715
  });
@@ -116412,9 +116717,9 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
116412
116717
  async uninstall() {
116413
116718
  await run5("schtasks", ["/Delete", "/TN", task, "/F"]).catch(() => {
116414
116719
  });
116415
- if (existsSync46(wrapperPath())) {
116720
+ if (existsSync47(wrapperPath())) {
116416
116721
  try {
116417
- unlinkSync9(wrapperPath());
116722
+ unlinkSync10(wrapperPath());
116418
116723
  } catch {
116419
116724
  }
116420
116725
  }
@@ -116486,7 +116791,7 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
116486
116791
  },
116487
116792
  async logs(follow) {
116488
116793
  const f = logFile();
116489
- if (!existsSync46(f)) {
116794
+ if (!existsSync47(f)) {
116490
116795
  console.log(`No log yet at ${f} \u2014 has the task run?`);
116491
116796
  return;
116492
116797
  }
@@ -116517,9 +116822,9 @@ init_safe_kill();
116517
116822
 
116518
116823
  // src/auth.ts
116519
116824
  var import_qrcode_terminal = __toESM(require_main(), 1);
116520
- import { randomUUID as randomUUID30 } from "node:crypto";
116521
- import { existsSync as existsSync47, rmSync as rmSync12 } from "node:fs";
116522
- 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";
116523
116828
 
116524
116829
  // src/config.ts
116525
116830
  import { hostname as hostname6 } from "node:os";
@@ -116659,7 +116964,7 @@ async function login(opts) {
116659
116964
  process.exit(1);
116660
116965
  }
116661
116966
  }
116662
- 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);
116663
116968
  const label = opts.name ?? defaultLabel();
116664
116969
  if (opts.token) {
116665
116970
  const dt = await fetchJson(`${api}/auth/device-token`, {
@@ -116720,8 +117025,8 @@ async function logout() {
116720
117025
  }
116721
117026
  for (const f of ["credentials.json", "status.json", "daemon.lock"]) {
116722
117027
  try {
116723
- const p = join85(daemonDir2(), f);
116724
- if (existsSync47(p)) rmSync12(p);
117028
+ const p = join86(daemonDir2(), f);
117029
+ if (existsSync48(p)) rmSync12(p);
116725
117030
  } catch {
116726
117031
  }
116727
117032
  }
@@ -116879,9 +117184,9 @@ function startSelfUpdater(current) {
116879
117184
  }
116880
117185
 
116881
117186
  // src/service.ts
116882
- import { join as join86 } from "node:path";
117187
+ import { join as join87 } from "node:path";
116883
117188
  import { platform as platform7 } from "node:os";
116884
- import { existsSync as existsSync48, readFileSync as readFileSync53 } from "node:fs";
117189
+ import { existsSync as existsSync49, readFileSync as readFileSync54 } from "node:fs";
116885
117190
  function controller(instanceId) {
116886
117191
  const c = getServiceController(instanceId);
116887
117192
  if (!c) {
@@ -116894,7 +117199,7 @@ function buildSpec(cliEntry) {
116894
117199
  exec: process.execPath,
116895
117200
  args: [cliEntry, "run"],
116896
117201
  env: { CCB_DAEMON_DIR: daemonDir2() },
116897
- logPath: join86(daemonDir2(), "daemon.log")
117202
+ logPath: join87(daemonDir2(), "daemon.log")
116898
117203
  };
116899
117204
  }
116900
117205
  var isAlive = (pid) => {
@@ -116906,10 +117211,10 @@ var isAlive = (pid) => {
116906
117211
  }
116907
117212
  };
116908
117213
  function runningDaemonInfo() {
116909
- const lock = join86(daemonDir2(), "daemon.lock");
117214
+ const lock = join87(daemonDir2(), "daemon.lock");
116910
117215
  try {
116911
- if (!existsSync48(lock)) return null;
116912
- const pid = Number(readFileSync53(lock, "utf-8").trim());
117216
+ if (!existsSync49(lock)) return null;
117217
+ const pid = Number(readFileSync54(lock, "utf-8").trim());
116913
117218
  if (!pid || !isAlive(pid)) return null;
116914
117219
  return { pid, device: readCredentials()?.deviceId };
116915
117220
  } catch {
@@ -116943,7 +117248,7 @@ async function logs(instanceId, follow) {
116943
117248
  }
116944
117249
 
116945
117250
  // src/net.ts
116946
- import { readFileSync as readFileSync55 } from "node:fs";
117251
+ import { readFileSync as readFileSync56 } from "node:fs";
116947
117252
  import { randomBytes as randomBytes11 } from "node:crypto";
116948
117253
  import { hostname as hostname7 } from "node:os";
116949
117254
  import { resolve as resolve14 } from "node:path";
@@ -117008,7 +117313,7 @@ function readOrDie(label, p) {
117008
117313
  process.exit(1);
117009
117314
  }
117010
117315
  try {
117011
- return new Uint8Array(readFileSync55(resolve14(p)));
117316
+ return new Uint8Array(readFileSync56(resolve14(p)));
117012
117317
  } catch (e) {
117013
117318
  console.error(`net enroll: could not read --${label} ${p}: ${e instanceof Error ? e.message : e}`);
117014
117319
  process.exit(1);
@@ -117561,8 +117866,8 @@ async function netCommand(rest, flags) {
117561
117866
  // src/cli.ts
117562
117867
  function pkgVersion() {
117563
117868
  try {
117564
- const p = join88(dirname40(fileURLToPath8(import.meta.url)), "..", "package.json");
117565
- 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";
117566
117871
  } catch {
117567
117872
  return "0.0.0";
117568
117873
  }
@@ -117790,7 +118095,7 @@ async function linkCommand(rest, flags) {
117790
118095
  process.exit(1);
117791
118096
  }
117792
118097
  async function captureClaudeSubscription(flags) {
117793
- const home = mkdtempSync4(join88(tmpdir8(), "tesseract-claude-login-"));
118098
+ const home = mkdtempSync4(join89(tmpdir8(), "tesseract-claude-login-"));
117794
118099
  const binary = typeof flags["claude-path"] === "string" ? flags["claude-path"] : process.env.CCB_ENGINE_PATH_CLAUDE_CODE || "claude";
117795
118100
  const args = ["auth", "login", "--claudeai"];
117796
118101
  if (typeof flags.email === "string") args.push("--email", flags.email);
@@ -117807,8 +118112,8 @@ async function captureClaudeSubscription(flags) {
117807
118112
  child.once("close", (exitCode, signal) => resolveCode(signal ? 1 : exitCode ?? 1));
117808
118113
  });
117809
118114
  if (code !== 0) throw new Error(`Claude sign-in did not complete (exit ${code}).`);
117810
- const file2 = join88(home, ".credentials.json");
117811
- if (existsSync50(file2)) return readFileSync56(file2, "utf8");
118115
+ const file2 = join89(home, ".credentials.json");
118116
+ if (existsSync51(file2)) return readFileSync57(file2, "utf8");
117812
118117
  if (process.platform === "darwin") {
117813
118118
  const value = execFileSync6("security", [
117814
118119
  "find-generic-password",
@@ -117890,7 +118195,7 @@ async function runnerCommand(rest, flags) {
117890
118195
  process.exit(1);
117891
118196
  }
117892
118197
  const oauthFilePath = typeof flags["oauth-file"] === "string" ? resolve15(flags["oauth-file"]) : void 0;
117893
- const oauthAuthFile = oauthFilePath ? readFileSync56(oauthFilePath, "utf8") : void 0;
118198
+ const oauthAuthFile = oauthFilePath ? readFileSync57(oauthFilePath, "utf8") : void 0;
117894
118199
  if (oauthAuthFile) {
117895
118200
  try {
117896
118201
  JSON.parse(oauthAuthFile);