tesseract-agent 0.10.8 → 0.10.9

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.
@@ -4010,6 +4010,20 @@ var init_app_elements = __esm({
4010
4010
  title: "Search",
4011
4011
  description: "Opens search and the command palette \u2014 the fastest way to find anything."
4012
4012
  },
4013
+ {
4014
+ id: "guide.dock",
4015
+ area: "guide",
4016
+ title: "The guide",
4017
+ // No `reveal`: the dock only exists while the guide is summoned, and a tour step that
4018
+ // silently opened it would be pointing at something it had just conjured.
4019
+ description: "Sits in the bottom corner when summoned. Type or say what you want and she does it."
4020
+ },
4021
+ {
4022
+ id: "titlebar.guide",
4023
+ area: "titlebar",
4024
+ title: "Ask the guide",
4025
+ description: "Opens the guide \u2014 say or type what you want and she does it, or shows you where."
4026
+ },
4013
4027
  {
4014
4028
  id: "titlebar.settings",
4015
4029
  area: "titlebar",
@@ -4253,8 +4267,8 @@ function parseModelJsonArray(raw) {
4253
4267
  function schemaRejected(status2) {
4254
4268
  return status2 === 400 || status2 === 422;
4255
4269
  }
4256
- function anthropicBaseUrl() {
4257
- return process.env.ANTHROPIC_BASE_URL?.trim() || "https://api.anthropic.com";
4270
+ function anthropicBaseUrl(env) {
4271
+ return env?.ANTHROPIC_BASE_URL?.trim() || process.env.ANTHROPIC_BASE_URL?.trim() || "https://api.anthropic.com";
4258
4272
  }
4259
4273
  var OAUTH_BETA_HEADER;
4260
4274
  var init_model_json = __esm({
@@ -4278,6 +4292,56 @@ var init_domain_id = __esm({
4278
4292
  }
4279
4293
  });
4280
4294
 
4295
+ // ../../packages/shared/dist/run-directive.js
4296
+ function withRunDirective(userText, directive) {
4297
+ if (!directive.trim())
4298
+ return userText;
4299
+ const head = userText ? `${userText}
4300
+
4301
+ ` : "";
4302
+ return `${head}${RUN_DIRECTIVE_MARK}
4303
+ ${directive}`;
4304
+ }
4305
+ var RUN_DIRECTIVE_MARK;
4306
+ var init_run_directive = __esm({
4307
+ "../../packages/shared/dist/run-directive.js"() {
4308
+ "use strict";
4309
+ RUN_DIRECTIVE_MARK = "<!-- tesseract:run-directive -->";
4310
+ }
4311
+ });
4312
+
4313
+ // ../../packages/shared/dist/proactive-compaction.js
4314
+ function proactiveCompactionVerdict(a) {
4315
+ if (a.inFlight)
4316
+ return "skip";
4317
+ if (typeof a.pct !== "number" || !Number.isFinite(a.pct) || a.pct <= 0 || a.pct >= 100)
4318
+ return "skip";
4319
+ if (typeof a.usagePct !== "number" || !Number.isFinite(a.usagePct))
4320
+ return "skip";
4321
+ if (a.usagePct > IMPOSSIBLE_FILL_PCT)
4322
+ return "skip";
4323
+ if (a.usagePct < a.pct)
4324
+ return "reset";
4325
+ if (typeof a.lastCompactPct === "number" && a.usagePct < a.lastCompactPct + PROACTIVE_REGROWTH_POINTS)
4326
+ return "skip";
4327
+ return "compact";
4328
+ }
4329
+ var PROACTIVE_REGROWTH_POINTS, IMPOSSIBLE_FILL_PCT;
4330
+ var init_proactive_compaction = __esm({
4331
+ "../../packages/shared/dist/proactive-compaction.js"() {
4332
+ "use strict";
4333
+ PROACTIVE_REGROWTH_POINTS = 5;
4334
+ IMPOSSIBLE_FILL_PCT = 100;
4335
+ }
4336
+ });
4337
+
4338
+ // ../../packages/shared/dist/digit-recall.js
4339
+ var init_digit_recall = __esm({
4340
+ "../../packages/shared/dist/digit-recall.js"() {
4341
+ "use strict";
4342
+ }
4343
+ });
4344
+
4281
4345
  // ../../packages/shared/dist/telemetry.js
4282
4346
  var TELEMETRY_EVENTS, EVENT_CATEGORY;
4283
4347
  var init_telemetry = __esm({
@@ -4705,14 +4769,67 @@ var init_hosting = __esm({
4705
4769
  }
4706
4770
  });
4707
4771
 
4772
+ // ../../packages/shared/dist/model-long-context.js
4773
+ function supportsOneMillionContext(model) {
4774
+ const id = (model ?? "").trim();
4775
+ if (!id)
4776
+ return false;
4777
+ if (/haiku/i.test(id))
4778
+ return false;
4779
+ return ONE_MILLION_FAMILIES.some((re) => re.test(id));
4780
+ }
4781
+ function hasOneMillionSuffix(model) {
4782
+ return /\[1m\]$/i.test((model ?? "").trim());
4783
+ }
4784
+ function withOneMillionContext(model) {
4785
+ const id = model?.trim();
4786
+ if (!id)
4787
+ return model;
4788
+ if (hasOneMillionSuffix(id))
4789
+ return id;
4790
+ if (!supportsOneMillionContext(id))
4791
+ return id;
4792
+ return `${id}${SUFFIX}`;
4793
+ }
4794
+ function withoutOneMillionContext(model) {
4795
+ const id = model?.trim();
4796
+ if (!id)
4797
+ return model;
4798
+ return id.replace(/\[1m\]$/i, "");
4799
+ }
4800
+ var ONE_MILLION_FAMILIES, SUFFIX;
4801
+ var init_model_long_context = __esm({
4802
+ "../../packages/shared/dist/model-long-context.js"() {
4803
+ "use strict";
4804
+ ONE_MILLION_FAMILIES = [
4805
+ /(^|[/.])claude-sonnet-(4-6|4-7|4-8|5)\b/i,
4806
+ /(^|[/.])claude-opus-(4-6|4-7|4-8|5)\b/i,
4807
+ /(^|[/.])claude-fable-5\b/i,
4808
+ // The CLI's own short aliases.
4809
+ /^(sonnet|opus|fable)$/i
4810
+ ];
4811
+ SUFFIX = "[1m]";
4812
+ }
4813
+ });
4814
+
4708
4815
  // ../../packages/shared/dist/settings.js
4709
4816
  function canCallDirectly(modelId) {
4710
4817
  return !!modelId && MODEL_OPTIONS.some((m) => m.id === modelId);
4711
4818
  }
4712
- var MODEL_OPTIONS, DEFAULT_VERIFIER_MODEL;
4819
+ function isCliModelAlias(model) {
4820
+ return CLI_MODEL_ALIASES.test((model ?? "").trim());
4821
+ }
4822
+ function verifierModelLadder(model) {
4823
+ const bare = withoutOneMillionContext(model) ?? model;
4824
+ const first = canCallDirectly(bare) ? bare : DEFAULT_VERIFIER_MODEL;
4825
+ const rest = MODEL_OPTIONS.map((m) => m.id).filter((id) => id !== first && !/haiku/i.test(id));
4826
+ return [first, ...rest];
4827
+ }
4828
+ var MODEL_OPTIONS, DEFAULT_VERIFIER_MODEL, CLI_MODEL_ALIASES;
4713
4829
  var init_settings = __esm({
4714
4830
  "../../packages/shared/dist/settings.js"() {
4715
4831
  "use strict";
4832
+ init_model_long_context();
4716
4833
  MODEL_OPTIONS = [
4717
4834
  { id: "claude-opus-5", label: "Claude Opus 5" },
4718
4835
  { id: "claude-sonnet-5", label: "Claude Sonnet 5" },
@@ -4722,6 +4839,7 @@ var init_settings = __esm({
4722
4839
  { id: "claude-haiku-4-5", label: "Claude Haiku 4.5" }
4723
4840
  ];
4724
4841
  DEFAULT_VERIFIER_MODEL = MODEL_OPTIONS[0].id;
4842
+ CLI_MODEL_ALIASES = /^(?:default|sonnet|opus|haiku|fable)(?:\[1m\])?$/i;
4725
4843
  }
4726
4844
  });
4727
4845
 
@@ -6400,9 +6518,9 @@ function kebab(s) {
6400
6518
  return s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
6401
6519
  }
6402
6520
  function tokenCssVarName(path6, token3) {
6403
- const override2 = token3 ? tessExt(token3)?.cssVar : void 0;
6404
- if (override2) {
6405
- const name = override2.startsWith("--") ? override2 : `--${override2}`;
6521
+ const override3 = token3 ? tessExt(token3)?.cssVar : void 0;
6522
+ if (override3) {
6523
+ const name = override3.startsWith("--") ? override3 : `--${override3}`;
6406
6524
  if (/^--[A-Za-z0-9-]+$/.test(name))
6407
6525
  return name;
6408
6526
  }
@@ -7256,6 +7374,9 @@ var init_dist = __esm({
7256
7374
  init_ws_protocol();
7257
7375
  init_frame();
7258
7376
  init_domain_id();
7377
+ init_run_directive();
7378
+ init_proactive_compaction();
7379
+ init_digit_recall();
7259
7380
  init_telemetry();
7260
7381
  init_error_report();
7261
7382
  init_eula();
@@ -7947,8 +8068,9 @@ function materializeClaudeAuthHome(contents) {
7947
8068
  return home;
7948
8069
  }
7949
8070
  function withClaudeModels(env, main2, fast) {
7950
- if (main2)
7951
- env.ANTHROPIC_MODEL = main2;
8071
+ if (main2) {
8072
+ env.ANTHROPIC_MODEL = process.env.TESSERACT_DISABLE_1M_CONTEXT === "1" ? main2 : withOneMillionContext(main2) ?? main2;
8073
+ }
7952
8074
  if (fast)
7953
8075
  env.ANTHROPIC_SMALL_FAST_MODEL = fast;
7954
8076
  return env;
@@ -7975,14 +8097,14 @@ function resolveRunnerEnv(spec) {
7975
8097
  return {};
7976
8098
  const key2 = spec?.secret?.trim();
7977
8099
  if (provider.claudeEnterprise) {
7978
- const run5 = claudeEnterpriseRun(provider.claudeEnterprise, { secret: key2, baseUrl: spec?.baseUrl, main: main2, fast });
7979
- if (run5.error)
7980
- return { CCB_RUNNER_CONFIG_ERROR: run5.error };
7981
- if (!run5.file)
7982
- return run5.env;
8100
+ const run8 = claudeEnterpriseRun(provider.claudeEnterprise, { secret: key2, baseUrl: spec?.baseUrl, main: main2, fast });
8101
+ if (run8.error)
8102
+ return { CCB_RUNNER_CONFIG_ERROR: run8.error };
8103
+ if (!run8.file)
8104
+ return run8.env;
7983
8105
  try {
7984
- const path6 = materializeEnterpriseCredential(run5.file.suggestedName, run5.file.contents);
7985
- return { ...run5.env, [run5.file.envVar]: path6 };
8106
+ const path6 = materializeEnterpriseCredential(run8.file.suggestedName, run8.file.contents);
8107
+ return { ...run8.env, [run8.file.envVar]: path6 };
7986
8108
  } catch (e) {
7987
8109
  return { CCB_RUNNER_CONFIG_ERROR: `Could not write the ${provider.label} credential on this machine: ${e.message}` };
7988
8110
  }
@@ -8049,6 +8171,7 @@ var init_resolve = __esm({
8049
8171
  "../../packages/host-core/dist/runners/resolve.js"() {
8050
8172
  "use strict";
8051
8173
  init_base_paths();
8174
+ init_model_long_context();
8052
8175
  init_file_lock();
8053
8176
  init_dist();
8054
8177
  init_proxy_router();
@@ -8589,21 +8712,27 @@ function readDaemonAgentSettings() {
8589
8712
  return snap;
8590
8713
  }
8591
8714
  }
8715
+ function gatewayCanCall(model, snapshot4) {
8716
+ const tiers2 = snapshot4.gatewayTiers;
8717
+ if (!tiers2?.length)
8718
+ return true;
8719
+ return tiers2.includes(model) || snapshot4.gatewayDirectNaming === true;
8720
+ }
8592
8721
  function gatewayTierRejection(model) {
8593
8722
  if (!model)
8594
8723
  return null;
8595
- const tiers2 = readDaemonAgentSettings().gatewayTiers;
8596
- if (!tiers2?.length || tiers2.includes(model))
8724
+ const snap = readDaemonAgentSettings();
8725
+ if (gatewayCanCall(model, snap))
8597
8726
  return null;
8598
- return { model, tiers: [...tiers2] };
8727
+ return { model, tiers: [...snap.gatewayTiers ?? []] };
8599
8728
  }
8600
8729
  function gatewayTierClamp(model) {
8601
8730
  if (!model)
8602
8731
  return model;
8603
- const tiers2 = readDaemonAgentSettings().gatewayTiers;
8604
- if (!tiers2?.length || tiers2.includes(model))
8732
+ const snap = readDaemonAgentSettings();
8733
+ if (gatewayCanCall(model, snap))
8605
8734
  return model;
8606
- console.warn(`[gateway] Model "${model}" isn't served by this device's gateway key (${tiers2.join(", ")}) \u2014 dropping it so the gateway picks one it can reach.`);
8735
+ console.warn(`[gateway] Model "${model}" isn't served by this device's gateway key (${(snap.gatewayTiers ?? []).join(", ")}) \u2014 dropping it so the gateway picks one it can reach.`);
8607
8736
  return void 0;
8608
8737
  }
8609
8738
  function chatSendToParams(msg, defaults) {
@@ -8630,6 +8759,10 @@ function chatSendToParams(msg, defaults) {
8630
8759
  // one OFF for one conversation could not actually turn it off.
8631
8760
  ...msg.unattended !== void 0 ? { unattended: msg.unattended } : {},
8632
8761
  ...msg.reinforcedVerification !== void 0 ? { reinforcedVerification: msg.reinforcedVerification } : {},
8762
+ // Forwarded even at 0/100 (both mean "no proactive compaction"), for the same reason as
8763
+ // the two flags above: falling through to the machine-wide number would make a
8764
+ // conversation that opted out of compaction impossible to express.
8765
+ ...msg.autoCompactPct !== void 0 ? { autoCompactPct: msg.autoCompactPct } : {},
8633
8766
  ...msg.autoContinuation ? { autoContinuation: true } : {},
8634
8767
  ...msg.model ? { model: msg.model } : {},
8635
8768
  ...msg.jsonSchema ? { jsonSchema: msg.jsonSchema } : {},
@@ -8699,11 +8832,15 @@ function mergeDaemonAgentSettings(params) {
8699
8832
  // local override (single-config CLI). Enabled skills' env is folded in. Empty ⇒
8700
8833
  // ambient Claude.
8701
8834
  engineEnv: params.engineEnv ?? {
8702
- ...poolActiveEngineEnv() ?? (s.runnerSpec ? resolveRunnerEnv(s.runnerSpec) : resolveOverrideEngineEnv()),
8835
+ ...daemonEngineEnv(),
8703
8836
  ...s.skillEnv ?? {}
8704
8837
  }
8705
8838
  };
8706
8839
  }
8840
+ function daemonEngineEnv() {
8841
+ const s = readDaemonAgentSettings();
8842
+ return poolActiveEngineEnv() ?? (s.runnerSpec ? resolveRunnerEnv(s.runnerSpec) : resolveOverrideEngineEnv());
8843
+ }
8707
8844
  var init_daemon_settings = __esm({
8708
8845
  "../../packages/host-core/dist/daemon-settings.js"() {
8709
8846
  "use strict";
@@ -12058,10 +12195,10 @@ var init_schemas = __esm({
12058
12195
  $ZodType.init(inst, def);
12059
12196
  const desc = Object.getOwnPropertyDescriptor(def, "shape");
12060
12197
  if (!desc?.get) {
12061
- const sh = def.shape;
12198
+ const sh3 = def.shape;
12062
12199
  Object.defineProperty(def, "shape", {
12063
12200
  get: () => {
12064
- const newSh = { ...sh };
12201
+ const newSh = { ...sh3 };
12065
12202
  Object.defineProperty(def, "shape", {
12066
12203
  value: newSh
12067
12204
  });
@@ -28566,8 +28703,8 @@ function prompt(id, vars) {
28566
28703
  }
28567
28704
  return "";
28568
28705
  }
28569
- const override2 = snapshot2.entries[id];
28570
- return interpolatePrompt(typeof override2 === "string" ? override2 : spec.content, vars);
28706
+ const override3 = snapshot2.entries[id];
28707
+ return interpolatePrompt(typeof override3 === "string" ? override3 : spec.content, vars);
28571
28708
  }
28572
28709
  function describedBy(idPrefix, specs, key2 = (s) => s.name) {
28573
28710
  return specs.map((spec) => Object.defineProperty({ ...spec }, "description", {
@@ -28708,7 +28845,7 @@ function buildPack(s) {
28708
28845
  const dual = (lv) => ({ $value: lv[0], $extensions: { "com.tesseract": { modes: { dark: lv[1] } } } });
28709
28846
  const val = (v) => Array.isArray(v) ? dual(v) : { $value: v };
28710
28847
  const r = s.radius ?? { sm: "6px", md: "10px", lg: "16px" };
28711
- const sh = s.shadow ?? {
28848
+ const sh3 = s.shadow ?? {
28712
28849
  sm: "0 1px 2px rgb(0 0 0 / 0.06)",
28713
28850
  md: "0 4px 12px rgb(0 0 0 / 0.08)",
28714
28851
  lg: "0 12px 32px rgb(0 0 0 / 0.12)"
@@ -28753,7 +28890,7 @@ function buildPack(s) {
28753
28890
  xl: { $value: "40px" }
28754
28891
  },
28755
28892
  radius: { $type: "dimension", sm: { $value: r.sm }, md: { $value: r.md }, lg: { $value: r.lg }, full: { $value: "9999px" } },
28756
- shadow: { $type: "shadow", sm: { $value: sh.sm }, md: { $value: sh.md }, lg: { $value: sh.lg } }
28893
+ shadow: { $type: "shadow", sm: { $value: sh3.sm }, md: { $value: sh3.md }, lg: { $value: sh3.lg } }
28757
28894
  };
28758
28895
  return { $packSchema: DESIGN_PACK_SCHEMA, id: s.id, name: s.name, description: s.description, style: s.style, tokens: tokens3 };
28759
28896
  }
@@ -31716,7 +31853,7 @@ var init_job_registry = __esm({
31716
31853
  * the calling tool can return `{ id, logPath }` to the model in the same tick, so the
31717
31854
  * turn continues instead of blocking. `run` is deliberately NOT awaited here.
31718
31855
  */
31719
- start(kind, description, run5) {
31856
+ start(kind, description, run8) {
31720
31857
  const id = makeId(++this.seq);
31721
31858
  const logPath = join16(this.dir, `${id}.output`);
31722
31859
  const abort = new AbortController();
@@ -31736,7 +31873,7 @@ var init_job_registry = __esm({
31736
31873
  this.evict();
31737
31874
  void (async () => {
31738
31875
  try {
31739
- const tail3 = await run5((chunk) => this.write(id, chunk), abort.signal);
31876
+ const tail3 = await run8((chunk) => this.write(id, chunk), abort.signal);
31740
31877
  if (typeof tail3 === "string" && tail3)
31741
31878
  this.write(id, tail3);
31742
31879
  this.settle(id, abort.signal.aborted ? "stopped" : "completed", abort.signal.aborted ? 130 : 0);
@@ -33485,9 +33622,9 @@ function paginationSignature(engine) {
33485
33622
  return [...engine.pagination.params].sort().join("+");
33486
33623
  }
33487
33624
  function pageStrategy(engine) {
33488
- const override2 = OVERRIDES[engine.id];
33489
- if (override2)
33490
- return override2;
33625
+ const override3 = OVERRIDES[engine.id];
33626
+ if (override3)
33627
+ return override3;
33491
33628
  const sig = paginationSignature(engine);
33492
33629
  if (!sig)
33493
33630
  return { kind: "none", reason: "This engine declares no pagination parameters." };
@@ -36635,27 +36772,18 @@ function autoCompactEnvFor(pct2, supplied) {
36635
36772
  function shouldCompactProactively(a) {
36636
36773
  if (a.mode === "off")
36637
36774
  return "skip";
36638
- if (a.inFlight)
36639
- return "skip";
36640
- if (typeof a.pct !== "number" || !Number.isFinite(a.pct) || a.pct <= 0 || a.pct >= 100)
36641
- return "skip";
36642
- if (typeof a.usagePct !== "number" || !Number.isFinite(a.usagePct))
36643
- return "skip";
36644
- if (a.usagePct < a.pct)
36645
- return "reset";
36646
- if (typeof a.lastCompactPct === "number" && a.usagePct < a.lastCompactPct + PROACTIVE_REGROWTH_POINTS)
36647
- return "skip";
36648
- return "compact";
36775
+ return proactiveCompactionVerdict(a);
36649
36776
  }
36650
- var OVERFLOW_MAX_TRIES, OVERFLOW_COMPACT_MESSAGE, OVERFLOW_RESUME_MESSAGE, PROACTIVE_REGROWTH_POINTS;
36777
+ var OVERFLOW_MAX_TRIES, OVERFLOW_COMPACT_MESSAGE, OVERFLOW_RESUME_MESSAGE;
36651
36778
  var init_context_recovery = __esm({
36652
36779
  "../../packages/agent-core/dist/context-recovery.js"() {
36653
36780
  "use strict";
36781
+ init_dist();
36654
36782
  init_unattended_log();
36783
+ init_dist();
36655
36784
  OVERFLOW_MAX_TRIES = 3;
36656
36785
  OVERFLOW_COMPACT_MESSAGE = "/compact";
36657
36786
  OVERFLOW_RESUME_MESSAGE = "Continue.";
36658
- PROACTIVE_REGROWTH_POINTS = 5;
36659
36787
  }
36660
36788
  });
36661
36789
 
@@ -37483,13 +37611,16 @@ async function fetchSessionUsage(env) {
37483
37611
  }
37484
37612
  async function anthropicHeaders(env) {
37485
37613
  const apiKey = env?.ANTHROPIC_API_KEY?.trim() || process.env.ANTHROPIC_API_KEY?.trim() || "";
37486
- const oauth = apiKey ? "" : await resolveOauthToken(env) || "";
37487
- if (!apiKey && !oauth)
37614
+ const authToken = apiKey ? "" : env?.ANTHROPIC_AUTH_TOKEN?.trim() || "";
37615
+ const oauth = apiKey || authToken ? "" : await resolveOauthToken(env) || "";
37616
+ if (!apiKey && !authToken && !oauth)
37488
37617
  return null;
37489
37618
  const headers = { "content-type": "application/json", "anthropic-version": "2023-06-01" };
37490
37619
  if (apiKey)
37491
37620
  headers["x-api-key"] = apiKey;
37492
- else {
37621
+ else if (authToken) {
37622
+ headers.authorization = `Bearer ${authToken}`;
37623
+ } else {
37493
37624
  headers.authorization = `Bearer ${oauth}`;
37494
37625
  headers["anthropic-beta"] = OAUTH_BETA_HEADER;
37495
37626
  }
@@ -37499,27 +37630,31 @@ async function hasAnthropicCred(env) {
37499
37630
  return await anthropicHeaders(env) !== null;
37500
37631
  }
37501
37632
  async function anthropicMessage(args) {
37633
+ return (await anthropicCall(args)).text;
37634
+ }
37635
+ async function anthropicCall(args) {
37502
37636
  const { env, model, system, content, maxTokens, timeoutMs, label } = args;
37503
37637
  const attempts = Math.max(1, args.attempts ?? 1);
37504
37638
  const budgetMs = args.budgetMs ?? attempts * timeoutMs + 4e3;
37505
37639
  const deadline = Date.now() + budgetMs;
37506
- const base = { model, max_tokens: maxTokens, system, messages: [{ role: "user", content }] };
37507
- let body = JSON.stringify(args.schema ? { ...base, output_config: { format: { type: "json_schema", schema: args.schema } } } : base);
37508
- let schemaDropped = false;
37640
+ const base = { ...model ? { model } : {}, max_tokens: maxTokens, system, messages: [{ role: "user", content }] };
37641
+ const useSchema = !!args.schema && !schemaUnsupported.has(schemaKey(anthropicBaseUrl(env), model));
37642
+ let body = JSON.stringify(useSchema ? { ...base, output_config: { format: { type: "json_schema", schema: args.schema } } } : base);
37643
+ let schemaDropped = !useSchema;
37509
37644
  const headers = await anthropicHeaders(env);
37510
37645
  if (!headers)
37511
- return null;
37646
+ return { text: null, rateLimited: false };
37512
37647
  for (let attempt = 0; attempt < attempts; attempt++) {
37513
37648
  const remaining = deadline - Date.now();
37514
37649
  if (remaining < 1e3) {
37515
37650
  log(`${label}: out of budget after ${attempt} attempt(s) \u2014 giving up rather than starting a leg that cannot finish.`);
37516
- return null;
37651
+ return { text: null, rateLimited: false };
37517
37652
  }
37518
37653
  const ac = new AbortController();
37519
37654
  const legMs = Math.min(timeoutMs, remaining);
37520
37655
  const legTimer = setTimeout(() => ac.abort(new Error("The operation was aborted due to timeout")), legMs);
37521
37656
  try {
37522
- const res = await fetch(`${anthropicBaseUrl()}/v1/messages`, {
37657
+ const res = await fetch(`${anthropicBaseUrl(env)}/v1/messages`, {
37523
37658
  method: "POST",
37524
37659
  headers,
37525
37660
  body,
@@ -37527,23 +37662,34 @@ async function anthropicMessage(args) {
37527
37662
  });
37528
37663
  if (res.ok) {
37529
37664
  const j = await res.json();
37530
- return (j.content ?? []).filter((b) => b.type === "text").map((b) => b.text ?? "").join("").trim() || null;
37665
+ const text12 = (j.content ?? []).filter((b) => b.type === "text").map((b) => b.text ?? "").join("").trim() || null;
37666
+ return { text: text12, rateLimited: false };
37531
37667
  }
37532
37668
  if (schemaRejected(res.status) && args.schema && !schemaDropped) {
37533
37669
  schemaDropped = true;
37670
+ schemaUnsupported.add(schemaKey(anthropicBaseUrl(env), model));
37534
37671
  body = JSON.stringify(base);
37535
37672
  log(`${label}: the endpoint rejected output_config (${model}) \u2014 retrying without the schema and parsing the reply as text.`);
37536
37673
  attempt--;
37537
37674
  continue;
37538
37675
  }
37539
- if ((res.status === 429 || res.status === 529) && attempt < attempts - 1) {
37540
- const wait = Math.max(0, Math.min(800 * (attempt + 1) * (attempt + 1), deadline - Date.now()));
37676
+ const rateLimited = res.status === 429 || res.status === 529;
37677
+ const modelRejected = (res.status === 400 || res.status === 403 || res.status === 404) && !!model;
37678
+ if (rateLimited && attempt < attempts - 1) {
37679
+ let stated = 0;
37680
+ try {
37681
+ stated = Number(res.headers?.get?.("retry-after")) * 1e3;
37682
+ } catch {
37683
+ stated = 0;
37684
+ }
37685
+ const backoff3 = Number.isFinite(stated) && stated > 0 ? stated : 800 * (attempt + 1) * (attempt + 1);
37686
+ const wait = Math.max(0, Math.min(backoff3, deadline - Date.now()));
37541
37687
  log(`${label}: HTTP ${res.status} (${model}) \u2014 retry ${attempt + 1} in ${wait}ms`);
37542
37688
  await new Promise((r) => setTimeout(r, wait));
37543
37689
  continue;
37544
37690
  }
37545
37691
  log(`${label}: HTTP ${res.status} (${model})`);
37546
- return null;
37692
+ return { text: null, rateLimited, modelRejected };
37547
37693
  } catch (err2) {
37548
37694
  if (args.retryOnThrow && attempt < attempts - 1) {
37549
37695
  const wait = Math.max(0, Math.min(800 * (attempt + 1) * (attempt + 1), deadline - Date.now()));
@@ -37552,19 +37698,27 @@ async function anthropicMessage(args) {
37552
37698
  continue;
37553
37699
  }
37554
37700
  log(`${label}: call failed:`, err2 instanceof Error ? err2.message : String(err2));
37555
- return null;
37701
+ return { text: null, rateLimited: false };
37556
37702
  } finally {
37557
37703
  clearTimeout(legTimer);
37558
37704
  }
37559
37705
  }
37560
- return null;
37706
+ return { text: null, rateLimited: false };
37707
+ }
37708
+ function isDirectAnthropic(env) {
37709
+ try {
37710
+ return /(^|\.)api\.anthropic\.com$/i.test(new URL(anthropicBaseUrl(env)).hostname);
37711
+ } catch {
37712
+ return false;
37713
+ }
37561
37714
  }
37562
37715
  async function buildClaudeNarrationLlm(env) {
37563
37716
  if (!await hasAnthropicCred(env))
37564
37717
  return null;
37718
+ const model = isDirectAnthropic(env) ? "claude-haiku-4-5" : env?.ANTHROPIC_SMALL_FAST_MODEL?.trim() || env?.ANTHROPIC_MODEL?.trim() || "";
37565
37719
  const complete = ({ system, prompt: prompt2, maxTokens, schema }) => anthropicMessage({
37566
37720
  env,
37567
- model: "claude-haiku-4-5",
37721
+ model,
37568
37722
  system,
37569
37723
  content: prompt2,
37570
37724
  maxTokens,
@@ -37574,43 +37728,60 @@ async function buildClaudeNarrationLlm(env) {
37574
37728
  });
37575
37729
  return { complete, engineLabel: "Claude Code" };
37576
37730
  }
37577
- async function buildClaudeSmartLlm(env) {
37578
- if (!await hasAnthropicCred(env))
37731
+ function graderLadder(model, env) {
37732
+ if (isDirectAnthropic(env))
37733
+ return verifierModelLadder(model);
37734
+ const configured = env?.ANTHROPIC_MODEL?.trim();
37735
+ const named = model?.trim();
37736
+ const wanted2 = named && !isCliModelAlias(named) ? named : configured;
37737
+ return [...new Set([wanted2, configured].filter((m) => !!m))];
37738
+ }
37739
+ async function buildClaudeSmartLlm(builderEnv) {
37740
+ return async ({ model, system, prompt: prompt2, maxTokens, schema, env: callEnv }) => {
37741
+ const env = callEnv && Object.keys(callEnv).length ? callEnv : builderEnv;
37742
+ const deadline = Date.now() + RV_GRADE_ATTEMPTS * RV_GRADE_TIMEOUT_MS + RV_GRADE_BACKOFF_MS;
37743
+ const ladder = graderLadder(model, env);
37744
+ let rejectedOnce = false;
37745
+ for (let i = 0; i < Math.max(1, ladder.length); i++) {
37746
+ const remaining = deadline - Date.now();
37747
+ if (remaining < 2e3)
37748
+ break;
37749
+ const out = await anthropicCall({
37750
+ env,
37751
+ schema,
37752
+ model: ladder[i] ?? "",
37753
+ // No `thinking` on purpose: the accepted shape differs per model generation
37754
+ // (adaptive-only, budget_tokens, disabled-at-effort), and a 400 here costs the whole
37755
+ // verification pass. The models we call think by default where it matters.
37756
+ system,
37757
+ content: prompt2,
37758
+ maxTokens,
37759
+ timeoutMs: Math.min(SMART_TIMEOUT_MS, remaining),
37760
+ label: "verifier",
37761
+ // TWO attempts, not three (RV_GRADE_ATTEMPTS) — see the deadline above. Only the
37762
+ // FIRST model gets them: a fallback leg exists because the first was rate-limited,
37763
+ // and spending the remaining budget re-asking one model would leave none for the
37764
+ // model that can actually answer.
37765
+ attempts: i === 0 ? RV_GRADE_ATTEMPTS : 1,
37766
+ retryOnThrow: i === 0,
37767
+ budgetMs: remaining
37768
+ });
37769
+ if (out.text) {
37770
+ if (i > 0)
37771
+ log(`verifier: graded with ${ladder[i]} \u2014 ${ladder[0]} was unavailable`);
37772
+ return out.text;
37773
+ }
37774
+ if (out.rateLimited)
37775
+ continue;
37776
+ if (out.modelRejected && !rejectedOnce) {
37777
+ rejectedOnce = true;
37778
+ continue;
37779
+ }
37780
+ return null;
37781
+ }
37782
+ log("verifier: every model was rate-limited or out of budget \u2014 this run cannot be graded now");
37579
37783
  return null;
37580
- return ({ model, system, prompt: prompt2, maxTokens, schema }) => anthropicMessage({
37581
- env,
37582
- schema,
37583
- // Only a model this endpoint actually serves. `/^claude-/` was a PROVIDER-NAME test
37584
- // standing in for "can this be called": it passed a gateway tier alias or a dated id
37585
- // straight through (400 → the schema-drop retry → 400 again → every verified run on that
37586
- // model reporting "the verifier did not return a usable verdict"), and it FAILED
37587
- // `us.anthropic.claude-*`, silently downgrading a Claude session's grader. The catalog
37588
- // answers the question the regex was imitating.
37589
- model: canCallDirectly(model) ? model : DEFAULT_VERIFIER_MODEL,
37590
- // No `thinking` / `output_config` on purpose: the accepted shape differs per model
37591
- // generation (adaptive-only, budget_tokens, disabled-at-effort), and a 400 here costs
37592
- // the whole verification pass. The models we call think by default where it matters.
37593
- system,
37594
- content: prompt2,
37595
- maxTokens,
37596
- timeoutMs: SMART_TIMEOUT_MS,
37597
- label: "verifier",
37598
- // TWO attempts, not three (RV_GRADE_ATTEMPTS). The desktop gives a grade
37599
- // RV_VERDICT_GRACE_MS before it stops waiting and ends the run itself; a third attempt
37600
- // plus backoff pushes the sum past it, so the verdict would land after the client had
37601
- // already moved on — and then dispatch a "continue and finish it" turn into whatever
37602
- // the user started next.
37603
- attempts: RV_GRADE_ATTEMPTS,
37604
- retryOnThrow: true,
37605
- // The ATTEMPT PLAN, not the client's grace — the two are different numbers on purpose.
37606
- // The desktop stops waiting at RV_VERDICT_GRACE_MS (180s), ends the run itself, and a
37607
- // late verdict then dispatches a "continue and finish it" turn on top of whatever the
37608
- // user started next. The shared constants already encode the gap: 2 x 75s + 4s = 154s of
37609
- // trying, leaving 26s for the verdict to actually get back and be applied. Budgeting to
37610
- // the grace itself would spend that margin and land the answer exactly as the client
37611
- // gives up, which is a race rather than a deadline.
37612
- budgetMs: RV_GRADE_ATTEMPTS * RV_GRADE_TIMEOUT_MS + RV_GRADE_BACKOFF_MS
37613
- });
37784
+ };
37614
37785
  }
37615
37786
  async function buildClaudeVisionLlm(env) {
37616
37787
  if (!await hasAnthropicCred(env))
@@ -37630,7 +37801,7 @@ async function buildClaudeVisionLlm(env) {
37630
37801
  ]
37631
37802
  });
37632
37803
  }
37633
- var execFileP, USAGE_URL, FETCH_TIMEOUT_MS, cache4, TTL_MS, SMART_TIMEOUT_MS, VISION_TIMEOUT_MS;
37804
+ var execFileP, USAGE_URL, FETCH_TIMEOUT_MS, cache4, TTL_MS, schemaUnsupported, schemaKey, SMART_TIMEOUT_MS, VISION_TIMEOUT_MS;
37634
37805
  var init_session_usage = __esm({
37635
37806
  "../../packages/agent-core/dist/session-usage.js"() {
37636
37807
  "use strict";
@@ -37642,6 +37813,8 @@ var init_session_usage = __esm({
37642
37813
  FETCH_TIMEOUT_MS = 5e3;
37643
37814
  cache4 = null;
37644
37815
  TTL_MS = 2e4;
37816
+ schemaUnsupported = /* @__PURE__ */ new Set();
37817
+ schemaKey = (base, model) => `${base}|${model}`;
37645
37818
  SMART_TIMEOUT_MS = RV_GRADE_TIMEOUT_MS;
37646
37819
  VISION_TIMEOUT_MS = 2e4;
37647
37820
  }
@@ -38088,6 +38261,26 @@ function sessionStoreFor(mode) {
38088
38261
  function unattendedReportDirective(send4) {
38089
38262
  return unattendedModeFor({ optedIn: send4.unattended, origin: send4.origin }) !== "off" ? prompt("agent.system.unattended-report") : "";
38090
38263
  }
38264
+ function sdkModelId(model) {
38265
+ const id = model?.trim();
38266
+ if (!id)
38267
+ return void 0;
38268
+ if (process.env.TESSERACT_DISABLE_1M_CONTEXT === "1")
38269
+ return id;
38270
+ if (/[/]/.test(id) || /^[a-z]{2,}\./i.test(id))
38271
+ return id;
38272
+ return withOneMillionContext(id) ?? id;
38273
+ }
38274
+ function anthropicEnvOf(env) {
38275
+ const keys = ["ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_API_KEY", "ANTHROPIC_MODEL", "ANTHROPIC_SMALL_FAST_MODEL", "CLAUDE_CODE_OAUTH_TOKEN", "CLAUDE_CONFIG_DIR"];
38276
+ const out = {};
38277
+ for (const k of keys) {
38278
+ const v = env[k];
38279
+ if (typeof v === "string" && v.trim())
38280
+ out[k] = v;
38281
+ }
38282
+ return out;
38283
+ }
38091
38284
  function unknownModelEnv(model) {
38092
38285
  const id = (model ?? "").trim();
38093
38286
  if (!id || /^claude-/i.test(id))
@@ -38351,8 +38544,8 @@ function taskNotificationNotices(content) {
38351
38544
  }
38352
38545
  if (!text12.includes("<task-notification>"))
38353
38546
  return [];
38354
- const tag = (xml2, name) => {
38355
- const m = new RegExp(`<${name}>([\\s\\S]*?)</${name}>`).exec(xml2);
38547
+ const tag = (xml3, name) => {
38548
+ const m = new RegExp(`<${name}>([\\s\\S]*?)</${name}>`).exec(xml3);
38356
38549
  return m ? m[1].trim() : "";
38357
38550
  };
38358
38551
  const specs = [];
@@ -38641,6 +38834,12 @@ function withPinnedSource(sources, pinned) {
38641
38834
  return sources;
38642
38835
  return [...sources, pinned];
38643
38836
  }
38837
+ function isCompactionPrompt(prompt2) {
38838
+ const p = (prompt2 ?? "").trim();
38839
+ if (!p.startsWith("/compact"))
38840
+ return false;
38841
+ return p.length === "/compact".length || /^[\s\n]/.test(p.slice("/compact".length));
38842
+ }
38644
38843
  function buildMobileClause(dir2) {
38645
38844
  try {
38646
38845
  let fw = "";
@@ -38738,6 +38937,8 @@ var init_agent_manager = __esm({
38738
38937
  init_reinforced_verification();
38739
38938
  init_unattended_log();
38740
38939
  init_context_recovery();
38940
+ init_model_long_context();
38941
+ init_dist();
38741
38942
  init_dist();
38742
38943
  init_dist();
38743
38944
  init_base_paths();
@@ -39258,7 +39459,7 @@ var init_agent_manager = __esm({
39258
39459
  * doing it would spend two turns on one reclaim.
39259
39460
  */
39260
39461
  async maybeCompactProactively(live) {
39261
- const pct2 = (() => {
39462
+ const pct2 = live.autoCompactPct ?? (() => {
39262
39463
  try {
39263
39464
  return this.autoCompactPct?.();
39264
39465
  } catch {
@@ -39371,6 +39572,13 @@ var init_agent_manager = __esm({
39371
39572
  this.narrator.setConfig(cfg2);
39372
39573
  this.cheapLlm = cfg2?.complete ?? null;
39373
39574
  }
39575
+ /** The endpoint + credential this HOST runs agents against, for the manager's own
39576
+ * on-demand model calls (see summarizeSession). Injected by the host, which is the only
39577
+ * side that can resolve it — see host-core `daemonEngineEnv`. */
39578
+ hostEnv = null;
39579
+ setHostEnv(env) {
39580
+ this.hostEnv = env && Object.keys(env).length ? env : null;
39581
+ }
39374
39582
  /** Summarize a session transcript into concise Markdown with the injected cheap
39375
39583
  * (Haiku) model. Runs in the daemon — the desktop forwards the request rather
39376
39584
  * than calling a model itself. Keeps the HEAD + TAIL of a long transcript. */
@@ -39380,7 +39588,7 @@ var init_agent_manager = __esm({
39380
39588
  let llm = this.cheapLlm;
39381
39589
  if (!llm) {
39382
39590
  try {
39383
- llm = (await buildClaudeNarrationLlm())?.complete ?? null;
39591
+ llm = (await buildClaudeNarrationLlm(this.hostEnv ?? void 0))?.complete ?? null;
39384
39592
  } catch {
39385
39593
  }
39386
39594
  }
@@ -39577,7 +39785,15 @@ ${full.slice(-8e3)}`;
39577
39785
  }
39578
39786
  const todos = live.todos?.map((t) => ({ content: t.content, status: String(t.status) }));
39579
39787
  const call3 = gate === "review" ? reviewGrade(rv, finalText, todos) : gate === "phase" ? phaseGrade(rv, rv.lastVerdict?.phaseName ?? "", finalText, todos) : completenessGrade(rv, finalText, todos);
39580
- const raw = await llm({ model: live.model, system: call3.system, prompt: call3.prompt, maxTokens: 16e3, schema: call3.schema });
39788
+ const raw = await llm({
39789
+ model: live.model,
39790
+ system: call3.system,
39791
+ prompt: call3.prompt,
39792
+ maxTokens: 16e3,
39793
+ schema: call3.schema,
39794
+ // Grade THIS session on the endpoint it is running on — see live.endpointEnv.
39795
+ env: live.endpointEnv
39796
+ });
39581
39797
  if (live.rv !== rv || live.reaped) {
39582
39798
  if (live.reaped || live.rv === void 0) {
39583
39799
  emitVerification({ action: "done", gate, cycle: rv.cycles, maxCycles: RV_MAX_CYCLES, unavailable: "This run ended before it could be verified." });
@@ -39655,6 +39871,8 @@ ${full.slice(-8e3)}`;
39655
39871
  * and the 20-cycle cap silently stops capping anything. */
39656
39872
  applyTurnPolicy(live, p) {
39657
39873
  live.unattended = unattendedModeFor({ optedIn: p.unattended, origin: p.origin });
39874
+ if (p.autoCompactPct !== void 0)
39875
+ live.autoCompactPct = p.autoCompactPct;
39658
39876
  live.autoDecisions = 0;
39659
39877
  if (p.model !== void 0)
39660
39878
  live.model = p.model || void 0;
@@ -40361,7 +40579,7 @@ ${lines}`;
40361
40579
  if (opts.permissionMode)
40362
40580
  await live.query.setPermissionMode(opts.permissionMode);
40363
40581
  if (opts.model !== void 0) {
40364
- await live.query.setModel(opts.model || void 0);
40582
+ await live.query.setModel(sdkModelId(opts.model));
40365
40583
  live.model = opts.model || void 0;
40366
40584
  }
40367
40585
  if (opts.maxThinkingTokens !== void 0)
@@ -40481,7 +40699,7 @@ ${lines}`;
40481
40699
  live.windowId = params.windowId;
40482
40700
  live.pendingTitle = params.message.trim().slice(0, 80);
40483
40701
  if (params.model)
40484
- void live.query.setModel(params.model || void 0).catch(() => {
40702
+ void live.query.setModel(sdkModelId(params.model)).catch(() => {
40485
40703
  });
40486
40704
  if (params.permissionMode)
40487
40705
  void live.query.setPermissionMode(params.permissionMode).catch(() => {
@@ -40656,6 +40874,7 @@ ${prompt("agent.system.project-dir", { dir: projectDir })}` : "";
40656
40874
  windowId: params.windowId,
40657
40875
  sources: params.sources,
40658
40876
  unattended: params.unattended,
40877
+ autoCompactPct: params.autoCompactPct,
40659
40878
  reinforcedVerification: params.reinforcedVerification,
40660
40879
  task: params.message,
40661
40880
  rvInjected: params.rvInjected,
@@ -40721,12 +40940,17 @@ ${prompt("agent.system.project-dir", { dir: projectDir })}` : "";
40721
40940
  const lateDirective = live.unattendedReportSent ? "" : unattendedReportDirective(params);
40722
40941
  if (lateDirective)
40723
40942
  live.unattendedReportSent = true;
40943
+ const hostTurn = (params.autoContinuation || params.rvInjected) && !userText.trimStart().startsWith("/");
40724
40944
  const sdkMsg = {
40725
40945
  type: "user",
40726
40946
  parent_tool_use_id: null,
40727
- message: { role: "user", content: lateDirective ? `${userText}
40728
-
40729
- ${lateDirective}` : userText }
40947
+ // MARKED, so a client can show the user's own words and not the instruction we
40948
+ // appended to them — the engine writes this combined text into its transcript, so it
40949
+ // comes back on every resume (see shared/run-directive).
40950
+ message: {
40951
+ role: "user",
40952
+ content: lateDirective ? withRunDirective(userText, lateDirective) : hostTurn ? withRunDirective("", userText) : userText
40953
+ }
40730
40954
  };
40731
40955
  live.pump.push(sdkMsg);
40732
40956
  }
@@ -40841,14 +41065,19 @@ ${lateDirective}` : userText }
40841
41065
  // it. It only *permits* bypass — the active behavior is still governed by
40842
41066
  // permissionMode, so it's safe to set unconditionally.
40843
41067
  allowDangerouslySkipPermissions: true,
40844
- ...params.model ? { model: params.model } : {},
41068
+ // Suffixed for the long window where the family has one — see sdkModelId. Without
41069
+ // this the CLI reports a 200k window for a 1M model and compaction acts on a fill
41070
+ // that is up to five times too high.
41071
+ ...params.model ? { model: sdkModelId(params.model) } : {},
40845
41072
  // Clamp to what THIS CLI accepts — an unsupported level is a hard exit-1, not
40846
41073
  // a warning. See clampEffort.
40847
41074
  ...ultracodeEffort ? { effort: ultracodeEffort } : {},
40848
41075
  // Model-level fallback. Ours rotates CREDENTIALS on failure; this rotates the
40849
41076
  // MODEL before the turn fails at all, so an overloaded primary degrades instead
40850
41077
  // of surfacing an error the user has to act on.
40851
- ...params.fallbackModel ? { fallbackModel: params.fallbackModel } : {},
41078
+ // Same for the fallback: it REPLACES the main model on an overload, so a bare id here
41079
+ // would quietly move a long conversation onto a 200k window mid-run.
41080
+ ...params.fallbackModel ? { fallbackModel: sdkModelId(params.fallbackModel) } : {},
40852
41081
  ...params.enableFileCheckpointing ? { enableFileCheckpointing: true } : {},
40853
41082
  ...params.agentProgressSummaries ? { agentProgressSummaries: true } : {},
40854
41083
  ...params.includeHookEvents ? { includeHookEvents: true } : {},
@@ -41448,6 +41677,7 @@ ${lateDirective}` : userText }
41448
41677
  ...params.engineEnv ?? {},
41449
41678
  CCB_IPC_PORT: String(live.ipcPort)
41450
41679
  };
41680
+ live.endpointEnv = anthropicEnvOf(spawnEnv);
41451
41681
  const child = spawn3(options.command, options.args, {
41452
41682
  cwd: options.cwd,
41453
41683
  env: spawnEnv,
@@ -42489,6 +42719,11 @@ ${err2.stack}` : ""}` : String(err2);
42489
42719
  * the stream was actually alive. */
42490
42720
  touchStream(live, firstFrame = false) {
42491
42721
  live.lastFrameAt = monoNowMs();
42722
+ if (isCompactionPrompt(live.lastPrompt)) {
42723
+ live.stallWindowMs = void 0;
42724
+ this.clearStall(live);
42725
+ return;
42726
+ }
42492
42727
  const window2 = firstFrame ? STREAM_FIRST_FRAME_MS : STREAM_STALL_MS;
42493
42728
  live.stallWindowMs = window2;
42494
42729
  if (!live.streaming) {
@@ -42533,7 +42768,7 @@ ${err2.stack}` : ""}` : String(err2);
42533
42768
  this.armStall(live, decision.ms);
42534
42769
  return;
42535
42770
  }
42536
- log(`Stream stall: no frames for ${STREAM_STALL_MS}ms on session ${live.sessionId || "(pending)"} \u2014 killing the dead turn so it can be retried`);
42771
+ log(`Stream stall: no frames for ${live.stallWindowMs ?? STREAM_STALL_MS}ms on session ${live.sessionId || "(pending)"} \u2014 killing the dead turn so it can be retried`);
42537
42772
  live.stalled = true;
42538
42773
  this.hardKillSession(live);
42539
42774
  }
@@ -43989,10 +44224,10 @@ async function startHostedToolset(deps) {
43989
44224
  if (asyncTools) {
43990
44225
  try {
43991
44226
  hostedJobs = await Promise.resolve().then(() => (init_hosted_jobs(), hosted_jobs_exports));
43992
- const { tmpdir: tmpdir7 } = await import("node:os");
44227
+ const { tmpdir: tmpdir9 } = await import("node:os");
43993
44228
  const { join: joinPath3 } = await import("node:path");
43994
44229
  const made = hostedJobs.createHostedJobRegistry({
43995
- dir: joinPath3(tmpdir7(), "tesseract-hosted-jobs", randomUUID9()),
44230
+ dir: joinPath3(tmpdir9(), "tesseract-hosted-jobs", randomUUID9()),
43996
44231
  notifyModel: deps.notifyModel
43997
44232
  });
43998
44233
  jobs = made.registry;
@@ -44059,7 +44294,7 @@ async function startHostedToolset(deps) {
44059
44294
  await build();
44060
44295
  return { endpoint: endpoint2, sendBrowserResponse, tasks, refresh: build };
44061
44296
  }
44062
- function buildHostTaskTools(registry3, run5) {
44297
+ function buildHostTaskTools(registry3, run8) {
44063
44298
  const text12 = (t, isError = false) => ({ content: [{ type: "text", text: t }], ...isError ? { isError: true } : {} });
44064
44299
  return [
44065
44300
  {
@@ -44081,7 +44316,7 @@ function buildHostTaskTools(registry3, run5) {
44081
44316
  const task = registry3.start("subagent", description);
44082
44317
  task.messages.push({ role: "user", content: prompt2 });
44083
44318
  try {
44084
- const out = await run5(prompt2, { signal: task.abort.signal });
44319
+ const out = await run8(prompt2, { signal: task.abort.signal });
44085
44320
  if (task.status === "stopped")
44086
44321
  return text12(`Subagent "${description}" was stopped.`, true);
44087
44322
  task.status = "done";
@@ -78701,8 +78936,8 @@ var mesh_ca_exports = {};
78701
78936
  __export(mesh_ca_exports, {
78702
78937
  netCaCommand: () => netCaCommand
78703
78938
  });
78704
- import { chmodSync as chmodSync8, existsSync as existsSync44, mkdirSync as mkdirSync44, readFileSync as readFileSync50, writeFileSync as writeFileSync43 } from "node:fs";
78705
- import { join as join82, resolve as resolve13 } from "node:path";
78939
+ import { chmodSync as chmodSync8, existsSync as existsSync48, mkdirSync as mkdirSync44, readFileSync as readFileSync50, writeFileSync as writeFileSync45 } from "node:fs";
78940
+ import { join as join86, resolve as resolve13 } from "node:path";
78706
78941
  import { createInterface } from "node:readline";
78707
78942
  function die(msg) {
78708
78943
  console.error(msg);
@@ -78733,7 +78968,7 @@ async function readPassphrase(prompt2) {
78733
78968
  }
78734
78969
  }
78735
78970
  function writeSecretFile(p, bytes2) {
78736
- writeFileSync43(p, bytes2, { mode: 384 });
78971
+ writeFileSync45(p, bytes2, { mode: 384 });
78737
78972
  try {
78738
78973
  chmodSync8(p, 384);
78739
78974
  } catch {
@@ -78747,9 +78982,9 @@ function ensureDir(p) {
78747
78982
  }
78748
78983
  }
78749
78984
  async function openCa(dir2) {
78750
- const gPath = join82(dir2, "genesis.bin");
78751
- const sPath = join82(dir2, "ca.sealed");
78752
- if (!existsSync44(gPath) || !existsSync44(sPath)) {
78985
+ const gPath = join86(dir2, "genesis.bin");
78986
+ const sPath = join86(dir2, "ca.sealed");
78987
+ if (!existsSync48(gPath) || !existsSync48(sPath)) {
78753
78988
  die(`No mesh CA in ${dir2}. Run: tesseract-agent net init --org NAME --ca-dir ${dir2}`);
78754
78989
  }
78755
78990
  const genesisBytes = new Uint8Array(readFileSync50(gPath));
@@ -78770,7 +79005,7 @@ async function netCaCommand(rest, flags) {
78770
79005
  if (sub === "init") {
78771
79006
  const org = typeof flags.org === "string" ? flags.org.trim() : "";
78772
79007
  if (!org) die("Usage: tesseract-agent net init --org NAME [--ca-dir DIR]");
78773
- if (existsSync44(join82(caDir, "ca.sealed"))) {
79008
+ if (existsSync48(join86(caDir, "ca.sealed"))) {
78774
79009
  die(`A mesh CA already exists in ${caDir}. Refusing to overwrite it.`);
78775
79010
  }
78776
79011
  const pass = await readPassphrase("New CA passphrase: ");
@@ -78792,9 +79027,9 @@ async function netCaCommand(rest, flags) {
78792
79027
  const genesisBytes = encodeGenesis(genesis);
78793
79028
  const fp = await genesisFingerprint(genesis);
78794
79029
  ensureDir(caDir);
78795
- writeFileSync43(join82(caDir, "genesis.bin"), genesisBytes);
78796
- writeSecretFile(join82(caDir, "ca.sealed"), encodeRecoveryBundle(await sealCaKey(seed, pass, `${org} mesh CA`)));
78797
- writeSecretFile(join82(caDir, "disablement.secret"), hex3(disable.secret));
79030
+ writeFileSync45(join86(caDir, "genesis.bin"), genesisBytes);
79031
+ writeSecretFile(join86(caDir, "ca.sealed"), encodeRecoveryBundle(await sealCaKey(seed, pass, `${org} mesh CA`)));
79032
+ writeSecretFile(join86(caDir, "disablement.secret"), hex3(disable.secret));
78798
79033
  console.log(`
78799
79034
  Mesh created for "${org}".`);
78800
79035
  console.log(` fingerprint: ${hex3(fp)}`);
@@ -78809,7 +79044,7 @@ Mesh created for "${org}".`);
78809
79044
  console.log(` ${hex3(disable.secret)}`);
78810
79045
  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");
78811
79046
  console.log(`
78812
- A copy of the disablement secret is in ${join82(caDir, "disablement.secret")}.`);
79047
+ A copy of the disablement secret is in ${join86(caDir, "disablement.secret")}.`);
78813
79048
  console.log("Move it somewhere the CA directory is not \u2014 holding both in one place");
78814
79049
  console.log("defeats the point of having two.");
78815
79050
  const caFlag = caDir === resolve13("./mesh-ca") ? "" : ` --ca-dir ${caDir}`;
@@ -78862,14 +79097,14 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
78862
79097
  [{ keyIndex: 0, privateKey: ca.privateKey }]
78863
79098
  );
78864
79099
  ensureDir(outDir);
78865
- writeFileSync43(join82(outDir, "genesis.bin"), genesisBytes);
78866
- writeFileSync43(join82(outDir, "node.cert"), encodeCert(cert));
78867
- writeSecretFile(join82(outDir, "node.key"), await exportStaticPrivate(nodeKey));
79100
+ writeFileSync45(join86(outDir, "genesis.bin"), genesisBytes);
79101
+ writeFileSync45(join86(outDir, "node.cert"), encodeCert(cert));
79102
+ writeSecretFile(join86(outDir, "node.key"), await exportStaticPrivate(nodeKey));
78868
79103
  console.log(`Minted "${name}" at ${ip4}.`);
78869
79104
  console.log(` ${outDir}`);
78870
79105
  console.log("\nCopy that directory to the node and run there:");
78871
- console.log(` tesseract-agent net enroll --genesis ${join82(outDir, "genesis.bin")} \\`);
78872
- console.log(` --cert ${join82(outDir, "node.cert")} --key ${join82(outDir, "node.key")}`);
79106
+ console.log(` tesseract-agent net enroll --genesis ${join86(outDir, "genesis.bin")} \\`);
79107
+ console.log(` --cert ${join86(outDir, "node.cert")} --key ${join86(outDir, "node.key")}`);
78873
79108
  console.log("\nnode.key is the node's identity \u2014 send it over a channel you trust, and");
78874
79109
  console.log("delete this copy once the node has it.");
78875
79110
  return;
@@ -78905,8 +79140,8 @@ Next, issue an identity for a machine (pick a free address in ${formatPrefix(gen
78905
79140
  ip4Exceptions: []
78906
79141
  };
78907
79142
  const signed = await signBundle(bundle, [{ keyIndex: 0, privateKey: ca.privateKey }]);
78908
- const out = resolve13(typeof flags.out === "string" ? flags.out : join82(caDir, "bundle.bin"));
78909
- writeFileSync43(out, encodeSignedBundle(signed));
79143
+ const out = resolve13(typeof flags.out === "string" ? flags.out : join86(caDir, "bundle.bin"));
79144
+ writeFileSync45(out, encodeSignedBundle(signed));
78910
79145
  console.log(`Signed policy bundle (epoch ${epoch2}) \u2192 ${out}`);
78911
79146
  console.log("Every node must receive it; the relay distributes it, or copy it to");
78912
79147
  console.log(`each node's mesh directory as bundle.bin.`);
@@ -78928,12 +79163,12 @@ var init_mesh_ca = __esm({
78928
79163
 
78929
79164
  // src/cli.ts
78930
79165
  init_base_paths();
78931
- import { existsSync as existsSync45, mkdtempSync as mkdtempSync2, readFileSync as readFileSync52, rmSync as rmSync11 } from "node:fs";
79166
+ import { existsSync as existsSync49, mkdtempSync as mkdtempSync4, readFileSync as readFileSync52, rmSync as rmSync13 } from "node:fs";
78932
79167
  import { createHash as createHash9 } from "node:crypto";
78933
- import { execFileSync as execFileSync6, spawn as spawn11 } from "node:child_process";
78934
- import { fileURLToPath as fileURLToPath7 } from "node:url";
78935
- import { tmpdir as tmpdir6 } from "node:os";
78936
- import { dirname as dirname36, join as join83, resolve as resolve15 } from "node:path";
79168
+ import { execFileSync as execFileSync6, spawn as spawn14 } from "node:child_process";
79169
+ import { fileURLToPath as fileURLToPath8 } from "node:url";
79170
+ import { tmpdir as tmpdir8 } from "node:os";
79171
+ import { dirname as dirname38, join as join87, resolve as resolve15 } from "node:path";
78937
79172
  import { createInterface as createInterface2 } from "node:readline/promises";
78938
79173
 
78939
79174
  // ../../packages/host-core/dist/control-link.js
@@ -80492,6 +80727,7 @@ async function createClaudeCodeBackend(send4, onBrowserRequest, loadPluginRuntim
80492
80727
  respondToPermission: (requestId, decision, callerOrigin) => manager2.respondToPermission(requestId, decision, callerOrigin),
80493
80728
  setNarrationLlm: (cfg2) => manager2.setNarrationLlm(cfg2),
80494
80729
  setVerifierLlm: (fn) => manager2.setVerifierLlm(fn),
80730
+ setHostEnv: (env) => manager2.setHostEnv(env),
80495
80731
  setImageGen: (runner3) => manager2.setImageGen(runner3),
80496
80732
  setSerpApi: (deps) => manager2.setSerpApi(deps),
80497
80733
  setVideoGen: (runner3) => manager2.setVideoGen(runner3),
@@ -81796,9 +82032,9 @@ function resolveBundledMcpBin(basename14, envOverride) {
81796
82032
  if (cached3 !== void 0)
81797
82033
  return cached3;
81798
82034
  const candidates = [];
81799
- const override2 = envOverride ? process.env[envOverride] : void 0;
81800
- if (override2)
81801
- candidates.push(override2);
82035
+ const override3 = envOverride ? process.env[envOverride] : void 0;
82036
+ if (override3)
82037
+ candidates.push(override3);
81802
82038
  const rp = process.resourcesPath;
81803
82039
  if (rp)
81804
82040
  candidates.push(join26(rp, "host-daemon", basename14));
@@ -83076,7 +83312,7 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
83076
83312
  return;
83077
83313
  return sendMessage({ ...prev, message, sessionId: sid, autoContinuation: true });
83078
83314
  },
83079
- log: (m) => console.warn(`[${LABEL2}] ${m}`)
83315
+ log: (m) => console.warn(`[${LABEL3}] ${m}`)
83080
83316
  });
83081
83317
  return noticeDispatcher;
83082
83318
  };
@@ -83298,7 +83534,7 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
83298
83534
  ...cappedOut ? { cappedOut: true } : {}
83299
83535
  }, turn.origin);
83300
83536
  },
83301
- log: (m, e) => console.warn(`[${LABEL2}] ${m}`, e ?? "")
83537
+ log: (m, e) => console.warn(`[${LABEL3}] ${m}`, e ?? "")
83302
83538
  });
83303
83539
  });
83304
83540
  }
@@ -83536,7 +83772,7 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
83536
83772
  ...cappedOut ? { cappedOut: true } : {}
83537
83773
  }, turn.origin);
83538
83774
  },
83539
- log: (m, e) => console.warn(`[${LABEL2}] ${m}`, e ?? "")
83775
+ log: (m, e) => console.warn(`[${LABEL3}] ${m}`, e ?? "")
83540
83776
  });
83541
83777
  });
83542
83778
  });
@@ -83589,13 +83825,13 @@ function createAcpBackend(engine, send4, resolve16, onBrowserRequest, loadPlugin
83589
83825
  agentMcp = agentCaps?.mcpCapabilities;
83590
83826
  const authed = await withTimeout2(authenticateIfOffered(t, init?.authMethods), AUTH_TIMEOUT_MS, `${engine.label} did not finish authenticating.`).catch(() => false);
83591
83827
  if (init?.authMethods?.length && !authed) {
83592
- console.warn(`[${LABEL2}] no authentication method was accepted; session/load and resume may fail.`);
83828
+ console.warn(`[${LABEL3}] no authentication method was accepted; session/load and resume may fail.`);
83593
83829
  }
83594
83830
  if (apiPort) {
83595
83831
  const api = createEngineHttpApi(apiPort, engine.httpApi?.host ?? "127.0.0.1");
83596
83832
  httpApi = await api.ready() ? api : null;
83597
83833
  if (!httpApi)
83598
- console.warn(`[${LABEL2}] its HTTP API did not come up on ${apiPort}; using the ACP path only.`);
83834
+ console.warn(`[${LABEL3}] its HTTP API did not come up on ${apiPort}; using the ACP path only.`);
83599
83835
  }
83600
83836
  } catch (e) {
83601
83837
  try {
@@ -83942,7 +84178,9 @@ ${text12}`);
83942
84178
  const usage2 = contextUsageFor(live);
83943
84179
  const verdict = shouldCompactProactively({
83944
84180
  mode: unattendedModeFor({ optedIn: params.unattended, origin: params.origin }),
83945
- pct: readDaemonAgentSettings().autoCompactPct,
84181
+ // The conversation's own threshold when its client sent one (per-conversation there),
84182
+ // else the machine-wide setting.
84183
+ pct: params.autoCompactPct ?? readDaemonAgentSettings().autoCompactPct,
83946
84184
  usagePct: typeof usage2?.percentage === "number" ? usage2.percentage : null,
83947
84185
  lastCompactPct: proactiveCompactedAt.get(live) ?? null,
83948
84186
  inFlight: false
@@ -83954,7 +84192,7 @@ ${text12}`);
83954
84192
  if (verdict !== "compact")
83955
84193
  return;
83956
84194
  proactiveCompactedAt.set(live, usage2?.percentage ?? 0);
83957
- console.warn(`[${LABEL2}] auto-compact: ${Math.round(usage2?.percentage ?? 0)}% of the window used \u2014 compacting`);
84195
+ console.warn(`[${LABEL3}] auto-compact: ${Math.round(usage2?.percentage ?? 0)}% of the window used \u2014 compacting`);
83958
84196
  await sendMessage({ ...params, message: OVERFLOW_COMPACT_MESSAGE, sessionId: live, autoContinuation: true });
83959
84197
  const now2 = sessionRekey.get(live) ?? live;
83960
84198
  if (now2 !== live) {
@@ -83962,7 +84200,7 @@ ${text12}`);
83962
84200
  proactiveCompactedAt.delete(live);
83963
84201
  }
83964
84202
  } catch (err2) {
83965
- console.warn(`[${LABEL2}] auto-compact failed:`, err2 instanceof Error ? err2.message : String(err2));
84203
+ console.warn(`[${LABEL3}] auto-compact failed:`, err2 instanceof Error ? err2.message : String(err2));
83966
84204
  }
83967
84205
  }
83968
84206
  async function sendMessage(params) {
@@ -84281,7 +84519,7 @@ ${detail}` : detail, !overflow);
84281
84519
  }
84282
84520
  }
84283
84521
  const declared = declaredCaps;
84284
- const LABEL2 = engine.label;
84522
+ const LABEL3 = engine.label;
84285
84523
  let hostedBoot = null;
84286
84524
  async function ensureHostedToolset() {
84287
84525
  if (!declared.toolInjection || hostedEndpoint)
@@ -84313,7 +84551,7 @@ ${detail}` : detail, !overflow);
84313
84551
  // own permission gate, and it cannot disturb the parent's turn state.
84314
84552
  runSubagent: async (prompt2, { signal }) => {
84315
84553
  if (!transport || !spawnedCwd)
84316
- throw new Error(`${LABEL2} is not running.`);
84554
+ throw new Error(`${LABEL3} is not running.`);
84317
84555
  const res = await transport.request("session/new", { cwd: spawnedCwd, mcpServers: [] });
84318
84556
  const sub = res?.sessionId;
84319
84557
  if (!sub)
@@ -84340,7 +84578,7 @@ ${detail}` : detail, !overflow);
84340
84578
  hostTasks = ht.tasks;
84341
84579
  refreshHostedTools = ht.refresh;
84342
84580
  } catch (e) {
84343
- console.warn(`[${LABEL2}] host toolset unavailable:`, e);
84581
+ console.warn(`[${LABEL3}] host toolset unavailable:`, e);
84344
84582
  }
84345
84583
  })();
84346
84584
  await hostedBoot;
@@ -85155,7 +85393,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
85155
85393
  const HOSTED_TOKEN_ENV = "TESSERACT_MCP_TOKEN";
85156
85394
  const label = engineById(ENGINE_ID2)?.label ?? "Codex";
85157
85395
  const declared = engineById(ENGINE_ID2)?.capabilities ?? {};
85158
- const LABEL2 = label;
85396
+ const LABEL3 = label;
85159
85397
  const lastSendParams = /* @__PURE__ */ new Map();
85160
85398
  let noticeDispatcher = null;
85161
85399
  const jobNotices = () => {
@@ -85243,7 +85481,7 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
85243
85481
  hostTasks = ht.tasks;
85244
85482
  refreshHostedTools = ht.refresh;
85245
85483
  } catch (e) {
85246
- console.warn(`[${LABEL2}] host toolset unavailable:`, e);
85484
+ console.warn(`[${LABEL3}] host toolset unavailable:`, e);
85247
85485
  }
85248
85486
  })();
85249
85487
  await hostedBoot;
@@ -85769,7 +86007,9 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
85769
86007
  const usage2 = contextUsageFor(threadId);
85770
86008
  const verdict = shouldCompactProactively({
85771
86009
  mode: unattendedModeFor({ optedIn: params.unattended, origin: params.origin }),
85772
- pct: readDaemonAgentSettings().autoCompactPct,
86010
+ // The conversation's own threshold when its client sent one (per-conversation there),
86011
+ // else the machine-wide setting.
86012
+ pct: params.autoCompactPct ?? readDaemonAgentSettings().autoCompactPct,
85773
86013
  usagePct: typeof usage2?.percentage === "number" ? usage2.percentage : null,
85774
86014
  lastCompactPct: proactiveCompactedAt.get(threadId) ?? null,
85775
86015
  inFlight: false
@@ -85781,10 +86021,10 @@ function createCodexAppServerBackend(send4, resolve16, onBrowserRequest, loadPlu
85781
86021
  if (verdict !== "compact")
85782
86022
  return;
85783
86023
  proactiveCompactedAt.set(threadId, usage2?.percentage ?? 0);
85784
- console.warn(`[${LABEL2}] auto-compact: ${Math.round(usage2?.percentage ?? 0)}% of the window used \u2014 compacting`);
86024
+ console.warn(`[${LABEL3}] auto-compact: ${Math.round(usage2?.percentage ?? 0)}% of the window used \u2014 compacting`);
85785
86025
  await sendMessage({ ...params, message: OVERFLOW_COMPACT_MESSAGE, sessionId: threadId, autoContinuation: true });
85786
86026
  } catch (err2) {
85787
- console.warn(`[${LABEL2}] auto-compact failed:`, err2 instanceof Error ? err2.message : String(err2));
86027
+ console.warn(`[${LABEL3}] auto-compact failed:`, err2 instanceof Error ? err2.message : String(err2));
85788
86028
  }
85789
86029
  }
85790
86030
  async function sendMessage(params) {
@@ -87243,8 +87483,8 @@ var pluginTtsProviders = [];
87243
87483
  var loadedGeneration = [];
87244
87484
  var loadQueue = Promise.resolve();
87245
87485
  function loadPluginRuntime(opts) {
87246
- const run5 = () => loadPluginRuntimeSerial(opts);
87247
- const next = loadQueue.then(run5, run5);
87486
+ const run8 = () => loadPluginRuntimeSerial(opts);
87487
+ const next = loadQueue.then(run8, run8);
87248
87488
  loadQueue = next.catch(() => void 0);
87249
87489
  return next;
87250
87490
  }
@@ -89957,7 +90197,7 @@ var VoiceControl = class {
89957
90197
  };
89958
90198
  let llm = null;
89959
90199
  try {
89960
- const cfg2 = await buildClaudeNarrationLlm();
90200
+ const cfg2 = await buildClaudeNarrationLlm(daemonEngineEnv());
89961
90201
  llm = cfg2?.complete ?? null;
89962
90202
  } catch {
89963
90203
  }
@@ -90164,17 +90404,17 @@ async function launchCompanionBrowser() {
90164
90404
  if (!first) {
90165
90405
  throw new Error('No browser on this machine has the Tesseract Companion extension installed, so there is nothing to drive. Install the Companion in Chrome (or another Chromium browser), or use target:"internal" to use the browser inside Tesseract.');
90166
90406
  }
90167
- const { execFile: execFile11 } = await import("node:child_process");
90168
- const run5 = (cmd, args) => new Promise((resolve16, reject) => {
90169
- execFile11(cmd, args, { timeout: 15e3 }, (err2) => err2 ? reject(err2) : resolve16());
90407
+ const { execFile: execFile15 } = await import("node:child_process");
90408
+ const run8 = (cmd, args) => new Promise((resolve16, reject) => {
90409
+ execFile15(cmd, args, { timeout: 15e3 }, (err2) => err2 ? reject(err2) : resolve16());
90170
90410
  });
90171
90411
  try {
90172
90412
  if (process.platform === "darwin")
90173
- await run5("open", ["-a", first.launch]);
90413
+ await run8("open", ["-a", first.launch]);
90174
90414
  else if (process.platform === "win32")
90175
- await run5("cmd", ["/c", "start", "", first.launch]);
90415
+ await run8("cmd", ["/c", "start", "", first.launch]);
90176
90416
  else
90177
- await run5(first.launch, []);
90417
+ await run8(first.launch, []);
90178
90418
  } catch (err2) {
90179
90419
  throw new Error(`Could not start ${first.name}: ${err2 instanceof Error ? err2.message : String(err2)}`);
90180
90420
  }
@@ -91434,10 +91674,10 @@ function buildEnhanceChain(spec) {
91434
91674
  steps.push(`upscale\xD7${f}`);
91435
91675
  resizes = true;
91436
91676
  }
91437
- const sh = spec.sharpen ?? "light";
91438
- if (sh !== "none") {
91439
- parts.push(`cas=strength=${SHARPEN[sh]}`);
91440
- steps.push(`sharpen:${sh}`);
91677
+ const sh3 = spec.sharpen ?? "light";
91678
+ if (sh3 !== "none") {
91679
+ parts.push(`cas=strength=${SHARPEN[sh3]}`);
91680
+ steps.push(`sharpen:${sh3}`);
91441
91681
  }
91442
91682
  if (spec.deband) {
91443
91683
  parts.push("deband");
@@ -92368,11 +92608,11 @@ function pickProvider(c) {
92368
92608
  return null;
92369
92609
  }
92370
92610
  function modelFor(id, pc, quality) {
92371
- const override2 = pc.model?.trim();
92611
+ const override3 = pc.model?.trim();
92372
92612
  if (id === "tesseract")
92373
- return override2 || FREE_MODEL;
92374
- if (override2)
92375
- return override2;
92613
+ return override3 || FREE_MODEL;
92614
+ if (override3)
92615
+ return override3;
92376
92616
  return quality === "standard" ? STANDARD_MODEL : FAST_MODEL;
92377
92617
  }
92378
92618
  function estimateFor(id, model, durationSec) {
@@ -93212,8 +93452,8 @@ async function falTopazEnhance(path6, spec, opts) {
93212
93452
  const dir2 = opts.outDir ?? workDir();
93213
93453
  mkdirSync21(dir2, { recursive: true });
93214
93454
  const outPath = join42(dir2, "enhanced.mp4");
93215
- const { writeFileSync: writeFileSync44 } = await import("node:fs");
93216
- writeFileSync44(outPath, Buffer.from(await dl.arrayBuffer()));
93455
+ const { writeFileSync: writeFileSync46 } = await import("node:fs");
93456
+ writeFileSync46(outPath, Buffer.from(await dl.arrayBuffer()));
93217
93457
  const out = await probeMedia(outPath).catch(() => null);
93218
93458
  opts.onProgress?.(100, "Enhance complete");
93219
93459
  return { path: outPath, mime: MIME, width: out?.width ?? null, height: out?.height ?? null, durationSec: out?.durationSec ?? p.durationSec, summary: `fal Topaz ${spec.model ?? "Proteus"} \xD7${spec.upscaleFactor ?? 2}` };
@@ -95048,17 +95288,25 @@ function buildSharedBackend(engineId) {
95048
95288
  return b;
95049
95289
  backend = b;
95050
95290
  refreshDaemonScheduling(b);
95051
- void buildClaudeNarrationLlm().then((cfg2) => {
95291
+ const runnerEnv = (() => {
95292
+ try {
95293
+ return daemonEngineEnv();
95294
+ } catch {
95295
+ return void 0;
95296
+ }
95297
+ })();
95298
+ b.setHostEnv?.(runnerEnv ?? null);
95299
+ void buildClaudeNarrationLlm(runnerEnv).then((cfg2) => {
95052
95300
  if (cfg2) {
95053
95301
  b.setNarrationLlm?.(cfg2);
95054
- log("narration: enabled (Claude Haiku)");
95302
+ log(`narration: enabled (${runnerEnv?.ANTHROPIC_BASE_URL ?? "api.anthropic.com"})`);
95055
95303
  } else
95056
95304
  log("narration: disabled \u2014 no Claude creds resolved");
95057
95305
  }).catch((e) => log("narration: setup failed:", e instanceof Error ? e.message : String(e)));
95058
- void buildClaudeSmartLlm().then((fn) => {
95306
+ void buildClaudeSmartLlm(runnerEnv).then((fn) => {
95059
95307
  if (fn) {
95060
95308
  b.setVerifierLlm?.(fn);
95061
- log("reinforced-verification: grader enabled");
95309
+ log(`reinforced-verification: grader enabled (${runnerEnv?.ANTHROPIC_BASE_URL ?? "api.anthropic.com"})`);
95062
95310
  } else
95063
95311
  log("reinforced-verification: disabled \u2014 no Claude creds resolved");
95064
95312
  }).catch((e) => log("reinforced-verification: setup failed:", e instanceof Error ? e.message : String(e)));
@@ -98827,9 +99075,9 @@ var NodeFsHandler = class {
98827
99075
  if (this.fsw.closed) {
98828
99076
  return;
98829
99077
  }
98830
- const dirname37 = sysPath.dirname(file2);
99078
+ const dirname39 = sysPath.dirname(file2);
98831
99079
  const basename14 = sysPath.basename(file2);
98832
- const parent = this.fsw._getWatchedDir(dirname37);
99080
+ const parent = this.fsw._getWatchedDir(dirname39);
98833
99081
  let prevStats = stats;
98834
99082
  if (parent.has(basename14))
98835
99083
  return;
@@ -98856,7 +99104,7 @@ var NodeFsHandler = class {
98856
99104
  prevStats = newStats2;
98857
99105
  }
98858
99106
  } catch (error51) {
98859
- this.fsw._remove(dirname37, basename14);
99107
+ this.fsw._remove(dirname39, basename14);
98860
99108
  }
98861
99109
  } else if (parent.has(basename14)) {
98862
99110
  const at = newStats.atimeMs;
@@ -103299,8 +103547,8 @@ async function wakeDisplay(log9) {
103299
103547
  if (process.platform !== "darwin")
103300
103548
  return;
103301
103549
  try {
103302
- const { spawn: spawn12 } = await import("node:child_process");
103303
- spawn12("caffeinate", ["-u", "-t", "5"], { detached: true, stdio: "ignore" }).unref();
103550
+ const { spawn: spawn15 } = await import("node:child_process");
103551
+ spawn15("caffeinate", ["-u", "-t", "5"], { detached: true, stdio: "ignore" }).unref();
103304
103552
  log9?.("display was asleep \u2014 declared user activity to wake it");
103305
103553
  await new Promise((r) => setTimeout(r, 1200));
103306
103554
  } catch {
@@ -104136,9 +104384,9 @@ function hasRdeskPassword() {
104136
104384
  function verifyRdeskPassword(password) {
104137
104385
  if (!password)
104138
104386
  return false;
104139
- const override2 = process.env.CCB_RDESK_PASSWORD;
104140
- if (override2)
104141
- return password.length === override2.length && timingSafeEqual4(Buffer.from(password), Buffer.from(override2));
104387
+ const override3 = process.env.CCB_RDESK_PASSWORD;
104388
+ if (override3)
104389
+ return password.length === override3.length && timingSafeEqual4(Buffer.from(password), Buffer.from(override3));
104142
104390
  try {
104143
104391
  const { salt, hash: hash2 } = JSON.parse(readFileSync40(pwFile(), "utf8"));
104144
104392
  const got = scryptSync(password, Buffer.from(salt, "hex"), 32);
@@ -107563,6 +107811,16 @@ var LanDiscovery = class {
107563
107811
  var _a3;
107564
107812
  var requireCjs = createRequire4(import.meta.url);
107565
107813
  function loadMeshCore() {
107814
+ for (const spec of [
107815
+ "@fineguide-tesseract/mesh-core",
107816
+ "./mesh-core/index.js",
107817
+ "../mesh-core/index.js"
107818
+ ]) {
107819
+ try {
107820
+ return requireCjs(spec);
107821
+ } catch {
107822
+ }
107823
+ }
107566
107824
  try {
107567
107825
  return requireCjs("@fineguide-tesseract/mesh-core");
107568
107826
  } catch (e) {
@@ -109475,12 +109733,12 @@ function watchForIdentity(deps) {
109475
109733
  const wait = Math.min(max, Math.round(delay3 * (1 + (random() * 2 - 1) * JITTER)));
109476
109734
  timer2 = setTimeout(() => {
109477
109735
  timer2 = null;
109478
- void run5("backoff");
109736
+ void run8("backoff");
109479
109737
  }, wait);
109480
109738
  timer2.unref?.();
109481
109739
  delay3 = Math.min(max, Math.round(delay3 * FACTOR));
109482
109740
  };
109483
- async function run5(reason) {
109741
+ async function run8(reason) {
109484
109742
  if (stopped2 || settled || inFlight2)
109485
109743
  return;
109486
109744
  inFlight2 = true;
@@ -109512,10 +109770,10 @@ function watchForIdentity(deps) {
109512
109770
  return;
109513
109771
  delay3 = first;
109514
109772
  clear();
109515
- void run5(reason);
109773
+ void run8(reason);
109516
109774
  };
109517
109775
  unsubscribe = (deps.subscribe ?? subscribeToWakeSignals)(nudge);
109518
- void run5("boot");
109776
+ void run8("boot");
109519
109777
  return {
109520
109778
  ready,
109521
109779
  nudge,
@@ -112114,9 +112372,8 @@ function meshIdOf(cert) {
112114
112372
  // ../../packages/host-core/dist/mesh/full-tunnel.js
112115
112373
  function fullTunnelState(i) {
112116
112374
  const no2 = (reason) => ({ allowed: false, reason, warnings: [] });
112117
- if (i.platform !== "linux") {
112118
- const name = i.platform === "darwin" ? "macOS" : i.platform === "win32" ? "Windows" : i.platform;
112119
- return no2(`Routing all traffic needs the network helper, which does not exist on ${name} yet.`);
112375
+ if (i.platform !== "linux" && i.platform !== "darwin" && i.platform !== "win32") {
112376
+ return no2(`Routing all traffic needs the network helper, which does not exist on ${i.platform} yet.`);
112120
112377
  }
112121
112378
  if (!i.engineAvailable) {
112122
112379
  return no2("This build shipped without the network engine, so no traffic can be routed. That is a packaging fault \u2014 please report it.");
@@ -112169,21 +112426,685 @@ function bundleGrantsExitNode(bundle) {
112169
112426
  // ../../packages/host-core/dist/mesh/machine-owner.js
112170
112427
  init_credentials();
112171
112428
 
112172
- // ../../packages/host-core/dist/service/exec.js
112173
- import { execFile as execFile10, spawn as spawn9 } from "node:child_process";
112429
+ // ../../packages/host-core/dist/net-service/ensure-installed.js
112430
+ import { execFile as execFile14 } from "node:child_process";
112431
+ import { existsSync as existsSync42 } from "node:fs";
112432
+ import { dirname as dirname34, join as join80 } from "node:path";
112433
+ import { promisify as promisify10 } from "node:util";
112434
+
112435
+ // ../../packages/host-core/dist/net-service/launchd-system.js
112436
+ import { spawn as spawn9 } from "node:child_process";
112437
+ import { existsSync as existsSync39, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync40, rmSync as rmSync10 } from "node:fs";
112438
+ import { tmpdir as tmpdir6 } from "node:os";
112439
+ import { join as join77 } from "node:path";
112440
+
112441
+ // ../../packages/host-core/dist/net-service/elevation.js
112442
+ import { execFile as execFile10 } from "node:child_process";
112174
112443
  import { promisify as promisify6 } from "node:util";
112175
112444
  var run4 = promisify6(execFile10);
112176
- function runInherit(cmd, args) {
112445
+ async function alreadyElevated() {
112446
+ if (process.platform === "win32") {
112447
+ try {
112448
+ const { stdout } = await run4("powershell.exe", [
112449
+ "-NoProfile",
112450
+ "-Command",
112451
+ "(New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"
112452
+ ]);
112453
+ return String(stdout).trim().toLowerCase() === "true";
112454
+ } catch {
112455
+ return false;
112456
+ }
112457
+ }
112458
+ return typeof process.getuid === "function" && process.getuid() === 0;
112459
+ }
112460
+
112461
+ // ../../packages/host-core/dist/net-service/launchd-system.js
112462
+ var LABEL2 = "dev.tesseract.netd";
112463
+ var PLIST = `/Library/LaunchDaemons/${LABEL2}.plist`;
112464
+ function xml(s) {
112465
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
112466
+ }
112467
+ function sh(s) {
112468
+ return `'${s.replace(/'/g, `'\\''`)}'`;
112469
+ }
112470
+ function buildPlist(spec) {
112471
+ const argv = [
112472
+ spec.exec,
112473
+ "--state-dir",
112474
+ spec.stateDir,
112475
+ "--socket",
112476
+ spec.socket,
112477
+ "--owner-uid",
112478
+ String(spec.ownerUid)
112479
+ ];
112480
+ const args = argv.map((a) => ` <string>${xml(a)}</string>`).join("\n");
112481
+ return `<?xml version="1.0" encoding="UTF-8"?>
112482
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
112483
+ <plist version="1.0">
112484
+ <dict>
112485
+ <key>Label</key>
112486
+ <string>${LABEL2}</string>
112487
+ <key>ProgramArguments</key>
112488
+ <array>
112489
+ ${args}
112490
+ </array>
112491
+ <key>RunAtLoad</key>
112492
+ <true/>
112493
+ <!-- on-failure only, exactly like systemd's Restart=on-failure: a helper that exits 0
112494
+ has been asked to stop, and restarting it would fight the operator. -->
112495
+ <key>KeepAlive</key>
112496
+ <dict>
112497
+ <key>SuccessfulExit</key>
112498
+ <false/>
112499
+ </dict>
112500
+ <!-- launchd has no equivalent of systemd's StartLimitBurst, so a PERMANENT failure \u2014
112501
+ netd refusing to start on an unreadable journal \u2014 respawns forever rather than
112502
+ landing in a failed state. 30s keeps that out of the log and off the CPU; the
112503
+ remedy is still 'net doctor', which reads the real table. -->
112504
+ <key>ThrottleInterval</key>
112505
+ <integer>30</integer>
112506
+ <key>ProcessType</key>
112507
+ <string>Interactive</string>
112508
+ <key>StandardErrorPath</key>
112509
+ <string>${xml(join77(spec.stateDir, "netd.log"))}</string>
112510
+ <key>StandardOutPath</key>
112511
+ <string>${xml(join77(spec.stateDir, "netd.log"))}</string>
112512
+ </dict>
112513
+ </plist>
112514
+ `;
112515
+ }
112516
+ function runForCode(cmd, args) {
112177
112517
  return new Promise((resolve16) => {
112178
112518
  const p = spawn9(cmd, args, { stdio: "inherit" });
112519
+ p.on("error", () => resolve16(127));
112520
+ p.on("close", (code) => resolve16(code ?? 1));
112521
+ });
112522
+ }
112523
+ async function elevate(script) {
112524
+ const dir2 = mkdtempSync2(join77(tmpdir6(), "tesseract-netd-"));
112525
+ const path6 = join77(dir2, "install.sh");
112526
+ try {
112527
+ writeFileSync40(path6, script, { mode: 384 });
112528
+ if (await alreadyElevated()) {
112529
+ return { code: await runForCode("/bin/sh", [path6]), declined: false };
112530
+ }
112531
+ const code = await runForCode("osascript", [
112532
+ "-e",
112533
+ `do shell script "/bin/sh " & quoted form of "${path6}" with administrator privileges`
112534
+ ]);
112535
+ return { code, declined: code === 1 };
112536
+ } finally {
112537
+ try {
112538
+ rmSync10(dir2, { recursive: true, force: true });
112539
+ } catch {
112540
+ }
112541
+ }
112542
+ }
112543
+ function makeLaunchDaemon() {
112544
+ return {
112545
+ supported: process.platform === "darwin",
112546
+ async install(spec) {
112547
+ const plist = buildPlist(spec);
112548
+ const script = [
112549
+ "set -e",
112550
+ `/usr/bin/install -d -m 0700 -o root -g wheel ${sh(spec.stateDir)}`,
112551
+ `cat > ${sh(PLIST)} <<'TESSERACT_PLIST_EOF'
112552
+ ${plist}TESSERACT_PLIST_EOF`,
112553
+ // launchd REFUSES to load a plist that is group- or world-writable, and says so in
112554
+ // a way that reads as a permissions problem with the binary rather than the file.
112555
+ `chown root:wheel ${sh(PLIST)}`,
112556
+ `chmod 644 ${sh(PLIST)}`,
112557
+ // bootout first so a reinstall replaces a loaded job rather than failing with
112558
+ // "service already loaded". `|| true` because not-loaded is the ordinary case.
112559
+ `/bin/launchctl bootout system/${LABEL2} 2>/dev/null || true`,
112560
+ `/bin/launchctl bootstrap system ${sh(PLIST)}`,
112561
+ `/bin/launchctl enable system/${LABEL2}`
112562
+ ].join("\n");
112563
+ const { code, declined } = await elevate(`${script}
112564
+ `);
112565
+ if (code !== 0) {
112566
+ return {
112567
+ ok: false,
112568
+ detail: declined ? "the elevation prompt was declined" : `installing the helper failed (exit ${code})`
112569
+ };
112570
+ }
112571
+ return { ok: true };
112572
+ },
112573
+ async uninstall() {
112574
+ const script = [
112575
+ `/bin/launchctl bootout system/${LABEL2} 2>/dev/null || true`,
112576
+ `rm -f ${sh(PLIST)}`
112577
+ ].join("\n");
112578
+ const { code, declined } = await elevate(`${script}
112579
+ `);
112580
+ return code === 0 ? { ok: true } : {
112581
+ ok: false,
112582
+ detail: declined ? "the elevation prompt was declined" : `removing the helper failed (exit ${code})`
112583
+ };
112584
+ },
112585
+ async state() {
112586
+ if (!existsSync39(PLIST))
112587
+ return { installed: false, running: false };
112588
+ const running2 = await netdAvailable();
112589
+ return {
112590
+ installed: true,
112591
+ running: running2,
112592
+ ...running2 ? {} : {
112593
+ detail: `the helper is installed but not answering \u2014 check ${LABEL2} in Console, or reinstall it`
112594
+ }
112595
+ };
112596
+ },
112597
+ async openApprovalSettings() {
112598
+ }
112599
+ };
112600
+ }
112601
+
112602
+ // ../../packages/host-core/dist/net-service/systemd-system.js
112603
+ import { spawn as spawn11 } from "node:child_process";
112604
+ import { existsSync as existsSync40 } from "node:fs";
112605
+
112606
+ // ../../packages/host-core/dist/service/exec.js
112607
+ import { execFile as execFile11, spawn as spawn10 } from "node:child_process";
112608
+ import { promisify as promisify7 } from "node:util";
112609
+ var run5 = promisify7(execFile11);
112610
+ function runInherit(cmd, args) {
112611
+ return new Promise((resolve16) => {
112612
+ const p = spawn10(cmd, args, { stdio: "inherit" });
112179
112613
  p.on("error", () => resolve16());
112180
112614
  p.on("close", () => resolve16());
112181
112615
  });
112182
112616
  }
112183
112617
 
112184
112618
  // ../../packages/host-core/dist/net-service/systemd-system.js
112619
+ function runForCode2(cmd, args) {
112620
+ return new Promise((resolve16) => {
112621
+ const p = spawn11(cmd, args, { stdio: "inherit" });
112622
+ p.on("error", () => resolve16(127));
112623
+ p.on("close", (code) => resolve16(code ?? 1));
112624
+ });
112625
+ }
112626
+ async function tryRun(cmd, args) {
112627
+ try {
112628
+ const { stdout } = await run5(cmd, args);
112629
+ return { stdout: String(stdout), code: 0 };
112630
+ } catch (e) {
112631
+ const err2 = e;
112632
+ return { stdout: String(err2.stdout ?? ""), code: typeof err2.code === "number" ? err2.code : 1 };
112633
+ }
112634
+ }
112635
+ async function elevated(script) {
112636
+ return await alreadyElevated() ? runForCode2("sh", ["-c", script]) : runForCode2("pkexec", ["sh", "-c", script]);
112637
+ }
112185
112638
  var UNIT = "tesseract-netd.service";
112186
112639
  var UNIT_PATH = `/etc/systemd/system/${UNIT}`;
112640
+ function unitVal(v) {
112641
+ return v.replace(/%/g, "%%");
112642
+ }
112643
+ function buildUnit(spec) {
112644
+ const exec2 = [
112645
+ spec.exec,
112646
+ "--state-dir",
112647
+ spec.stateDir,
112648
+ "--socket",
112649
+ spec.socket,
112650
+ "--owner-uid",
112651
+ String(spec.ownerUid)
112652
+ ].map(unitVal).join(" ");
112653
+ return `[Unit]
112654
+ Description=Tesseract network helper (mesh routes and tunnel device)
112655
+ Documentation=https://tesseract.dev/docs/mesh
112656
+ After=network-online.target
112657
+ Wants=network-online.target
112658
+ # A START LIMIT, because some failures are PERMANENT and restarting cannot fix them. An
112659
+ # unreadable journal is the one that proved it: netd refuses to start while routes may be
112660
+ # installed that it cannot identify, and without this the unit loops forever \u2014 measured at
112661
+ # 7 attempts in 30s on a real box, filling the log and never reaching a state an operator
112662
+ # can see as "stopped, needs attention". After 5 failures in 60s systemd gives up and marks
112663
+ # it failed, which is what state() reports.
112664
+ #
112665
+ # These belong in [Unit]: they are documented in systemd.unit(5), not systemd.service(5),
112666
+ # and systemd silently IGNORES them in the [Service] section \u2014 which is where I first put
112667
+ # them.
112668
+ StartLimitIntervalSec=60
112669
+ StartLimitBurst=5
112670
+
112671
+ [Service]
112672
+ # notify, so 'systemctl start' does not return before the socket exists \u2014 otherwise the
112673
+ # app connects to a service systemd calls started and gets ENOENT.
112674
+ Type=notify
112675
+ NotifyAccess=main
112676
+ ExecStart=${exec2}
112677
+ # Exactly what programming routes and opening a tun device need. NOT setcap: that grants
112678
+ # the capability to the FILE, so anything executing it inherits the grant, and it is
112679
+ # silently ignored on AppImage's nosuid FUSE mount \u2014 the only auto-updating Linux target.
112680
+ AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
112681
+ CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
112682
+ NoNewPrivileges=yes
112683
+ # This process is reachable over a socket by anything on the machine. Everything below
112684
+ # bounds what a bug in it could reach.
112685
+ ProtectSystem=strict
112686
+ ProtectHome=yes
112687
+ PrivateTmp=yes
112688
+ ProtectKernelModules=yes
112689
+ ProtectKernelLogs=yes
112690
+ ProtectControlGroups=yes
112691
+ RestrictSUIDSGID=yes
112692
+ RestrictNamespaces=yes
112693
+ LockPersonality=yes
112694
+ MemoryDenyWriteExecute=yes
112695
+ SystemCallArchitectures=native
112696
+ # The journal directory is the ONLY thing it may write.
112697
+ ReadWritePaths=${unitVal(spec.stateDir)}
112698
+ DeviceAllow=/dev/net/tun rw
112699
+ # on-failure, never always: a helper that exits 0 has been asked to stop, and restarting
112700
+ # it would fight the operator.
112701
+ Restart=on-failure
112702
+ RestartSec=5
112703
+
112704
+ [Install]
112705
+ WantedBy=multi-user.target
112706
+ `;
112707
+ }
112708
+ function makeSystemdSystem() {
112709
+ return {
112710
+ supported: process.platform === "linux",
112711
+ async install(spec) {
112712
+ const unit = buildUnit(spec);
112713
+ const script = [
112714
+ `install -d -m 0700 ${sh2(spec.stateDir)}`,
112715
+ `cat > ${sh2(UNIT_PATH)} <<'TESSERACT_UNIT_EOF'
112716
+ ${unit}TESSERACT_UNIT_EOF`,
112717
+ "systemctl daemon-reload",
112718
+ `systemctl enable --now ${UNIT}`
112719
+ ].join("\n");
112720
+ const code = await elevated(script);
112721
+ if (code !== 0) {
112722
+ const declined = code === 126 || code === 127;
112723
+ return {
112724
+ ok: false,
112725
+ detail: declined ? "the elevation prompt was declined" : `installing the helper failed (exit ${code})`
112726
+ };
112727
+ }
112728
+ return { ok: true };
112729
+ },
112730
+ async uninstall() {
112731
+ const script = [
112732
+ `systemctl disable --now ${UNIT} || true`,
112733
+ `rm -f ${sh2(UNIT_PATH)}`,
112734
+ "systemctl daemon-reload"
112735
+ ].join("\n");
112736
+ const code = await elevated(script);
112737
+ return code === 0 ? { ok: true } : { ok: false, detail: `removing the helper failed (exit ${code})` };
112738
+ },
112739
+ async state() {
112740
+ if (!existsSync40(UNIT_PATH))
112741
+ return { installed: false, running: false };
112742
+ const active = await tryRun("systemctl", ["is-active", UNIT]);
112743
+ const running2 = active.stdout.trim() === "active";
112744
+ if (running2)
112745
+ return { installed: true, running: true };
112746
+ const show = await tryRun("systemctl", ["show", UNIT, "--property=Result", "--value"]);
112747
+ const result = show.stdout.trim();
112748
+ return {
112749
+ installed: true,
112750
+ running: false,
112751
+ ...result && result !== "success" ? { detail: `the helper failed: ${result}` } : {}
112752
+ };
112753
+ },
112754
+ async openApprovalSettings() {
112755
+ }
112756
+ };
112757
+ }
112758
+ function sh2(s) {
112759
+ return `'${s.replace(/'/g, `'\\''`)}'`;
112760
+ }
112761
+
112762
+ // ../../packages/host-core/dist/net-service/windows-service.js
112763
+ import { execFile as execFile12, spawn as spawn12 } from "node:child_process";
112764
+ import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync41, rmSync as rmSync11 } from "node:fs";
112765
+ import { tmpdir as tmpdir7 } from "node:os";
112766
+ import { join as join78 } from "node:path";
112767
+ import { promisify as promisify8 } from "node:util";
112768
+ var run6 = promisify8(execFile12);
112769
+ var SERVICE = "TesseractNetd";
112770
+ var DISPLAY = "Tesseract network helper";
112771
+ var ERROR_CANCELLED = 1223;
112772
+ function ps(s) {
112773
+ return `'${s.replace(/'/g, "''")}'`;
112774
+ }
112775
+ function buildBinaryPath(spec) {
112776
+ const parts = [
112777
+ spec.exec,
112778
+ // NOT optional, and its absence is silent. The SCM launches the process and waits for it
112779
+ // to call `StartServiceCtrlDispatcher`; without this flag netd runs its console path
112780
+ // instead, never reports a status, and the SCM gives up — leaving a service that is
112781
+ // registered, visible in services.msc, refuses to start, and reports exit code 0. That
112782
+ // exact state was reproduced on the Windows build machine before the flag existed.
112783
+ "--service",
112784
+ "--state-dir",
112785
+ spec.stateDir,
112786
+ "--socket",
112787
+ spec.socket
112788
+ ];
112789
+ if (spec.ownerSid)
112790
+ parts.push("--owner-sid", spec.ownerSid);
112791
+ return parts.map((p) => `"${p}"`).join(" ");
112792
+ }
112793
+ async function elevatePowerShell(script) {
112794
+ const dir2 = mkdtempSync3(join78(tmpdir7(), "tesseract-netd-"));
112795
+ const inner = join78(dir2, "install.ps1");
112796
+ writeFileSync41(inner, script, { encoding: "utf8" });
112797
+ if (await alreadyElevated()) {
112798
+ return new Promise((resolve16) => {
112799
+ const p = spawn12("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", inner], { stdio: "inherit" });
112800
+ const finish = (code) => {
112801
+ try {
112802
+ rmSync11(dir2, { recursive: true, force: true });
112803
+ } catch {
112804
+ }
112805
+ resolve16({ code, declined: false });
112806
+ };
112807
+ p.on("error", () => finish(127));
112808
+ p.on("close", (code) => finish(code ?? 1));
112809
+ });
112810
+ }
112811
+ const outer = join78(dir2, "elevate.ps1");
112812
+ writeFileSync41(outer, [
112813
+ '$ErrorActionPreference = "Stop"',
112814
+ "try {",
112815
+ ` $p = Start-Process -FilePath "powershell.exe" -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File",${ps(inner)}) -Verb RunAs -Wait -PassThru`,
112816
+ " exit $p.ExitCode",
112817
+ "} catch {",
112818
+ ` exit ${ERROR_CANCELLED}`,
112819
+ "}"
112820
+ ].join("\n"), { encoding: "utf8" });
112821
+ return new Promise((resolve16) => {
112822
+ const p = spawn12("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", outer], { stdio: "inherit" });
112823
+ const finish = (code) => {
112824
+ try {
112825
+ rmSync11(dir2, { recursive: true, force: true });
112826
+ } catch {
112827
+ }
112828
+ resolve16({ code, declined: code === ERROR_CANCELLED });
112829
+ };
112830
+ p.on("error", () => finish(127));
112831
+ p.on("close", (code) => finish(code ?? 1));
112832
+ });
112833
+ }
112834
+ function buildInstallScript(spec) {
112835
+ const bin = buildBinaryPath(spec);
112836
+ return [
112837
+ '$ErrorActionPreference = "Stop"',
112838
+ `New-Item -ItemType Directory -Force -Path ${ps(spec.stateDir)} | Out-Null`,
112839
+ // A reinstall must replace, not fail. Stop first: New-Service refuses a name that
112840
+ // exists, and sc.exe delete on a running service only marks it for deletion.
112841
+ `$existing = Get-Service -Name ${ps(SERVICE)} -ErrorAction SilentlyContinue`,
112842
+ "if ($existing) {",
112843
+ ` Stop-Service -Name ${ps(SERVICE)} -Force -ErrorAction SilentlyContinue`,
112844
+ ` & sc.exe delete ${SERVICE} | Out-Null`,
112845
+ " Start-Sleep -Milliseconds 500",
112846
+ "}",
112847
+ `New-Service -Name ${ps(SERVICE)} -BinaryPathName ${ps(bin)} -DisplayName ${ps(DISPLAY)} -Description ${ps("Programs the routes for Tesseract private networks and owns the tunnel device.")} -StartupType Automatic | Out-Null`,
112848
+ // Restart on failure, three times, then stop trying. The Windows equivalent of
112849
+ // systemd's Restart=on-failure with a start limit — netd refuses to start while an
112850
+ // unreadable journal may mean routes are installed, and that is a PERMANENT failure
112851
+ // no amount of restarting fixes.
112852
+ `& sc.exe failure ${SERVICE} reset= 86400 actions= restart/5000/restart/5000/restart/5000 | Out-Null`,
112853
+ `Start-Service -Name ${ps(SERVICE)}`,
112854
+ "exit 0"
112855
+ ].join("\n");
112856
+ }
112857
+ function buildUninstallScript() {
112858
+ return [
112859
+ `Stop-Service -Name ${ps(SERVICE)} -Force -ErrorAction SilentlyContinue`,
112860
+ `& sc.exe delete ${SERVICE} | Out-Null`,
112861
+ "exit 0"
112862
+ ].join("\n");
112863
+ }
112864
+ function makeWindowsService() {
112865
+ return {
112866
+ supported: process.platform === "win32",
112867
+ async install(spec) {
112868
+ const { code, declined } = await elevatePowerShell(`${buildInstallScript(spec)}
112869
+ `);
112870
+ if (code !== 0) {
112871
+ return {
112872
+ ok: false,
112873
+ detail: declined ? "the elevation prompt was declined" : `installing the helper failed (exit ${code})`
112874
+ };
112875
+ }
112876
+ return { ok: true };
112877
+ },
112878
+ async uninstall() {
112879
+ const { code, declined } = await elevatePowerShell(`${buildUninstallScript()}
112880
+ `);
112881
+ return code === 0 ? { ok: true } : {
112882
+ ok: false,
112883
+ detail: declined ? "the elevation prompt was declined" : `removing the helper failed (exit ${code})`
112884
+ };
112885
+ },
112886
+ async state() {
112887
+ try {
112888
+ const { stdout } = await run6("sc.exe", ["query", SERVICE]);
112889
+ const out = String(stdout);
112890
+ const running2 = /STATE\s*:\s*4\b/.test(out);
112891
+ if (running2)
112892
+ return { installed: true, running: true };
112893
+ return {
112894
+ installed: true,
112895
+ running: false,
112896
+ detail: "the helper is installed but not running \u2014 reinstall it, or start the Tesseract network helper service"
112897
+ };
112898
+ } catch {
112899
+ return { installed: false, running: false };
112900
+ }
112901
+ },
112902
+ async openApprovalSettings() {
112903
+ }
112904
+ };
112905
+ }
112906
+
112907
+ // ../../packages/host-core/dist/net-service/windows-nat.js
112908
+ import { execFile as execFile13 } from "node:child_process";
112909
+ import { promisify as promisify9 } from "node:util";
112910
+ var run7 = promisify9(execFile13);
112911
+ var NAT_FEATURE = "Containers-HNS";
112912
+ async function natCapability() {
112913
+ if (process.platform !== "win32") {
112914
+ return { available: true, reason: "", needsRestart: false };
112915
+ }
112916
+ try {
112917
+ const { stdout } = await run7("powershell.exe", [
112918
+ "-NoProfile",
112919
+ "-NonInteractive",
112920
+ "-Command",
112921
+ "if (Get-CimClass -Namespace root/StandardCimv2 -ClassName MSFT_NetNat -ErrorAction SilentlyContinue) { 'yes' } else { 'no' }"
112922
+ ]);
112923
+ if (String(stdout).trim() === "yes") {
112924
+ return { available: true, reason: "", needsRestart: false };
112925
+ }
112926
+ } catch {
112927
+ }
112928
+ return {
112929
+ available: false,
112930
+ reason: "Windows needs one more component before this machine can be the way out for others. It is an optional Windows feature, and turning it on needs a restart. Nothing else about the private network needs it \u2014 this machine can already join, and route all of its own traffic through someone else.",
112931
+ needsRestart: true
112932
+ };
112933
+ }
112934
+ function buildEnableNatScript() {
112935
+ return [
112936
+ '$ErrorActionPreference = "Stop"',
112937
+ // -NoRestart, ALWAYS. We report that a restart is needed; we never perform one. An
112938
+ // application that reboots a machine is one nobody leaves running.
112939
+ `$r = Enable-WindowsOptionalFeature -Online -FeatureName ${NAT_FEATURE} -All -NoRestart`,
112940
+ // 3010 is ERROR_SUCCESS_REBOOT_REQUIRED and is a SUCCESS. Treating it as a failure
112941
+ // would tell the user their install failed on the machine where it worked.
112942
+ "if ($r.RestartNeeded) { exit 3010 }",
112943
+ "exit 0"
112944
+ ].join("\n");
112945
+ }
112946
+ async function enableNatProvider() {
112947
+ if (process.platform !== "win32") {
112948
+ return { ok: false, reason: "unsupported", detail: "this is a Windows-only component" };
112949
+ }
112950
+ const { code, declined } = await elevatePowerShell(`${buildEnableNatScript()}
112951
+ `);
112952
+ if (code === 0)
112953
+ return { ok: true, restartRequired: false };
112954
+ if (code === 3010)
112955
+ return { ok: true, restartRequired: true };
112956
+ return {
112957
+ ok: false,
112958
+ reason: declined ? "declined" : "failed",
112959
+ detail: declined ? "the elevation prompt was declined" : `enabling the Windows NAT component failed (exit ${code})`
112960
+ };
112961
+ }
112962
+
112963
+ // ../../packages/host-core/dist/net-service/index.js
112964
+ function inert(reason) {
112965
+ return {
112966
+ supported: false,
112967
+ async install() {
112968
+ return { ok: false, detail: reason };
112969
+ },
112970
+ async uninstall() {
112971
+ return { ok: false, detail: reason };
112972
+ },
112973
+ async state() {
112974
+ return { installed: false, running: false, detail: reason };
112975
+ },
112976
+ async openApprovalSettings() {
112977
+ }
112978
+ };
112979
+ }
112980
+ function makeNetService() {
112981
+ switch (process.platform) {
112982
+ case "linux":
112983
+ return makeSystemdSystem();
112984
+ // A root LaunchDaemon, not a System Extension. The extension is still the right end
112985
+ // state — it brings split DNS, On-Demand and an OS kill switch — but it is an Xcode
112986
+ // project, a second signing identity and a user approval, and none of that is needed to
112987
+ // open a utun and program routes. See `launchd-system.ts`.
112988
+ case "darwin":
112989
+ return makeLaunchDaemon();
112990
+ // A LocalSystem service, separate from the daemon's per-user Scheduled Task, which stays
112991
+ // unprivileged. See `windows-service.ts`.
112992
+ case "win32":
112993
+ return makeWindowsService();
112994
+ default:
112995
+ return inert(`no network helper for ${process.platform}`);
112996
+ }
112997
+ }
112998
+
112999
+ // ../../packages/host-core/dist/net-service/netd-binary.js
113000
+ import { existsSync as existsSync41 } from "node:fs";
113001
+ import { dirname as dirname33, join as join79 } from "node:path";
113002
+ import { fileURLToPath as fileURLToPath7 } from "node:url";
113003
+ function netdBinaryName() {
113004
+ return process.platform === "win32" ? "tesseract-netd.exe" : "tesseract-netd";
113005
+ }
113006
+ function override2() {
113007
+ const p = process.env.CCB_NETD_BIN;
113008
+ return p && existsSync41(p) ? p : null;
113009
+ }
113010
+ function netdBinaryPath() {
113011
+ const fromEnv = override2();
113012
+ if (fromEnv)
113013
+ return fromEnv;
113014
+ const name = netdBinaryName();
113015
+ const candidates = [];
113016
+ const resources = process.resourcesPath;
113017
+ if (resources)
113018
+ candidates.push(join79(resources, "netd", name));
113019
+ try {
113020
+ const here = dirname33(fileURLToPath7(import.meta.url));
113021
+ candidates.push(join79(here, "..", "..", "netd", name));
113022
+ candidates.push(join79(here, "..", "..", "..", "netd", name));
113023
+ const triple = `${process.platform}-${process.arch}`;
113024
+ for (const root of [here, join79(here, ".."), join79(here, "..", "..")]) {
113025
+ candidates.push(join79(root, "mesh-core", "prebuilds", triple, "netd", name));
113026
+ }
113027
+ } catch {
113028
+ }
113029
+ if (process.env.CCB_REPO_ROOT) {
113030
+ candidates.push(join79(process.env.CCB_REPO_ROOT, "crates", "target", "release", name));
113031
+ }
113032
+ candidates.push(join79(process.cwd(), "crates", "target", "release", name));
113033
+ for (const c of candidates) {
113034
+ try {
113035
+ if (existsSync41(c))
113036
+ return c;
113037
+ } catch {
113038
+ }
113039
+ }
113040
+ return null;
113041
+ }
113042
+
113043
+ // ../../packages/host-core/dist/net-service/ensure-installed.js
113044
+ function stateDir() {
113045
+ switch (process.platform) {
113046
+ case "win32":
113047
+ return "C:\\ProgramData\\Tesseract\\netd";
113048
+ case "darwin":
113049
+ return "/Library/Application Support/Tesseract/netd";
113050
+ default:
113051
+ return "/var/lib/tesseract-netd";
113052
+ }
113053
+ }
113054
+ async function ownerSid() {
113055
+ if (process.platform !== "win32")
113056
+ return void 0;
113057
+ try {
113058
+ const { stdout } = await promisify10(execFile14)("whoami", ["/user", "/fo", "csv", "/nh"]);
113059
+ const m = /"(S-1-[0-9-]+)"/.exec(String(stdout));
113060
+ return m?.[1];
113061
+ } catch {
113062
+ return void 0;
113063
+ }
113064
+ }
113065
+ async function ensureNetHelperInstalled() {
113066
+ const svc = makeNetService();
113067
+ if (!svc.supported) {
113068
+ const st2 = await svc.state();
113069
+ return { ok: false, reason: "unsupported", detail: st2.detail ?? "no helper on this platform" };
113070
+ }
113071
+ const st = await svc.state();
113072
+ if (st.installed)
113073
+ return { ok: true, already: true };
113074
+ const exec2 = netdBinaryPath();
113075
+ if (exec2 && process.platform === "win32" && !existsSync42(join80(dirname34(exec2), "wintun.dll"))) {
113076
+ return {
113077
+ ok: false,
113078
+ reason: "no-binary",
113079
+ detail: "this build shipped the network helper without wintun.dll, so it cannot open a tunnel"
113080
+ };
113081
+ }
113082
+ if (!exec2) {
113083
+ return {
113084
+ ok: false,
113085
+ reason: "no-binary",
113086
+ detail: "this build did not ship the network helper"
113087
+ };
113088
+ }
113089
+ const r = await svc.install({
113090
+ exec: exec2,
113091
+ stateDir: stateDir(),
113092
+ socket: netdEndpoint(),
113093
+ ...await ownerSid().then((sid) => sid ? { ownerSid: sid } : {}),
113094
+ // The uid whose requests may mutate. Read HERE, at install time, by the process the
113095
+ // user is actually running — the helper starts as a system service with no session, so
113096
+ // reading it there would be wrong in every interesting case.
113097
+ ownerUid: typeof process.getuid === "function" ? process.getuid() : 0
113098
+ });
113099
+ if (r.ok)
113100
+ return { ok: true, already: false };
113101
+ const declined = /declin|cancel/i.test(r.detail ?? "");
113102
+ return {
113103
+ ok: false,
113104
+ reason: declined ? "declined" : "failed",
113105
+ detail: r.detail ?? "installing the helper failed"
113106
+ };
113107
+ }
112187
113108
 
112188
113109
  // ../../packages/host-core/dist/clipboard/clipboard-sync.js
112189
113110
  var MAX_IMAGE_BYTES3 = 10 * 1024 * 1024;
@@ -112202,24 +113123,24 @@ import { platform as platform6 } from "node:os";
112202
113123
 
112203
113124
  // ../../packages/host-core/dist/service/launchd.js
112204
113125
  init_credentials();
112205
- import { writeFileSync as writeFileSync40, existsSync as existsSync39, mkdirSync as mkdirSync41, unlinkSync as unlinkSync7 } from "node:fs";
112206
- import { dirname as dirname33, join as join77 } from "node:path";
113126
+ import { writeFileSync as writeFileSync42, existsSync as existsSync43, mkdirSync as mkdirSync41, unlinkSync as unlinkSync7 } from "node:fs";
113127
+ import { dirname as dirname35, join as join81 } from "node:path";
112207
113128
  import { homedir as homedir13, userInfo as userInfo2 } from "node:os";
112208
- function xml(s) {
113129
+ function xml2(s) {
112209
113130
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
112210
113131
  }
112211
113132
  function makeLaunchd(instanceId) {
112212
113133
  const suffix = instanceSuffix(instanceId);
112213
113134
  const label = SERVICE_LABEL_BASE + (suffix ? `.${suffix}` : "");
112214
- const plistPath = () => join77(homedir13(), "Library", "LaunchAgents", `${label}.plist`);
113135
+ const plistPath = () => join81(homedir13(), "Library", "LaunchAgents", `${label}.plist`);
112215
113136
  const domainTarget = () => `gui/${userInfo2().uid}`;
112216
113137
  const serviceTarget = () => `${domainTarget()}/${label}`;
112217
- const logFile = () => join77(daemonDir2(), "daemon.log");
113138
+ const logFile = () => join81(daemonDir2(), "daemon.log");
112218
113139
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
112219
- function buildPlist(spec) {
112220
- const args = [spec.exec, ...spec.args].map((a) => ` <string>${xml(a)}</string>`).join("\n");
112221
- const env = Object.entries(spec.env).map(([k, v]) => ` <key>${xml(k)}</key>
112222
- <string>${xml(v)}</string>`).join("\n");
113140
+ function buildPlist2(spec) {
113141
+ const args = [spec.exec, ...spec.args].map((a) => ` <string>${xml2(a)}</string>`).join("\n");
113142
+ const env = Object.entries(spec.env).map(([k, v]) => ` <key>${xml2(k)}</key>
113143
+ <string>${xml2(v)}</string>`).join("\n");
112223
113144
  return `<?xml version="1.0" encoding="UTF-8"?>
112224
113145
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
112225
113146
  <plist version="1.0">
@@ -112235,7 +113156,7 @@ ${args}
112235
113156
  ${env}
112236
113157
  </dict>
112237
113158
  <key>WorkingDirectory</key>
112238
- <string>${xml(workDirOf(spec))}</string>
113159
+ <string>${xml2(workDirOf(spec))}</string>
112239
113160
  <key>RunAtLoad</key>
112240
113161
  <true/>
112241
113162
  <key>KeepAlive</key>
@@ -112250,9 +113171,9 @@ ${env}
112250
113171
  <key>LimitLoadToSessionType</key>
112251
113172
  <string>Aqua</string>
112252
113173
  <key>StandardOutPath</key>
112253
- <string>${xml(spec.logPath)}</string>
113174
+ <string>${xml2(spec.logPath)}</string>
112254
113175
  <key>StandardErrorPath</key>
112255
- <string>${xml(spec.logPath)}</string>
113176
+ <string>${xml2(spec.logPath)}</string>
112256
113177
  </dict>
112257
113178
  </plist>
112258
113179
  `;
@@ -112260,21 +113181,21 @@ ${env}
112260
113181
  return {
112261
113182
  async install(spec) {
112262
113183
  mkdirSync41(workDirOf(spec), { recursive: true });
112263
- mkdirSync41(dirname33(plistPath()), { recursive: true });
112264
- mkdirSync41(dirname33(spec.logPath), { recursive: true });
112265
- writeFileSync40(plistPath(), buildPlist(spec));
112266
- await run4("launchctl", ["bootout", serviceTarget()]).catch(() => {
113184
+ mkdirSync41(dirname35(plistPath()), { recursive: true });
113185
+ mkdirSync41(dirname35(spec.logPath), { recursive: true });
113186
+ writeFileSync42(plistPath(), buildPlist2(spec));
113187
+ await run5("launchctl", ["bootout", serviceTarget()]).catch(() => {
112267
113188
  });
112268
- await run4("launchctl", ["bootstrap", domainTarget(), plistPath()]);
112269
- await run4("launchctl", ["enable", serviceTarget()]).catch(() => {
113189
+ await run5("launchctl", ["bootstrap", domainTarget(), plistPath()]);
113190
+ await run5("launchctl", ["enable", serviceTarget()]).catch(() => {
112270
113191
  });
112271
- await run4("launchctl", ["kickstart", "-k", serviceTarget()]).catch(() => {
113192
+ await run5("launchctl", ["kickstart", "-k", serviceTarget()]).catch(() => {
112272
113193
  });
112273
113194
  },
112274
113195
  async uninstall() {
112275
- await run4("launchctl", ["bootout", serviceTarget()]).catch(() => {
113196
+ await run5("launchctl", ["bootout", serviceTarget()]).catch(() => {
112276
113197
  });
112277
- if (existsSync39(plistPath())) {
113198
+ if (existsSync43(plistPath())) {
112278
113199
  try {
112279
113200
  unlinkSync7(plistPath());
112280
113201
  } catch {
@@ -112285,16 +113206,16 @@ ${env}
112285
113206
  await this.install(spec);
112286
113207
  },
112287
113208
  async isInstalled() {
112288
- return existsSync39(plistPath());
113209
+ return existsSync43(plistPath());
112289
113210
  },
112290
113211
  async start() {
112291
- await run4("launchctl", ["bootstrap", domainTarget(), plistPath()]).catch(() => {
113212
+ await run5("launchctl", ["bootstrap", domainTarget(), plistPath()]).catch(() => {
112292
113213
  });
112293
- await run4("launchctl", ["kickstart", serviceTarget()]).catch(() => {
113214
+ await run5("launchctl", ["kickstart", serviceTarget()]).catch(() => {
112294
113215
  });
112295
113216
  },
112296
113217
  async stop() {
112297
- await run4("launchctl", ["bootout", serviceTarget()]).catch(() => {
113218
+ await run5("launchctl", ["bootout", serviceTarget()]).catch(() => {
112298
113219
  });
112299
113220
  },
112300
113221
  async status() {
@@ -112302,7 +113223,7 @@ ${env}
112302
113223
  },
112303
113224
  async logs(follow) {
112304
113225
  const f = logFile();
112305
- if (!existsSync39(f)) {
113226
+ if (!existsSync43(f)) {
112306
113227
  console.log(`No log yet at ${f} \u2014 has the service started?`);
112307
113228
  return;
112308
113229
  }
@@ -112313,10 +113234,10 @@ ${env}
112313
113234
 
112314
113235
  // ../../packages/host-core/dist/service/systemd.js
112315
113236
  init_credentials();
112316
- import { writeFileSync as writeFileSync41, existsSync as existsSync40, mkdirSync as mkdirSync42, unlinkSync as unlinkSync8 } from "node:fs";
112317
- import { dirname as dirname34, join as join78 } from "node:path";
113237
+ import { writeFileSync as writeFileSync43, existsSync as existsSync44, mkdirSync as mkdirSync42, unlinkSync as unlinkSync8 } from "node:fs";
113238
+ import { dirname as dirname36, join as join82 } from "node:path";
112318
113239
  import { homedir as homedir14, userInfo as userInfo3 } from "node:os";
112319
- function unitVal(v) {
113240
+ function unitVal2(v) {
112320
113241
  return v.replace(/%/g, "%%");
112321
113242
  }
112322
113243
  function shq(s) {
@@ -112326,8 +113247,8 @@ function makeSystemd(instanceId) {
112326
113247
  const suffix = instanceSuffix(instanceId);
112327
113248
  const unit = `tesseract-host${suffix ? `-${suffix}` : ""}.service`;
112328
113249
  const unitPath = () => {
112329
- const base = process.env.XDG_CONFIG_HOME || join78(homedir14(), ".config");
112330
- return join78(base, "systemd", "user", unit);
113250
+ const base = process.env.XDG_CONFIG_HOME || join82(homedir14(), ".config");
113251
+ return join82(base, "systemd", "user", unit);
112331
113252
  };
112332
113253
  const workDirOf = (spec) => spec.workingDirectory ?? daemonDir2();
112333
113254
  function buildUnit2(spec) {
@@ -112341,7 +113262,7 @@ Wants=network-online.target
112341
113262
  [Service]
112342
113263
  Type=simple
112343
113264
  ${env}
112344
- WorkingDirectory=${unitVal(workDirOf(spec))}
113265
+ WorkingDirectory=${unitVal2(workDirOf(spec))}
112345
113266
  ExecStart=${execStart}
112346
113267
  Restart=on-failure
112347
113268
  RestartSec=30
@@ -112355,40 +113276,40 @@ WantedBy=default.target
112355
113276
  return {
112356
113277
  async install(spec) {
112357
113278
  mkdirSync42(workDirOf(spec), { recursive: true });
112358
- mkdirSync42(dirname34(unitPath()), { recursive: true });
112359
- mkdirSync42(dirname34(spec.logPath), { recursive: true });
112360
- writeFileSync41(unitPath(), buildUnit2(spec));
112361
- await run4("loginctl", ["enable-linger", userInfo3().username]).catch(() => {
113279
+ mkdirSync42(dirname36(unitPath()), { recursive: true });
113280
+ mkdirSync42(dirname36(spec.logPath), { recursive: true });
113281
+ writeFileSync43(unitPath(), buildUnit2(spec));
113282
+ await run5("loginctl", ["enable-linger", userInfo3().username]).catch(() => {
112362
113283
  });
112363
- await run4("systemctl", ["--user", "daemon-reload"]).catch(() => {
113284
+ await run5("systemctl", ["--user", "daemon-reload"]).catch(() => {
112364
113285
  });
112365
- await run4("systemctl", ["--user", "enable", unit]).catch(() => {
113286
+ await run5("systemctl", ["--user", "enable", unit]).catch(() => {
112366
113287
  });
112367
- await run4("systemctl", ["--user", "restart", unit]);
113288
+ await run5("systemctl", ["--user", "restart", unit]);
112368
113289
  },
112369
113290
  async uninstall() {
112370
- await run4("systemctl", ["--user", "disable", "--now", unit]).catch(() => {
113291
+ await run5("systemctl", ["--user", "disable", "--now", unit]).catch(() => {
112371
113292
  });
112372
- if (existsSync40(unitPath())) {
113293
+ if (existsSync44(unitPath())) {
112373
113294
  try {
112374
113295
  unlinkSync8(unitPath());
112375
113296
  } catch {
112376
113297
  }
112377
113298
  }
112378
- await run4("systemctl", ["--user", "daemon-reload"]).catch(() => {
113299
+ await run5("systemctl", ["--user", "daemon-reload"]).catch(() => {
112379
113300
  });
112380
113301
  },
112381
113302
  async restart(spec) {
112382
113303
  await this.install(spec);
112383
113304
  },
112384
113305
  async isInstalled() {
112385
- return existsSync40(unitPath());
113306
+ return existsSync44(unitPath());
112386
113307
  },
112387
113308
  async start() {
112388
- await run4("systemctl", ["--user", "start", unit]);
113309
+ await run5("systemctl", ["--user", "start", unit]);
112389
113310
  },
112390
113311
  async stop() {
112391
- await run4("systemctl", ["--user", "stop", unit]);
113312
+ await run5("systemctl", ["--user", "stop", unit]);
112392
113313
  },
112393
113314
  async status() {
112394
113315
  await runInherit("systemctl", ["--user", "status", unit, "--no-pager"]);
@@ -112401,13 +113322,13 @@ WantedBy=default.target
112401
113322
 
112402
113323
  // ../../packages/host-core/dist/service/windows.js
112403
113324
  init_credentials();
112404
- import { writeFileSync as writeFileSync42, existsSync as existsSync41, mkdirSync as mkdirSync43, unlinkSync as unlinkSync9 } from "node:fs";
112405
- import { dirname as dirname35, join as join79 } from "node:path";
113325
+ import { writeFileSync as writeFileSync44, existsSync as existsSync45, mkdirSync as mkdirSync43, unlinkSync as unlinkSync9 } from "node:fs";
113326
+ import { dirname as dirname37, join as join83 } from "node:path";
112406
113327
  function makeWindowsTask(instanceId) {
112407
113328
  const suffix = instanceSuffix(instanceId);
112408
113329
  const task = `Fineguide\\TesseractHost${suffix ? `-${suffix}` : ""}`;
112409
- const wrapperPath = () => join79(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
112410
- const logFile = () => join79(daemonDir2(), "daemon.log");
113330
+ const wrapperPath = () => join83(daemonDir2(), `run-host${suffix ? `-${suffix}` : ""}.cmd`);
113331
+ const logFile = () => join83(daemonDir2(), "daemon.log");
112411
113332
  const oneLine2 = (s) => s.replace(/[\r\n]+/g, " ");
112412
113333
  const envVal = (v) => oneLine2(v).replace(/%/g, "%%").replace(/"/g, "");
112413
113334
  const cmdArg = (a) => `"${oneLine2(a).replace(/"/g, "")}"`;
@@ -112424,17 +113345,17 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
112424
113345
  return {
112425
113346
  async install(spec) {
112426
113347
  mkdirSync43(spec.workingDirectory ?? daemonDir2(), { recursive: true });
112427
- mkdirSync43(dirname35(spec.logPath), { recursive: true });
112428
- mkdirSync43(dirname35(wrapperPath()), { recursive: true });
112429
- writeFileSync42(wrapperPath(), buildWrapper(spec));
112430
- await run4("schtasks", ["/Create", "/TN", task, "/SC", "ONLOGON", "/RL", "LIMITED", "/F", "/TR", `"${wrapperPath()}"`]);
112431
- await run4("schtasks", ["/Run", "/TN", task]).catch(() => {
113348
+ mkdirSync43(dirname37(spec.logPath), { recursive: true });
113349
+ mkdirSync43(dirname37(wrapperPath()), { recursive: true });
113350
+ writeFileSync44(wrapperPath(), buildWrapper(spec));
113351
+ await run5("schtasks", ["/Create", "/TN", task, "/SC", "ONLOGON", "/RL", "LIMITED", "/F", "/TR", `"${wrapperPath()}"`]);
113352
+ await run5("schtasks", ["/Run", "/TN", task]).catch(() => {
112432
113353
  });
112433
113354
  },
112434
113355
  async uninstall() {
112435
- await run4("schtasks", ["/Delete", "/TN", task, "/F"]).catch(() => {
113356
+ await run5("schtasks", ["/Delete", "/TN", task, "/F"]).catch(() => {
112436
113357
  });
112437
- if (existsSync41(wrapperPath())) {
113358
+ if (existsSync45(wrapperPath())) {
112438
113359
  try {
112439
113360
  unlinkSync9(wrapperPath());
112440
113361
  } catch {
@@ -112446,17 +113367,17 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
112446
113367
  },
112447
113368
  async isInstalled() {
112448
113369
  try {
112449
- await run4("schtasks", ["/Query", "/TN", task]);
113370
+ await run5("schtasks", ["/Query", "/TN", task]);
112450
113371
  return true;
112451
113372
  } catch {
112452
113373
  return false;
112453
113374
  }
112454
113375
  },
112455
113376
  async start() {
112456
- await run4("schtasks", ["/Run", "/TN", task]);
113377
+ await run5("schtasks", ["/Run", "/TN", task]);
112457
113378
  },
112458
113379
  async stop() {
112459
- await run4("schtasks", ["/End", "/TN", task]).catch(() => {
113380
+ await run5("schtasks", ["/End", "/TN", task]).catch(() => {
112460
113381
  });
112461
113382
  },
112462
113383
  async status() {
@@ -112464,7 +113385,7 @@ start "" /b ${cmd} >> "${oneLine2(spec.logPath).replace(/"/g, "")}" 2>&1\r
112464
113385
  },
112465
113386
  async logs(follow) {
112466
113387
  const f = logFile();
112467
- if (!existsSync41(f)) {
113388
+ if (!existsSync45(f)) {
112468
113389
  console.log(`No log yet at ${f} \u2014 has the task run?`);
112469
113390
  return;
112470
113391
  }
@@ -112496,8 +113417,8 @@ init_safe_kill();
112496
113417
  // src/auth.ts
112497
113418
  var import_qrcode_terminal = __toESM(require_main(), 1);
112498
113419
  import { randomUUID as randomUUID29 } from "node:crypto";
112499
- import { existsSync as existsSync42, rmSync as rmSync10 } from "node:fs";
112500
- import { join as join80 } from "node:path";
113420
+ import { existsSync as existsSync46, rmSync as rmSync12 } from "node:fs";
113421
+ import { join as join84 } from "node:path";
112501
113422
 
112502
113423
  // src/config.ts
112503
113424
  import { hostname as hostname6 } from "node:os";
@@ -112698,8 +113619,8 @@ async function logout() {
112698
113619
  }
112699
113620
  for (const f of ["credentials.json", "status.json", "daemon.lock"]) {
112700
113621
  try {
112701
- const p = join80(daemonDir2(), f);
112702
- if (existsSync42(p)) rmSync10(p);
113622
+ const p = join84(daemonDir2(), f);
113623
+ if (existsSync46(p)) rmSync12(p);
112703
113624
  } catch {
112704
113625
  }
112705
113626
  }
@@ -112719,7 +113640,7 @@ function whoami() {
112719
113640
  }
112720
113641
 
112721
113642
  // src/self-update.ts
112722
- import { spawn as spawn10 } from "node:child_process";
113643
+ import { spawn as spawn13 } from "node:child_process";
112723
113644
  import { createPublicKey, verify as cryptoVerify } from "node:crypto";
112724
113645
  var RESTART_EXIT_CODE = 75;
112725
113646
  var REGISTRY_BASE = "https://registry.npmjs.org/tesseract-agent";
@@ -112794,7 +113715,7 @@ function installVersion(target) {
112794
113715
  log8(`installing tesseract-agent@${target} \u2026`);
112795
113716
  let child;
112796
113717
  try {
112797
- child = spawn10(npm, ["install", "-g", `tesseract-agent@${target}`], { stdio: ["ignore", "inherit", "inherit"] });
113718
+ child = spawn13(npm, ["install", "-g", `tesseract-agent@${target}`], { stdio: ["ignore", "inherit", "inherit"] });
112798
113719
  } catch (e) {
112799
113720
  log8("npm spawn threw:", e instanceof Error ? e.message : String(e));
112800
113721
  resolve16(false);
@@ -112857,9 +113778,9 @@ function startSelfUpdater(current) {
112857
113778
  }
112858
113779
 
112859
113780
  // src/service.ts
112860
- import { join as join81 } from "node:path";
113781
+ import { join as join85 } from "node:path";
112861
113782
  import { platform as platform7 } from "node:os";
112862
- import { existsSync as existsSync43, readFileSync as readFileSync49 } from "node:fs";
113783
+ import { existsSync as existsSync47, readFileSync as readFileSync49 } from "node:fs";
112863
113784
  function controller(instanceId) {
112864
113785
  const c = getServiceController(instanceId);
112865
113786
  if (!c) {
@@ -112872,7 +113793,7 @@ function buildSpec(cliEntry) {
112872
113793
  exec: process.execPath,
112873
113794
  args: [cliEntry, "run"],
112874
113795
  env: { CCB_DAEMON_DIR: daemonDir2() },
112875
- logPath: join81(daemonDir2(), "daemon.log")
113796
+ logPath: join85(daemonDir2(), "daemon.log")
112876
113797
  };
112877
113798
  }
112878
113799
  var isAlive = (pid) => {
@@ -112884,9 +113805,9 @@ var isAlive = (pid) => {
112884
113805
  }
112885
113806
  };
112886
113807
  function runningDaemonInfo() {
112887
- const lock = join81(daemonDir2(), "daemon.lock");
113808
+ const lock = join85(daemonDir2(), "daemon.lock");
112888
113809
  try {
112889
- if (!existsSync43(lock)) return null;
113810
+ if (!existsSync47(lock)) return null;
112890
113811
  const pid = Number(readFileSync49(lock, "utf-8").trim());
112891
113812
  if (!pid || !isAlive(pid)) return null;
112892
113813
  return { pid, device: readCredentials()?.deviceId };
@@ -112939,6 +113860,16 @@ function usage() {
112939
113860
  Join a network. The token is all you need;
112940
113861
  the name defaults to this machine's hostname.
112941
113862
  tesseract-agent net leave MESH [--yes] Forget a mesh entirely, key included
113863
+ tesseract-agent net helper [status|install|uninstall|enable-nat]
113864
+ The privileged network helper, which is what
113865
+ actually programs the routes. Without it a
113866
+ machine joins, holds a certificate, shows a
113867
+ roster \u2014 and carries no packets. Run the
113868
+ install under sudo (Windows: an elevated
113869
+ shell); there is nothing to prompt on a server.
113870
+ enable-nat is WINDOWS ONLY and only needed to
113871
+ be the way out FOR OTHERS \u2014 it turns on a
113872
+ Windows optional feature and needs a restart.
112942
113873
 
112943
113874
  Running a network (needs a signed-in account):
112944
113875
  tesseract-agent net new [NAME] Create a network and print its join token.
@@ -113120,9 +114051,80 @@ async function netCommand(rest, flags) {
113120
114051
  updateLocal(meshId, { enabled: sub === "up" });
113121
114052
  console.log(`${meshId} ${sub === "up" ? "enabled" : "disabled"}`);
113122
114053
  }
113123
- console.log("Run `tesseract-agent restart` for this to take effect now.");
114054
+ if (sub === "down") {
114055
+ const stillOn = listMeshIds().filter((id) => readLocal(id)?.enabled !== false);
114056
+ const r = await syncRoutes(stillOn);
114057
+ if (r.helperAbsent) {
114058
+ console.log("The network helper is not installed, so nothing was routed anyway.");
114059
+ } else {
114060
+ if (r.down.length) console.log(`routes removed: ${r.down.join(", ")}`);
114061
+ for (const f of r.failed) console.error(`routes ${f.meshId}: ${f.reason}`);
114062
+ }
114063
+ } else if (!await netdAvailable()) {
114064
+ console.log("The network helper is not installed, so nothing will be routed yet.");
114065
+ console.log("Install it with: sudo tesseract-agent net helper install");
114066
+ }
114067
+ console.log("Run `tesseract-agent restart` to start or stop the node itself.");
113124
114068
  return;
113125
114069
  }
114070
+ if (sub === "helper") {
114071
+ const action = rest[1] ?? "status";
114072
+ const svc = makeNetService();
114073
+ if (action === "status") {
114074
+ const st = await svc.state();
114075
+ const bin = netdBinaryPath();
114076
+ console.log(`platform ${process.platform}${svc.supported ? "" : " (no helper for this platform)"}`);
114077
+ console.log(`binary ${bin ?? "NOT SHIPPED IN THIS BUILD"}`);
114078
+ console.log(`installed ${st.installed ? "yes" : "no"}`);
114079
+ console.log(`running ${st.running ? "yes" : "no"}`);
114080
+ console.log(`answering ${await netdAvailable() ? "yes" : "no"}`);
114081
+ if (st.detail) console.log(`note ${st.detail}`);
114082
+ const nat = await natCapability();
114083
+ console.log(`way out for others ${nat.available ? "yes" : "NOT YET"}`);
114084
+ if (!nat.available) {
114085
+ console.log(` ${nat.reason}`);
114086
+ console.log(" Turn it on with: tesseract-agent net helper enable-nat");
114087
+ }
114088
+ return;
114089
+ }
114090
+ if (action === "enable-nat") {
114091
+ const nat = await natCapability();
114092
+ if (nat.available) {
114093
+ console.log("This machine can already be the way out for others. Nothing to do.");
114094
+ return;
114095
+ }
114096
+ const r = await enableNatProvider();
114097
+ if (r.ok) {
114098
+ console.log("The Windows NAT component is enabled.");
114099
+ if (r.restartRequired) {
114100
+ console.log("RESTART REQUIRED to finish. Nothing was restarted for you.");
114101
+ }
114102
+ return;
114103
+ }
114104
+ console.error(`net helper enable-nat: ${r.detail}`);
114105
+ process.exit(r.reason === "unsupported" ? 2 : 1);
114106
+ }
114107
+ if (action === "install") {
114108
+ const r = await ensureNetHelperInstalled();
114109
+ if (r.ok) {
114110
+ console.log(r.already ? "The network helper is already installed." : "The network helper is installed.");
114111
+ return;
114112
+ }
114113
+ console.error(`net helper install: ${r.detail}`);
114114
+ process.exit(r.reason === "unsupported" || r.reason === "no-binary" ? 2 : 1);
114115
+ }
114116
+ if (action === "uninstall") {
114117
+ const r = await svc.uninstall();
114118
+ if (r.ok) {
114119
+ console.log("The network helper is removed.");
114120
+ return;
114121
+ }
114122
+ console.error(`net helper uninstall: ${r.detail ?? "failed"}`);
114123
+ process.exit(1);
114124
+ }
114125
+ console.error(`net helper: unknown action ${action} (status | install | uninstall | enable-nat)`);
114126
+ process.exit(1);
114127
+ }
113126
114128
  if (sub === "join") {
113127
114129
  const token3 = rest[1] ?? str2(flags.token);
113128
114130
  const code = str2(flags.code);
@@ -113442,7 +114444,7 @@ async function netCommand(rest, flags) {
113442
114444
  // src/cli.ts
113443
114445
  function pkgVersion() {
113444
114446
  try {
113445
- const p = join83(dirname36(fileURLToPath7(import.meta.url)), "..", "package.json");
114447
+ const p = join87(dirname38(fileURLToPath8(import.meta.url)), "..", "package.json");
113446
114448
  return JSON.parse(readFileSync52(p, "utf8")).version ?? "0.0.0";
113447
114449
  } catch {
113448
114450
  return "0.0.0";
@@ -113499,7 +114501,7 @@ async function superviseDaemon(cliEntry) {
113499
114501
  let stopping3 = false;
113500
114502
  let child = null;
113501
114503
  const spawnWorker = () => {
113502
- const c = spawn11(process.execPath, [cliEntry, "__worker"], { stdio: "inherit", env: process.env });
114504
+ const c = spawn14(process.execPath, [cliEntry, "__worker"], { stdio: "inherit", env: process.env });
113503
114505
  child = c;
113504
114506
  let settled = false;
113505
114507
  const settle = (fn) => {
@@ -113671,7 +114673,7 @@ async function linkCommand(rest, flags) {
113671
114673
  process.exit(1);
113672
114674
  }
113673
114675
  async function captureClaudeSubscription(flags) {
113674
- const home = mkdtempSync2(join83(tmpdir6(), "tesseract-claude-login-"));
114676
+ const home = mkdtempSync4(join87(tmpdir8(), "tesseract-claude-login-"));
113675
114677
  const binary = typeof flags["claude-path"] === "string" ? flags["claude-path"] : process.env.CCB_ENGINE_PATH_CLAUDE_CODE || "claude";
113676
114678
  const args = ["auth", "login", "--claudeai"];
113677
114679
  if (typeof flags.email === "string") args.push("--email", flags.email);
@@ -113680,7 +114682,7 @@ async function captureClaudeSubscription(flags) {
113680
114682
  console.log("Open the authorization URL in any browser; paste the returned code here if Claude asks for it.");
113681
114683
  try {
113682
114684
  const code = await new Promise((resolveCode, reject) => {
113683
- const child = spawn11(binary, args, {
114685
+ const child = spawn14(binary, args, {
113684
114686
  env: { ...process.env, CLAUDE_CONFIG_DIR: home },
113685
114687
  stdio: "inherit"
113686
114688
  });
@@ -113688,8 +114690,8 @@ async function captureClaudeSubscription(flags) {
113688
114690
  child.once("close", (exitCode, signal) => resolveCode(signal ? 1 : exitCode ?? 1));
113689
114691
  });
113690
114692
  if (code !== 0) throw new Error(`Claude sign-in did not complete (exit ${code}).`);
113691
- const file2 = join83(home, ".credentials.json");
113692
- if (existsSync45(file2)) return readFileSync52(file2, "utf8");
114693
+ const file2 = join87(home, ".credentials.json");
114694
+ if (existsSync49(file2)) return readFileSync52(file2, "utf8");
113693
114695
  if (process.platform === "darwin") {
113694
114696
  const value = execFileSync6("security", [
113695
114697
  "find-generic-password",
@@ -113701,7 +114703,7 @@ async function captureClaudeSubscription(flags) {
113701
114703
  }
113702
114704
  throw new Error("Claude reported success but no credentials were captured.");
113703
114705
  } finally {
113704
- rmSync11(home, { recursive: true, force: true });
114706
+ rmSync13(home, { recursive: true, force: true });
113705
114707
  }
113706
114708
  }
113707
114709
  async function runnerCommand(rest, flags) {
@@ -113816,7 +114818,7 @@ async function main() {
113816
114818
  process.env.CCB_DAEMON_DIR = tessPath(`daemon-${instance}`);
113817
114819
  }
113818
114820
  const force = flags.yes === true || flags.force === true;
113819
- const cliEntry = fileURLToPath7(import.meta.url);
114821
+ const cliEntry = fileURLToPath8(import.meta.url);
113820
114822
  switch (cmd) {
113821
114823
  case "login":
113822
114824
  await login({