tesseract-agent 0.11.9 → 0.11.10

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.
@@ -23829,12 +23829,12 @@ function buildCronTools(deps) {
23829
23829
  }),
23830
23830
  tool("Sleep", prompt("tool.cron.Sleep"), { seconds: external_exports.number().describe("Seconds to sleep (clamped to 0\u2013120)") }, async (args, extra) => {
23831
23831
  const s = Math.max(0, Math.min(120, Math.floor(args.seconds)));
23832
- const signal = extra?.signal;
23832
+ const signal2 = extra?.signal;
23833
23833
  const interrupted = await new Promise((res) => {
23834
- if (signal?.aborted)
23834
+ if (signal2?.aborted)
23835
23835
  return res(true);
23836
23836
  const id = setTimeout(() => res(false), s * 1e3);
23837
- signal?.addEventListener("abort", () => {
23837
+ signal2?.addEventListener("abort", () => {
23838
23838
  clearTimeout(id);
23839
23839
  res(true);
23840
23840
  }, { once: true });
@@ -26047,8 +26047,8 @@ var init_cloud_agent = __esm({
26047
26047
 
26048
26048
  // ../../packages/shared/dist/engine-endpoint.js
26049
26049
  function joinPath(...parts) {
26050
- const sep11 = process.platform === "win32" ? "\\" : "/";
26051
- return parts.filter(Boolean).map((p, i) => i === 0 ? p.replace(/[\\/]+$/, "") : p.replace(/^[\\/]+|[\\/]+$/g, "")).join(sep11);
26050
+ const sep12 = process.platform === "win32" ? "\\" : "/";
26051
+ return parts.filter(Boolean).map((p, i) => i === 0 ? p.replace(/[\\/]+$/, "") : p.replace(/^[\\/]+|[\\/]+$/g, "")).join(sep12);
26052
26052
  }
26053
26053
  function toml(value) {
26054
26054
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
@@ -26246,6 +26246,12 @@ var init_enterprise_env = __esm({
26246
26246
  });
26247
26247
 
26248
26248
  // ../../packages/shared/dist/runtimes.js
26249
+ function runtimeUserPrefix(platform8) {
26250
+ return platform8 === "win32" ? "$env:USERPROFILE\\.tesseract\\runtimes" : "$HOME/.tesseract/runtimes";
26251
+ }
26252
+ function runtimeUserBinDir(platform8) {
26253
+ return platform8 === "win32" ? runtimeUserPrefix(platform8) : `${runtimeUserPrefix(platform8)}/bin`;
26254
+ }
26249
26255
  var RUNTIME_CATALOG, RUNTIME_IDS;
26250
26256
  var init_runtimes = __esm({
26251
26257
  "../../packages/shared/dist/runtimes.js"() {
@@ -26266,57 +26272,10 @@ var init_runtimes = __esm({
26266
26272
  }
26267
26273
  });
26268
26274
 
26269
- // ../../packages/shared/dist/gateway-plan.js
26270
- function providerBase(key2, which2) {
26271
- const fromServer = key2.endpoints?.[which2]?.trim();
26272
- if (fromServer)
26273
- return fromServer;
26274
- return which2 === "anthropic" ? gatewayAnthropicBaseUrl(key2.baseUrl) : which2 === "openai" ? gatewayOpenAiBaseUrl(key2.baseUrl) : gatewayGeminiBaseUrl(key2.baseUrl);
26275
- }
26276
- function tiers(engineId, key2, models) {
26277
- const claudeDefaults = engineId === "claude-code";
26278
- const served = new Set(Object.values(key2.models).filter((v) => typeof v === "string" && !!v));
26279
- const asked = (v) => {
26280
- const t = v?.trim();
26281
- if (!t)
26282
- return void 0;
26283
- if (t.includes("/"))
26284
- return t;
26285
- return served.has(t) ? t : void 0;
26286
- };
26287
- const main2 = asked(models.main) || (claudeDefaults ? key2.models.claude : void 0) || key2.models.high;
26288
- const fast = asked(models.fast) || (claudeDefaults ? key2.models.claudeFast : void 0) || key2.models.low;
26289
- return { main: main2, fast };
26290
- }
26291
- function planGatewayRun(engineId, key2, models, homeBase) {
26292
- const wire = gatewayWireFor(engineId);
26293
- if (!wire)
26294
- return void 0;
26295
- const { main: main2, fast } = tiers(engineId, key2, models);
26296
- const effort = ENGINE_CATALOG[engineId]?.modelControls.reasoningEfforts?.includes(models.reasoningEffort ?? "") ? models.reasoningEffort : void 0;
26297
- return planEndpointRun(wire.kind, {
26298
- baseUrl: wire.kind === "anthropic-env" ? providerBase(key2, "anthropic") : wire.kind === "gemini-env" ? providerBase(key2, "gemini") : providerBase(key2, "openai"),
26299
- apiKey: key2.apiKey,
26300
- main: main2,
26301
- fast,
26302
- ...effort ? { reasoningEffort: effort } : {},
26303
- label: "Tesseract Gateway",
26304
- // The gateway's OWN homes, unchanged: an upgrading install must not re-materialize
26305
- // under a new name and leave the old one behind.
26306
- homeKey: HOME_DIR_NAME[engineId]
26307
- }, homeBase);
26308
- }
26309
- var HOME_DIR_NAME;
26310
- var init_gateway_plan = __esm({
26311
- "../../packages/shared/dist/gateway-plan.js"() {
26275
+ // ../../packages/shared/dist/component-compat.js
26276
+ var init_component_compat = __esm({
26277
+ "../../packages/shared/dist/component-compat.js"() {
26312
26278
  "use strict";
26313
- init_runner_compat();
26314
- init_engine_endpoint();
26315
- init_engines();
26316
- HOME_DIR_NAME = {
26317
- opencode: "opencode-bundled",
26318
- "openai-codex": "gateway-openai-codex"
26319
- };
26320
26279
  }
26321
26280
  });
26322
26281
 
@@ -26350,8 +26309,8 @@ function pathSep(platform8) {
26350
26309
  return platform8 === "win32" ? "\\" : "/";
26351
26310
  }
26352
26311
  function joinPath2(platform8, ...parts) {
26353
- const sep11 = pathSep(platform8);
26354
- return parts.filter((p) => p !== "").map((p, i) => i === 0 ? p.replace(/[\\/]+$/, "") : p.replace(/^[\\/]+|[\\/]+$/g, "")).join(sep11);
26312
+ const sep12 = pathSep(platform8);
26313
+ return parts.filter((p) => p !== "").map((p, i) => i === 0 ? p.replace(/[\\/]+$/, "") : p.replace(/^[\\/]+|[\\/]+$/g, "")).join(sep12);
26355
26314
  }
26356
26315
  function dedupe(dirs) {
26357
26316
  const seen = /* @__PURE__ */ new Set();
@@ -26406,13 +26365,93 @@ function engineSearchDirs(opts) {
26406
26365
  "/snap/bin"
26407
26366
  ]);
26408
26367
  }
26409
- var EMPTY_ENGINE_PATH_STORE, VIA_VALUES;
26368
+ var EMPTY_ENGINE_PATH_STORE, VIA_VALUES, ENGINE_EXTRA_DIRS;
26410
26369
  var init_engine_paths = __esm({
26411
26370
  "../../packages/shared/dist/engine-paths.js"() {
26412
26371
  "use strict";
26413
26372
  init_engines();
26414
26373
  EMPTY_ENGINE_PATH_STORE = { version: 1, entries: {} };
26415
26374
  VIA_VALUES = ["user", "env", "path", "well-known", "install"];
26375
+ ENGINE_EXTRA_DIRS = {
26376
+ // Mirrors agent-core's findUserInstalledClaude — Claude's installer puts it here.
26377
+ "claude-code": ["~/.claude/local"],
26378
+ "openai-codex": ["~/.codex/bin"],
26379
+ opencode: ["~/.opencode/bin"],
26380
+ "gemini-cli": ["~/.gemini/bin"]
26381
+ };
26382
+ }
26383
+ });
26384
+
26385
+ // ../../packages/shared/dist/runtime-probe.js
26386
+ var PROBE_PATH_PREFIX;
26387
+ var init_runtime_probe = __esm({
26388
+ "../../packages/shared/dist/runtime-probe.js"() {
26389
+ "use strict";
26390
+ init_engine_paths();
26391
+ init_runtimes();
26392
+ PROBE_PATH_PREFIX = [
26393
+ // FIRST, deliberately: this is where we install, and a machine with an old system-wide copy
26394
+ // must resolve OURS. That is the whole reason a user-path install can fix a root-owned one
26395
+ // we are not allowed to touch.
26396
+ runtimeUserBinDir("linux"),
26397
+ ...engineSearchDirs({ home: "$HOME", platform: "linux" }),
26398
+ ...engineSearchDirs({ home: "$HOME", platform: "darwin" }),
26399
+ ...Object.values(ENGINE_EXTRA_DIRS).flat().map((d) => d.replace(/^~/, "$HOME"))
26400
+ ].filter((d, i, a) => a.indexOf(d) === i).join(":");
26401
+ }
26402
+ });
26403
+
26404
+ // ../../packages/shared/dist/gateway-plan.js
26405
+ function providerBase(key2, which2) {
26406
+ const fromServer = key2.endpoints?.[which2]?.trim();
26407
+ if (fromServer)
26408
+ return fromServer;
26409
+ return which2 === "anthropic" ? gatewayAnthropicBaseUrl(key2.baseUrl) : which2 === "openai" ? gatewayOpenAiBaseUrl(key2.baseUrl) : gatewayGeminiBaseUrl(key2.baseUrl);
26410
+ }
26411
+ function tiers(engineId, key2, models) {
26412
+ const claudeDefaults = engineId === "claude-code";
26413
+ const served = new Set(Object.values(key2.models).filter((v) => typeof v === "string" && !!v));
26414
+ const asked = (v) => {
26415
+ const t = v?.trim();
26416
+ if (!t)
26417
+ return void 0;
26418
+ if (t.includes("/"))
26419
+ return t;
26420
+ return served.has(t) ? t : void 0;
26421
+ };
26422
+ const main2 = asked(models.main) || (claudeDefaults ? key2.models.claude : void 0) || key2.models.high;
26423
+ const fast = asked(models.fast) || (claudeDefaults ? key2.models.claudeFast : void 0) || key2.models.low;
26424
+ return { main: main2, fast };
26425
+ }
26426
+ function planGatewayRun(engineId, key2, models, homeBase) {
26427
+ const wire = gatewayWireFor(engineId);
26428
+ if (!wire)
26429
+ return void 0;
26430
+ const { main: main2, fast } = tiers(engineId, key2, models);
26431
+ const effort = ENGINE_CATALOG[engineId]?.modelControls.reasoningEfforts?.includes(models.reasoningEffort ?? "") ? models.reasoningEffort : void 0;
26432
+ return planEndpointRun(wire.kind, {
26433
+ baseUrl: wire.kind === "anthropic-env" ? providerBase(key2, "anthropic") : wire.kind === "gemini-env" ? providerBase(key2, "gemini") : providerBase(key2, "openai"),
26434
+ apiKey: key2.apiKey,
26435
+ main: main2,
26436
+ fast,
26437
+ ...effort ? { reasoningEffort: effort } : {},
26438
+ label: "Tesseract Gateway",
26439
+ // The gateway's OWN homes, unchanged: an upgrading install must not re-materialize
26440
+ // under a new name and leave the old one behind.
26441
+ homeKey: HOME_DIR_NAME[engineId]
26442
+ }, homeBase);
26443
+ }
26444
+ var HOME_DIR_NAME;
26445
+ var init_gateway_plan = __esm({
26446
+ "../../packages/shared/dist/gateway-plan.js"() {
26447
+ "use strict";
26448
+ init_runner_compat();
26449
+ init_engine_endpoint();
26450
+ init_engines();
26451
+ HOME_DIR_NAME = {
26452
+ opencode: "opencode-bundled",
26453
+ "openai-codex": "gateway-openai-codex"
26454
+ };
26416
26455
  }
26417
26456
  });
26418
26457
 
@@ -27709,6 +27748,8 @@ var init_dist2 = __esm({
27709
27748
  init_enterprise_env();
27710
27749
  init_providers();
27711
27750
  init_runtimes();
27751
+ init_component_compat();
27752
+ init_runtime_probe();
27712
27753
  init_runner_configs();
27713
27754
  init_runner_compat();
27714
27755
  init_gateway_plan();
@@ -33583,10 +33624,10 @@ var init_client = __esm({
33583
33624
  const creds3 = await this.creds().catch(() => void 0);
33584
33625
  const remaining = Math.max(1, deadline - Date.now());
33585
33626
  const timeout = AbortSignal.timeout(remaining);
33586
- const signal = opts.signal ? AbortSignal.any([opts.signal, timeout]) : timeout;
33627
+ const signal2 = opts.signal ? AbortSignal.any([opts.signal, timeout]) : timeout;
33587
33628
  return this.fetchImpl(url2, {
33588
33629
  headers: { accept: "application/json", ...creds3?.baseUrl ? creds3.headers ?? {} : {} },
33589
- signal
33630
+ signal: signal2
33590
33631
  });
33591
33632
  }
33592
33633
  /**
@@ -35442,7 +35483,7 @@ function scheduleUnattendedAnswer(prompt2, deps) {
35442
35483
  ...extra
35443
35484
  });
35444
35485
  };
35445
- const timer2 = setTimeout(() => {
35486
+ const timer2 = setTimeout(async () => {
35446
35487
  const mode = deps.mode();
35447
35488
  if (mode === "off") {
35448
35489
  record2("off", "skipped", { reason: "unattended switched off before the answer landed" });
@@ -35457,7 +35498,7 @@ function scheduleUnattendedAnswer(prompt2, deps) {
35457
35498
  return;
35458
35499
  }
35459
35500
  const cappedOut = spent > UNATTENDED_MAX_DECISIONS;
35460
- const answer = unattendedAnswer(mode, prompt2, { capped: cappedOut });
35501
+ let answer = unattendedAnswer(mode, prompt2, { capped: cappedOut });
35461
35502
  if (!answer) {
35462
35503
  try {
35463
35504
  deps.refund();
@@ -35466,6 +35507,23 @@ function scheduleUnattendedAnswer(prompt2, deps) {
35466
35507
  record2(mode, "skipped", { reason: "no policy answer for this prompt kind", spent });
35467
35508
  return;
35468
35509
  }
35510
+ if (deps.prepare && !cappedOut) {
35511
+ try {
35512
+ const better = await deps.prepare();
35513
+ if (better)
35514
+ answer = { ...answer, ...better };
35515
+ } catch (err2) {
35516
+ deps.log?.("unattended: preparing a better answer failed \u2014 the policy answer stands", err2);
35517
+ }
35518
+ if (deps.mode() === "off") {
35519
+ try {
35520
+ deps.refund();
35521
+ } catch {
35522
+ }
35523
+ record2("off", "skipped", { reason: "unattended switched off before the answer landed", spent });
35524
+ return;
35525
+ }
35526
+ }
35469
35527
  let applied = false;
35470
35528
  try {
35471
35529
  applied = deps.apply(answer);
@@ -37402,6 +37460,42 @@ var init_session_mirror = __esm({
37402
37460
  }
37403
37461
  });
37404
37462
 
37463
+ // ../../packages/agent-core/dist/prompt-withdrawal.js
37464
+ var PROMPT_WITHDRAWN_NOTE, PROMPT_WITHDRAWN_DECISION;
37465
+ var init_prompt_withdrawal = __esm({
37466
+ "../../packages/agent-core/dist/prompt-withdrawal.js"() {
37467
+ "use strict";
37468
+ PROMPT_WITHDRAWN_NOTE = "The user replied in the chat instead of answering this prompt, so it was withdrawn. Their message follows \u2014 take it into account and continue from it.";
37469
+ PROMPT_WITHDRAWN_DECISION = "Withdrawn \u2014 you replied in the chat instead, so your message went to the agent.";
37470
+ }
37471
+ });
37472
+
37473
+ // ../../packages/agent-core/dist/question-recommendation.js
37474
+ function pickRecommendedAnswers(questions, recommendations) {
37475
+ if (!questions.length)
37476
+ return null;
37477
+ const answers = {};
37478
+ const said = [];
37479
+ for (const [qi, q] of questions.entries()) {
37480
+ const labels = new Set((q.options ?? []).map((o) => o.label));
37481
+ const usable = recommendations.filter((r) => r.questionIndex === qi && labels.has(r.optionLabel) && RANK[r.level] < 9).sort((a, b) => RANK[a.level] - RANK[b.level]);
37482
+ if (!usable.length)
37483
+ return null;
37484
+ const chosen = q.multiSelect ? usable.filter((r, i) => i === 0 || RANK[r.level] <= RANK.recommended) : [usable[0]];
37485
+ const picked = [...new Set(chosen.map((r) => r.optionLabel))];
37486
+ answers[q.question] = picked.join(",");
37487
+ said.push(`"${picked.join('" + "')}" for "${q.question.length > 60 ? `${q.question.slice(0, 57)}\u2026` : q.question}"`);
37488
+ }
37489
+ return { answers, decision: `Chose the recommended answer${questions.length > 1 ? "s" : ""}: ${said.join("; ")}` };
37490
+ }
37491
+ var RANK;
37492
+ var init_question_recommendation = __esm({
37493
+ "../../packages/agent-core/dist/question-recommendation.js"() {
37494
+ "use strict";
37495
+ RANK = { highly_recommended: 0, recommended: 1, neutral: 2, caution: 9, discouraged: 9 };
37496
+ }
37497
+ });
37498
+
37405
37499
  // ../../packages/agent-core/dist/trace-store.js
37406
37500
  import { promises as fs } from "node:fs";
37407
37501
  import path from "node:path";
@@ -38195,7 +38289,7 @@ var init_session_usage = __esm({
38195
38289
 
38196
38290
  // ../../packages/agent-core/dist/kill-tree.js
38197
38291
  import { spawn } from "node:child_process";
38198
- function killProcessTree(child, signal = "SIGKILL") {
38292
+ function killProcessTree(child, signal2 = "SIGKILL") {
38199
38293
  if (!child || typeof child.pid !== "number" || child.pid <= 0 || child.exitCode !== null)
38200
38294
  return;
38201
38295
  const pid = child.pid;
@@ -38207,10 +38301,10 @@ function killProcessTree(child, signal = "SIGKILL") {
38207
38301
  return;
38208
38302
  }
38209
38303
  try {
38210
- process.kill(-pid, signal);
38304
+ process.kill(-pid, signal2);
38211
38305
  } catch {
38212
38306
  try {
38213
- child.kill(signal);
38307
+ child.kill(signal2);
38214
38308
  } catch {
38215
38309
  }
38216
38310
  }
@@ -38353,13 +38447,13 @@ function assistantUsageLimitFallback(content) {
38353
38447
  const text12 = blocks.map((block2) => typeof block2.text === "string" ? block2.text : "").join("\n").trim();
38354
38448
  if (!text12 || text12.length > 600)
38355
38449
  return void 0;
38356
- const signal = classifyUsageMessage(text12);
38357
- if (signal !== "limit" && signal !== "org-policy")
38450
+ const signal2 = classifyUsageMessage(text12);
38451
+ if (signal2 !== "limit" && signal2 !== "org-policy")
38358
38452
  return void 0;
38359
38453
  const isoReset = text12.match(/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z\b/i)?.[0];
38360
38454
  const resetMatch = text12.match(/(?:reset|resets|available again)(?:s| at| on| in)?\s+([^\n]+)/i);
38361
38455
  const parsed = Date.parse(isoReset ?? resetMatch?.[1].trim() ?? "");
38362
- return { retryAt: Number.isFinite(parsed) ? parsed : void 0, signal };
38456
+ return { retryAt: Number.isFinite(parsed) ? parsed : void 0, signal: signal2 };
38363
38457
  }
38364
38458
  function usageLimitErrorMessage(rejection) {
38365
38459
  if (rejection.signal === "org-policy") {
@@ -39313,7 +39407,7 @@ ${next}` : next;
39313
39407
  function autoDecisionSubject(prompt2) {
39314
39408
  return prompt2.kind === "permission" ? prompt2.tool : void 0;
39315
39409
  }
39316
- var browserExtensionConnected, TURN_OPENING_GRACE_MS, STRIP_SETTLE_MS, INFLIGHT_RESUME_DELAY_MS, REDISPATCH_DIRECTIVE, 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, MODEL_FALLBACK_MAX_HOPS, MODEL_FALLBACK_RESUME_MESSAGE, QUIESCENCE_POLL_MS, BATCH_WAIT_MS, INLINE_TOOL_NAMES, STOP_HARD_KILL_AFTER_MS, STREAM_STALL_MS, STREAM_FIRST_FRAME_MS, OVERFLOW_SILENCE_MS, RV_TASK_MAX, OPTION_RATING_JSON_SCHEMA, AgentManager;
39410
+ var browserExtensionConnected, TURN_OPENING_GRACE_MS, RECOMMEND_ANSWER_TIMEOUT_MS, STRIP_SETTLE_MS, INFLIGHT_RESUME_DELAY_MS, REDISPATCH_DIRECTIVE, 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, MODEL_FALLBACK_MAX_HOPS, MODEL_FALLBACK_RESUME_MESSAGE, QUIESCENCE_POLL_MS, BATCH_WAIT_MS, INLINE_TOOL_NAMES, STOP_HARD_KILL_AFTER_MS, STREAM_STALL_MS, STREAM_FIRST_FRAME_MS, OVERFLOW_SILENCE_MS, RV_TASK_MAX, OPTION_RATING_JSON_SCHEMA, AgentManager;
39317
39411
  var init_agent_manager = __esm({
39318
39412
  "../../packages/agent-core/dist/agent-manager.js"() {
39319
39413
  "use strict";
@@ -39368,6 +39462,8 @@ var init_agent_manager = __esm({
39368
39462
  init_session_edit();
39369
39463
  init_session_transfer();
39370
39464
  init_session_mirror();
39465
+ init_prompt_withdrawal();
39466
+ init_question_recommendation();
39371
39467
  init_trace_store();
39372
39468
  init_cost_ledger();
39373
39469
  init_session_store();
@@ -39379,6 +39475,7 @@ var init_agent_manager = __esm({
39379
39475
  init_usage_limit();
39380
39476
  browserExtensionConnected = () => false;
39381
39477
  TURN_OPENING_GRACE_MS = 5 * 6e4;
39478
+ RECOMMEND_ANSWER_TIMEOUT_MS = 25e3;
39382
39479
  STRIP_SETTLE_MS = 750;
39383
39480
  INFLIGHT_RESUME_DELAY_MS = 8e3;
39384
39481
  REDISPATCH_DIRECTIVE = "This message is being re-sent because the app restarted while you were working on it. If the same request already appears above, do not start over \u2014 continue from where you left off, keeping what was already done.";
@@ -40657,6 +40754,64 @@ ${full.slice(-8e3)}`;
40657
40754
  * No-op if the request is unknown (already resolved / aborted). On "allow &
40658
40755
  * don't ask again" (persist) we hand the SDK its own suggested permission
40659
40756
  * updates so the same call won't prompt again this session. */
40757
+ /**
40758
+ * Withdraw every prompt parked on THIS session — the user answered in the chat instead.
40759
+ *
40760
+ * Each is answered the way "no" is answered for its kind (deny / decline / cancel), with
40761
+ * PROMPT_WITHDRAWN_NOTE where a note can travel, and announced to the client as an
40762
+ * agent:auto_decision so the card it drew resolves. WITHOUT interrupt: a denial returns
40763
+ * control to the model mid-turn, and the user's message (steered in right after) is the
40764
+ * next thing it reads — so it continues from the message rather than starting over.
40765
+ * Matched by session object, not id: a prompt can be parked before the id is resolved.
40766
+ */
40767
+ withdrawParkedPrompts(live) {
40768
+ let n = 0;
40769
+ const announce = (requestId, promptKind, behavior, subject) => {
40770
+ const evt = {
40771
+ type: "agent:auto_decision",
40772
+ sessionId: live.sessionId,
40773
+ requestId,
40774
+ promptKind,
40775
+ ...subject ? { subject } : {},
40776
+ decision: PROMPT_WITHDRAWN_DECISION,
40777
+ behavior
40778
+ };
40779
+ if (live.clientRequestId)
40780
+ this.send({ ...evt, clientRequestId: live.clientRequestId }, live.origin);
40781
+ else
40782
+ this.send(evt, live.origin);
40783
+ };
40784
+ for (const [id, e] of [...this.pendingPermissions]) {
40785
+ if (e.live !== live)
40786
+ continue;
40787
+ const kind = e.tool === "ExitPlanMode" ? "plan" : e.tool === "AskUserQuestion" ? "question" : "permission";
40788
+ this.respondToPermission(id, { behavior: "deny", message: PROMPT_WITHDRAWN_NOTE });
40789
+ announce(id, kind, "deny", kind === "permission" ? e.tool : void 0);
40790
+ n++;
40791
+ }
40792
+ for (const [id, e] of [...this.pendingElicitations]) {
40793
+ if (e.live !== live)
40794
+ continue;
40795
+ this.respondToElicitation(id, { action: "decline" });
40796
+ announce(id, "elicitation", "decline");
40797
+ n++;
40798
+ }
40799
+ for (const [id, e] of [...this.pendingUserDialogs]) {
40800
+ if (e.live !== live)
40801
+ continue;
40802
+ this.respondToUserDialog(id, { behavior: "cancelled" });
40803
+ announce(id, "dialog", "cancel");
40804
+ n++;
40805
+ }
40806
+ for (const [id, e] of [...this.pendingUiRequests]) {
40807
+ if (!live.sessionId || e.sessionId !== live.sessionId)
40808
+ continue;
40809
+ this.respondToUiRequest(id, { cancelled: true });
40810
+ announce(id, "skill_ui", "cancel");
40811
+ n++;
40812
+ }
40813
+ return n;
40814
+ }
40660
40815
  respondToPermission(requestId, decision, callerOrigin) {
40661
40816
  const entry = this.pendingPermissions.get(requestId);
40662
40817
  if (!entry)
@@ -40968,7 +41123,7 @@ ${full.slice(-8e3)}`;
40968
41123
  * The per-turn budget is spent here rather than in the policy so that BLOWING it is
40969
41124
  * still an answer: a capped prompt is declined with an explanation, never abandoned.
40970
41125
  * Abandoning it is a hang — the precise failure this whole path exists to prevent. */
40971
- autoAnswerPrompt(live, requestId, prompt2, apply2) {
41126
+ autoAnswerPrompt(live, requestId, prompt2, apply2, prepare) {
40972
41127
  scheduleUnattendedAnswer(prompt2, {
40973
41128
  context: { sessionId: live.sessionId, engine: "claude-code" },
40974
41129
  mode: () => live.unattended ?? "off",
@@ -40981,6 +41136,7 @@ ${full.slice(-8e3)}`;
40981
41136
  // the parked promise themselves, so `apply` reports that there is nothing left to
40982
41137
  // answer and we stay silent rather than logging a phantom decision.
40983
41138
  apply: apply2,
41139
+ ...prepare ? { prepare } : {},
40984
41140
  report: (answer, cappedOut) => {
40985
41141
  const subject = autoDecisionSubject(prompt2);
40986
41142
  const evt = {
@@ -41011,7 +41167,7 @@ ${full.slice(-8e3)}`;
41011
41167
  * than canUseTool because hooks fire in EVERY permission mode — bypassPermissions
41012
41168
  * (the app default) shadows canUseTool but never hooks. Mirrors canUseTool's
41013
41169
  * abort/cleanup handling so an interrupted turn never leaks a parked card. */
41014
- raiseQuestion(live, input, toolUseId, signal, agentId) {
41170
+ raiseQuestion(live, input, toolUseId, signal2, agentId) {
41015
41171
  return new Promise((resolve16) => {
41016
41172
  const requestId = randomUUID4();
41017
41173
  let holding = false;
@@ -41029,17 +41185,18 @@ ${full.slice(-8e3)}`;
41029
41185
  };
41030
41186
  const cleanup2 = () => {
41031
41187
  unpark();
41032
- signal.removeEventListener("abort", onAbort);
41188
+ signal2.removeEventListener("abort", onAbort);
41033
41189
  };
41034
- if (signal.aborted) {
41190
+ if (signal2.aborted) {
41035
41191
  resolve16({ behavior: "deny", message: "Interrupted.", interrupt: true });
41036
41192
  return;
41037
41193
  }
41038
- signal.addEventListener("abort", onAbort, { once: true });
41194
+ signal2.addEventListener("abort", onAbort, { once: true });
41039
41195
  holding = true;
41040
41196
  live.parked = (live.parked ?? 0) + 1;
41041
- this.pendingPermissions.set(requestId, { resolve: resolve16, cleanup: cleanup2, origin: live.origin });
41197
+ this.pendingPermissions.set(requestId, { resolve: resolve16, cleanup: cleanup2, origin: live.origin, live, tool: "AskUserQuestion" });
41042
41198
  const willEvaluate = !!this.cheapLlm && Array.isArray(input.questions) && input.questions.length > 0;
41199
+ const recommendAsAnswer = willEvaluate && live.unattended === "auto";
41043
41200
  const evt = {
41044
41201
  type: "agent:permission_request",
41045
41202
  sessionId: live.sessionId,
@@ -41054,14 +41211,26 @@ ${full.slice(-8e3)}`;
41054
41211
  this.send({ ...evt, clientRequestId: live.clientRequestId }, live.origin);
41055
41212
  else
41056
41213
  this.send(evt, live.origin);
41057
- if (willEvaluate)
41214
+ if (willEvaluate && !recommendAsAnswer)
41058
41215
  void this.evaluateOptions(live, requestId, input);
41059
41216
  this.autoAnswerPrompt(live, requestId, { kind: "question", tool: "AskUserQuestion" }, (a) => {
41060
41217
  if (!this.pendingPermissions.has(requestId))
41061
41218
  return false;
41062
- this.respondToPermission(requestId, { behavior: "deny", message: a.message });
41219
+ this.respondToPermission(requestId, a.behavior === "allow" ? { behavior: "allow", ...a.updatedInput ? { updatedInput: a.updatedInput } : {} } : { behavior: "deny", message: a.message });
41063
41220
  return true;
41064
- });
41221
+ }, recommendAsAnswer ? async () => {
41222
+ const questions = input.questions;
41223
+ const recs = await Promise.race([
41224
+ this.evaluateOptions(live, requestId, input),
41225
+ new Promise((r) => setTimeout(() => r([]), RECOMMEND_ANSWER_TIMEOUT_MS))
41226
+ ]);
41227
+ const pick3 = pickRecommendedAnswers(questions, recs);
41228
+ if (!pick3) {
41229
+ log(`unattended: no usable recommendation for the question \u2014 handing it back to the agent`);
41230
+ return null;
41231
+ }
41232
+ return { behavior: "allow", updatedInput: { answers: pick3.answers }, message: void 0, decision: pick3.decision };
41233
+ } : void 0);
41065
41234
  });
41066
41235
  }
41067
41236
  /** Compile a compact context summary for the option-recommendation LLM: the project,
@@ -41087,10 +41256,10 @@ ${text12.slice(0, 1600)}`);
41087
41256
  async evaluateOptions(live, requestId, input) {
41088
41257
  const llm = this.cheapLlm;
41089
41258
  if (!llm)
41090
- return;
41259
+ return [];
41091
41260
  const questions = Array.isArray(input.questions) ? input.questions : [];
41092
41261
  if (!questions.length)
41093
- return;
41262
+ return [];
41094
41263
  try {
41095
41264
  const qText = questions.map((q, qi) => {
41096
41265
  const opts = Array.isArray(q.options) ? q.options : [];
@@ -41106,19 +41275,21 @@ ${lines}`;
41106
41275
  });
41107
41276
  const out = await llm({ system, prompt: userPrompt, maxTokens: 1400, schema: OPTION_RATING_JSON_SCHEMA });
41108
41277
  if (!out)
41109
- return;
41278
+ return [];
41110
41279
  const parsed = parseModelJson(out) ?? {};
41111
41280
  const LEVELS = /* @__PURE__ */ new Set(["highly_recommended", "recommended", "neutral", "caution", "discouraged"]);
41112
41281
  const clean2 = (Array.isArray(parsed.recommendations) ? parsed.recommendations : []).map((r) => r).filter((r) => r && typeof r.optionLabel === "string" && typeof r.questionIndex === "number" && typeof r.level === "string" && LEVELS.has(r.level)).map((r) => ({ questionIndex: r.questionIndex, optionLabel: r.optionLabel, level: r.level, reason: typeof r.reason === "string" ? r.reason.slice(0, 140) : "" }));
41113
41282
  if (!clean2.length || !this.pendingPermissions.has(requestId))
41114
- return;
41283
+ return clean2;
41115
41284
  const evt = { type: "agent:option_recommendations", sessionId: live.sessionId, requestId, recommendations: clean2 };
41116
41285
  if (live.clientRequestId)
41117
41286
  this.send({ ...evt, clientRequestId: live.clientRequestId }, live.origin);
41118
41287
  else
41119
41288
  this.send(evt, live.origin);
41289
+ return clean2;
41120
41290
  } catch (err2) {
41121
41291
  log("option recommendation eval failed:", err2 instanceof Error ? err2.message : String(err2));
41292
+ return [];
41122
41293
  }
41123
41294
  }
41124
41295
  /** request_user_dialog: park a promise, raise the dialog card
@@ -41126,7 +41297,7 @@ ${lines}`;
41126
41297
  * reply (→ respondToUserDialog). Mirrors onElicitation: the CLI parks the flow until
41127
41298
  * we answer; an unanswered/aborted dialog resolves 'cancelled' so the CLI applies the
41128
41299
  * dialog's default behavior (e.g. the classic refusal message) rather than hanging. */
41129
- raiseUserDialog(live, request2, signal) {
41300
+ raiseUserDialog(live, request2, signal2) {
41130
41301
  return new Promise((resolve16) => {
41131
41302
  const requestId = randomUUID4();
41132
41303
  log("user_dialog raised:", request2.dialogKind, "requestId=" + requestId, "payloadKeys=" + Object.keys(request2.payload ?? {}).join(","));
@@ -41136,14 +41307,14 @@ ${lines}`;
41136
41307
  resolve16({ behavior: "cancelled" });
41137
41308
  }
41138
41309
  };
41139
- const cleanup2 = () => signal.removeEventListener("abort", onAbort);
41140
- if (signal.aborted) {
41310
+ const cleanup2 = () => signal2.removeEventListener("abort", onAbort);
41311
+ if (signal2.aborted) {
41141
41312
  log("user_dialog pre-aborted (cancelled):", request2.dialogKind);
41142
41313
  resolve16({ behavior: "cancelled" });
41143
41314
  return;
41144
41315
  }
41145
- signal.addEventListener("abort", onAbort, { once: true });
41146
- this.pendingUserDialogs.set(requestId, { resolve: resolve16, cleanup: cleanup2, origin: live.origin });
41316
+ signal2.addEventListener("abort", onAbort, { once: true });
41317
+ this.pendingUserDialogs.set(requestId, { resolve: resolve16, cleanup: cleanup2, origin: live.origin, live });
41147
41318
  const evt = {
41148
41319
  type: "agent:user_dialog_request",
41149
41320
  sessionId: live.sessionId,
@@ -42054,6 +42225,11 @@ ${prompt("agent.system.long-running")}`;
42054
42225
  }
42055
42226
  }
42056
42227
  if (live && live.streaming) {
42228
+ if (!params.autoContinuation && !params.rvInjected) {
42229
+ const withdrawn = this.withdrawParkedPrompts(live);
42230
+ if (withdrawn)
42231
+ log(`[prompt] ${live.sessionId || "(pending)"}: ${withdrawn} parked prompt(s) withdrawn \u2014 the user replied in the chat`);
42232
+ }
42057
42233
  const sameOrigin = (params.origin ?? void 0) === (live.origin ?? void 0);
42058
42234
  if (sameOrigin) {
42059
42235
  live.lastActivity = Date.now();
@@ -42805,7 +42981,7 @@ ${prompt("agent.system.long-running")}`;
42805
42981
  opts.signal.addEventListener("abort", onAbort, { once: true });
42806
42982
  holding = true;
42807
42983
  live.parked = (live.parked ?? 0) + 1;
42808
- this.pendingPermissions.set(requestId, { resolve: resolve16, suggestions: opts.suggestions, cleanup: cleanup2, origin: live.origin });
42984
+ this.pendingPermissions.set(requestId, { resolve: resolve16, suggestions: opts.suggestions, cleanup: cleanup2, origin: live.origin, live, tool: toolName });
42809
42985
  const evt = {
42810
42986
  type: "agent:permission_request",
42811
42987
  sessionId: live.sessionId,
@@ -42850,7 +43026,7 @@ ${prompt("agent.system.long-running")}`;
42850
43026
  return;
42851
43027
  }
42852
43028
  opts.signal.addEventListener("abort", onAbort, { once: true });
42853
- this.pendingElicitations.set(requestId, { resolve: resolve16, cleanup: cleanup2, origin: live.origin });
43029
+ this.pendingElicitations.set(requestId, { resolve: resolve16, cleanup: cleanup2, origin: live.origin, live });
42854
43030
  const evt = {
42855
43031
  type: "agent:elicitation_request",
42856
43032
  sessionId: live.sessionId,
@@ -43139,6 +43315,7 @@ ${prompt("agent.system.long-running")}`;
43139
43315
  if (errSeen >= 8e3)
43140
43316
  log("[engine stderr] \u2026 further output suppressed for this turn");
43141
43317
  });
43318
+ child.once("exit", (code, signal2) => log(`[engine exit] ${live.sessionId || "(pending)"} pid=${child.pid} code=${code} signal=${signal2}`));
43142
43319
  live.child = child;
43143
43320
  return child;
43144
43321
  },
@@ -44108,9 +44285,10 @@ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
44108
44285
  reportUsageLimit(live.usageLimitRejection, sid);
44109
44286
  log("Claude subscription usage limit rejected the turn:", sid);
44110
44287
  } else if (live.interrupted || live.abort.signal.aborted) {
44288
+ const byUser = live.interrupted;
44111
44289
  live.interrupted = false;
44112
44290
  this.clearStopWatchdog(live);
44113
- log("Session interrupted by user (caught from iterator):", sid);
44291
+ log(`Session interrupted (caught from iterator): ${sid} \u2014 ${byUser ? "user stop" : "abort signal"}; engine said: ${err2 instanceof Error ? err2.message : String(err2)}`);
44114
44292
  emit2({ type: "chat:error", sessionId: sid, error: "Interrupted." });
44115
44293
  emit2({ type: "agent:status", sessionId: sid, status: "idle" });
44116
44294
  } else if (live.resultErrorReported) {
@@ -44555,7 +44733,7 @@ ${err2.stack}` : ""}` : String(err2);
44555
44733
  * `capMs` is a seam for the tests: the real cap is a minute, and a test that had to sleep
44556
44734
  * through it would either be a minute long or would assert a timeout instead of the report.
44557
44735
  */
44558
- async waitForBatchWork(live, signal, capMs = BATCH_WAIT_MS) {
44736
+ async waitForBatchWork(live, signal2, capMs = BATCH_WAIT_MS) {
44559
44737
  const started2 = Date.now();
44560
44738
  this.refreshLedgerLiveness(live, started2);
44561
44739
  live.ledger.sweep(started2);
@@ -44572,7 +44750,7 @@ ${err2.stack}` : ""}` : String(err2);
44572
44750
  const turn = live.turnSeq;
44573
44751
  log(`[work] batch barrier: waiting for ${watched.length} item(s) on ${live.sessionId}`);
44574
44752
  while (Date.now() - started2 < capMs) {
44575
- if (signal?.aborted || live.turnSeq !== turn) {
44753
+ if (signal2?.aborted || live.turnSeq !== turn) {
44576
44754
  log("[work] batch barrier abandoned \u2014 the turn it belonged to is gone");
44577
44755
  return void 0;
44578
44756
  }
@@ -45534,6 +45712,8 @@ __export(dist_exports2, {
45534
45712
  PRESENT_TOOL_NAMES: () => PRESENT_TOOL_NAMES,
45535
45713
  PRESENT_TOOL_SPECS: () => PRESENT_TOOL_SPECS,
45536
45714
  PROACTIVE_REGROWTH_POINTS: () => PROACTIVE_REGROWTH_POINTS,
45715
+ PROMPT_WITHDRAWN_DECISION: () => PROMPT_WITHDRAWN_DECISION,
45716
+ PROMPT_WITHDRAWN_NOTE: () => PROMPT_WITHDRAWN_NOTE,
45537
45717
  SLIM_KEEP_RECENT_TURNS: () => SLIM_KEEP_RECENT_TURNS,
45538
45718
  SessionStore: () => SessionStore,
45539
45719
  TOKENS_CSS_FILE: () => TOKENS_CSS_FILE,
@@ -45591,6 +45771,7 @@ __export(dist_exports2, {
45591
45771
  normalizeTokens: () => normalizeTokens,
45592
45772
  offloadDirFor: () => offloadDirFor,
45593
45773
  parseColorToRgb: () => parseColorToRgb,
45774
+ pickRecommendedAnswers: () => pickRecommendedAnswers,
45594
45775
  readSessionArtifacts: () => readSessionArtifacts,
45595
45776
  readSessionRowsForDisplay: () => readSessionRowsForDisplay,
45596
45777
  readUnattendedDecisions: () => readUnattendedDecisions,
@@ -45648,6 +45829,8 @@ var init_dist5 = __esm({
45648
45829
  init_context_recovery();
45649
45830
  init_session_transfer();
45650
45831
  init_log();
45832
+ init_prompt_withdrawal();
45833
+ init_question_recommendation();
45651
45834
  init_session_mirror();
45652
45835
  init_history_slim();
45653
45836
  init_history_filter();
@@ -45819,7 +46002,7 @@ var init_reaper_binary = __esm({
45819
46002
  function hasLivePid(child) {
45820
46003
  return !!child && typeof child.pid === "number" && Number.isFinite(child.pid) && child.pid > 0;
45821
46004
  }
45822
- function killChild(child, signal = "SIGTERM", label = "child", log10 = (m) => console.warn(m)) {
46005
+ function killChild(child, signal2 = "SIGTERM", label = "child", log10 = (m) => console.warn(m)) {
45823
46006
  if (!hasLivePid(child)) {
45824
46007
  try {
45825
46008
  log10(`[safe-kill] refused to signal ${label}: no live pid (pid=${String(child?.pid)}) \u2014 kill() on a handle without a pid becomes kill(0), which signals our OWN process group`);
@@ -45828,7 +46011,7 @@ function killChild(child, signal = "SIGTERM", label = "child", log10 = (m) => co
45828
46011
  return false;
45829
46012
  }
45830
46013
  try {
45831
- child.kill(signal);
46014
+ child.kill(signal2);
45832
46015
  return true;
45833
46016
  } catch {
45834
46017
  return false;
@@ -46693,17 +46876,17 @@ import { execFileSync as execFileSync2 } from "node:child_process";
46693
46876
  import { existsSync as existsSync11, readFileSync as readFileSync18 } from "node:fs";
46694
46877
  import { homedir as homedir4 } from "node:os";
46695
46878
  function augmentedPath() {
46696
- const sep11 = process.platform === "win32" ? ";" : ":";
46879
+ const sep12 = process.platform === "win32" ? ";" : ":";
46697
46880
  const extra = engineSearchDirs({ home: homedir4(), platform: process.platform, env: process.env });
46698
46881
  const seen = /* @__PURE__ */ new Set();
46699
46882
  const parts = [];
46700
- for (const p of [...(process.env.PATH ?? "").split(sep11), ...extra]) {
46883
+ for (const p of [...(process.env.PATH ?? "").split(sep12), ...extra]) {
46701
46884
  if (p && !seen.has(p)) {
46702
46885
  seen.add(p);
46703
46886
  parts.push(p);
46704
46887
  }
46705
46888
  }
46706
- return parts.join(sep11);
46889
+ return parts.join(sep12);
46707
46890
  }
46708
46891
  function rememberedPath(engineId) {
46709
46892
  try {
@@ -76440,10 +76623,10 @@ var init_codec = __esm({
76440
76623
  if (items.length > max)
76441
76624
  fail("too-long", `vec ${items.length} > ${max}`);
76442
76625
  for (let i = 1; i < items.length; i++) {
76443
- const cmp = compareUtf8(items[i - 1], items[i]);
76444
- if (cmp === 0)
76626
+ const cmp2 = compareUtf8(items[i - 1], items[i]);
76627
+ if (cmp2 === 0)
76445
76628
  fail("duplicate", items[i]);
76446
- if (cmp > 0)
76629
+ if (cmp2 > 0)
76447
76630
  fail("not-sorted", `${items[i - 1]} > ${items[i]}`);
76448
76631
  }
76449
76632
  this.u16(items.length);
@@ -76542,10 +76725,10 @@ var init_codec = __esm({
76542
76725
  for (let i = 0; i < n; i++) {
76543
76726
  const s = this.str();
76544
76727
  if (i > 0) {
76545
- const cmp = compareUtf8(out[i - 1], s);
76546
- if (cmp === 0)
76728
+ const cmp2 = compareUtf8(out[i - 1], s);
76729
+ if (cmp2 === 0)
76547
76730
  fail("duplicate", s);
76548
- if (cmp > 0)
76731
+ if (cmp2 > 0)
76549
76732
  fail("not-sorted", `${out[i - 1]} > ${s}`);
76550
76733
  }
76551
76734
  out.push(s);
@@ -76646,10 +76829,10 @@ function writePrefixes(w, items) {
76646
76829
  if (items.length > LIMITS.VEC)
76647
76830
  throw new MeshCodecError("too-long", `routes ${items.length}`);
76648
76831
  for (let i = 1; i < items.length; i++) {
76649
- const cmp = comparePrefix(items[i - 1], items[i]);
76650
- if (cmp === 0)
76832
+ const cmp2 = comparePrefix(items[i - 1], items[i]);
76833
+ if (cmp2 === 0)
76651
76834
  throw new MeshCodecError("duplicate", "route");
76652
- if (cmp > 0)
76835
+ if (cmp2 > 0)
76653
76836
  throw new MeshCodecError("not-sorted", "route");
76654
76837
  }
76655
76838
  w.u16(items.length);
@@ -76664,10 +76847,10 @@ function readPrefixes(r) {
76664
76847
  for (let i = 0; i < n; i++) {
76665
76848
  const p = readPrefix(r);
76666
76849
  if (i > 0) {
76667
- const cmp = comparePrefix(out[i - 1], p);
76668
- if (cmp === 0)
76850
+ const cmp2 = comparePrefix(out[i - 1], p);
76851
+ if (cmp2 === 0)
76669
76852
  throw new MeshCodecError("duplicate", "route");
76670
- if (cmp > 0)
76853
+ if (cmp2 > 0)
76671
76854
  throw new MeshCodecError("not-sorted", "route");
76672
76855
  }
76673
76856
  out.push(p);
@@ -80538,7 +80721,7 @@ function alphabet(letters) {
80538
80721
  };
80539
80722
  }
80540
80723
  // @__NO_SIDE_EFFECTS__
80541
- function join69(separator = "") {
80724
+ function join70(separator = "") {
80542
80725
  astr("join", separator);
80543
80726
  return {
80544
80727
  encode: (from) => {
@@ -80743,7 +80926,7 @@ var init_esm = __esm({
80743
80926
  convertRadix2,
80744
80927
  radix,
80745
80928
  radix2,
80746
- join: join69,
80929
+ join: join70,
80747
80930
  padding
80748
80931
  };
80749
80932
  }
@@ -82289,8 +82472,8 @@ var mesh_ca_exports = {};
82289
82472
  __export(mesh_ca_exports, {
82290
82473
  netCaCommand: () => netCaCommand
82291
82474
  });
82292
- import { chmodSync as chmodSync8, existsSync as existsSync54, mkdirSync as mkdirSync49, readFileSync as readFileSync58, writeFileSync as writeFileSync49 } from "node:fs";
82293
- import { join as join93, resolve as resolve13 } from "node:path";
82475
+ import { chmodSync as chmodSync8, existsSync as existsSync55, mkdirSync as mkdirSync49, readFileSync as readFileSync61, writeFileSync as writeFileSync49 } from "node:fs";
82476
+ import { join as join94, resolve as resolve13 } from "node:path";
82294
82477
  import { createInterface as createInterface2 } from "node:readline";
82295
82478
  function die(msg) {
82296
82479
  console.error(msg);
@@ -82335,14 +82518,14 @@ function ensureDir(p) {
82335
82518
  }
82336
82519
  }
82337
82520
  async function openCa(dir2) {
82338
- const gPath = join93(dir2, "genesis.bin");
82339
- const sPath = join93(dir2, "ca.sealed");
82340
- if (!existsSync54(gPath) || !existsSync54(sPath)) {
82521
+ const gPath = join94(dir2, "genesis.bin");
82522
+ const sPath = join94(dir2, "ca.sealed");
82523
+ if (!existsSync55(gPath) || !existsSync55(sPath)) {
82341
82524
  die(`No mesh CA in ${dir2}. Run: tesseract-agent net init --org NAME --ca-dir ${dir2}`);
82342
82525
  }
82343
- const genesisBytes = new Uint8Array(readFileSync58(gPath));
82526
+ const genesisBytes = new Uint8Array(readFileSync61(gPath));
82344
82527
  const genesis = decodeGenesis(genesisBytes);
82345
- const sealed = decodeRecoveryBundle(new Uint8Array(readFileSync58(sPath)));
82528
+ const sealed = decodeRecoveryBundle(new Uint8Array(readFileSync61(sPath)));
82346
82529
  const pass = await readPassphrase("CA passphrase: ");
82347
82530
  let seed;
82348
82531
  try {
@@ -82358,7 +82541,7 @@ async function netCaCommand(rest, flags) {
82358
82541
  if (sub === "init") {
82359
82542
  const org = typeof flags.org === "string" ? flags.org.trim() : "";
82360
82543
  if (!org) die("Usage: tesseract-agent net init --org NAME [--ca-dir DIR]");
82361
- if (existsSync54(join93(caDir, "ca.sealed"))) {
82544
+ if (existsSync55(join94(caDir, "ca.sealed"))) {
82362
82545
  die(`A mesh CA already exists in ${caDir}. Refusing to overwrite it.`);
82363
82546
  }
82364
82547
  const pass = await readPassphrase("New CA passphrase: ");
@@ -82380,9 +82563,9 @@ async function netCaCommand(rest, flags) {
82380
82563
  const genesisBytes = encodeGenesis(genesis);
82381
82564
  const fp = await genesisFingerprint(genesis);
82382
82565
  ensureDir(caDir);
82383
- writeFileSync49(join93(caDir, "genesis.bin"), genesisBytes);
82384
- writeSecretFile(join93(caDir, "ca.sealed"), encodeRecoveryBundle(await sealCaKey(seed, pass, `${org} mesh CA`)));
82385
- writeSecretFile(join93(caDir, "disablement.secret"), hex3(disable.secret));
82566
+ writeFileSync49(join94(caDir, "genesis.bin"), genesisBytes);
82567
+ writeSecretFile(join94(caDir, "ca.sealed"), encodeRecoveryBundle(await sealCaKey(seed, pass, `${org} mesh CA`)));
82568
+ writeSecretFile(join94(caDir, "disablement.secret"), hex3(disable.secret));
82386
82569
  console.log(`
82387
82570
  Mesh created for "${org}".`);
82388
82571
  console.log(` fingerprint: ${hex3(fp)}`);
@@ -82397,7 +82580,7 @@ Mesh created for "${org}".`);
82397
82580
  console.log(` ${hex3(disable.secret)}`);
82398
82581
  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");
82399
82582
  console.log(`
82400
- A copy of the disablement secret is in ${join93(caDir, "disablement.secret")}.`);
82583
+ A copy of the disablement secret is in ${join94(caDir, "disablement.secret")}.`);
82401
82584
  console.log("Move it somewhere the CA directory is not \u2014 holding both in one place");
82402
82585
  console.log("defeats the point of having two.");
82403
82586
  const caFlag = caDir === resolve13("./mesh-ca") ? "" : ` --ca-dir ${caDir}`;
@@ -82450,14 +82633,14 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
82450
82633
  [{ keyIndex: 0, privateKey: ca.privateKey }]
82451
82634
  );
82452
82635
  ensureDir(outDir);
82453
- writeFileSync49(join93(outDir, "genesis.bin"), genesisBytes);
82454
- writeFileSync49(join93(outDir, "node.cert"), encodeCert(cert));
82455
- writeSecretFile(join93(outDir, "node.key"), await exportStaticPrivate(nodeKey));
82636
+ writeFileSync49(join94(outDir, "genesis.bin"), genesisBytes);
82637
+ writeFileSync49(join94(outDir, "node.cert"), encodeCert(cert));
82638
+ writeSecretFile(join94(outDir, "node.key"), await exportStaticPrivate(nodeKey));
82456
82639
  console.log(`Minted "${name}" at ${ip4}.`);
82457
82640
  console.log(` ${outDir}`);
82458
82641
  console.log("\nCopy that directory to the node and run there:");
82459
- console.log(` tesseract-agent net enroll --genesis ${join93(outDir, "genesis.bin")} \\`);
82460
- console.log(` --cert ${join93(outDir, "node.cert")} --key ${join93(outDir, "node.key")}`);
82642
+ console.log(` tesseract-agent net enroll --genesis ${join94(outDir, "genesis.bin")} \\`);
82643
+ console.log(` --cert ${join94(outDir, "node.cert")} --key ${join94(outDir, "node.key")}`);
82461
82644
  console.log("\nnode.key is the node's identity \u2014 send it over a channel you trust, and");
82462
82645
  console.log("delete this copy once the node has it.");
82463
82646
  return;
@@ -82493,7 +82676,7 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
82493
82676
  ip4Exceptions: []
82494
82677
  };
82495
82678
  const signed = await signBundle(bundle, [{ keyIndex: 0, privateKey: ca.privateKey }]);
82496
- const out = resolve13(typeof flags.out === "string" ? flags.out : join93(caDir, "bundle.bin"));
82679
+ const out = resolve13(typeof flags.out === "string" ? flags.out : join94(caDir, "bundle.bin"));
82497
82680
  writeFileSync49(out, encodeSignedBundle(signed));
82498
82681
  console.log(`Signed policy bundle (epoch ${epoch2}) \u2192 ${out}`);
82499
82682
  console.log("Every node must receive it; the relay distributes it, or copy it to");
@@ -82516,12 +82699,12 @@ var init_mesh_ca = __esm({
82516
82699
 
82517
82700
  // src/cli.ts
82518
82701
  init_base_paths();
82519
- import { existsSync as existsSync55, mkdtempSync as mkdtempSync4, readFileSync as readFileSync60, rmSync as rmSync14 } from "node:fs";
82702
+ import { existsSync as existsSync56, mkdtempSync as mkdtempSync4, readFileSync as readFileSync63, rmSync as rmSync14 } from "node:fs";
82520
82703
  import { createHash as createHash9 } from "node:crypto";
82521
- import { execFileSync as execFileSync7, spawn as spawn14 } from "node:child_process";
82704
+ import { execFileSync as execFileSync8, spawn as spawn14 } from "node:child_process";
82522
82705
  import { fileURLToPath as fileURLToPath8 } from "node:url";
82523
82706
  import { tmpdir as tmpdir8 } from "node:os";
82524
- import { dirname as dirname44, join as join94, resolve as resolve15 } from "node:path";
82707
+ import { dirname as dirname44, join as join95, resolve as resolve15 } from "node:path";
82525
82708
  import { createInterface as createInterface3 } from "node:readline/promises";
82526
82709
 
82527
82710
  // ../../packages/host-core/dist/control-link.js
@@ -85360,8 +85543,8 @@ function installWorkspaceHandlers(t, opts) {
85360
85543
  w(term.exit);
85361
85544
  }
85362
85545
  });
85363
- child.on("exit", (code, signal) => {
85364
- term.exit = { exitCode: code, signal: signal ?? null };
85546
+ child.on("exit", (code, signal2) => {
85547
+ term.exit = { exitCode: code, signal: signal2 ?? null };
85365
85548
  for (const w of term.waiters.splice(0))
85366
85549
  w(term.exit);
85367
85550
  });
@@ -85692,6 +85875,9 @@ var SEED = {
85692
85875
  // itself and the 5.4 mini/nano are 400k.
85693
85876
  "gpt-6-astra": 105e4,
85694
85877
  "gpt-5.6": 105e4,
85878
+ "gpt-5.6-sol": 105e4,
85879
+ "gpt-5.6-terra": 105e4,
85880
+ "gpt-5.6-luna": 105e4,
85695
85881
  "gpt-5.5": 105e4,
85696
85882
  "gpt-5.4": 105e4,
85697
85883
  "gpt-5": 4e5,
@@ -86633,6 +86819,18 @@ function toolOutputText(content) {
86633
86819
  const c = content;
86634
86820
  return c?.text ?? "";
86635
86821
  }
86822
+ async function pickDefaultModel(current, offered, floor, windowOf) {
86823
+ if (current && await windowOf(current) >= floor.minWindow)
86824
+ return null;
86825
+ const set2 = new Set(offered);
86826
+ for (const id of floor.preferred)
86827
+ if (set2.has(id) && id !== current)
86828
+ return id;
86829
+ for (const id of offered)
86830
+ if (id !== current && await windowOf(id) >= floor.minWindow)
86831
+ return id;
86832
+ return null;
86833
+ }
86636
86834
  function modelMemoPath(engineId) {
86637
86835
  return join30(daemonDir2(), "engine-config", engineId, "last-model.txt");
86638
86836
  }
@@ -86690,6 +86888,23 @@ ${snapshot4}
86690
86888
  </context_from_compaction>`;
86691
86889
  }
86692
86890
  var OPENCODE_ACP = {
86891
+ // 200k is the one window the operator called unusable; big-pickle is OpenCode's default.
86892
+ // Preference: the strongest 1M-class model per provider the user is likely to have, the
86893
+ // engine's own zen mirrors of them, then its free 1M tier. All published at ≥1M (2026-09).
86894
+ defaultModelFloor: {
86895
+ minWindow: 1e6,
86896
+ preferred: [
86897
+ "anthropic/claude-sonnet-5",
86898
+ "openai/gpt-5.6",
86899
+ "google/gemini-3.5-flash",
86900
+ "opencode/claude-sonnet-5",
86901
+ "opencode/gpt-5.6",
86902
+ "opencode/gemini-3.5-flash",
86903
+ "opencode/nemotron-3-ultra-free",
86904
+ "opencode/muse-spark-1.3-contributor-free",
86905
+ "opencode/mimo-v2-pro-free"
86906
+ ]
86907
+ },
86693
86908
  // Its shipped ruleset is `"*": "allow"`, so its ACP layer — which forwards permissions
86694
86909
  // correctly, and auto-REJECTS when the client advertises no responder — never had anything
86695
86910
  // to forward. `OPENCODE_PERMISSION` is applied last in its config assembly, so this is the
@@ -87964,6 +88179,30 @@ ${text12}`);
87964
88179
  send: send5,
87965
88180
  log: (m) => console.warn(`[${engine.label}] ${m}`)
87966
88181
  });
88182
+ function withdrawParkedPrompts(sid, clientRequestId, origin) {
88183
+ let n = 0;
88184
+ const announce = (requestId, promptKind, behavior) => send5({ type: "agent:auto_decision", sessionId: sid, clientRequestId, requestId, promptKind, decision: PROMPT_WITHDRAWN_DECISION, behavior }, origin);
88185
+ for (const [rid, pend] of [...pendingPermissions]) {
88186
+ if (pend.sid !== sid)
88187
+ continue;
88188
+ pendingPermissions.delete(rid);
88189
+ const id = pend.options.find((o) => o.kind === "reject_once")?.optionId ?? pend.options.find((o) => o.kind?.startsWith("reject"))?.optionId;
88190
+ pend.resolve(id ? { outcome: { outcome: "selected", optionId: id } } : { outcome: { outcome: "cancelled" } });
88191
+ announce(rid, "permission", "deny");
88192
+ n++;
88193
+ }
88194
+ if (turns.size <= 1) {
88195
+ for (const [rid, pend] of [...pendingDialogs]) {
88196
+ pendingDialogs.delete(rid);
88197
+ pend.resolve({ action: "decline" });
88198
+ announce(rid, "elicitation", "decline");
88199
+ n++;
88200
+ }
88201
+ }
88202
+ if (n)
88203
+ console.warn(`[${engine.label}] ${sid}: ${n} parked prompt(s) withdrawn \u2014 the user replied in the chat`);
88204
+ return n;
88205
+ }
87967
88206
  async function maybeCompactProactively(sid, params) {
87968
88207
  try {
87969
88208
  if (params.autoContinuation)
@@ -88100,6 +88339,17 @@ ${text12}`);
88100
88339
  knownSessions.add(sid);
88101
88340
  sessionIndex.record({ id: sid, cwd: params.projectDir, title: firstLine(params.message) });
88102
88341
  sessionConfig.set(sid, readSessionConfig(res));
88342
+ if (!params.model && engine.defaultModelFloor) {
88343
+ const cfg2 = sessionConfig.get(sid);
88344
+ const pick3 = await pickDefaultModel(cfg2?.currentModel, (cfg2?.models ?? []).map((m) => m.id), engine.defaultModelFloor, (id) => resolveContextWindow(id).catch(() => 0));
88345
+ if (pick3 && cfg2) {
88346
+ const ok = await t.request("session/set_model", { sessionId: sid, modelId: pick3 }).then(() => true).catch(() => false);
88347
+ if (ok) {
88348
+ console.warn(`[${engine.label}] default model ${cfg2.currentModel ?? "(none)"} is under ${engine.defaultModelFloor.minWindow.toLocaleString()} tokens \u2014 new session switched to ${pick3}`);
88349
+ cfg2.currentModel = pick3;
88350
+ }
88351
+ }
88352
+ }
88103
88353
  rememberModel(engine.id, sessionConfig.get(sid)?.currentModel);
88104
88354
  sessionCwd.set(sid, params.projectDir);
88105
88355
  if (hostedHold.token) {
@@ -88126,6 +88376,8 @@ ${text12}`);
88126
88376
  if (declared.fileRewind && params.projectDir) {
88127
88377
  await snapshots.take(sid, snapKey, params.projectDir);
88128
88378
  }
88379
+ if (!params.autoContinuation)
88380
+ withdrawParkedPrompts(sid, params.clientRequestId, origin);
88129
88381
  const messageId = randomUUID14();
88130
88382
  const turnId = randomUUID14();
88131
88383
  const startedAt2 = Date.now();
@@ -88312,7 +88564,7 @@ ${detail}` : detail, !overflow);
88312
88564
  ],
88313
88565
  // A subagent is a SEPARATE ACP session on the same live process: no history, its
88314
88566
  // own permission gate, and it cannot disturb the parent's turn state.
88315
- runSubagent: async (prompt2, { signal }) => {
88567
+ runSubagent: async (prompt2, { signal: signal2 }) => {
88316
88568
  if (!transport || !spawnedCwd)
88317
88569
  throw new Error(`${LABEL3} is not running.`);
88318
88570
  const res = await transport.request("session/new", { cwd: spawnedCwd, mcpServers: [] });
@@ -88320,7 +88572,7 @@ ${detail}` : detail, !overflow);
88320
88572
  if (!sub)
88321
88573
  throw new Error("could not start a subagent session");
88322
88574
  knownSessions.add(sub);
88323
- signal.addEventListener("abort", () => {
88575
+ signal2.addEventListener("abort", () => {
88324
88576
  try {
88325
88577
  transport?.notify("session/cancel", { sessionId: sub });
88326
88578
  } catch {
@@ -88989,6 +89241,7 @@ import { mkdirSync as mkdirSync18, readFileSync as readFileSync24, writeFileSync
88989
89241
  import { join as join31 } from "node:path";
88990
89242
  init_daemon_settings();
88991
89243
  init_dist5();
89244
+ import { homedir as homedir8 } from "node:os";
88992
89245
  init_prompts();
88993
89246
  init_hosted_jobs();
88994
89247
  var TESSERACT_INTERNAL_SECRET3 = /^(CCB_JWT_SECRET|JWT_SECRET|TESSERACT_TOKEN|CCB_RELAY_SECRET|TURN_SECRET|LIVEKIT_API_SECRET)$/;
@@ -89169,6 +89422,28 @@ function itemToolName(item) {
89169
89422
  return null;
89170
89423
  }
89171
89424
  }
89425
+ function configuredCodexModel(home = process.env.CODEX_HOME ?? join31(homedir8(), ".codex")) {
89426
+ try {
89427
+ const m = /^\s*model\s*=\s*"([^"]+)"/m.exec(readFileSync24(join31(home, "config.toml"), "utf8"));
89428
+ return m?.[1] || void 0;
89429
+ } catch {
89430
+ return void 0;
89431
+ }
89432
+ }
89433
+ function codexWindowFlags(published, remembered, pct2) {
89434
+ const flags = [];
89435
+ if (published > 0)
89436
+ flags.push("-c", `model_context_window=${published}`);
89437
+ if (!pct2 || pct2 <= 0 || pct2 >= 100)
89438
+ return flags;
89439
+ const base = remembered && (!published || remembered >= published * 0.7) ? remembered : published;
89440
+ if (!base)
89441
+ return flags;
89442
+ const limit = Math.round(base * (pct2 / 100));
89443
+ if (limit > 0)
89444
+ flags.push("-c", `model_auto_compact_token_limit=${limit}`);
89445
+ return flags;
89446
+ }
89172
89447
  function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPluginRuntime2) {
89173
89448
  const ENGINE_ID2 = "openai-codex";
89174
89449
  const HOSTED_TOKEN_ENV = "TESSERACT_MCP_TOKEN";
@@ -89222,7 +89497,7 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89222
89497
  extraTools: () => scheduling.tools(),
89223
89498
  // A subagent is a separate THREAD on the same app-server: its own history, its own
89224
89499
  // approval policy, and it cannot disturb the parent turn.
89225
- runSubagent: async (prompt2, { signal }) => {
89500
+ runSubagent: async (prompt2, { signal: signal2 }) => {
89226
89501
  if (!transport || !spawnedCwd)
89227
89502
  throw new Error(`${label} is not running.`);
89228
89503
  const started2 = await transport.request("thread/start", {
@@ -89235,7 +89510,7 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89235
89510
  throw new Error("could not start a subagent thread");
89236
89511
  const out = [];
89237
89512
  subagentSinks.set(sub, out);
89238
- signal.addEventListener("abort", () => {
89513
+ signal2.addEventListener("abort", () => {
89239
89514
  void transport?.request("turn/interrupt", { threadId: sub }).catch(() => {
89240
89515
  });
89241
89516
  });
@@ -89247,7 +89522,7 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89247
89522
  resolveWait();
89248
89523
  };
89249
89524
  subagentDone.set(sub, done);
89250
- signal.addEventListener("abort", done);
89525
+ signal2.addEventListener("abort", done);
89251
89526
  });
89252
89527
  } finally {
89253
89528
  subagentSinks.delete(sub);
@@ -89611,17 +89886,12 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89611
89886
  return void 0;
89612
89887
  }
89613
89888
  }
89614
- function compactionFlags() {
89615
- const pct2 = readDaemonAgentSettings().autoCompactPct;
89616
- if (!pct2 || pct2 <= 0 || pct2 >= 100)
89617
- return [];
89618
- const window2 = rememberedWindow();
89619
- if (!window2)
89620
- return [];
89621
- const limit = Math.round(window2 * (pct2 / 100));
89622
- return limit > 0 ? ["-c", `model_auto_compact_token_limit=${limit}`] : [];
89889
+ async function spawnFlags(model) {
89890
+ const id = model ?? configuredCodexModel();
89891
+ const published = id ? await resolveContextWindow(id).catch(() => 0) : 0;
89892
+ return codexWindowFlags(published, rememberedWindow(), readDaemonAgentSettings().autoCompactPct);
89623
89893
  }
89624
- async function ensureProcess(command, env, cwd) {
89894
+ async function ensureProcess(command, env, cwd, model) {
89625
89895
  if (transport && child && !child.killed && spawnedCwd === cwd)
89626
89896
  return transport;
89627
89897
  if (transport && child && !child.killed && spawnedCwd !== cwd) {
@@ -89636,7 +89906,7 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89636
89906
  if (initPromise)
89637
89907
  return initPromise;
89638
89908
  initPromise = (async () => {
89639
- const c = spawnManaged(command, ["app-server", ...compactionFlags()], {
89909
+ const c = spawnManaged(command, ["app-server", ...await spawnFlags(model)], {
89640
89910
  name: "codex",
89641
89911
  killSignal: "SIGKILL",
89642
89912
  cwd,
@@ -89862,6 +90132,34 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89862
90132
  send: send5,
89863
90133
  log: (m) => console.warn(`[${label}] ${m}`)
89864
90134
  });
90135
+ function withdrawParkedPrompts(threadId, clientRequestId, origin) {
90136
+ let n = 0;
90137
+ const announce = (requestId, promptKind, behavior) => send5({ type: "agent:auto_decision", sessionId: threadId, clientRequestId, requestId, promptKind, decision: PROMPT_WITHDRAWN_DECISION, behavior }, origin);
90138
+ for (const [rid, pend] of [...pendingApprovals]) {
90139
+ if (pend.threadId !== threadId)
90140
+ continue;
90141
+ pendingApprovals.delete(rid);
90142
+ pend.resolve(pend.deny);
90143
+ announce(rid, "permission", "deny");
90144
+ n++;
90145
+ }
90146
+ if (turns.size <= 1) {
90147
+ for (const [rid, pend] of [...pendingDialogs]) {
90148
+ pendingDialogs.delete(rid);
90149
+ if (pend.kind === "userDialog") {
90150
+ pend.resolve({ answers: {} });
90151
+ announce(rid, "dialog", "cancel");
90152
+ } else {
90153
+ pend.resolve({ action: "decline" });
90154
+ announce(rid, "elicitation", "decline");
90155
+ }
90156
+ n++;
90157
+ }
90158
+ }
90159
+ if (n)
90160
+ console.warn(`[${label}] ${threadId}: ${n} parked prompt(s) withdrawn \u2014 the user replied in the chat`);
90161
+ return n;
90162
+ }
89865
90163
  async function maybeCompactProactively(threadId, params) {
89866
90164
  try {
89867
90165
  if (params.autoContinuation)
@@ -89908,17 +90206,17 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89908
90206
  return;
89909
90207
  }
89910
90208
  await ensureHostedToolset();
90209
+ const live = params.sessionId ? liveRunModes.get(params.sessionId) : void 0;
90210
+ const permissionMode = live?.permissionMode ?? params.permissionMode;
90211
+ const model = live?.model ?? params.model;
89911
90212
  let t;
89912
90213
  try {
89913
- t = await ensureProcess(cfg2.command, cfg2.env, params.projectDir);
90214
+ t = await ensureProcess(cfg2.command, cfg2.env, params.projectDir, model);
89914
90215
  } catch (e) {
89915
90216
  fail4(params.sessionId ?? "", params.clientRequestId, `${label} failed to start: ${String(e?.message ?? e)}`, origin, true);
89916
90217
  return;
89917
90218
  }
89918
90219
  await installTools(t, { ...injectedServers, ...params.mcpServers ?? {} });
89919
- const live = params.sessionId ? liveRunModes.get(params.sessionId) : void 0;
89920
- const permissionMode = live?.permissionMode ?? params.permissionMode;
89921
- const model = live?.model ?? params.model;
89922
90220
  let threadId = params.sessionId ? followRekey(params.sessionId) : params.sessionId;
89923
90221
  if (threadId && threadId !== params.sessionId)
89924
90222
  send5({ type: "session:created", sessionId: threadId, clientRequestId: params.clientRequestId }, origin);
@@ -89992,6 +90290,8 @@ function createCodexAppServerBackend(send5, resolve16, onBrowserRequest, loadPlu
89992
90290
  await snapshots.take(threadId, snapKey, params.projectDir);
89993
90291
  }
89994
90292
  userTurnSeq.set(threadId, userSeq + 1);
90293
+ if (!params.autoContinuation)
90294
+ withdrawParkedPrompts(threadId, params.clientRequestId, origin);
89995
90295
  const messageId = randomUUID15();
89996
90296
  const turnId = randomUUID15();
89997
90297
  const startedAt2 = Date.now();
@@ -91726,7 +92026,8 @@ import { join as join35, dirname as dirname16 } from "node:path";
91726
92026
 
91727
92027
  // ../../packages/host-core/dist/service/types.js
91728
92028
  init_base_paths();
91729
- var SERVICE_LABEL_BASE = "dev.tesseract.app.host";
92029
+ var SERVICE_LABEL_BASE = "dev.tesseract.agent";
92030
+ var LEGACY_SERVICE_LABEL_BASE = "dev.tesseract.app.host";
91730
92031
  function instanceSuffix(instanceId) {
91731
92032
  if (instanceId)
91732
92033
  return instanceId;
@@ -92334,17 +92635,17 @@ function createDaemonOsControlRunner() {
92334
92635
  const n = await nutOrThrow();
92335
92636
  const btn = NUT_BTN[opts?.button ?? "left"];
92336
92637
  const stepPx = opts?.stepPx ?? 5, stepMs = opts?.stepMs ?? 12;
92337
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
92638
+ const sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
92338
92639
  const move = (x, y) => {
92339
92640
  const rx = Math.round(x), ry = Math.round(y);
92340
92641
  n.moveMouse(rx, ry);
92341
92642
  opts?.onStep?.({ x: rx, y: ry });
92342
92643
  };
92343
92644
  move(points[0].x, points[0].y);
92344
- await sleep(120);
92645
+ await sleep2(120);
92345
92646
  n.mouseToggle("down", btn);
92346
92647
  if (opts?.grabMs)
92347
- await sleep(opts.grabMs);
92648
+ await sleep2(opts.grabMs);
92348
92649
  try {
92349
92650
  for (let i = 1; i < points.length; i++) {
92350
92651
  const a = points[i - 1], b = points[i];
@@ -92354,11 +92655,11 @@ function createDaemonOsControlRunner() {
92354
92655
  if (opts?.signal?.aborted)
92355
92656
  return;
92356
92657
  move(a.x + (b.x - a.x) * s / segs, a.y + (b.y - a.y) * s / segs);
92357
- await sleep(stepMs);
92658
+ await sleep2(stepMs);
92358
92659
  }
92359
92660
  }
92360
92661
  if (opts?.dropMs && !opts?.signal?.aborted)
92361
- await sleep(opts.dropMs);
92662
+ await sleep2(opts.dropMs);
92362
92663
  } finally {
92363
92664
  n.mouseToggle("up", btn);
92364
92665
  }
@@ -92419,7 +92720,7 @@ function wireIpcOnce() {
92419
92720
  }
92420
92721
  });
92421
92722
  }
92422
- function showFormWindow(kind, payload, signal) {
92723
+ function showFormWindow(kind, payload, signal2) {
92423
92724
  const el2 = electronModule();
92424
92725
  if (!el2)
92425
92726
  notReady("Asking for input");
@@ -92453,7 +92754,7 @@ function showFormWindow(kind, payload, signal) {
92453
92754
  if (done)
92454
92755
  return;
92455
92756
  done = true;
92456
- signal?.removeEventListener("abort", onAbort);
92757
+ signal2?.removeEventListener("abort", onAbort);
92457
92758
  pendingInput.delete(reqId);
92458
92759
  try {
92459
92760
  if (!win3.isDestroyed())
@@ -92464,10 +92765,10 @@ function showFormWindow(kind, payload, signal) {
92464
92765
  };
92465
92766
  pendingInput.set(reqId, finish);
92466
92767
  win3.on("closed", () => finish({ submitted: false, values: {} }));
92467
- if (signal?.aborted)
92768
+ if (signal2?.aborted)
92468
92769
  onAbort();
92469
92770
  else
92470
- signal?.addEventListener("abort", onAbort);
92771
+ signal2?.addEventListener("abort", onAbort);
92471
92772
  });
92472
92773
  }
92473
92774
  async function confirmAction(spec, opts) {
@@ -93586,9 +93887,9 @@ function isNotice(toolName) {
93586
93887
  return toolName === "_notice_";
93587
93888
  }
93588
93889
  function parseNotice(summary) {
93589
- const sep11 = summary.indexOf("\n\n");
93590
- const headerRaw = (sep11 >= 0 ? summary.slice(0, sep11) : summary).trim();
93591
- const body = sep11 >= 0 ? summary.slice(sep11 + 2).trim() : "";
93890
+ const sep12 = summary.indexOf("\n\n");
93891
+ const headerRaw = (sep12 >= 0 ? summary.slice(0, sep12) : summary).trim();
93892
+ const body = sep12 >= 0 ? summary.slice(sep12 + 2).trim() : "";
93592
93893
  const subtype = headerRaw.replace(/^_+|_+$/g, "");
93593
93894
  return { subtype, body };
93594
93895
  }
@@ -94191,7 +94492,7 @@ import { randomUUID as randomUUID24 } from "node:crypto";
94191
94492
 
94192
94493
  // ../../packages/host-core/dist/companion-browsers.js
94193
94494
  import { existsSync as existsSync17, readdirSync as readdirSync8, readFileSync as readFileSync26, statSync as statSync12 } from "node:fs";
94194
- import { homedir as homedir8 } from "node:os";
94495
+ import { homedir as homedir9 } from "node:os";
94195
94496
  import { join as join39 } from "node:path";
94196
94497
  var COMPANION_EXTENSION_IDS = [
94197
94498
  "icpnghhpcmaonjckkpilpajblfehpplo",
@@ -94224,7 +94525,7 @@ var WIN = [
94224
94525
  ["Chromium/User Data", "Chromium", "chrome"]
94225
94526
  ];
94226
94527
  function roots() {
94227
- const home = homedir8();
94528
+ const home = homedir9();
94228
94529
  if (process.platform === "darwin") {
94229
94530
  const base = join39(home, "Library/Application Support");
94230
94531
  return MAC.map(([d, n, a]) => [join39(base, d), n, a]);
@@ -94893,7 +95194,7 @@ var SUPPORTED_DURATIONS = [4, 6, 8];
94893
95194
  var DEFAULT_DURATION = 8;
94894
95195
  var REQUEST_TIMEOUT_MS = 9e4;
94895
95196
  var DOWNLOAD_TIMEOUT_MS = 18e4;
94896
- var withTimeout3 = (signal, ms) => signal ?? AbortSignal.timeout(ms);
95197
+ var withTimeout3 = (signal2, ms) => signal2 ?? AbortSignal.timeout(ms);
94897
95198
  function clampDuration(requested) {
94898
95199
  if (!requested || !Number.isFinite(requested))
94899
95200
  return DEFAULT_DURATION;
@@ -95007,7 +95308,7 @@ var GeminiVeoProvider = class {
95007
95308
  var DEFAULT_MODEL4 = "tsr-video";
95008
95309
  var REQUEST_TIMEOUT_MS2 = 9e4;
95009
95310
  var DOWNLOAD_TIMEOUT_MS2 = 18e4;
95010
- var withTimeout4 = (signal, ms) => signal ?? AbortSignal.timeout(ms);
95311
+ var withTimeout4 = (signal2, ms) => signal2 ?? AbortSignal.timeout(ms);
95011
95312
  var TesseractVeoProvider = class {
95012
95313
  id = "tesseract";
95013
95314
  model;
@@ -96147,7 +96448,7 @@ var HEYGEN_DIRECT_BASE_URL = "https://api.heygen.com";
96147
96448
  var DEFAULT_DIM = { width: 1280, height: 720 };
96148
96449
  var HG_REQUEST_TIMEOUT_MS = 6e4;
96149
96450
  var HG_DOWNLOAD_TIMEOUT_MS = 18e4;
96150
- async function hgFetch(path6, cfg2, init, signal) {
96451
+ async function hgFetch(path6, cfg2, init, signal2) {
96151
96452
  const base = (cfg2.baseUrl || HEYGEN_DIRECT_BASE_URL).replace(/\/+$/, "");
96152
96453
  let res;
96153
96454
  try {
@@ -96155,7 +96456,7 @@ async function hgFetch(path6, cfg2, init, signal) {
96155
96456
  method: init.method,
96156
96457
  headers: { "X-Api-Key": cfg2.apiKey, ...init.body != null ? { "Content-Type": "application/json" } : {} },
96157
96458
  ...init.body != null ? { body: JSON.stringify(init.body) } : {},
96158
- signal: signal ?? AbortSignal.timeout(HG_REQUEST_TIMEOUT_MS)
96459
+ signal: signal2 ?? AbortSignal.timeout(HG_REQUEST_TIMEOUT_MS)
96159
96460
  });
96160
96461
  } catch (e) {
96161
96462
  throw new Error(`HeyGen: network error \u2014 ${e instanceof Error ? e.message : String(e)}`);
@@ -96169,11 +96470,11 @@ async function hgFetch(path6, cfg2, init, signal) {
96169
96470
  }
96170
96471
  return json3;
96171
96472
  }
96172
- async function listAvatarsHeyGen(cfg2, signal) {
96173
- const j = await hgFetch("/v2/avatars", cfg2, { method: "GET" }, signal);
96473
+ async function listAvatarsHeyGen(cfg2, signal2) {
96474
+ const j = await hgFetch("/v2/avatars", cfg2, { method: "GET" }, signal2);
96174
96475
  return (j.data?.avatars ?? []).map((a) => ({ avatarId: a.avatar_id, name: a.avatar_name ?? a.avatar_id }));
96175
96476
  }
96176
- async function submitAvatarVideoHeyGen(spec, cfg2, signal) {
96477
+ async function submitAvatarVideoHeyGen(spec, cfg2, signal2) {
96177
96478
  if (!spec.avatarId && !spec.talkingPhotoId)
96178
96479
  throw new Error("HeyGen: provide an avatarId or talkingPhotoId.");
96179
96480
  const character = spec.talkingPhotoId ? { type: "talking_photo", talking_photo_id: spec.talkingPhotoId } : { type: "avatar", avatar_id: spec.avatarId, avatar_style: "normal" };
@@ -96187,21 +96488,21 @@ async function submitAvatarVideoHeyGen(spec, cfg2, signal) {
96187
96488
  ],
96188
96489
  dimension: { width: spec.width ?? DEFAULT_DIM.width, height: spec.height ?? DEFAULT_DIM.height }
96189
96490
  };
96190
- const j = await hgFetch("/v2/video/generate", cfg2, { method: "POST", body }, signal);
96491
+ const j = await hgFetch("/v2/video/generate", cfg2, { method: "POST", body }, signal2);
96191
96492
  const id = j.data?.video_id;
96192
96493
  if (!id)
96193
96494
  throw new Error("HeyGen returned no video_id.");
96194
96495
  return id;
96195
96496
  }
96196
- async function pollAvatarVideoHeyGen(videoId, cfg2, signal) {
96197
- const j = await hgFetch(`/v1/video_status.get?video_id=${encodeURIComponent(videoId)}`, cfg2, { method: "GET" }, signal);
96497
+ async function pollAvatarVideoHeyGen(videoId, cfg2, signal2) {
96498
+ const j = await hgFetch(`/v1/video_status.get?video_id=${encodeURIComponent(videoId)}`, cfg2, { method: "GET" }, signal2);
96198
96499
  const d = j.data ?? {};
96199
96500
  const error51 = typeof d.error === "string" ? d.error : d.error?.message;
96200
96501
  return { status: d.status ?? "processing", videoUrl: d.video_url, error: error51 };
96201
96502
  }
96202
- async function downloadHeyGenVideo(url2, signal) {
96503
+ async function downloadHeyGenVideo(url2, signal2) {
96203
96504
  try {
96204
- const res = await fetch(url2, { signal: signal ?? AbortSignal.timeout(HG_DOWNLOAD_TIMEOUT_MS) });
96505
+ const res = await fetch(url2, { signal: signal2 ?? AbortSignal.timeout(HG_DOWNLOAD_TIMEOUT_MS) });
96205
96506
  if (!res.ok)
96206
96507
  throw new Error(`HeyGen video download failed (${res.status})`);
96207
96508
  return { bytes: new Uint8Array(await res.arrayBuffer()), mime: "video/mp4" };
@@ -98966,14 +99267,14 @@ function parseExternalTabId(browserId) {
98966
99267
  if (!browserId.startsWith("ext:"))
98967
99268
  return null;
98968
99269
  const rest = browserId.slice(4);
98969
- const sep11 = rest.lastIndexOf(":");
98970
- const digits = sep11 < 0 ? rest : rest.slice(sep11 + 1);
99270
+ const sep12 = rest.lastIndexOf(":");
99271
+ const digits = sep12 < 0 ? rest : rest.slice(sep12 + 1);
98971
99272
  if (!/^\d+$/.test(digits))
98972
99273
  return null;
98973
99274
  const tabId = Number(digits);
98974
- if (sep11 < 0)
99275
+ if (sep12 < 0)
98975
99276
  return { key: null, tabId };
98976
- const key2 = rest.slice(0, sep11);
99277
+ const key2 = rest.slice(0, sep12);
98977
99278
  return key2 ? { key: key2, tabId } : null;
98978
99279
  }
98979
99280
  function preferredCompanion() {
@@ -99362,7 +99663,7 @@ init_base_paths();
99362
99663
  import { readFile as readFile12 } from "node:fs/promises";
99363
99664
  import { statSync as statSync13 } from "node:fs";
99364
99665
  import { execFile as execFile5 } from "node:child_process";
99365
- import { homedir as homedir9 } from "node:os";
99666
+ import { homedir as homedir10 } from "node:os";
99366
99667
  import { basename as basename7, join as join49 } from "node:path";
99367
99668
  var recentsProvider = () => [];
99368
99669
  var ownDeviceIdProvider = () => "";
@@ -99432,7 +99733,7 @@ function prettyName(p) {
99432
99733
  return basename7(p) || p;
99433
99734
  }
99434
99735
  async function macFavorites() {
99435
- const dir2 = join49(homedir9(), "Library", "Application Support", "com.apple.sharedfilelist");
99736
+ const dir2 = join49(homedir10(), "Library", "Application Support", "com.apple.sharedfilelist");
99436
99737
  let denied = false;
99437
99738
  for (const ext of ["sfl3", "sfl2"]) {
99438
99739
  try {
@@ -99449,7 +99750,7 @@ async function macFavorites() {
99449
99750
  return { favorites: macFallback(), needsFda: denied };
99450
99751
  }
99451
99752
  function macFallback() {
99452
- const home = homedir9();
99753
+ const home = homedir10();
99453
99754
  const known = [
99454
99755
  { label: "Applications", path: "/Applications" },
99455
99756
  { label: "iCloud Drive", path: join49(home, "Library", "Mobile Documents", "com~apple~CloudDocs") },
@@ -99594,11 +99895,11 @@ async function windowsFavorites() {
99594
99895
  return finalize2(items);
99595
99896
  }
99596
99897
  async function linuxFavorites() {
99597
- const config2 = process.env.XDG_CONFIG_HOME || join49(homedir9(), ".config");
99898
+ const config2 = process.env.XDG_CONFIG_HOME || join49(homedir10(), ".config");
99598
99899
  const candidates = [
99599
99900
  join49(config2, "gtk-3.0", "bookmarks"),
99600
99901
  join49(config2, "gtk-4.0", "bookmarks"),
99601
- join49(homedir9(), ".gtk-bookmarks")
99902
+ join49(homedir10(), ".gtk-bookmarks")
99602
99903
  // legacy GTK2
99603
99904
  ];
99604
99905
  for (const file2 of candidates) {
@@ -102208,7 +102509,7 @@ function sameState(a, b) {
102208
102509
  return true;
102209
102510
  return false;
102210
102511
  }
102211
- function decide(local, remote, ownWinsTie) {
102512
+ function decide2(local, remote, ownWinsTie) {
102212
102513
  if (sameState(local, remote))
102213
102514
  return "noop";
102214
102515
  if (remote.t > local.t)
@@ -104601,7 +104902,7 @@ var ActiveLinkEngine = class {
104601
104902
  const local = this.manifest.effective(rel);
104602
104903
  const entry = peerMap.get(rel);
104603
104904
  const remote = entry ? LinkManifest.sideOf(entry) : ABSENT;
104604
- if (decide(local, remote, this.ownWinsTie) !== "pull")
104905
+ if (decide2(local, remote, this.ownWinsTie) !== "pull")
104605
104906
  continue;
104606
104907
  if (remote.kind === "deleted")
104607
104908
  void this.applyDelete(rel, remote.t);
@@ -104613,13 +104914,13 @@ var ActiveLinkEngine = class {
104613
104914
  onFile(rel, kind, mtimeMs, hash2) {
104614
104915
  const local = this.manifest.effective(rel);
104615
104916
  const remote = { kind, t: mtimeMs, hash: hash2 };
104616
- if (decide(local, remote, this.ownWinsTie) === "pull")
104917
+ if (decide2(local, remote, this.ownWinsTie) === "pull")
104617
104918
  this.pull(rel, kind);
104618
104919
  }
104619
104920
  async onDelete(rel, deletedAtMs) {
104620
104921
  const local = this.manifest.effective(rel);
104621
104922
  const remote = { kind: "deleted", t: deletedAtMs, hash: "" };
104622
- if (decide(local, remote, this.ownWinsTie) === "pull")
104923
+ if (decide2(local, remote, this.ownWinsTie) === "pull")
104623
104924
  await this.applyDelete(rel, deletedAtMs);
104624
104925
  }
104625
104926
  /** Request content for a path we've decided the peer wins: symlinks (and the
@@ -104979,7 +105280,7 @@ var ActiveLinkEngine = class {
104979
105280
  /** Would an incoming file@(mtimeMs,hash) still win against our CURRENT local state?
104980
105281
  * Used to drop a pull that a concurrent local write has overtaken. */
104981
105282
  incomingStillWins(rel, mtimeMs, hash2) {
104982
- return decide(this.manifest.effective(rel), { kind: "file", t: mtimeMs, hash: hash2 }, this.ownWinsTie) === "pull";
105283
+ return decide2(this.manifest.effective(rel), { kind: "file", t: mtimeMs, hash: hash2 }, this.ownWinsTie) === "pull";
104983
105284
  }
104984
105285
  async reconcileScan() {
104985
105286
  this.allow = await gitSyncedFiles(this.opts.localRoot);
@@ -105280,7 +105581,7 @@ init_dist5();
105280
105581
 
105281
105582
  // ../../packages/host-core/dist/pty-manager.js
105282
105583
  import { existsSync as existsSync28 } from "node:fs";
105283
- import { homedir as homedir10 } from "node:os";
105584
+ import { homedir as homedir11 } from "node:os";
105284
105585
  init_safe_kill();
105285
105586
  var ptyPromise = null;
105286
105587
  function loadPty() {
@@ -105348,10 +105649,10 @@ async function openPty(opts, sink3) {
105348
105649
  else if (!s.timer)
105349
105650
  s.timer = setTimeout(() => flush(opts.ptyId, s, sink3), FLUSH_MS);
105350
105651
  });
105351
- proc.onExit(({ exitCode, signal }) => {
105652
+ proc.onExit(({ exitCode, signal: signal2 }) => {
105352
105653
  flush(opts.ptyId, s, sink3);
105353
105654
  sessions2.delete(k);
105354
- sink3.exit(opts.ptyId, exitCode ?? null, signal ?? null);
105655
+ sink3.exit(opts.ptyId, exitCode ?? null, signal2 ?? null);
105355
105656
  });
105356
105657
  return { pid: proc.pid };
105357
105658
  }
@@ -105373,7 +105674,7 @@ function resizePty(ptyId, cols, rows, clientId) {
105373
105674
  }
105374
105675
  }
105375
105676
  }
105376
- function killPty(ptyId, signal, clientId) {
105677
+ function killPty(ptyId, signal2, clientId) {
105377
105678
  const k = key(clientId, ptyId);
105378
105679
  const s = sessions2.get(k);
105379
105680
  if (!s)
@@ -105382,7 +105683,7 @@ function killPty(ptyId, signal, clientId) {
105382
105683
  clearTimeout(s.timer);
105383
105684
  s.timer = null;
105384
105685
  }
105385
- killChild(s.proc, signal, "pty session");
105686
+ killChild(s.proc, signal2, "pty session");
105386
105687
  }
105387
105688
  function releaseClientPtys(clientId) {
105388
105689
  for (const [k, s] of [...sessions2]) {
@@ -105522,7 +105823,7 @@ function buildChildEnv(opts) {
105522
105823
  return base;
105523
105824
  }
105524
105825
  function resolveCwd(cwd, hostRoot) {
105525
- const fallback = hostRoot || homedir10();
105826
+ const fallback = hostRoot || homedir11();
105526
105827
  if (!cwd)
105527
105828
  return fallback;
105528
105829
  if (!existsSync28(cwd))
@@ -106431,7 +106732,7 @@ async function serveInboundTerm(p, driverClientId) {
106431
106732
  case "term:open": {
106432
106733
  const sink3 = {
106433
106734
  output: (ptyId, base643) => send3("term", { type: "term:output", ptyId, base64: base643 }, route3),
106434
- exit: (ptyId, exitCode, signal) => send3("term", { type: "term:exit", ptyId, exitCode, signal }, route3)
106735
+ exit: (ptyId, exitCode, signal2) => send3("term", { type: "term:exit", ptyId, exitCode, signal: signal2 }, route3)
106435
106736
  };
106436
106737
  try {
106437
106738
  const { pid } = await openPty({ ptyId: p.ptyId, clientId: driverClientId, shell: p.shell, args: p.args, cwd: p.cwd, cols: p.cols, rows: p.rows, env: p.env, hostRoot: HOST_CONTAIN }, sink3);
@@ -107404,11 +107705,15 @@ var RdeskSessionManager = class {
107404
107705
  onCapture: (ok, message) => this.reportCapture(sessionId, viewer.clientId, ok, message)
107405
107706
  };
107406
107707
  let engine;
107708
+ let session;
107407
107709
  try {
107408
107710
  engine = await this.deps.createEngine(engineKind, ctx2);
107711
+ session = { sessionId, viewer, grant, accessLevel, engine, startedAt: this.now() };
107712
+ this.sessions.set(sessionId, session);
107409
107713
  const dq = this.deps.defaultQuality;
107410
107714
  await engine.start({ monitorId: void 0, quality: (typeof dq === "function" ? dq() : dq) ?? "auto" });
107411
107715
  } catch (e) {
107716
+ this.sessions.delete(sessionId);
107412
107717
  const err2 = e instanceof Error ? e.message : String(e);
107413
107718
  this.log(`engine start failed sessionId=${sessionId}: ${err2}`);
107414
107719
  this.deps.onCaptureBlocked?.({ sessionId, viewerName: viewer.name, error: err2 });
@@ -107418,8 +107723,6 @@ var RdeskSessionManager = class {
107418
107723
  const sources = await engine.listSources?.().catch(() => []) ?? [];
107419
107724
  const activeMonitor = monitors.find((m) => m.primary)?.id ?? monitors[0]?.id ?? "";
107420
107725
  const activeSource = sources.find((s) => s.kind === "screen" && s.primary)?.id ?? sources[0]?.id ?? "";
107421
- const session = { sessionId, viewer, grant, accessLevel, engine, startedAt: this.now() };
107422
- this.sessions.set(sessionId, session);
107423
107726
  this.log(`accepted sessionId=${sessionId} grant=${grant} engine=${engine.id} access=${accessLevel}`);
107424
107727
  this.audit({ event: "accept", sessionId, viewerUserId: viewer.userId, viewerName: viewer.name, grant, detail: `engine=${engine.id}` });
107425
107728
  this.deps.sendControl(sessionId, viewer.clientId, {
@@ -110848,7 +111151,7 @@ async function startLocalServer(opts) {
110848
111151
  let participantId = null;
110849
111152
  const termSink = {
110850
111153
  output: (ptyId, base643) => send5("term", { type: "term:output", ptyId, base64: base643 }),
110851
- exit: (ptyId, exitCode, signal) => send5("term", { type: "term:exit", ptyId, exitCode, signal })
111154
+ exit: (ptyId, exitCode, signal2) => send5("term", { type: "term:exit", ptyId, exitCode, signal: signal2 })
110852
111155
  };
110853
111156
  const heldSessions = /* @__PURE__ */ new Set();
110854
111157
  let focusedTab;
@@ -111557,9 +111860,9 @@ async function startLocalServer(opts) {
111557
111860
 
111558
111861
  // ../../packages/host-core/dist/daemon-runtime.js
111559
111862
  init_base_paths();
111560
- import { readFileSync as readFileSync53, writeFileSync as writeFileSync43, existsSync as existsSync43, mkdirSync as mkdirSync45, unlinkSync as unlinkSync7, chmodSync as chmodSync7, statSync as statSync17 } from "node:fs";
111561
- import { execFileSync as execFileSync5 } from "node:child_process";
111562
- import { join as join82 } from "node:path";
111863
+ import { readFileSync as readFileSync54, writeFileSync as writeFileSync43, existsSync as existsSync44, mkdirSync as mkdirSync45, unlinkSync as unlinkSync8, chmodSync as chmodSync7, statSync as statSync17 } from "node:fs";
111864
+ import { execFileSync as execFileSync6 } from "node:child_process";
111865
+ import { join as join83 } from "node:path";
111563
111866
  import { randomBytes as randomBytes11 } from "node:crypto";
111564
111867
  import { hostname as hostname6 } from "node:os";
111565
111868
 
@@ -111685,6 +111988,37 @@ function registeredDaemons(selfPid) {
111685
111988
  }
111686
111989
  return out;
111687
111990
  }
111991
+ function readProcessTable() {
111992
+ const rows = [];
111993
+ try {
111994
+ if (process.platform === "win32") {
111995
+ const raw2 = execFileSync3("powershell.exe", [
111996
+ "-NoProfile",
111997
+ "-NonInteractive",
111998
+ "-Command",
111999
+ 'Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId)`t$($_.ParentProcessId)`t$($_.CommandLine)" }'
112000
+ ], { encoding: "utf8", timeout: 8e3, windowsHide: true });
112001
+ for (const line of raw2.split(/\r?\n/)) {
112002
+ const p = line.split(" ");
112003
+ if (p.length < 3)
112004
+ continue;
112005
+ const pid = Number(p[0]);
112006
+ const ppid = Number(p[1]);
112007
+ if (pid > 0)
112008
+ rows.push({ pid, ppid, cmd: p.slice(2).join(" ") });
112009
+ }
112010
+ return rows;
112011
+ }
112012
+ const raw = execFileSync3("ps", ["-axww", "-o", "pid=,ppid=,command="], { encoding: "utf8", timeout: 8e3, env: PS_ENV });
112013
+ for (const line of raw.split("\n")) {
112014
+ const m = line.match(/^\s*(\d+)\s+(\d+)\s+(.*)$/);
112015
+ if (m)
112016
+ rows.push({ pid: Number(m[1]), ppid: Number(m[2]), cmd: m[3] });
112017
+ }
112018
+ } catch {
112019
+ }
112020
+ return rows;
112021
+ }
111688
112022
  var supervisorCache = null;
111689
112023
  function invalidateSupervisorCache() {
111690
112024
  supervisorCache = null;
@@ -111699,19 +112033,138 @@ function liveDaemons() {
111699
112033
  return out;
111700
112034
  }
111701
112035
 
112036
+ // ../../packages/host-core/dist/cli-agent.js
112037
+ import { execFileSync as execFileSync4 } from "node:child_process";
112038
+ import { existsSync as existsSync33, readFileSync as readFileSync47, unlinkSync as unlinkSync7 } from "node:fs";
112039
+ import { join as join68, sep as sep11 } from "node:path";
112040
+ init_credentials();
112041
+ var statusFile = () => join68(daemonDir2(), "status.json");
112042
+ var pidfile = () => join68(daemonDir2(), "daemon.lock");
112043
+ var CLI_PKG = `${sep11}node_modules${sep11}tesseract-agent${sep11}`;
112044
+ function isCliExecPath(execPath) {
112045
+ if (!execPath)
112046
+ return false;
112047
+ return execPath.includes(CLI_PKG) || execPath.endsWith(`${sep11}tesseract-agent`);
112048
+ }
112049
+ function readMachineHolder() {
112050
+ let raw;
112051
+ try {
112052
+ raw = readFileSync47(statusFile(), "utf-8");
112053
+ } catch {
112054
+ return null;
112055
+ }
112056
+ let s;
112057
+ try {
112058
+ s = JSON.parse(raw);
112059
+ } catch {
112060
+ return null;
112061
+ }
112062
+ const pid = Number(s.pid);
112063
+ if (!Number.isInteger(pid) || pid <= 0 || !isPidAlive2(pid))
112064
+ return null;
112065
+ const execPath = typeof s.execPath === "string" ? s.execPath : "";
112066
+ const stamped = s.kind === "cli" || s.kind === "app" ? s.kind : void 0;
112067
+ return {
112068
+ pid,
112069
+ kind: stamped ?? (isCliExecPath(execPath) ? "cli" : "app"),
112070
+ execPath,
112071
+ version: typeof s.version === "string" ? s.version : "unknown"
112072
+ };
112073
+ }
112074
+ function descendantsOf(pid, table = readProcessTable()) {
112075
+ const byParent = /* @__PURE__ */ new Map();
112076
+ for (const r of table) {
112077
+ if (r.ppid === r.pid)
112078
+ continue;
112079
+ byParent.set(r.ppid, [...byParent.get(r.ppid) ?? [], r.pid]);
112080
+ }
112081
+ const out = [];
112082
+ const seen = /* @__PURE__ */ new Set([pid]);
112083
+ const walk2 = (p) => {
112084
+ for (const child of byParent.get(p) ?? []) {
112085
+ if (seen.has(child))
112086
+ continue;
112087
+ seen.add(child);
112088
+ walk2(child);
112089
+ out.push(child);
112090
+ }
112091
+ };
112092
+ walk2(pid);
112093
+ return out;
112094
+ }
112095
+ function signal(pid, sig) {
112096
+ if (!Number.isInteger(pid) || pid <= 0)
112097
+ return;
112098
+ try {
112099
+ process.kill(pid, sig);
112100
+ } catch {
112101
+ }
112102
+ }
112103
+ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
112104
+ async function stopCliAgent(holder, log10 = console.log) {
112105
+ const tree = [...descendantsOf(holder.pid), holder.pid];
112106
+ log10(`[cli-agent] stopping the headless agent: pid ${holder.pid} (+${tree.length - 1} child process(es)), v${holder.version}`);
112107
+ for (const pid of tree)
112108
+ signal(pid, "SIGTERM");
112109
+ for (let i = 0; i < 20 && tree.some(isPidAlive2); i++)
112110
+ await sleep(250);
112111
+ const stubborn = tree.filter(isPidAlive2);
112112
+ if (stubborn.length) {
112113
+ log10(`[cli-agent] ${stubborn.length} process(es) ignored SIGTERM \u2014 escalating to SIGKILL`);
112114
+ for (const pid of stubborn)
112115
+ signal(pid, "SIGKILL");
112116
+ await sleep(500);
112117
+ }
112118
+ const alive = tree.filter(isPidAlive2);
112119
+ if (alive.length) {
112120
+ log10(`[cli-agent] could NOT stop pid(s) ${alive.join(", ")}`);
112121
+ return false;
112122
+ }
112123
+ try {
112124
+ if (existsSync33(pidfile()) && Number(readFileSync47(pidfile(), "utf-8").trim()) === holder.pid)
112125
+ unlinkSync7(pidfile());
112126
+ } catch {
112127
+ }
112128
+ log10("[cli-agent] stopped");
112129
+ return true;
112130
+ }
112131
+ function uninstallCliAgent(log10 = console.log) {
112132
+ try {
112133
+ log10("[cli-agent] uninstalling the tesseract-agent npm package");
112134
+ execFileSync4(process.platform === "win32" ? "npm.cmd" : "npm", ["uninstall", "-g", "tesseract-agent"], {
112135
+ stdio: ["ignore", "pipe", "pipe"],
112136
+ timeout: 12e4
112137
+ });
112138
+ log10("[cli-agent] uninstalled");
112139
+ return true;
112140
+ } catch (e) {
112141
+ log10("[cli-agent] uninstall failed (the agent is stopped regardless):", e?.message ?? e);
112142
+ return false;
112143
+ }
112144
+ }
112145
+ async function evictCliAgent(log10 = console.log) {
112146
+ const holder = readMachineHolder();
112147
+ if (!holder || holder.kind !== "cli")
112148
+ return "none";
112149
+ log10(`[cli-agent] the headless CLI agent owns this machine (${holder.execPath}); the desktop app takes over`);
112150
+ if (!await stopCliAgent(holder, log10))
112151
+ return "failed";
112152
+ return uninstallCliAgent(log10) ? "stopped-and-uninstalled" : "stopped";
112153
+ }
112154
+
111702
112155
  // ../../packages/host-core/dist/device-identity.js
111703
- import { join as join68 } from "node:path";
111704
- import { readFileSync as readFileSync47, writeFileSync as writeFileSync35, existsSync as existsSync33, mkdirSync as mkdirSync36, renameSync as renameSync11, chmodSync as chmodSync4 } from "node:fs";
112156
+ import { join as join69 } from "node:path";
112157
+ import { readFileSync as readFileSync48, writeFileSync as writeFileSync35, existsSync as existsSync34, mkdirSync as mkdirSync36, renameSync as renameSync11, chmodSync as chmodSync4 } from "node:fs";
111705
112158
  init_credentials();
111706
112159
  var cached3 = null;
111707
112160
  function identityPath() {
111708
- return join68(daemonDir2(), "identity.json");
112161
+ return join69(daemonDir2(), "identity.json");
111709
112162
  }
111710
112163
  async function loadOrCreateDeviceIdentity() {
111711
112164
  if (cached3)
111712
112165
  return cached3;
111713
112166
  try {
111714
- const stored = JSON.parse(readFileSync47(identityPath(), "utf-8"));
112167
+ const stored = JSON.parse(readFileSync48(identityPath(), "utf-8"));
111715
112168
  if (stored?.privateJwk) {
111716
112169
  cached3 = await importIdentity(stored.privateJwk);
111717
112170
  return cached3;
@@ -111721,7 +112174,7 @@ async function loadOrCreateDeviceIdentity() {
111721
112174
  const kp = await generateIdentityKeyPair(true);
111722
112175
  const { privateJwk, publicRaw } = await exportIdentity(kp);
111723
112176
  const dir2 = daemonDir2();
111724
- if (!existsSync33(dir2))
112177
+ if (!existsSync34(dir2))
111725
112178
  mkdirSync36(dir2, { recursive: true, mode: 448 });
111726
112179
  const tmp = `${identityPath()}.tmp`;
111727
112180
  writeFileSync35(tmp, JSON.stringify({ privateJwk, publicRaw, alg: "P256-ECDSA" }, null, 2), { mode: 384 });
@@ -111735,7 +112188,7 @@ async function loadOrCreateDeviceIdentity() {
111735
112188
  }
111736
112189
  var sealingCached = null;
111737
112190
  function sealingPath() {
111738
- return join68(daemonDir2(), "sealing.json");
112191
+ return join69(daemonDir2(), "sealing.json");
111739
112192
  }
111740
112193
  var EC_DH = { name: "ECDH", namedCurve: "P-256" };
111741
112194
  async function loadOrCreateSealingKey() {
@@ -111743,7 +112196,7 @@ async function loadOrCreateSealingKey() {
111743
112196
  return sealingCached;
111744
112197
  const { subtle: subtle5 } = globalThis.crypto;
111745
112198
  try {
111746
- const stored = JSON.parse(readFileSync47(sealingPath(), "utf-8"));
112199
+ const stored = JSON.parse(readFileSync48(sealingPath(), "utf-8"));
111747
112200
  if (stored?.privateJwk && stored.publicRaw) {
111748
112201
  const privateKey = await subtle5.importKey("jwk", stored.privateJwk, EC_DH, true, ["deriveBits"]);
111749
112202
  sealingCached = { privateKey, publicRaw: unb64u(stored.publicRaw) };
@@ -111755,7 +112208,7 @@ async function loadOrCreateSealingKey() {
111755
112208
  const publicRaw = new Uint8Array(await subtle5.exportKey("raw", kp.publicKey));
111756
112209
  const privateJwk = await subtle5.exportKey("jwk", kp.privateKey);
111757
112210
  const dir2 = daemonDir2();
111758
- if (!existsSync33(dir2))
112211
+ if (!existsSync34(dir2))
111759
112212
  mkdirSync36(dir2, { recursive: true, mode: 448 });
111760
112213
  const tmp = `${sealingPath()}.tmp`;
111761
112214
  writeFileSync35(tmp, JSON.stringify({ privateJwk, publicRaw: b64u(publicRaw), alg: "P256-ECDH" }, null, 2), { mode: 384 });
@@ -111855,7 +112308,7 @@ var BundleOfferLedger = class {
111855
112308
  init_dist6();
111856
112309
 
111857
112310
  // ../../packages/host-core/dist/mesh/netd-client.js
111858
- import { existsSync as existsSync34, readdirSync as readdirSync13 } from "node:fs";
112311
+ import { existsSync as existsSync35, readdirSync as readdirSync13 } from "node:fs";
111859
112312
  import { connect as connect2 } from "node:net";
111860
112313
  import { platform as platform3 } from "node:process";
111861
112314
  var NETD_WIRE_VERSION = 2;
@@ -111871,7 +112324,7 @@ function netdEndpoint() {
111871
112324
  function netdListening() {
111872
112325
  const ep = endpointOverride() ?? netdEndpoint();
111873
112326
  if (process.platform !== "win32")
111874
- return existsSync34(ep);
112327
+ return existsSync35(ep);
111875
112328
  try {
111876
112329
  const name = ep.replace(/^\\\\\.\\pipe\\/, "");
111877
112330
  return readdirSync13("\\\\.\\pipe\\").includes(name);
@@ -112323,13 +112776,13 @@ ${ts}`);
112323
112776
 
112324
112777
  // ../../packages/host-core/dist/mesh/config.js
112325
112778
  init_credentials();
112326
- import { chmodSync as chmodSync5, existsSync as existsSync35, mkdirSync as mkdirSync37, readdirSync as readdirSync14, readFileSync as readFileSync48, renameSync as renameSync12, rmSync as rmSync8, writeFileSync as writeFileSync36 } from "node:fs";
112327
- import { dirname as dirname31, join as join70 } from "node:path";
112779
+ import { chmodSync as chmodSync5, existsSync as existsSync36, mkdirSync as mkdirSync37, readdirSync as readdirSync14, readFileSync as readFileSync49, renameSync as renameSync12, rmSync as rmSync8, writeFileSync as writeFileSync36 } from "node:fs";
112780
+ import { dirname as dirname31, join as join71 } from "node:path";
112328
112781
  function meshDir() {
112329
- return join70(daemonDir2(), "mesh");
112782
+ return join71(daemonDir2(), "mesh");
112330
112783
  }
112331
112784
  function meshesDir() {
112332
- return join70(meshDir(), "meshes");
112785
+ return join71(meshDir(), "meshes");
112333
112786
  }
112334
112787
  var MESH_DIR_NAME_BYTES = 8;
112335
112788
  function meshDirName(genesisFp) {
@@ -112347,7 +112800,7 @@ function oneMeshDir(meshId) {
112347
112800
  if (!isMeshId(meshId)) {
112348
112801
  throw new Error(`not a mesh id: ${JSON.stringify(meshId.slice(0, 64))}`);
112349
112802
  }
112350
- return join70(meshesDir(), meshId);
112803
+ return join71(meshesDir(), meshId);
112351
112804
  }
112352
112805
  var LEGACY_MESH_ID = "legacy";
112353
112806
  var CERT_GENESIS_FP_OFFSET = 19;
@@ -112365,16 +112818,16 @@ var FILES = {
112365
112818
  local: "local.json"
112366
112819
  };
112367
112820
  function readIfPresent(name, dir2 = meshDir()) {
112368
- const p = join70(dir2, name);
112821
+ const p = join71(dir2, name);
112369
112822
  try {
112370
- return existsSync35(p) ? new Uint8Array(readFileSync48(p)) : void 0;
112823
+ return existsSync36(p) ? new Uint8Array(readFileSync49(p)) : void 0;
112371
112824
  } catch {
112372
112825
  return void 0;
112373
112826
  }
112374
112827
  }
112375
112828
  function migrateSingleMesh() {
112376
- const legacyGenesis = join70(meshDir(), FILES.genesis);
112377
- if (!existsSync35(legacyGenesis))
112829
+ const legacyGenesis = join71(meshDir(), FILES.genesis);
112830
+ if (!existsSync36(legacyGenesis))
112378
112831
  return null;
112379
112832
  const id = meshIdFromCert(readIfPresent(FILES.cert)) ?? LEGACY_MESH_ID;
112380
112833
  const dest = oneMeshDir(id);
@@ -112382,12 +112835,12 @@ function migrateSingleMesh() {
112382
112835
  mkdirSync37(dest, { recursive: true, mode: 448 });
112383
112836
  chmodSync5(dest, 448);
112384
112837
  for (const f of Object.values(FILES)) {
112385
- const from = join70(meshDir(), f);
112386
- if (existsSync35(from))
112387
- renameSync12(from, join70(dest, f));
112838
+ const from = join71(meshDir(), f);
112839
+ if (existsSync36(from))
112840
+ renameSync12(from, join71(dest, f));
112388
112841
  }
112389
- const key2 = join70(dest, FILES.key);
112390
- if (existsSync35(key2))
112842
+ const key2 = join71(dest, FILES.key);
112843
+ if (existsSync36(key2))
112391
112844
  chmodSync5(key2, 384);
112392
112845
  } catch {
112393
112846
  return null;
@@ -112410,7 +112863,7 @@ function listMeshIds() {
112410
112863
  }
112411
112864
  function readLocal(meshId) {
112412
112865
  try {
112413
- return JSON.parse(readFileSync48(join70(oneMeshDir(meshId), FILES.local), "utf8"));
112866
+ return JSON.parse(readFileSync49(join71(oneMeshDir(meshId), FILES.local), "utf8"));
112414
112867
  } catch {
112415
112868
  return null;
112416
112869
  }
@@ -112418,7 +112871,7 @@ function readLocal(meshId) {
112418
112871
  function writeLocal(meshId, state3) {
112419
112872
  try {
112420
112873
  mkdirSync37(oneMeshDir(meshId), { recursive: true, mode: 448 });
112421
- writeFileSync36(join70(oneMeshDir(meshId), FILES.local), JSON.stringify(state3, null, 2), { mode: 384 });
112874
+ writeFileSync36(join71(oneMeshDir(meshId), FILES.local), JSON.stringify(state3, null, 2), { mode: 384 });
112422
112875
  } catch {
112423
112876
  }
112424
112877
  }
@@ -112451,7 +112904,7 @@ function loadMeshIdentity() {
112451
112904
  return first === void 0 ? null : loadMesh(first);
112452
112905
  }
112453
112906
  function writeSecret(name, bytes3, dir2 = meshDir()) {
112454
- const p = join70(dir2, name);
112907
+ const p = join71(dir2, name);
112455
112908
  writeFileSync36(p, bytes3, { mode: 384 });
112456
112909
  try {
112457
112910
  chmodSync5(p, 384);
@@ -112469,11 +112922,11 @@ function saveMeshIdentity(id) {
112469
112922
  chmodSync5(meshDir(), 448);
112470
112923
  } catch {
112471
112924
  }
112472
- writeFileSync36(join70(meshDir(), FILES.genesis), id.genesis);
112473
- writeFileSync36(join70(meshDir(), FILES.cert), id.cert);
112925
+ writeFileSync36(join71(meshDir(), FILES.genesis), id.genesis);
112926
+ writeFileSync36(join71(meshDir(), FILES.cert), id.cert);
112474
112927
  writeSecret(FILES.key, id.staticPrivate);
112475
112928
  if (id.bundle)
112476
- writeFileSync36(join70(meshDir(), FILES.bundle), id.bundle);
112929
+ writeFileSync36(join71(meshDir(), FILES.bundle), id.bundle);
112477
112930
  }
112478
112931
  function saveMesh(meshId, id) {
112479
112932
  const dir2 = oneMeshDir(meshId);
@@ -112490,13 +112943,13 @@ function saveMesh(meshId, id) {
112490
112943
  chmodSync5(dir2, 448);
112491
112944
  } catch {
112492
112945
  }
112493
- writeFileSync36(join70(dir2, FILES.genesis), id.genesis);
112494
- writeFileSync36(join70(dir2, FILES.cert), id.cert);
112946
+ writeFileSync36(join71(dir2, FILES.genesis), id.genesis);
112947
+ writeFileSync36(join71(dir2, FILES.cert), id.cert);
112495
112948
  writeSecret(FILES.key, id.staticPrivate, dir2);
112496
112949
  if (id.sigPrivate)
112497
112950
  writeSecret(FILES.sigKey, id.sigPrivate, dir2);
112498
112951
  if (id.bundle)
112499
- writeFileSync36(join70(dir2, FILES.bundle), id.bundle);
112952
+ writeFileSync36(join71(dir2, FILES.bundle), id.bundle);
112500
112953
  if (readLocal(meshId) === null)
112501
112954
  writeLocal(meshId, { joinedAt: Date.now() });
112502
112955
  }
@@ -112506,7 +112959,7 @@ function removeMesh(meshId) {
112506
112959
  var STATUS_REFRESH_MS = 5e3;
112507
112960
  var STATUS_STALE_MS = 2e4;
112508
112961
  function statusPath(meshId) {
112509
- return meshId === void 0 ? join70(meshDir(), "status.json") : join70(oneMeshDir(meshId), "status.json");
112962
+ return meshId === void 0 ? join71(meshDir(), "status.json") : join71(oneMeshDir(meshId), "status.json");
112510
112963
  }
112511
112964
  function writeStatus(status2, meshId) {
112512
112965
  try {
@@ -112524,7 +112977,7 @@ function clearStatus(meshId) {
112524
112977
  }
112525
112978
  function readStatus(meshId) {
112526
112979
  try {
112527
- const raw = JSON.parse(readFileSync48(statusPath(meshId), "utf8"));
112980
+ const raw = JSON.parse(readFileSync49(statusPath(meshId), "utf8"));
112528
112981
  if (typeof raw.at !== "number")
112529
112982
  return null;
112530
112983
  return { ...raw, at: raw.at, stale: Date.now() - raw.at > STATUS_STALE_MS };
@@ -112537,7 +112990,7 @@ function cacheBundle(bundle, meshId) {
112537
112990
  const id = meshId ?? listMeshIds()[0];
112538
112991
  const dir2 = id === void 0 ? meshDir() : oneMeshDir(id);
112539
112992
  mkdirSync37(dir2, { recursive: true, mode: 448 });
112540
- writeFileSync36(join70(dir2, FILES.bundle), bundle);
112993
+ writeFileSync36(join71(dir2, FILES.bundle), bundle);
112541
112994
  } catch {
112542
112995
  }
112543
112996
  }
@@ -113534,11 +113987,11 @@ var MeshNode = class {
113534
113987
  return;
113535
113988
  const reflexive = [];
113536
113989
  for (const a of learned) {
113537
- const sep11 = a.lastIndexOf(":");
113538
- if (sep11 <= 0)
113990
+ const sep12 = a.lastIndexOf(":");
113991
+ if (sep12 <= 0)
113539
113992
  continue;
113540
- const ip = a.slice(0, sep11).replace(/^\[|\]$/g, "");
113541
- const port = Number(a.slice(sep11 + 1));
113993
+ const ip = a.slice(0, sep12).replace(/^\[|\]$/g, "");
113994
+ const port = Number(a.slice(sep12 + 1));
113542
113995
  if (!Number.isInteger(port) || port <= 0 || port > 65535)
113543
113996
  continue;
113544
113997
  reflexive.push({ type: "srflx", ip, port, priority: 0 });
@@ -114312,7 +114765,7 @@ import { basename as basename15 } from "node:path";
114312
114765
  // ../../packages/host-core/dist/drops/paths.js
114313
114766
  init_base_paths();
114314
114767
  import { mkdir as mkdir14 } from "node:fs/promises";
114315
- import { join as join71 } from "node:path";
114768
+ import { join as join72 } from "node:path";
114316
114769
 
114317
114770
  // ../../packages/host-core/dist/drops/names.js
114318
114771
  var WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
@@ -114401,7 +114854,7 @@ function basenameOf(p) {
114401
114854
  function resolveDropsRoot() {
114402
114855
  const root = resolveHostRoot();
114403
114856
  const preferred = dropsDir();
114404
- return isInsideRoot(preferred, root) ? preferred : join71(root, "Drops");
114857
+ return isInsideRoot(preferred, root) ? preferred : join72(root, "Drops");
114405
114858
  }
114406
114859
  async function ensureDropsRoot() {
114407
114860
  const dir2 = resolveDropsRoot();
@@ -114417,7 +114870,7 @@ async function ensureDropDir(opts) {
114417
114870
  parts.push(sanitizeDropName(opts.sender, "Unknown sender"));
114418
114871
  if (!opts.singleItem && opts.label)
114419
114872
  parts.push(sanitizeDropName(opts.label, "Files"));
114420
- const dir2 = join71(...parts);
114873
+ const dir2 = join72(...parts);
114421
114874
  await mkdir14(dir2, { recursive: true });
114422
114875
  return dir2;
114423
114876
  }
@@ -114560,7 +115013,7 @@ function createDropHandler(deps) {
114560
115013
  // ../../packages/host-core/dist/drops/blob-fetch.js
114561
115014
  import { createWriteStream as createWriteStream2 } from "node:fs";
114562
115015
  import { mkdir as mkdir15, rm as rm5, chmod as chmod3 } from "node:fs/promises";
114563
- import { dirname as dirname33, join as join72 } from "node:path";
115016
+ import { dirname as dirname33, join as join73 } from "node:path";
114564
115017
  import { Readable as Readable2 } from "node:stream";
114565
115018
  import { pipeline } from "node:stream/promises";
114566
115019
 
@@ -114732,7 +115185,7 @@ async function fetchBlobDrop(opts) {
114732
115185
  log7(`drop ${opts.dropId}: refusing directory "${item.rel}"`);
114733
115186
  continue;
114734
115187
  }
114735
- const abs = join72(opts.destDir, rel);
115188
+ const abs = join73(opts.destDir, rel);
114736
115189
  if (!isInsideRoot(abs, opts.destDir)) {
114737
115190
  log7(`drop ${opts.dropId}: refusing directory outside the destination`);
114738
115191
  continue;
@@ -114753,7 +115206,7 @@ async function fetchBlobDrop(opts) {
114753
115206
  log7(`drop ${opts.dropId}: refusing "${item.rel}"`);
114754
115207
  continue;
114755
115208
  }
114756
- let abs = join72(opts.destDir, rel);
115209
+ let abs = join73(opts.destDir, rel);
114757
115210
  if (!isInsideRoot(abs, opts.destDir)) {
114758
115211
  log7(`drop ${opts.dropId}: refusing a path outside the destination`);
114759
115212
  continue;
@@ -115028,13 +115481,13 @@ var RdeskServerChannel = class {
115028
115481
  };
115029
115482
 
115030
115483
  // ../../packages/host-core/dist/rdesk/channel-client.js
115031
- import { readFileSync as readFileSync49 } from "node:fs";
115032
- import { join as join73 } from "node:path";
115484
+ import { readFileSync as readFileSync50 } from "node:fs";
115485
+ import { join as join74 } from "node:path";
115033
115486
  var RECONNECT_MS = 2e3;
115034
115487
  var CLAIM_RETRY_MS = 5e3;
115035
115488
  function readEndpoint(dir2, selfPid) {
115036
115489
  try {
115037
- const s = JSON.parse(readFileSync49(join73(dir2, "status.json"), "utf8"));
115490
+ const s = JSON.parse(readFileSync50(join74(dir2, "status.json"), "utf8"));
115038
115491
  if (selfPid && s.pid === selfPid)
115039
115492
  return null;
115040
115493
  return s.localPort && s.localToken ? `ws://127.0.0.1:${s.localPort}/?token=${s.localToken}` : null;
@@ -115479,10 +115932,10 @@ function registerRdpEngine() {
115479
115932
  // ../../packages/host-core/dist/rdesk/audit.js
115480
115933
  init_credentials();
115481
115934
  import { appendFile, stat as stat9, rename as rename4 } from "node:fs/promises";
115482
- import { join as join74 } from "node:path";
115935
+ import { join as join75 } from "node:path";
115483
115936
  var MAX_BYTES2 = 2 * 1024 * 1024;
115484
115937
  function rdeskAuditPath() {
115485
- return join74(daemonDir2(), "rdesk-audit.jsonl");
115938
+ return join75(daemonDir2(), "rdesk-audit.jsonl");
115486
115939
  }
115487
115940
  var queue = [];
115488
115941
  var draining = false;
@@ -115524,13 +115977,13 @@ function appendRdeskAudit(e) {
115524
115977
 
115525
115978
  // ../../packages/host-core/dist/fileprovider-bridge.js
115526
115979
  init_managed_spawn();
115527
- import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync38, rmSync as rmSync9, existsSync as existsSync36 } from "node:fs";
115528
- import { homedir as homedir11 } from "node:os";
115529
- import { join as join75 } from "node:path";
115980
+ import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync38, rmSync as rmSync9, existsSync as existsSync37 } from "node:fs";
115981
+ import { homedir as homedir12 } from "node:os";
115982
+ import { join as join76 } from "node:path";
115530
115983
  init_safe_kill();
115531
115984
  var APPEX_BUNDLE_ID = "dev.tesseract.FileProvider";
115532
115985
  function appexBridgeInfoPath() {
115533
- return join75(homedir11(), "Library", "Containers", APPEX_BUNDLE_ID, "Data", "Library", "Application Support", "tesseract-bridge.json");
115986
+ return join76(homedir12(), "Library", "Containers", APPEX_BUNDLE_ID, "Data", "Library", "Application Support", "tesseract-bridge.json");
115534
115987
  }
115535
115988
  function clearBridgeInfo() {
115536
115989
  if (process.platform !== "darwin")
@@ -115696,8 +116149,8 @@ function stopFileProviderBridge() {
115696
116149
  // ../../packages/host-core/dist/file-share-server.js
115697
116150
  import { createServer as createServer5 } from "node:http";
115698
116151
  import { randomBytes as randomBytes9 } from "node:crypto";
115699
- import { existsSync as existsSync37, readFileSync as readFileSync50, writeFileSync as writeFileSync38, mkdirSync as mkdirSync39 } from "node:fs";
115700
- import { join as join76, dirname as dirname34 } from "node:path";
116152
+ import { existsSync as existsSync38, readFileSync as readFileSync51, writeFileSync as writeFileSync38, mkdirSync as mkdirSync39 } from "node:fs";
116153
+ import { join as join77, dirname as dirname34 } from "node:path";
115701
116154
  init_credentials();
115702
116155
  var SHARE_PORTS = [47831, 47832, 47833, 47834, 47835, 47836, 47837, 47838];
115703
116156
  var CHUNK4 = 1024 * 1024;
@@ -115707,10 +116160,10 @@ var token2 = "";
115707
116160
  var log8 = () => {
115708
116161
  };
115709
116162
  function loadOrCreateToken() {
115710
- const file2 = join76(daemonDir2(), "file-share-token");
116163
+ const file2 = join77(daemonDir2(), "file-share-token");
115711
116164
  try {
115712
- if (existsSync37(file2)) {
115713
- const t2 = readFileSync50(file2, "utf-8").trim();
116165
+ if (existsSync38(file2)) {
116166
+ const t2 = readFileSync51(file2, "utf-8").trim();
115714
116167
  if (/^[a-f0-9]{32}$/.test(t2))
115715
116168
  return t2;
115716
116169
  }
@@ -116106,9 +116559,9 @@ function fileShareToken() {
116106
116559
  // ../../packages/host-core/dist/file-share-mount.js
116107
116560
  import { execFile as execFile10 } from "node:child_process";
116108
116561
  import { promisify as promisify5 } from "node:util";
116109
- import { homedir as homedir12 } from "node:os";
116110
- import { existsSync as existsSync38, readFileSync as readFileSync51, appendFileSync as appendFileSync5, mkdirSync as mkdirSync40 } from "node:fs";
116111
- import { join as join77, dirname as dirname35 } from "node:path";
116562
+ import { homedir as homedir13 } from "node:os";
116563
+ import { existsSync as existsSync39, readFileSync as readFileSync52, appendFileSync as appendFileSync5, mkdirSync as mkdirSync40 } from "node:fs";
116564
+ import { join as join78, dirname as dirname35 } from "node:path";
116112
116565
  var run3 = promisify5(execFile10);
116113
116566
  var OPTS = { timeout: 2e4, windowsHide: true };
116114
116567
  var mounted = false;
@@ -116120,9 +116573,9 @@ function davUri() {
116120
116573
  }
116121
116574
  function addGtkBookmark(uri, label) {
116122
116575
  try {
116123
- const file2 = join77(homedir12(), ".config", "gtk-3.0", "bookmarks");
116576
+ const file2 = join78(homedir13(), ".config", "gtk-3.0", "bookmarks");
116124
116577
  const line = `${uri} ${label}`;
116125
- const cur = existsSync38(file2) ? readFileSync51(file2, "utf-8") : "";
116578
+ const cur = existsSync39(file2) ? readFileSync52(file2, "utf-8") : "";
116126
116579
  if (cur.split("\n").some((l) => l.trim() === line))
116127
116580
  return;
116128
116581
  mkdirSync40(dirname35(file2), { recursive: true });
@@ -116207,9 +116660,9 @@ async function unmountFileShare(log10 = () => {
116207
116660
 
116208
116661
  // ../../packages/host-core/dist/vault/autofill-bridge.js
116209
116662
  import { randomBytes as randomBytes10 } from "node:crypto";
116210
- import { existsSync as existsSync39, mkdirSync as mkdirSync41, writeFileSync as writeFileSync39, rmSync as rmSync10 } from "node:fs";
116211
- import { homedir as homedir13 } from "node:os";
116212
- import { join as join78 } from "node:path";
116663
+ import { existsSync as existsSync40, mkdirSync as mkdirSync41, writeFileSync as writeFileSync39, rmSync as rmSync10 } from "node:fs";
116664
+ import { homedir as homedir14 } from "node:os";
116665
+ import { join as join79 } from "node:path";
116213
116666
 
116214
116667
  // ../../packages/host-core/dist/vault/peer-verify.js
116215
116668
  import { execFile as execFile11 } from "node:child_process";
@@ -116271,10 +116724,10 @@ async function isTrustedAutofillPeer(remotePort) {
116271
116724
  var APPEX_BUNDLE_ID2 = "dev.tesseract.AutoFill";
116272
116725
  var BRIDGE_PORTS2 = [17872, 17873, 17874, 17875];
116273
116726
  function appexContainerData() {
116274
- return join78(homedir13(), "Library", "Containers", APPEX_BUNDLE_ID2, "Data");
116727
+ return join79(homedir14(), "Library", "Containers", APPEX_BUNDLE_ID2, "Data");
116275
116728
  }
116276
116729
  function bridgeInfoPath() {
116277
- return join78(appexContainerData(), "Library", "Application Support", "tesseract-autofill-bridge.json");
116730
+ return join79(appexContainerData(), "Library", "Application Support", "tesseract-autofill-bridge.json");
116278
116731
  }
116279
116732
  var infoLoggedOnce = false;
116280
116733
  function writeBridgeInfo(port, token4, log10) {
@@ -116282,14 +116735,14 @@ function writeBridgeInfo(port, token4, log10) {
116282
116735
  return;
116283
116736
  const containerData = appexContainerData();
116284
116737
  try {
116285
- if (!existsSync39(containerData)) {
116738
+ if (!existsSync40(containerData)) {
116286
116739
  if (!infoLoggedOnce) {
116287
116740
  infoLoggedOnce = true;
116288
116741
  log10("autofill bridge-info SKIP: no appex container yet at", containerData);
116289
116742
  }
116290
116743
  return;
116291
116744
  }
116292
- const dir2 = join78(containerData, "Library", "Application Support");
116745
+ const dir2 = join79(containerData, "Library", "Application Support");
116293
116746
  mkdirSync41(dir2, { recursive: true });
116294
116747
  writeFileSync39(bridgeInfoPath(), JSON.stringify({ port, token: token4, pid: process.pid, ts: Date.now() }), { mode: 384 });
116295
116748
  if (!infoLoggedOnce) {
@@ -116530,30 +116983,30 @@ function createNodePowerController() {
116530
116983
  }
116531
116984
 
116532
116985
  // ../../packages/host-core/dist/native-host.js
116533
- import { execFileSync as execFileSync4 } from "node:child_process";
116534
- import { chmodSync as chmodSync6, existsSync as existsSync40, mkdirSync as mkdirSync42, writeFileSync as writeFileSync40 } from "node:fs";
116535
- import { homedir as homedir14, platform as platform5 } from "node:os";
116536
- import { dirname as dirname36, join as join79, resolve as resolve12 } from "node:path";
116986
+ import { execFileSync as execFileSync5 } from "node:child_process";
116987
+ import { chmodSync as chmodSync6, existsSync as existsSync41, mkdirSync as mkdirSync42, writeFileSync as writeFileSync40 } from "node:fs";
116988
+ import { homedir as homedir15, platform as platform5 } from "node:os";
116989
+ import { dirname as dirname36, join as join80, resolve as resolve12 } from "node:path";
116537
116990
  import { fileURLToPath as fileURLToPath6 } from "node:url";
116538
116991
  var HOST_NAME = "com.tesseract.companion";
116539
116992
  var EXTENSION_IDS = ["icpnghhpcmaonjckkpilpajblfehpplo", "giolfpookdhjfafcchaflhmigghaeffn"];
116540
116993
  var BRIDGE_BASENAME = "host.cjs";
116541
116994
  function browserProfileDirs() {
116542
- const home = homedir14();
116995
+ const home = homedir15();
116543
116996
  const p = platform5();
116544
116997
  if (p === "darwin") {
116545
- const base = join79(home, "Library/Application Support");
116546
- return ["Google/Chrome", "Google/Chrome Beta", "Google/Chrome Dev", "Google/Chrome Canary", "Chromium", "Microsoft Edge", "BraveSoftware/Brave-Browser", "Vivaldi", "Arc"].map((b) => join79(base, b));
116998
+ const base = join80(home, "Library/Application Support");
116999
+ return ["Google/Chrome", "Google/Chrome Beta", "Google/Chrome Dev", "Google/Chrome Canary", "Chromium", "Microsoft Edge", "BraveSoftware/Brave-Browser", "Vivaldi", "Arc"].map((b) => join80(base, b));
116547
117000
  }
116548
117001
  if (p === "win32")
116549
117002
  return [];
116550
- const cfg2 = join79(home, ".config");
116551
- return ["google-chrome", "google-chrome-beta", "chromium", "microsoft-edge", "BraveSoftware/Brave-Browser", "vivaldi"].map((b) => join79(cfg2, b));
117003
+ const cfg2 = join80(home, ".config");
117004
+ return ["google-chrome", "google-chrome-beta", "chromium", "microsoft-edge", "BraveSoftware/Brave-Browser", "vivaldi"].map((b) => join80(cfg2, b));
116552
117005
  }
116553
117006
  function resolveBridge(log10) {
116554
117007
  const candidates = [
116555
117008
  process.env.CCB_COMPANION_HOST_JS,
116556
- process.resourcesPath ? join79(process.resourcesPath, "companion-host", BRIDGE_BASENAME) : void 0
117009
+ process.resourcesPath ? join80(process.resourcesPath, "companion-host", BRIDGE_BASENAME) : void 0
116557
117010
  ];
116558
117011
  try {
116559
117012
  const here = dirname36(fileURLToPath6(import.meta.url));
@@ -116562,14 +117015,14 @@ function resolveBridge(log10) {
116562
117015
  } catch {
116563
117016
  }
116564
117017
  for (const c of candidates)
116565
- if (c && existsSync40(c))
117018
+ if (c && existsSync41(c))
116566
117019
  return c;
116567
117020
  log10("companion native-host: bridge not found; skipping registration (looked in", candidates.filter(Boolean).join(" , "), ")");
116568
117021
  return null;
116569
117022
  }
116570
117023
  function writeLauncher(daemonDir3, bridge, runtime) {
116571
117024
  const isWin = platform5() === "win32";
116572
- const launcher = join79(daemonDir3, isWin ? "companion-host.cmd" : "companion-host.sh");
117025
+ const launcher = join80(daemonDir3, isWin ? "companion-host.cmd" : "companion-host.sh");
116573
117026
  if (isWin) {
116574
117027
  writeFileSync40(launcher, `@echo off\r
116575
117028
  set ELECTRON_RUN_AS_NODE=1\r
@@ -116604,12 +117057,12 @@ function registerNativeHost(opts) {
116604
117057
  return registerWindows(opts.daemonDir, manifestJson, log10);
116605
117058
  let wrote = 0;
116606
117059
  for (const profile of browserProfileDirs()) {
116607
- if (!existsSync40(profile))
117060
+ if (!existsSync41(profile))
116608
117061
  continue;
116609
117062
  try {
116610
- const dir2 = join79(profile, "NativeMessagingHosts");
117063
+ const dir2 = join80(profile, "NativeMessagingHosts");
116611
117064
  mkdirSync42(dir2, { recursive: true });
116612
- writeFileSync40(join79(dir2, `${HOST_NAME}.json`), manifestJson);
117065
+ writeFileSync40(join80(dir2, `${HOST_NAME}.json`), manifestJson);
116613
117066
  wrote++;
116614
117067
  } catch {
116615
117068
  }
@@ -116621,11 +117074,11 @@ function registerNativeHost(opts) {
116621
117074
  }
116622
117075
  function registerWindows(daemonDir3, manifestJson, log10) {
116623
117076
  try {
116624
- const manifestPath = join79(daemonDir3, `${HOST_NAME}.json`);
117077
+ const manifestPath = join80(daemonDir3, `${HOST_NAME}.json`);
116625
117078
  writeFileSync40(manifestPath, manifestJson);
116626
117079
  for (const root of ["Software\\Google\\Chrome", "Software\\Microsoft\\Edge", "Software\\BraveSoftware\\Brave-Browser"]) {
116627
117080
  try {
116628
- execFileSync4("reg", ["add", `HKCU\\${root}\\NativeMessagingHosts\\${HOST_NAME}`, "/ve", "/t", "REG_SZ", "/d", manifestPath, "/f"], { stdio: "ignore" });
117081
+ execFileSync5("reg", ["add", `HKCU\\${root}\\NativeMessagingHosts\\${HOST_NAME}`, "/ve", "/t", "REG_SZ", "/d", manifestPath, "/f"], { stdio: "ignore" });
116629
117082
  } catch {
116630
117083
  }
116631
117084
  }
@@ -116640,10 +117093,10 @@ init_daemon_settings();
116640
117093
 
116641
117094
  // ../../packages/host-core/dist/activity/activity-tracker.js
116642
117095
  init_credentials();
116643
- import { promises as fsp, writeFileSync as writeFileSync41, mkdirSync as mkdirSync43, existsSync as existsSync41 } from "node:fs";
116644
- import { join as join80 } from "node:path";
117096
+ import { promises as fsp, writeFileSync as writeFileSync41, mkdirSync as mkdirSync43, existsSync as existsSync42 } from "node:fs";
117097
+ import { join as join81 } from "node:path";
116645
117098
  function activityProfilePath() {
116646
- return join80(daemonDir2(), "activity-profile.json");
117099
+ return join81(daemonDir2(), "activity-profile.json");
116647
117100
  }
116648
117101
  var MAX_APPS = 300;
116649
117102
  var MAX_AGE_DAYS = 120;
@@ -116718,7 +117171,7 @@ function createActivityTracker(opts = {}) {
116718
117171
  return;
116719
117172
  const key2 = front.bundleId || front.name;
116720
117173
  await ensureLoaded();
116721
- if (profile && Object.keys(profile.apps).length && !existsSync41(activityProfilePath())) {
117174
+ if (profile && Object.keys(profile.apps).length && !existsSync42(activityProfilePath())) {
116722
117175
  log10("activity profile cleared externally \u2014 resetting in-memory");
116723
117176
  profile = { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), apps: {} };
116724
117177
  }
@@ -116835,15 +117288,15 @@ init_credentials();
116835
117288
 
116836
117289
  // ../../packages/shared/dist/identity.js
116837
117290
  init_base_paths();
116838
- import { existsSync as existsSync42, mkdirSync as mkdirSync44, readFileSync as readFileSync52, writeFileSync as writeFileSync42 } from "node:fs";
116839
- import { dirname as dirname37, join as join81 } from "node:path";
117291
+ import { existsSync as existsSync43, mkdirSync as mkdirSync44, readFileSync as readFileSync53, writeFileSync as writeFileSync42 } from "node:fs";
117292
+ import { dirname as dirname37, join as join82 } from "node:path";
116840
117293
  import { randomUUID as randomUUID31 } from "node:crypto";
116841
117294
  function deviceIdFile() {
116842
- return join81(tesseractHome(), "device-id.json");
117295
+ return join82(tesseractHome(), "device-id.json");
116843
117296
  }
116844
117297
  function readPersistedDeviceId() {
116845
117298
  try {
116846
- const raw = JSON.parse(readFileSync52(deviceIdFile(), "utf-8"));
117299
+ const raw = JSON.parse(readFileSync53(deviceIdFile(), "utf-8"));
116847
117300
  return typeof raw.deviceId === "string" && raw.deviceId ? raw.deviceId : null;
116848
117301
  } catch {
116849
117302
  return null;
@@ -116857,7 +117310,7 @@ function persistentDeviceId() {
116857
117310
  try {
116858
117311
  const f = deviceIdFile();
116859
117312
  const dir2 = dirname37(f);
116860
- if (!existsSync42(dir2))
117313
+ if (!existsSync43(dir2))
116861
117314
  mkdirSync44(dir2, { recursive: true });
116862
117315
  writeFileSync42(f, JSON.stringify({ deviceId: id }));
116863
117316
  } catch {
@@ -117013,12 +117466,13 @@ var REFRESH_INTERVAL_MS2 = 12 * 60 * 60 * 1e3;
117013
117466
  async function runDaemon(opts = {}) {
117014
117467
  const VERSION3 = opts.version ?? process.env.CCB_DAEMON_VERSION ?? "dev";
117015
117468
  const TAG = opts.tag ?? "host-daemon";
117469
+ const KIND = opts.kind ?? "app";
117016
117470
  const log10 = (...args) => console.log(`[${TAG} ${(/* @__PURE__ */ new Date()).toISOString()}]`, ...args);
117017
117471
  log10("paths", JSON.stringify(sealBasePaths()));
117018
117472
  const OUR_STARTED_AT = procStartedAt(process.pid);
117019
117473
  let ownsMachine = false;
117020
- const pidfile = () => join82(daemonDir2(), "daemon.lock");
117021
- const statusFile = () => join82(daemonDir2(), "status.json");
117474
+ const pidfile2 = () => join83(daemonDir2(), "daemon.lock");
117475
+ const statusFile2 = () => join83(daemonDir2(), "status.json");
117022
117476
  const isAlive2 = (pid) => {
117023
117477
  if (!Number.isFinite(pid) || pid <= 0)
117024
117478
  return false;
@@ -117031,7 +117485,7 @@ async function runDaemon(opts = {}) {
117031
117485
  };
117032
117486
  const lockHeldByAnother = () => {
117033
117487
  try {
117034
- const pid = Number(readFileSync53(pidfile(), "utf-8").trim());
117488
+ const pid = Number(readFileSync54(pidfile2(), "utf-8").trim());
117035
117489
  return Number.isFinite(pid) && pid > 0 && pid !== process.pid && isAlive2(pid);
117036
117490
  } catch {
117037
117491
  return false;
@@ -117039,7 +117493,7 @@ async function runDaemon(opts = {}) {
117039
117493
  };
117040
117494
  const lockHeldByYieldingSubset = () => {
117041
117495
  try {
117042
- const pid = Number(readFileSync53(pidfile(), "utf-8").trim());
117496
+ const pid = Number(readFileSync54(pidfile2(), "utf-8").trim());
117043
117497
  if (!Number.isFinite(pid) || pid <= 0 || pid === process.pid || !isAlive2(pid))
117044
117498
  return false;
117045
117499
  return liveDaemons().some((d) => d.pid === pid && d.rdeskOnly === true);
@@ -117048,9 +117502,9 @@ async function runDaemon(opts = {}) {
117048
117502
  }
117049
117503
  };
117050
117504
  function acquireLock2() {
117051
- const f = pidfile();
117505
+ const f = pidfile2();
117052
117506
  try {
117053
- if (!existsSync43(daemonDir2()))
117507
+ if (!existsSync44(daemonDir2()))
117054
117508
  mkdirSync45(daemonDir2(), { recursive: true, mode: 448 });
117055
117509
  } catch {
117056
117510
  }
@@ -117060,12 +117514,12 @@ async function runDaemon(opts = {}) {
117060
117514
  return true;
117061
117515
  } catch {
117062
117516
  try {
117063
- const prev = Number(readFileSync53(f, "utf-8").trim());
117517
+ const prev = Number(readFileSync54(f, "utf-8").trim());
117064
117518
  if (!prev)
117065
117519
  return false;
117066
117520
  if (prev !== process.pid && isAlive2(prev))
117067
117521
  return false;
117068
- unlinkSync7(f);
117522
+ unlinkSync8(f);
117069
117523
  } catch {
117070
117524
  return false;
117071
117525
  }
@@ -117075,9 +117529,9 @@ async function runDaemon(opts = {}) {
117075
117529
  }
117076
117530
  function releaseLock() {
117077
117531
  try {
117078
- const f = pidfile();
117079
- if (existsSync43(f) && Number(readFileSync53(f, "utf-8").trim()) === process.pid)
117080
- unlinkSync7(f);
117532
+ const f = pidfile2();
117533
+ if (existsSync44(f) && Number(readFileSync54(f, "utf-8").trim()) === process.pid)
117534
+ unlinkSync8(f);
117081
117535
  } catch {
117082
117536
  }
117083
117537
  }
@@ -117086,14 +117540,21 @@ async function runDaemon(opts = {}) {
117086
117540
  if (!ownsMachine)
117087
117541
  return;
117088
117542
  try {
117089
- writeFileSync43(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 }));
117090
- chmodSync7(statusFile(), 384);
117543
+ writeFileSync43(statusFile2(), JSON.stringify({ pid: process.pid, startedAt: OUR_STARTED_AT, role: process.env.CCB_RDESK_ROLE ?? "host", kind: KIND, version: VERSION3, execPath: process.env.CCB_DAEMON_EXECPATH ?? process.execPath, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), gui: daemonGuiTrayActive(), ...localInfo ?? {}, ...s }));
117544
+ chmodSync7(statusFile2(), 384);
117091
117545
  } catch {
117092
117546
  }
117093
117547
  }
117094
117548
  const standaloneViewer = process.env.CCB_RDESK_ROLE === "client";
117095
117549
  if (!standaloneViewer) {
117096
117550
  registerSelfAsDaemon(VERSION3);
117551
+ if (KIND === "app") {
117552
+ try {
117553
+ await evictCliAgent(log10);
117554
+ } catch (e) {
117555
+ log10("[cli-agent] eviction failed:", e?.message ?? e);
117556
+ }
117557
+ }
117097
117558
  if (acquireLock2()) {
117098
117559
  ownsMachine = true;
117099
117560
  } else if (!WE_ARE_RDESK_ONLY && lockHeldByYieldingSubset()) {
@@ -117111,6 +117572,12 @@ async function runDaemon(opts = {}) {
117111
117572
  unregisterSelfAsDaemon();
117112
117573
  ownsMachine = false;
117113
117574
  }
117575
+ } else if (KIND === "cli") {
117576
+ log10("the Tesseract desktop app already owns this machine \u2014 standing down.");
117577
+ log10("the desktop app and the tesseract-agent CLI cannot both run here; uninstall one (`npm uninstall -g tesseract-agent`) to stop seeing this.");
117578
+ unregisterSelfAsDaemon();
117579
+ releaseLock();
117580
+ process.exit(0);
117114
117581
  } else {
117115
117582
  log10("another live instance already owns this machine (holds the pid lock) \u2014 not taking over");
117116
117583
  unregisterSelfAsDaemon();
@@ -117193,7 +117660,7 @@ async function runDaemon(opts = {}) {
117193
117660
  }
117194
117661
  const snapshotProcs = (tag) => {
117195
117662
  try {
117196
- const raw = execFileSync5("ps", ["-axww", "-o", "pid=,ppid=,pcpu=,etime=,command="], { encoding: "utf8", timeout: 3e3 });
117663
+ const raw = execFileSync6("ps", ["-axww", "-o", "pid=,ppid=,pcpu=,etime=,command="], { encoding: "utf8", timeout: 3e3 });
117197
117664
  const rows = raw.split("\n").filter((l) => /[Tt]esseract|host-daemon/.test(l) && !/\bgrep\b|ps -axww/.test(l));
117198
117665
  log10(`PROC-SNAPSHOT [${tag}] me=${process.pid} ppid=${process.ppid} \u2014 ${rows.length} tesseract proc(s):`);
117199
117666
  for (const r of rows.slice(0, 40))
@@ -117636,7 +118103,7 @@ async function runDaemon(opts = {}) {
117636
118103
  if (r.status === 401) {
117637
118104
  log10("device token no longer valid \u2014 dropping to local-only on restart");
117638
118105
  try {
117639
- unlinkSync7(join82(daemonDir2(), "credentials.json"));
118106
+ unlinkSync8(join83(daemonDir2(), "credentials.json"));
117640
118107
  } catch {
117641
118108
  }
117642
118109
  shutdown(0, "token-revoked-401");
@@ -117708,7 +118175,7 @@ async function runDaemon(opts = {}) {
117708
118175
  deviceId: () => c.deviceId,
117709
118176
  ownHostId: () => ownHost() || null,
117710
118177
  canPrompt: () => !!electronModule(),
117711
- confirm: async (spec, signal) => (await confirmAction(spec, { signal })).confirmed,
118178
+ confirm: async (spec, signal2) => (await confirmAction(spec, { signal: signal2 })).confirmed,
117712
118179
  // Store-and-forward: we won the claim, so pull the bytes and (for cross-user
117713
118180
  // drops) open the one seal in the fan-out that was made for THIS device.
117714
118181
  fetchBlobDrop: async ({ dropId, destDir, claim, sender }) => {
@@ -117953,7 +118420,7 @@ async function runDaemon(opts = {}) {
117953
118420
  let freeTicks = 0;
117954
118421
  const lockHolder = () => {
117955
118422
  try {
117956
- return Number(readFileSync53(pidfile(), "utf-8").trim()) || 0;
118423
+ return Number(readFileSync54(pidfile2(), "utf-8").trim()) || 0;
117957
118424
  } catch {
117958
118425
  return 0;
117959
118426
  }
@@ -118123,7 +118590,7 @@ async function runDaemon(opts = {}) {
118123
118590
  onDeviceRevoked: () => {
118124
118591
  log10("this machine was removed from the account \u2014 dropping its credentials; it speaks for itself again");
118125
118592
  try {
118126
- unlinkSync7(join82(daemonDir2(), "credentials.json"));
118593
+ unlinkSync8(join83(daemonDir2(), "credentials.json"));
118127
118594
  } catch {
118128
118595
  }
118129
118596
  void reloadIdentity();
@@ -118176,7 +118643,7 @@ async function runDaemon(opts = {}) {
118176
118643
  if (appPid > 0 && appPid !== process.pid) {
118177
118644
  const quitMarker = () => {
118178
118645
  try {
118179
- return Number(readFileSync53(join82(daemonDir2(), "app-quit.marker"), "utf-8").trim()) || 0;
118646
+ return Number(readFileSync54(join83(daemonDir2(), "app-quit.marker"), "utf-8").trim()) || 0;
118180
118647
  } catch {
118181
118648
  return 0;
118182
118649
  }
@@ -118201,7 +118668,7 @@ async function runDaemon(opts = {}) {
118201
118668
  log10(`desktop app (pid ${appPid}) is gone with NO clean-quit marker \u2014 reporting`);
118202
118669
  const tail3 = (name) => {
118203
118670
  try {
118204
- const buf = readFileSync53(join82(daemonDir2(), name), "utf-8");
118671
+ const buf = readFileSync54(join83(daemonDir2(), name), "utf-8");
118205
118672
  return buf.length > 4096 ? buf.slice(-4096) : buf;
118206
118673
  } catch {
118207
118674
  return void 0;
@@ -118232,11 +118699,11 @@ async function runDaemon(opts = {}) {
118232
118699
  }
118233
118700
  try {
118234
118701
  const DAEMON_LOG_CAP = 2 * 1024 * 1024;
118235
- const daemonLogFile = join82(daemonDir2(), "daemon.log");
118702
+ const daemonLogFile = join83(daemonDir2(), "daemon.log");
118236
118703
  const capTimer = setInterval(() => {
118237
118704
  try {
118238
- if (existsSync43(daemonLogFile) && statSync17(daemonLogFile).size > DAEMON_LOG_CAP) {
118239
- const buf = readFileSync53(daemonLogFile, "utf-8");
118705
+ if (existsSync44(daemonLogFile) && statSync17(daemonLogFile).size > DAEMON_LOG_CAP) {
118706
+ const buf = readFileSync54(daemonLogFile, "utf-8");
118240
118707
  const kept = `\u2026[daemon.log capped at ${(/* @__PURE__ */ new Date()).toISOString()}]\u2026
118241
118708
  ` + buf.slice(-DAEMON_LOG_CAP / 2);
118242
118709
  writeFileSync43(daemonLogFile, kept);
@@ -118345,15 +118812,15 @@ init_credentials();
118345
118812
 
118346
118813
  // ../../packages/host-core/dist/net-service/ensure-installed.js
118347
118814
  import { execFile as execFile16 } from "node:child_process";
118348
- import { existsSync as existsSync48 } from "node:fs";
118349
- import { dirname as dirname40, join as join87 } from "node:path";
118815
+ import { existsSync as existsSync49 } from "node:fs";
118816
+ import { dirname as dirname40, join as join88 } from "node:path";
118350
118817
  import { promisify as promisify11 } from "node:util";
118351
118818
 
118352
118819
  // ../../packages/host-core/dist/net-service/launchd-system.js
118353
118820
  import { spawn as spawn9 } from "node:child_process";
118354
- import { existsSync as existsSync45, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync44, rmSync as rmSync11, readFileSync as readFileSync54 } from "node:fs";
118821
+ import { existsSync as existsSync46, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync44, rmSync as rmSync11, readFileSync as readFileSync55 } from "node:fs";
118355
118822
  import { tmpdir as tmpdir6 } from "node:os";
118356
- import { join as join84 } from "node:path";
118823
+ import { join as join85 } from "node:path";
118357
118824
 
118358
118825
  // ../../packages/host-core/dist/net-service/owner-uid.js
118359
118826
  function installOwnerUid(env = process.env, self2 = typeof process.getuid === "function" ? process.getuid() : 0) {
@@ -118398,14 +118865,14 @@ async function alreadyElevated() {
118398
118865
  }
118399
118866
 
118400
118867
  // ../../packages/host-core/dist/net-service/app-bundle.js
118401
- import { execFileSync as execFileSync6 } from "node:child_process";
118402
- import { existsSync as existsSync44 } from "node:fs";
118403
- import { dirname as dirname38, basename as basename16, join as join83 } from "node:path";
118868
+ import { execFileSync as execFileSync7 } from "node:child_process";
118869
+ import { existsSync as existsSync45 } from "node:fs";
118870
+ import { dirname as dirname38, basename as basename16, join as join84 } from "node:path";
118404
118871
  function appBundleFor(exec2) {
118405
118872
  let found;
118406
118873
  let dir2 = dirname38(exec2);
118407
118874
  for (let prev = ""; dir2 !== prev; prev = dir2, dir2 = dirname38(dir2)) {
118408
- if (basename16(dir2).endsWith(".app") && existsSync44(join83(dir2, "Contents", "Info.plist"))) {
118875
+ if (basename16(dir2).endsWith(".app") && existsSync45(join84(dir2, "Contents", "Info.plist"))) {
118409
118876
  found = dir2;
118410
118877
  }
118411
118878
  }
@@ -118421,7 +118888,7 @@ function bundleIdForExec(exec2) {
118421
118888
  if (!bundle)
118422
118889
  return void 0;
118423
118890
  try {
118424
- const id = execFileSync6("/usr/bin/plutil", ["-extract", "CFBundleIdentifier", "raw", "-o", "-", join83(bundle, "Contents", "Info.plist")], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
118891
+ const id = execFileSync7("/usr/bin/plutil", ["-extract", "CFBundleIdentifier", "raw", "-o", "-", join84(bundle, "Contents", "Info.plist")], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
118425
118892
  return looksLikeBundleId(id) ? id : void 0;
118426
118893
  } catch {
118427
118894
  return void 0;
@@ -118486,9 +118953,9 @@ ${args}
118486
118953
  <key>ProcessType</key>
118487
118954
  <string>Interactive</string>
118488
118955
  <key>StandardErrorPath</key>
118489
- <string>${xml(join84(spec.stateDir, "netd.log"))}</string>
118956
+ <string>${xml(join85(spec.stateDir, "netd.log"))}</string>
118490
118957
  <key>StandardOutPath</key>
118491
- <string>${xml(join84(spec.stateDir, "netd.log"))}</string>
118958
+ <string>${xml(join85(spec.stateDir, "netd.log"))}</string>
118492
118959
  </dict>
118493
118960
  </plist>
118494
118961
  `;
@@ -118501,8 +118968,8 @@ function runForCode(cmd, args) {
118501
118968
  });
118502
118969
  }
118503
118970
  async function elevate(script) {
118504
- const dir2 = mkdtempSync2(join84(tmpdir6(), "tesseract-netd-"));
118505
- const path6 = join84(dir2, "install.sh");
118971
+ const dir2 = mkdtempSync2(join85(tmpdir6(), "tesseract-netd-"));
118972
+ const path6 = join85(dir2, "install.sh");
118506
118973
  try {
118507
118974
  writeFileSync44(path6, script, { mode: 384 });
118508
118975
  if (await alreadyElevated()) {
@@ -118564,9 +119031,9 @@ ${plist}TESSERACT_PLIST_EOF`,
118564
119031
  };
118565
119032
  },
118566
119033
  async state() {
118567
- if (!existsSync45(PLIST))
119034
+ if (!existsSync46(PLIST))
118568
119035
  return { installed: false, running: false };
118569
- const text12 = readFileSync54(PLIST, "utf8");
119036
+ const text12 = readFileSync55(PLIST, "utf8");
118570
119037
  const owner = parseOwnerUid(text12);
118571
119038
  const assoc = parseAssociatedBundleId(text12);
118572
119039
  const running2 = await netdAvailable();
@@ -118587,7 +119054,7 @@ ${plist}TESSERACT_PLIST_EOF`,
118587
119054
 
118588
119055
  // ../../packages/host-core/dist/net-service/systemd-system.js
118589
119056
  import { spawn as spawn11 } from "node:child_process";
118590
- import { existsSync as existsSync46, readFileSync as readFileSync55 } from "node:fs";
119057
+ import { existsSync as existsSync47, readFileSync as readFileSync56 } from "node:fs";
118591
119058
 
118592
119059
  // ../../packages/host-core/dist/service/exec.js
118593
119060
  import { execFile as execFile13, spawn as spawn10 } from "node:child_process";
@@ -118755,9 +119222,9 @@ function makeSystemdSystem() {
118755
119222
  return code === 0 ? { ok: true } : { ok: false, detail: `removing the helper failed (exit ${code})` };
118756
119223
  },
118757
119224
  async state() {
118758
- if (!existsSync46(UNIT_PATH))
119225
+ if (!existsSync47(UNIT_PATH))
118759
119226
  return { installed: false, running: false };
118760
- const owner = parseOwnerUid(readFileSync55(UNIT_PATH, "utf8"));
119227
+ const owner = parseOwnerUid(readFileSync56(UNIT_PATH, "utf8"));
118761
119228
  const active = await tryRun("systemctl", ["is-active", UNIT]);
118762
119229
  const running2 = active.stdout.trim() === "active";
118763
119230
  const own2 = owner === void 0 ? {} : { ownerUid: owner };
@@ -118784,7 +119251,7 @@ function sh2(s) {
118784
119251
  import { execFile as execFile14, spawn as spawn12 } from "node:child_process";
118785
119252
  import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync45, rmSync as rmSync12 } from "node:fs";
118786
119253
  import { tmpdir as tmpdir7 } from "node:os";
118787
- import { join as join85 } from "node:path";
119254
+ import { join as join86 } from "node:path";
118788
119255
  import { promisify as promisify9 } from "node:util";
118789
119256
  var run7 = promisify9(execFile14);
118790
119257
  var SERVICE = "TesseractNetd";
@@ -118812,8 +119279,8 @@ function buildBinaryPath(spec) {
118812
119279
  return parts.map((p) => `"${p}"`).join(" ");
118813
119280
  }
118814
119281
  async function elevatePowerShell(script) {
118815
- const dir2 = mkdtempSync3(join85(tmpdir7(), "tesseract-netd-"));
118816
- const inner = join85(dir2, "install.ps1");
119282
+ const dir2 = mkdtempSync3(join86(tmpdir7(), "tesseract-netd-"));
119283
+ const inner = join86(dir2, "install.ps1");
118817
119284
  writeFileSync45(inner, script, { encoding: "utf8" });
118818
119285
  if (await alreadyElevated()) {
118819
119286
  return new Promise((resolve16) => {
@@ -118829,7 +119296,7 @@ async function elevatePowerShell(script) {
118829
119296
  p.on("close", (code) => finish(code ?? 1));
118830
119297
  });
118831
119298
  }
118832
- const outer = join85(dir2, "elevate.ps1");
119299
+ const outer = join86(dir2, "elevate.ps1");
118833
119300
  writeFileSync45(outer, [
118834
119301
  '$ErrorActionPreference = "Stop"',
118835
119302
  "try {",
@@ -119018,15 +119485,15 @@ function makeNetService() {
119018
119485
  }
119019
119486
 
119020
119487
  // ../../packages/host-core/dist/net-service/netd-binary.js
119021
- import { existsSync as existsSync47 } from "node:fs";
119022
- import { dirname as dirname39, join as join86 } from "node:path";
119488
+ import { existsSync as existsSync48 } from "node:fs";
119489
+ import { dirname as dirname39, join as join87 } from "node:path";
119023
119490
  import { fileURLToPath as fileURLToPath7 } from "node:url";
119024
119491
  function netdBinaryName() {
119025
119492
  return process.platform === "win32" ? "tesseract-netd.exe" : "tesseract-netd";
119026
119493
  }
119027
119494
  function override2() {
119028
119495
  const p = process.env.CCB_NETD_BIN;
119029
- return p && existsSync47(p) ? p : null;
119496
+ return p && existsSync48(p) ? p : null;
119030
119497
  }
119031
119498
  function netdBinaryPath() {
119032
119499
  const fromEnv = override2();
@@ -119036,24 +119503,24 @@ function netdBinaryPath() {
119036
119503
  const candidates = [];
119037
119504
  const resources = process.resourcesPath;
119038
119505
  if (resources)
119039
- candidates.push(join86(resources, "netd", name));
119506
+ candidates.push(join87(resources, "netd", name));
119040
119507
  try {
119041
119508
  const here = dirname39(fileURLToPath7(import.meta.url));
119042
- candidates.push(join86(here, "..", "..", "netd", name));
119043
- candidates.push(join86(here, "..", "..", "..", "netd", name));
119509
+ candidates.push(join87(here, "..", "..", "netd", name));
119510
+ candidates.push(join87(here, "..", "..", "..", "netd", name));
119044
119511
  const triple = `${process.platform}-${process.arch}`;
119045
- for (const root of [here, join86(here, ".."), join86(here, "..", "..")]) {
119046
- candidates.push(join86(root, "mesh-core", "prebuilds", triple, "netd", name));
119512
+ for (const root of [here, join87(here, ".."), join87(here, "..", "..")]) {
119513
+ candidates.push(join87(root, "mesh-core", "prebuilds", triple, "netd", name));
119047
119514
  }
119048
119515
  } catch {
119049
119516
  }
119050
119517
  if (process.env.CCB_REPO_ROOT) {
119051
- candidates.push(join86(process.env.CCB_REPO_ROOT, "crates", "target", "release", name));
119518
+ candidates.push(join87(process.env.CCB_REPO_ROOT, "crates", "target", "release", name));
119052
119519
  }
119053
- candidates.push(join86(process.cwd(), "crates", "target", "release", name));
119520
+ candidates.push(join87(process.cwd(), "crates", "target", "release", name));
119054
119521
  for (const c of candidates) {
119055
119522
  try {
119056
- if (existsSync47(c))
119523
+ if (existsSync48(c))
119057
119524
  return c;
119058
119525
  } catch {
119059
119526
  }
@@ -119097,7 +119564,7 @@ async function ensureNetHelperInstalled() {
119097
119564
  if (st.installed && !mismatched && !misattributed)
119098
119565
  return { ok: true, already: true };
119099
119566
  const exec2 = netdBinaryPath();
119100
- if (exec2 && process.platform === "win32" && !existsSync48(join87(dirname40(exec2), "wintun.dll"))) {
119567
+ if (exec2 && process.platform === "win32" && !existsSync49(join88(dirname40(exec2), "wintun.dll"))) {
119101
119568
  return {
119102
119569
  ok: false,
119103
119570
  reason: "no-binary",
@@ -119151,19 +119618,43 @@ import { platform as platform6 } from "node:os";
119151
119618
 
119152
119619
  // ../../packages/host-core/dist/service/launchd.js
119153
119620
  init_credentials();
119154
- import { writeFileSync as writeFileSync46, existsSync as existsSync49, mkdirSync as mkdirSync46, unlinkSync as unlinkSync8 } from "node:fs";
119155
- import { dirname as dirname41, join as join88 } from "node:path";
119156
- import { homedir as homedir15, userInfo as userInfo2 } from "node:os";
119621
+ import { writeFileSync as writeFileSync46, existsSync as existsSync50, mkdirSync as mkdirSync46, unlinkSync as unlinkSync9, readFileSync as readFileSync57 } from "node:fs";
119622
+ import { dirname as dirname41, join as join89 } from "node:path";
119623
+ import { homedir as homedir16, userInfo as userInfo2 } from "node:os";
119624
+
119625
+ // ../../packages/host-core/dist/service/legacy-label.js
119626
+ function definitionIsCli(text12) {
119627
+ if (!text12)
119628
+ return false;
119629
+ return /node_modules[/\\]tesseract-agent[/\\]/.test(text12) || /[/\\]bin[/\\]tesseract-agent(\.cmd|\.exe)?["'\s]*$/m.test(text12) || /[/\\]bin[/\\]tesseract-agent(\.cmd|\.exe)?[<"'\s]/.test(text12);
119630
+ }
119631
+
119632
+ // ../../packages/host-core/dist/service/launchd.js
119157
119633
  function xml2(s) {
119158
119634
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
119159
119635
  }
119160
119636
  function makeLaunchd(instanceId) {
119161
119637
  const suffix = instanceSuffix(instanceId);
119162
119638
  const label = SERVICE_LABEL_BASE + (suffix ? `.${suffix}` : "");
119163
- const plistPath = () => join88(homedir15(), "Library", "LaunchAgents", `${label}.plist`);
119639
+ const plistPath = () => join89(homedir16(), "Library", "LaunchAgents", `${label}.plist`);
119164
119640
  const domainTarget = () => `gui/${userInfo2().uid}`;
119165
119641
  const serviceTarget = () => `${domainTarget()}/${label}`;
119166
- const logFile = () => join88(daemonDir2(), "daemon.log");
119642
+ const logFile = () => join89(daemonDir2(), "daemon.log");
119643
+ const legacyLabel = LEGACY_SERVICE_LABEL_BASE + (suffix ? `.${suffix}` : "");
119644
+ const legacyPlistPath = () => join89(homedir16(), "Library", "LaunchAgents", `${legacyLabel}.plist`);
119645
+ async function removeLegacySharedJob() {
119646
+ try {
119647
+ const p = legacyPlistPath();
119648
+ if (!existsSync50(p))
119649
+ return;
119650
+ if (!definitionIsCli(readFileSync57(p, "utf-8")))
119651
+ return;
119652
+ await run6("launchctl", ["bootout", `${domainTarget()}/${legacyLabel}`]).catch(() => {
119653
+ });
119654
+ unlinkSync9(p);
119655
+ } catch {
119656
+ }
119657
+ }
119167
119658
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
119168
119659
  function buildPlist2(spec) {
119169
119660
  const args = [spec.exec, ...spec.args].map((a) => ` <string>${xml2(a)}</string>`).join("\n");
@@ -119238,6 +119729,7 @@ ${env}
119238
119729
  };
119239
119730
  return {
119240
119731
  async install(spec) {
119732
+ await removeLegacySharedJob();
119241
119733
  mkdirSync46(workDirOf(spec), { recursive: true });
119242
119734
  mkdirSync46(dirname41(plistPath()), { recursive: true });
119243
119735
  mkdirSync46(dirname41(spec.logPath), { recursive: true });
@@ -119257,9 +119749,9 @@ ${env}
119257
119749
  async uninstall() {
119258
119750
  await run6("launchctl", ["bootout", serviceTarget()]).catch(() => {
119259
119751
  });
119260
- if (existsSync49(plistPath())) {
119752
+ if (existsSync50(plistPath())) {
119261
119753
  try {
119262
- unlinkSync8(plistPath());
119754
+ unlinkSync9(plistPath());
119263
119755
  } catch {
119264
119756
  }
119265
119757
  }
@@ -119268,7 +119760,7 @@ ${env}
119268
119760
  await this.install(spec);
119269
119761
  },
119270
119762
  async isInstalled() {
119271
- return existsSync49(plistPath());
119763
+ return existsSync50(plistPath());
119272
119764
  },
119273
119765
  async start() {
119274
119766
  await run6("launchctl", ["bootstrap", domainTarget(), plistPath()]).catch(() => {
@@ -119285,7 +119777,7 @@ ${env}
119285
119777
  },
119286
119778
  async logs(follow) {
119287
119779
  const f = logFile();
119288
- if (!existsSync49(f)) {
119780
+ if (!existsSync50(f)) {
119289
119781
  console.log(`No log yet at ${f} \u2014 has the service started?`);
119290
119782
  return;
119291
119783
  }
@@ -119296,9 +119788,9 @@ ${env}
119296
119788
 
119297
119789
  // ../../packages/host-core/dist/service/systemd.js
119298
119790
  init_credentials();
119299
- import { writeFileSync as writeFileSync47, existsSync as existsSync50, mkdirSync as mkdirSync47, unlinkSync as unlinkSync9 } from "node:fs";
119300
- import { dirname as dirname42, join as join89 } from "node:path";
119301
- import { homedir as homedir16, userInfo as userInfo3 } from "node:os";
119791
+ import { writeFileSync as writeFileSync47, existsSync as existsSync51, mkdirSync as mkdirSync47, unlinkSync as unlinkSync10, readFileSync as readFileSync58 } from "node:fs";
119792
+ import { dirname as dirname42, join as join90 } from "node:path";
119793
+ import { homedir as homedir17, userInfo as userInfo3 } from "node:os";
119302
119794
  function unitVal2(v) {
119303
119795
  return v.replace(/%/g, "%%");
119304
119796
  }
@@ -119307,11 +119799,28 @@ function shq(s) {
119307
119799
  }
119308
119800
  function makeSystemd(instanceId) {
119309
119801
  const suffix = instanceSuffix(instanceId);
119310
- const unit = `tesseract-host${suffix ? `-${suffix}` : ""}.service`;
119802
+ const unit = `tesseract-agent${suffix ? `-${suffix}` : ""}.service`;
119803
+ const legacyUnit = `tesseract-host${suffix ? `-${suffix}` : ""}.service`;
119311
119804
  const unitPath = () => {
119312
- const base = process.env.XDG_CONFIG_HOME || join89(homedir16(), ".config");
119313
- return join89(base, "systemd", "user", unit);
119805
+ const base = process.env.XDG_CONFIG_HOME || join90(homedir17(), ".config");
119806
+ return join90(base, "systemd", "user", unit);
119314
119807
  };
119808
+ async function removeLegacySharedUnit() {
119809
+ try {
119810
+ const base = process.env.XDG_CONFIG_HOME || join90(homedir17(), ".config");
119811
+ const p = join90(base, "systemd", "user", legacyUnit);
119812
+ if (!existsSync51(p))
119813
+ return;
119814
+ if (!definitionIsCli(readFileSync58(p, "utf-8")))
119815
+ return;
119816
+ await run6("systemctl", ["--user", "disable", "--now", legacyUnit]).catch(() => {
119817
+ });
119818
+ unlinkSync10(p);
119819
+ await run6("systemctl", ["--user", "daemon-reload"]).catch(() => {
119820
+ });
119821
+ } catch {
119822
+ }
119823
+ }
119315
119824
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
119316
119825
  function buildUnit2(spec) {
119317
119826
  const execStart = [spec.exec, ...spec.args].map(shq).join(" ");
@@ -119337,6 +119846,7 @@ WantedBy=default.target
119337
119846
  }
119338
119847
  return {
119339
119848
  async install(spec) {
119849
+ await removeLegacySharedUnit();
119340
119850
  mkdirSync47(workDirOf(spec), { recursive: true });
119341
119851
  mkdirSync47(dirname42(unitPath()), { recursive: true });
119342
119852
  mkdirSync47(dirname42(spec.logPath), { recursive: true });
@@ -119352,9 +119862,9 @@ WantedBy=default.target
119352
119862
  async uninstall() {
119353
119863
  await run6("systemctl", ["--user", "disable", "--now", unit]).catch(() => {
119354
119864
  });
119355
- if (existsSync50(unitPath())) {
119865
+ if (existsSync51(unitPath())) {
119356
119866
  try {
119357
- unlinkSync9(unitPath());
119867
+ unlinkSync10(unitPath());
119358
119868
  } catch {
119359
119869
  }
119360
119870
  }
@@ -119365,7 +119875,7 @@ WantedBy=default.target
119365
119875
  await this.install(spec);
119366
119876
  },
119367
119877
  async isInstalled() {
119368
- return existsSync50(unitPath());
119878
+ return existsSync51(unitPath());
119369
119879
  },
119370
119880
  async start() {
119371
119881
  await run6("systemctl", ["--user", "start", unit]);
@@ -119377,8 +119887,8 @@ WantedBy=default.target
119377
119887
  await runInherit("systemctl", ["--user", "status", unit, "--no-pager"]);
119378
119888
  },
119379
119889
  async logs(follow) {
119380
- const f = join89(daemonDir2(), "daemon.log");
119381
- if (existsSync50(f)) {
119890
+ const f = join90(daemonDir2(), "daemon.log");
119891
+ if (existsSync51(f)) {
119382
119892
  await runInherit("tail", follow ? ["-f", f] : ["-n", "200", f]);
119383
119893
  return;
119384
119894
  }
@@ -119390,12 +119900,12 @@ WantedBy=default.target
119390
119900
 
119391
119901
  // ../../packages/host-core/dist/service/windows.js
119392
119902
  init_credentials();
119393
- import { writeFileSync as writeFileSync48, existsSync as existsSync51, mkdirSync as mkdirSync48, unlinkSync as unlinkSync10, readFileSync as readFileSync56 } from "node:fs";
119394
- import { dirname as dirname43, join as join90 } from "node:path";
119903
+ import { writeFileSync as writeFileSync48, existsSync as existsSync52, mkdirSync as mkdirSync48, unlinkSync as unlinkSync11, readFileSync as readFileSync59 } from "node:fs";
119904
+ import { dirname as dirname43, join as join91 } from "node:path";
119395
119905
  function publishedDaemonPid(dir2) {
119396
119906
  for (const f of ["status.json", "daemon.lock"]) {
119397
119907
  try {
119398
- const raw = readFileSync56(join90(dir2, f), "utf-8");
119908
+ const raw = readFileSync59(join91(dir2, f), "utf-8");
119399
119909
  const pid = f === "status.json" ? Number(JSON.parse(raw).pid) : Number(raw.trim());
119400
119910
  if (Number.isInteger(pid) && pid > 0)
119401
119911
  return pid;
@@ -119406,9 +119916,26 @@ function publishedDaemonPid(dir2) {
119406
119916
  }
119407
119917
  function makeWindowsTask(instanceId) {
119408
119918
  const suffix = instanceSuffix(instanceId);
119409
- const task = `Fineguide\\TesseractHost${suffix ? `-${suffix}` : ""}`;
119410
- const wrapperPath = () => join90(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
119411
- const logFile = () => join90(daemonDir2(), "daemon.log");
119919
+ const task = `Fineguide\\TesseractAgent${suffix ? `-${suffix}` : ""}`;
119920
+ const legacyTask = `Fineguide\\TesseractHost${suffix ? `-${suffix}` : ""}`;
119921
+ const wrapperPath = () => join91(daemonDir2(), `run-agent${suffix ? `-${suffix}` : ""}.cmd`);
119922
+ const legacyWrapperPath = () => join91(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
119923
+ const logFile = () => join91(daemonDir2(), "daemon.log");
119924
+ async function removeLegacySharedTask() {
119925
+ try {
119926
+ const w = legacyWrapperPath();
119927
+ if (!existsSync52(w))
119928
+ return;
119929
+ if (!definitionIsCli(readFileSync59(w, "utf-8")))
119930
+ return;
119931
+ await run6("schtasks", ["/End", "/TN", legacyTask]).catch(() => {
119932
+ });
119933
+ await run6("schtasks", ["/Delete", "/TN", legacyTask, "/F"]).catch(() => {
119934
+ });
119935
+ unlinkSync11(w);
119936
+ } catch {
119937
+ }
119938
+ }
119412
119939
  const oneLine2 = (s) => s.replace(/[\r\n]+/g, " ");
119413
119940
  const envVal = (v) => oneLine2(v).replace(/%/g, "%%").replace(/"/g, "");
119414
119941
  const cmdArg = (a) => `"${oneLine2(a).replace(/"/g, "")}"`;
@@ -119424,6 +119951,7 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
119424
119951
  }
119425
119952
  return {
119426
119953
  async install(spec) {
119954
+ await removeLegacySharedTask();
119427
119955
  mkdirSync48(spec.workingDirectory ?? daemonDir2(), { recursive: true });
119428
119956
  mkdirSync48(dirname43(spec.logPath), { recursive: true });
119429
119957
  mkdirSync48(dirname43(wrapperPath()), { recursive: true });
@@ -119435,9 +119963,9 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
119435
119963
  async uninstall() {
119436
119964
  await run6("schtasks", ["/Delete", "/TN", task, "/F"]).catch(() => {
119437
119965
  });
119438
- if (existsSync51(wrapperPath())) {
119966
+ if (existsSync52(wrapperPath())) {
119439
119967
  try {
119440
- unlinkSync10(wrapperPath());
119968
+ unlinkSync11(wrapperPath());
119441
119969
  } catch {
119442
119970
  }
119443
119971
  }
@@ -119509,7 +120037,7 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
119509
120037
  },
119510
120038
  async logs(follow) {
119511
120039
  const f = logFile();
119512
- if (!existsSync51(f)) {
120040
+ if (!existsSync52(f)) {
119513
120041
  console.log(`No log yet at ${f} \u2014 has the task run?`);
119514
120042
  return;
119515
120043
  }
@@ -119540,8 +120068,8 @@ init_safe_kill();
119540
120068
 
119541
120069
  // src/auth.ts
119542
120070
  var import_qrcode_terminal = __toESM(require_main(), 1);
119543
- import { existsSync as existsSync52, rmSync as rmSync13 } from "node:fs";
119544
- import { join as join91 } from "node:path";
120071
+ import { existsSync as existsSync53, rmSync as rmSync13 } from "node:fs";
120072
+ import { join as join92 } from "node:path";
119545
120073
 
119546
120074
  // src/config.ts
119547
120075
  import { hostname as hostname7 } from "node:os";
@@ -119742,8 +120270,8 @@ async function logout() {
119742
120270
  }
119743
120271
  for (const f of ["credentials.json", "status.json", "daemon.lock"]) {
119744
120272
  try {
119745
- const p = join91(daemonDir2(), f);
119746
- if (existsSync52(p)) rmSync13(p);
120273
+ const p = join92(daemonDir2(), f);
120274
+ if (existsSync53(p)) rmSync13(p);
119747
120275
  } catch {
119748
120276
  }
119749
120277
  }
@@ -119901,9 +120429,9 @@ function startSelfUpdater(current) {
119901
120429
  }
119902
120430
 
119903
120431
  // src/service.ts
119904
- import { join as join92 } from "node:path";
120432
+ import { join as join93 } from "node:path";
119905
120433
  import { platform as platform7 } from "node:os";
119906
- import { existsSync as existsSync53, readFileSync as readFileSync57 } from "node:fs";
120434
+ import { existsSync as existsSync54, readFileSync as readFileSync60 } from "node:fs";
119907
120435
  function controller(instanceId) {
119908
120436
  const c = getServiceController(instanceId);
119909
120437
  if (!c) {
@@ -119916,7 +120444,7 @@ function buildSpec(cliEntry) {
119916
120444
  exec: process.execPath,
119917
120445
  args: [cliEntry, "run"],
119918
120446
  env: { CCB_DAEMON_DIR: daemonDir2() },
119919
- logPath: join92(daemonDir2(), "daemon.log")
120447
+ logPath: join93(daemonDir2(), "daemon.log")
119920
120448
  };
119921
120449
  }
119922
120450
  var isAlive = (pid) => {
@@ -119928,10 +120456,10 @@ var isAlive = (pid) => {
119928
120456
  }
119929
120457
  };
119930
120458
  function runningDaemonInfo() {
119931
- const lock = join92(daemonDir2(), "daemon.lock");
120459
+ const lock = join93(daemonDir2(), "daemon.lock");
119932
120460
  try {
119933
- if (!existsSync53(lock)) return null;
119934
- const pid = Number(readFileSync57(lock, "utf-8").trim());
120461
+ if (!existsSync54(lock)) return null;
120462
+ const pid = Number(readFileSync60(lock, "utf-8").trim());
119935
120463
  if (!pid || !isAlive(pid)) return null;
119936
120464
  return { pid, device: readCredentials()?.deviceId };
119937
120465
  } catch {
@@ -119965,7 +120493,7 @@ async function logs(instanceId, follow) {
119965
120493
  }
119966
120494
 
119967
120495
  // src/net.ts
119968
- import { readFileSync as readFileSync59 } from "node:fs";
120496
+ import { readFileSync as readFileSync62 } from "node:fs";
119969
120497
  import { randomBytes as randomBytes12 } from "node:crypto";
119970
120498
  import { hostname as hostname8 } from "node:os";
119971
120499
  import { resolve as resolve14 } from "node:path";
@@ -120036,7 +120564,7 @@ function readOrDie(label, p) {
120036
120564
  process.exit(1);
120037
120565
  }
120038
120566
  try {
120039
- return new Uint8Array(readFileSync59(resolve14(p)));
120567
+ return new Uint8Array(readFileSync62(resolve14(p)));
120040
120568
  } catch (e) {
120041
120569
  console.error(`net enroll: could not read --${label} ${p}: ${e instanceof Error ? e.message : e}`);
120042
120570
  process.exit(1);
@@ -120715,8 +121243,8 @@ async function netCommand(rest, flags) {
120715
121243
  // src/cli.ts
120716
121244
  function pkgVersion() {
120717
121245
  try {
120718
- const p = join94(dirname44(fileURLToPath8(import.meta.url)), "..", "package.json");
120719
- return JSON.parse(readFileSync60(p, "utf8")).version ?? "0.0.0";
121246
+ const p = join95(dirname44(fileURLToPath8(import.meta.url)), "..", "package.json");
121247
+ return JSON.parse(readFileSync63(p, "utf8")).version ?? "0.0.0";
120720
121248
  } catch {
120721
121249
  return "0.0.0";
120722
121250
  }
@@ -120786,13 +121314,13 @@ async function superviseDaemon(cliEntry) {
120786
121314
  if (stopping3) process.exit(1);
120787
121315
  setTimeout(spawnWorker, 2e3).unref?.();
120788
121316
  }));
120789
- c.on("exit", (code, signal) => settle2(() => {
121317
+ c.on("exit", (code, signal2) => settle2(() => {
120790
121318
  if (stopping3) process.exit(typeof code === "number" ? code : 0);
120791
121319
  if (code === RESTART_EXIT_CODE) {
120792
121320
  spawnWorker();
120793
121321
  return;
120794
121322
  }
120795
- process.exit(typeof code === "number" ? code : signal ? 1 : 0);
121323
+ process.exit(typeof code === "number" ? code : signal2 ? 1 : 0);
120796
121324
  }));
120797
121325
  };
120798
121326
  const forward = (sig) => {
@@ -120944,7 +121472,7 @@ async function linkCommand(rest, flags) {
120944
121472
  process.exit(1);
120945
121473
  }
120946
121474
  async function captureClaudeSubscription(flags) {
120947
- const home = mkdtempSync4(join94(tmpdir8(), "tesseract-claude-login-"));
121475
+ const home = mkdtempSync4(join95(tmpdir8(), "tesseract-claude-login-"));
120948
121476
  const binary = typeof flags["claude-path"] === "string" ? flags["claude-path"] : process.env.CCB_ENGINE_PATH_CLAUDE_CODE || "claude";
120949
121477
  const args = ["auth", "login", "--claudeai"];
120950
121478
  if (typeof flags.email === "string") args.push("--email", flags.email);
@@ -120958,13 +121486,13 @@ async function captureClaudeSubscription(flags) {
120958
121486
  stdio: "inherit"
120959
121487
  });
120960
121488
  child.once("error", reject);
120961
- child.once("close", (exitCode, signal) => resolveCode(signal ? 1 : exitCode ?? 1));
121489
+ child.once("close", (exitCode, signal2) => resolveCode(signal2 ? 1 : exitCode ?? 1));
120962
121490
  });
120963
121491
  if (code !== 0) throw new Error(`Claude sign-in did not complete (exit ${code}).`);
120964
- const file2 = join94(home, ".credentials.json");
120965
- if (existsSync55(file2)) return readFileSync60(file2, "utf8");
121492
+ const file2 = join95(home, ".credentials.json");
121493
+ if (existsSync56(file2)) return readFileSync63(file2, "utf8");
120966
121494
  if (process.platform === "darwin") {
120967
- const value = execFileSync7("security", [
121495
+ const value = execFileSync8("security", [
120968
121496
  "find-generic-password",
120969
121497
  "-s",
120970
121498
  "Claude Code-credentials",
@@ -121044,7 +121572,7 @@ async function runnerCommand(rest, flags) {
121044
121572
  process.exit(1);
121045
121573
  }
121046
121574
  const oauthFilePath = typeof flags["oauth-file"] === "string" ? resolve15(flags["oauth-file"]) : void 0;
121047
- const oauthAuthFile = oauthFilePath ? readFileSync60(oauthFilePath, "utf8") : void 0;
121575
+ const oauthAuthFile = oauthFilePath ? readFileSync63(oauthFilePath, "utf8") : void 0;
121048
121576
  if (oauthAuthFile) {
121049
121577
  try {
121050
121578
  JSON.parse(oauthAuthFile);
@@ -121112,7 +121640,7 @@ async function main() {
121112
121640
  break;
121113
121641
  case "__worker":
121114
121642
  startSelfUpdater(CLI_VERSION);
121115
- await runDaemon({ tag: "tesseract", version: CLI_VERSION });
121643
+ await runDaemon({ tag: "tesseract", version: CLI_VERSION, kind: "cli" });
121116
121644
  break;
121117
121645
  case "install": {
121118
121646
  const info = runningDaemonInfo();