omnius 1.0.341 → 1.0.343

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -150501,9 +150501,9 @@ var require_mock_utils = __commonJS({
150501
150501
  if (mockDispatch2.data.callback) {
150502
150502
  mockDispatch2.data = { ...mockDispatch2.data, ...mockDispatch2.data.callback(opts) };
150503
150503
  }
150504
- const { data: { statusCode, data, headers, trailers, error }, delay: delay3, persist: persist3 } = mockDispatch2;
150504
+ const { data: { statusCode, data, headers, trailers, error }, delay: delay3, persist: persist4 } = mockDispatch2;
150505
150505
  const { timesInvoked, times } = mockDispatch2;
150506
- mockDispatch2.consumed = !persist3 && timesInvoked >= times;
150506
+ mockDispatch2.consumed = !persist4 && timesInvoked >= times;
150507
150507
  mockDispatch2.pending = timesInvoked < times;
150508
150508
  if (error !== null) {
150509
150509
  deleteMockDispatch(this[kDispatches], key);
@@ -151150,14 +151150,14 @@ var require_pending_interceptors_formatter = __commonJS({
151150
151150
  }
151151
151151
  format(pendingInterceptors) {
151152
151152
  const withPrettyHeaders = pendingInterceptors.map(
151153
- ({ method, path: path12, data: { statusCode }, persist: persist3, times, timesInvoked, origin }) => ({
151153
+ ({ method, path: path12, data: { statusCode }, persist: persist4, times, timesInvoked, origin }) => ({
151154
151154
  Method: method,
151155
151155
  Origin: origin,
151156
151156
  Path: path12,
151157
151157
  "Status code": statusCode,
151158
- Persistent: persist3 ? PERSISTENT : NOT_PERSISTENT,
151158
+ Persistent: persist4 ? PERSISTENT : NOT_PERSISTENT,
151159
151159
  Invocations: timesInvoked,
151160
- Remaining: persist3 ? Infinity : times - timesInvoked
151160
+ Remaining: persist4 ? Infinity : times - timesInvoked
151161
151161
  })
151162
151162
  );
151163
151163
  this.logger.table(withPrettyHeaders);
@@ -273135,9 +273135,9 @@ print("${sentinel}")
273135
273135
  if (!this.proc || this.proc.killed) {
273136
273136
  return { success: false, path: "" };
273137
273137
  }
273138
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = await import("node:fs");
273138
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
273139
273139
  const sessionDir2 = join43(this.cwd, ".omnius", "rlm");
273140
- mkdirSync105(sessionDir2, { recursive: true });
273140
+ mkdirSync106(sessionDir2, { recursive: true });
273141
273141
  const sessionPath2 = join43(sessionDir2, "session.json");
273142
273142
  try {
273143
273143
  const inspectCode = `
@@ -273161,7 +273161,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
273161
273161
  trajectoryCount: this.trajectory.length,
273162
273162
  subCallCount: this.subCallCount
273163
273163
  };
273164
- writeFileSync90(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
273164
+ writeFileSync91(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
273165
273165
  return { success: true, path: sessionPath2 };
273166
273166
  }
273167
273167
  } catch {
@@ -273173,11 +273173,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
273173
273173
  * what was previously computed. */
273174
273174
  async loadSessionInfo() {
273175
273175
  try {
273176
- const { readFileSync: readFileSync133, existsSync: existsSync163 } = await import("node:fs");
273176
+ const { readFileSync: readFileSync134, existsSync: existsSync164 } = await import("node:fs");
273177
273177
  const sessionPath2 = join43(this.cwd, ".omnius", "rlm", "session.json");
273178
- if (!existsSync163(sessionPath2))
273178
+ if (!existsSync164(sessionPath2))
273179
273179
  return null;
273180
- return JSON.parse(readFileSync133(sessionPath2, "utf8"));
273180
+ return JSON.parse(readFileSync134(sessionPath2, "utf8"));
273181
273181
  } catch {
273182
273182
  return null;
273183
273183
  }
@@ -273364,10 +273364,10 @@ var init_memory_metabolism = __esm({
273364
273364
  const trajDir = join44(this.cwd, ".omnius", "rlm-trajectories");
273365
273365
  let lessons = [];
273366
273366
  try {
273367
- const { readdirSync: readdirSync59, readFileSync: readFileSync133 } = await import("node:fs");
273367
+ const { readdirSync: readdirSync59, readFileSync: readFileSync134 } = await import("node:fs");
273368
273368
  const files = readdirSync59(trajDir).filter((f2) => f2.endsWith(".jsonl")).sort().reverse().slice(0, 3);
273369
273369
  for (const file of files) {
273370
- const lines = readFileSync133(join44(trajDir, file), "utf8").split("\n").filter((l2) => l2.trim());
273370
+ const lines = readFileSync134(join44(trajDir, file), "utf8").split("\n").filter((l2) => l2.trim());
273371
273371
  for (const line of lines) {
273372
273372
  try {
273373
273373
  const entry = JSON.parse(line);
@@ -273751,14 +273751,14 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
273751
273751
  * Optionally filter by task type for phase-aware context (FSM paper insight).
273752
273752
  */
273753
273753
  getTopMemoriesSync(k = 5, taskType) {
273754
- const { readFileSync: readFileSync133, existsSync: existsSync163 } = __require("node:fs");
273754
+ const { readFileSync: readFileSync134, existsSync: existsSync164 } = __require("node:fs");
273755
273755
  const metaDir = join44(this.cwd, ".omnius", "memory", "metabolism");
273756
273756
  const storeFile = join44(metaDir, "store.json");
273757
- if (!existsSync163(storeFile))
273757
+ if (!existsSync164(storeFile))
273758
273758
  return "";
273759
273759
  let store2 = [];
273760
273760
  try {
273761
- store2 = JSON.parse(readFileSync133(storeFile, "utf8"));
273761
+ store2 = JSON.parse(readFileSync134(storeFile, "utf8"));
273762
273762
  } catch {
273763
273763
  return "";
273764
273764
  }
@@ -273780,14 +273780,14 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
273780
273780
  /** Update memory scores based on task outcome. Called after task completion.
273781
273781
  * Memories used in successful tasks get boosted. Memories present during failures get decayed. */
273782
273782
  updateFromOutcomeSync(surfacedMemoryText, succeeded) {
273783
- const { readFileSync: readFileSync133, writeFileSync: writeFileSync90, existsSync: existsSync163, mkdirSync: mkdirSync105 } = __require("node:fs");
273783
+ const { readFileSync: readFileSync134, writeFileSync: writeFileSync91, existsSync: existsSync164, mkdirSync: mkdirSync106 } = __require("node:fs");
273784
273784
  const metaDir = join44(this.cwd, ".omnius", "memory", "metabolism");
273785
273785
  const storeFile = join44(metaDir, "store.json");
273786
- if (!existsSync163(storeFile))
273786
+ if (!existsSync164(storeFile))
273787
273787
  return;
273788
273788
  let store2 = [];
273789
273789
  try {
273790
- store2 = JSON.parse(readFileSync133(storeFile, "utf8"));
273790
+ store2 = JSON.parse(readFileSync134(storeFile, "utf8"));
273791
273791
  } catch {
273792
273792
  return;
273793
273793
  }
@@ -273811,8 +273811,8 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
273811
273811
  updated = true;
273812
273812
  }
273813
273813
  if (updated) {
273814
- mkdirSync105(metaDir, { recursive: true });
273815
- writeFileSync90(storeFile, JSON.stringify(store2, null, 2));
273814
+ mkdirSync106(metaDir, { recursive: true });
273815
+ writeFileSync91(storeFile, JSON.stringify(store2, null, 2));
273816
273816
  }
273817
273817
  }
273818
273818
  // ── Storage ──────────────────────────────────────────────────────────
@@ -274234,13 +274234,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
274234
274234
  // Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
274235
274235
  /** Retrieve top-K strategies for context injection. Returns "" if none. */
274236
274236
  getRelevantStrategiesSync(k = 3, taskType) {
274237
- const { readFileSync: readFileSync133, existsSync: existsSync163 } = __require("node:fs");
274237
+ const { readFileSync: readFileSync134, existsSync: existsSync164 } = __require("node:fs");
274238
274238
  const archiveFile = join46(this.cwd, ".omnius", "arche", "variants.json");
274239
- if (!existsSync163(archiveFile))
274239
+ if (!existsSync164(archiveFile))
274240
274240
  return "";
274241
274241
  let variants = [];
274242
274242
  try {
274243
- variants = JSON.parse(readFileSync133(archiveFile, "utf8"));
274243
+ variants = JSON.parse(readFileSync134(archiveFile, "utf8"));
274244
274244
  } catch {
274245
274245
  return "";
274246
274246
  }
@@ -274258,13 +274258,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
274258
274258
  }
274259
274259
  /** Archive a strategy variant synchronously (for task completion path) */
274260
274260
  archiveVariantSync(strategy, outcome, tags = []) {
274261
- const { readFileSync: readFileSync133, writeFileSync: writeFileSync90, existsSync: existsSync163, mkdirSync: mkdirSync105 } = __require("node:fs");
274261
+ const { readFileSync: readFileSync134, writeFileSync: writeFileSync91, existsSync: existsSync164, mkdirSync: mkdirSync106 } = __require("node:fs");
274262
274262
  const dir = join46(this.cwd, ".omnius", "arche");
274263
274263
  const archiveFile = join46(dir, "variants.json");
274264
274264
  let variants = [];
274265
274265
  try {
274266
- if (existsSync163(archiveFile))
274267
- variants = JSON.parse(readFileSync133(archiveFile, "utf8"));
274266
+ if (existsSync164(archiveFile))
274267
+ variants = JSON.parse(readFileSync134(archiveFile, "utf8"));
274268
274268
  } catch {
274269
274269
  }
274270
274270
  variants.push({
@@ -274279,8 +274279,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
274279
274279
  });
274280
274280
  if (variants.length > 50)
274281
274281
  variants = variants.slice(-50);
274282
- mkdirSync105(dir, { recursive: true });
274283
- writeFileSync90(archiveFile, JSON.stringify(variants, null, 2));
274282
+ mkdirSync106(dir, { recursive: true });
274283
+ writeFileSync91(archiveFile, JSON.stringify(variants, null, 2));
274284
274284
  }
274285
274285
  async saveArchive(variants) {
274286
274286
  const dir = join46(this.cwd, ".omnius", "arche");
@@ -296166,7 +296166,7 @@ var require_util9 = __commonJS({
296166
296166
  return path12;
296167
296167
  }
296168
296168
  exports.normalize = normalize2;
296169
- function join178(aRoot, aPath) {
296169
+ function join179(aRoot, aPath) {
296170
296170
  if (aRoot === "") {
296171
296171
  aRoot = ".";
296172
296172
  }
@@ -296198,7 +296198,7 @@ var require_util9 = __commonJS({
296198
296198
  }
296199
296199
  return joined;
296200
296200
  }
296201
- exports.join = join178;
296201
+ exports.join = join179;
296202
296202
  exports.isAbsolute = function(aPath) {
296203
296203
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
296204
296204
  };
@@ -296371,7 +296371,7 @@ var require_util9 = __commonJS({
296371
296371
  parsed.path = parsed.path.substring(0, index + 1);
296372
296372
  }
296373
296373
  }
296374
- sourceURL = join178(urlGenerate(parsed), sourceURL);
296374
+ sourceURL = join179(urlGenerate(parsed), sourceURL);
296375
296375
  }
296376
296376
  return normalize2(sourceURL);
296377
296377
  }
@@ -511784,7 +511784,7 @@ var require_path_browserify = __commonJS({
511784
511784
  assertPath(path12);
511785
511785
  return path12.length > 0 && path12.charCodeAt(0) === 47;
511786
511786
  },
511787
- join: function join178() {
511787
+ join: function join179() {
511788
511788
  if (arguments.length === 0)
511789
511789
  return ".";
511790
511790
  var joined;
@@ -563673,9 +563673,9 @@ var init_reflectionBuffer = __esm({
563673
563673
  this.persistPath = persistPath ?? null;
563674
563674
  if (this.persistPath) {
563675
563675
  try {
563676
- const { readFileSync: readFileSync133, existsSync: existsSync163 } = __require("node:fs");
563677
- if (existsSync163(this.persistPath)) {
563678
- this.state = JSON.parse(readFileSync133(this.persistPath, "utf-8"));
563676
+ const { readFileSync: readFileSync134, existsSync: existsSync164 } = __require("node:fs");
563677
+ if (existsSync164(this.persistPath)) {
563678
+ this.state = JSON.parse(readFileSync134(this.persistPath, "utf-8"));
563679
563679
  return;
563680
563680
  }
563681
563681
  } catch {
@@ -563954,12 +563954,12 @@ var init_reflectionBuffer = __esm({
563954
563954
  if (!this.persistPath)
563955
563955
  return;
563956
563956
  try {
563957
- const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync105, existsSync: existsSync163 } = __require("node:fs");
563958
- const { join: join178 } = __require("node:path");
563959
- const dir = join178(this.persistPath, "..");
563960
- if (!existsSync163(dir))
563961
- mkdirSync105(dir, { recursive: true });
563962
- writeFileSync90(this.persistPath, JSON.stringify(this.state, null, 2));
563957
+ const { writeFileSync: writeFileSync91, mkdirSync: mkdirSync106, existsSync: existsSync164 } = __require("node:fs");
563958
+ const { join: join179 } = __require("node:path");
563959
+ const dir = join179(this.persistPath, "..");
563960
+ if (!existsSync164(dir))
563961
+ mkdirSync106(dir, { recursive: true });
563962
+ writeFileSync91(this.persistPath, JSON.stringify(this.state, null, 2));
563963
563963
  } catch {
563964
563964
  }
563965
563965
  }
@@ -564747,6 +564747,111 @@ function recommendFanout(breadth) {
564747
564747
  return 3;
564748
564748
  return 1;
564749
564749
  }
564750
+ function deriveRegions(rootEntries, packagesEntries, opts = {}) {
564751
+ const max = Math.max(2, opts.max ?? 8);
564752
+ const keep = (e2) => e2.isDir && !e2.name.startsWith(".") && !REGION_IGNORE_RE.test(e2.name);
564753
+ const pkgs = (packagesEntries ?? []).filter(keep).map((e2) => `packages/${e2.name}`);
564754
+ if (pkgs.length >= 2)
564755
+ return pkgs.slice(0, max);
564756
+ const dirs = (rootEntries ?? []).filter(keep).map((e2) => e2.name);
564757
+ return dirs.slice(0, max);
564758
+ }
564759
+ function buildExplorerPrompt(brief) {
564760
+ return [
564761
+ `You are a READ-ONLY exploration sub-agent. Objective: ${brief.objective}`,
564762
+ `Your region (do NOT read outside it): ${brief.scope}`,
564763
+ "Boundaries:",
564764
+ ...brief.boundaries.map((b) => `- ${b}`),
564765
+ "FIRST run grep_search across your region for keywords from the objective; open only the most promising hits with file_read. Read NARROW — never dump whole files.",
564766
+ "Then call task_complete. In the summary, give one short line per genuinely-relevant file as `path — why it matters`.",
564767
+ "Your summary MUST END with a single line in EXACTLY this format, listing ONLY files that truly match the objective:",
564768
+ " RELEVANT_FILES: <comma-separated repo-relative paths>",
564769
+ "If your region has NOTHING pertinent, the final line must be exactly: RELEVANT_FILES: none",
564770
+ "Do NOT list files you merely read to rule the region out — only real matches go in RELEVANT_FILES."
564771
+ ].join("\n");
564772
+ }
564773
+ function extractPathFindings(text2) {
564774
+ const findings = [];
564775
+ const seen = /* @__PURE__ */ new Set();
564776
+ const pathRe = /([A-Za-z0-9_.@/-]+\/[A-Za-z0-9_./-]+\.[A-Za-z]{1,6})(?:\s*[—:\-]+\s*(.*))?/;
564777
+ for (const line of String(text2 || "").split(/\r?\n/)) {
564778
+ const m2 = line.match(pathRe);
564779
+ if (!m2 || !m2[1])
564780
+ continue;
564781
+ const path12 = m2[1].replace(/[)\]}.,;]+$/, "");
564782
+ if (seen.has(path12))
564783
+ continue;
564784
+ seen.add(path12);
564785
+ findings.push({ path: path12, whyRelevant: (m2[2] ?? "").trim().slice(0, 200) });
564786
+ }
564787
+ return findings;
564788
+ }
564789
+ function parseExplorerDigest(region, rawText) {
564790
+ const text2 = String(rawText || "");
564791
+ const reasonByPath = new Map(extractPathFindings(text2).map((f2) => [f2.path, f2.whyRelevant]));
564792
+ const relMatches = [...text2.matchAll(/RELEVANT_FILES?\s*:\s*(.+)/gi)];
564793
+ if (relMatches.length > 0) {
564794
+ const value2 = (relMatches[relMatches.length - 1][1] ?? "").trim();
564795
+ if (/^(none|n\/a|-|nil|empty)\b/i.test(value2)) {
564796
+ return { region, relevant: false, findings: [], summary: "" };
564797
+ }
564798
+ const paths = [];
564799
+ const seen = /* @__PURE__ */ new Set();
564800
+ for (const tok of value2.split(/[,|]/)) {
564801
+ const m2 = tok.match(PATH_LIKE_RE);
564802
+ if (!m2)
564803
+ continue;
564804
+ const p2 = m2[0];
564805
+ if (!seen.has(p2)) {
564806
+ seen.add(p2);
564807
+ paths.push(p2);
564808
+ }
564809
+ }
564810
+ if (paths.length > 0) {
564811
+ return compressFindings({
564812
+ region,
564813
+ relevant: true,
564814
+ findings: paths.map((p2) => ({ path: p2, whyRelevant: reasonByPath.get(p2) ?? "" })),
564815
+ summary: ""
564816
+ });
564817
+ }
564818
+ return { region, relevant: false, findings: [], summary: "" };
564819
+ }
564820
+ const jsonMatch = text2.match(/\{[\s\S]*\}/);
564821
+ if (jsonMatch) {
564822
+ try {
564823
+ const obj = JSON.parse(jsonMatch[0]);
564824
+ if (obj && typeof obj === "object") {
564825
+ const explicitlyIrrelevant = obj["relevant"] === false;
564826
+ const rawFindings = Array.isArray(obj["findings"]) ? obj["findings"] : [];
564827
+ const findings = rawFindings.map((f2) => {
564828
+ const o2 = f2 ?? {};
564829
+ const why = o2["whyRelevant"] ?? o2["why_relevant"] ?? o2["why"] ?? "";
564830
+ const snip = o2["snippet"];
564831
+ return {
564832
+ path: String(o2["path"] ?? ""),
564833
+ whyRelevant: String(why),
564834
+ ...snip ? { snippet: String(snip) } : {}
564835
+ };
564836
+ }).filter((f2) => f2.path);
564837
+ if (explicitlyIrrelevant || findings.length > 0) {
564838
+ return compressFindings({
564839
+ region,
564840
+ relevant: !explicitlyIrrelevant && findings.length > 0,
564841
+ findings,
564842
+ summary: typeof obj["summary"] === "string" ? obj["summary"] : ""
564843
+ });
564844
+ }
564845
+ }
564846
+ } catch {
564847
+ }
564848
+ }
564849
+ if (NEGATIVE_SIGNAL_RE.test(text2)) {
564850
+ return { region, relevant: false, findings: [], summary: "" };
564851
+ }
564852
+ const scraped = extractPathFindings(text2);
564853
+ return compressFindings({ region, relevant: scraped.length > 0, findings: scraped, summary: "" });
564854
+ }
564750
564855
  function buildExplorerBriefs(objectivePrefix, regions) {
564751
564856
  const outputSchema = "Return JSON: { relevant: boolean, findings: [{ path, why_relevant, snippet? }], summary }. Return relevant=false with empty findings if your region has nothing pertinent (do NOT pad).";
564752
564857
  return regions.map((region) => ({
@@ -564792,14 +564897,11 @@ function fanoutDirective(taskText) {
564792
564897
  const n2 = recommendFanout(classifyBreadth(sig));
564793
564898
  if (n2 < 2)
564794
564899
  return null;
564795
- const schema = buildExplorerBriefs("x", ["x"])[0].outputSchema;
564796
564900
  return [
564797
564901
  "[Exploration strategy — fan out]",
564798
- `This task is broad, read-heavy discovery. Prefer FANNING OUT over reading serially: split the search surface into ${n2} NON-OVERLAPPING regions (directories/subsystems) and spawn ${n2} parallel READ-ONLY \`sub_agent\` explorers one per region.`,
564799
- `Give each explorer: a one-line objective, its single region, and this exact return schema${schema}`,
564800
- "Explorers are READ-ONLY (no edit/write/mutating commands). Each returns a DISTILLED digest (paths + why-relevant + key snippets), and returns relevant=false / empty when its region has nothing pertinent — do NOT pad.",
564801
- "Then YOU merge the digests: drop the empty regions, dedupe paths, and work from the merged digest — keep your own context small by reasoning over the distilled findings, never raw file dumps.",
564802
- "Only fan out when the surface genuinely spans multiple regions; for a single-file or narrow change, just do it directly."
564902
+ "This task is broad, read-heavy discovery across multiple components. Do NOT grep the whole repo serially into your own context that floods you with raw output and is slow.",
564903
+ "Instead make ONE call to `fanout_explore` with a clear `objective` (what you need to find). It splits the codebase into non-overlapping regions, runs parallel READ-ONLY explorer sub-agents that each return a DISTILLED digest, merges them, and hands you back a compact map of relevant paths keeping your own context small.",
564904
+ "After fanout_explore returns, work from the merged digest: open only the paths it flagged. Fall back to direct grep_search/file_read only for a single-file or narrow follow-up."
564803
564905
  ].join("\n");
564804
564906
  }
564805
564907
  function mergeDigests(digests) {
@@ -564818,11 +564920,14 @@ function mergeDigests(digests) {
564818
564920
  const synthesis = relevant.length ? `${relevant.length} region(s) yielded ${paths.length} relevant path(s); ${emptyRegions.length} region(s) empty.` : `No relevant findings across ${digests.length} region(s).`;
564819
564921
  return { digests: relevant, paths, emptyRegions, synthesis };
564820
564922
  }
564821
- var EXPLORE_INTENT_RE;
564923
+ var EXPLORE_INTENT_RE, REGION_IGNORE_RE, PATH_LIKE_RE, NEGATIVE_SIGNAL_RE;
564822
564924
  var init_exploration_fanout = __esm({
564823
564925
  "packages/orchestrator/dist/exploration-fanout.js"() {
564824
564926
  "use strict";
564825
564927
  EXPLORE_INTENT_RE = /\b(explore|discover|find|locate|search|where\b|which file|map (out )?the|survey|audit|trace|understand the|gather|investigate|look (through|across)|grep|scan the (code|repo))\b/i;
564928
+ REGION_IGNORE_RE = /^(node_modules|dist|build|coverage|out|tmp|temp|\.git|\.next|\.turbo|\.cache|\.omnius|\.aiwg|\.vscode|\.idea|target|vendor)$/i;
564929
+ PATH_LIKE_RE = /[A-Za-z0-9_.@/-]+\/[A-Za-z0-9_./-]+\.[A-Za-z]{1,6}/;
564930
+ NEGATIVE_SIGNAL_RE = /findings?\s*:?\s*\**\s*none\b|\bnone\s+found\b|\bno\s+(relevant\s+)?(matches|results|findings|auth\w*|bearer|token)\b|\bnot\s+handled\b|\bnothing\s+(pertinent|relevant|found)\b|no[^.\n]{0,40}\b(was|were)\s+found\b/i;
564826
564931
  }
564827
564932
  });
564828
564933
 
@@ -568549,19 +568654,27 @@ function isOllamaModelNotFoundResponse(status, text2, model) {
568549
568654
  function isBackendConnectionError(err) {
568550
568655
  if (err instanceof Error && err.name === "AbortError")
568551
568656
  return false;
568657
+ return /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EHOSTUNREACH|ENOTFOUND|EPIPE|socket hang up|UND_ERR/i.test(flattenErrorText(err));
568658
+ }
568659
+ function flattenErrorText(err) {
568552
568660
  const parts = [];
568553
- if (err instanceof Error) {
568554
- parts.push(err.message);
568555
- const cause = err.cause;
568556
- if (cause instanceof Error)
568557
- parts.push(cause.message);
568558
- const code8 = cause?.code;
568559
- if (typeof code8 === "string")
568560
- parts.push(code8);
568561
- } else if (typeof err === "string") {
568562
- parts.push(err);
568563
- }
568564
- return /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EHOSTUNREACH|ENOTFOUND|EPIPE|socket hang up|UND_ERR/i.test(parts.join(" "));
568661
+ let cur = err;
568662
+ for (let depth = 0; depth < 5 && cur != null; depth++) {
568663
+ if (cur instanceof Error) {
568664
+ if (cur.message)
568665
+ parts.push(cur.message);
568666
+ const code8 = cur.code;
568667
+ if (typeof code8 === "string")
568668
+ parts.push(code8);
568669
+ cur = cur.cause;
568670
+ } else if (typeof cur === "string") {
568671
+ parts.push(cur);
568672
+ break;
568673
+ } else {
568674
+ break;
568675
+ }
568676
+ }
568677
+ return parts.join(" ");
568565
568678
  }
568566
568679
  function computeEffectiveThink(params) {
568567
568680
  if (process.env["OMNIUS_FORCE_NO_THINK"] === "1")
@@ -580061,10 +580174,10 @@ ${this._completionCaveat}` : this._completionCaveat;
580061
580174
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
580062
580175
  });
580063
580176
  try {
580064
- const { mkdirSync: mkdirSync105, readdirSync: readdirSync59, statSync: statSync59, unlinkSync: unlinkSync35, writeFileSync: writeFileSync90 } = __require("node:fs");
580065
- const { join: join178 } = __require("node:path");
580066
- const contextDir = join178(this._workingDirectory || process.cwd(), ".omnius", "context");
580067
- mkdirSync105(contextDir, { recursive: true });
580177
+ const { mkdirSync: mkdirSync106, readdirSync: readdirSync59, statSync: statSync59, unlinkSync: unlinkSync35, writeFileSync: writeFileSync91 } = __require("node:fs");
580178
+ const { join: join179 } = __require("node:path");
580179
+ const contextDir = join179(this._workingDirectory || process.cwd(), ".omnius", "context");
580180
+ mkdirSync106(contextDir, { recursive: true });
580068
580181
  const topEntities = this._temporalGraph.nodesByType("entity", 3);
580069
580182
  const topFiles = this._temporalGraph.nodesByType("file", 3);
580070
580183
  const topConcepts = this._temporalGraph.nodesByType("concept", 3);
@@ -580104,18 +580217,18 @@ ${this._completionCaveat}` : this._completionCaveat;
580104
580217
  section("Top Files", topFiles);
580105
580218
  section("Top Concepts", topConcepts);
580106
580219
  lines.push("(Use file_read on this file for quick recall. See provenance JSON for full edge detail.)");
580107
- const kgSummaryDir = join178(contextDir, "kg-summary");
580108
- mkdirSync105(kgSummaryDir, { recursive: true });
580220
+ const kgSummaryDir = join179(contextDir, "kg-summary");
580221
+ mkdirSync106(kgSummaryDir, { recursive: true });
580109
580222
  const summaryFilename = `kg-summary-${this._sessionId}.md`;
580110
- const outPath = join178(kgSummaryDir, summaryFilename);
580111
- writeFileSync90(outPath, lines.join("\n"), "utf-8");
580112
- writeFileSync90(join178(kgSummaryDir, "latest.md"), lines.join("\n"), "utf-8");
580113
- writeFileSync90(join178(contextDir, `kg-summary-latest.md`), [
580223
+ const outPath = join179(kgSummaryDir, summaryFilename);
580224
+ writeFileSync91(outPath, lines.join("\n"), "utf-8");
580225
+ writeFileSync91(join179(kgSummaryDir, "latest.md"), lines.join("\n"), "utf-8");
580226
+ writeFileSync91(join179(contextDir, `kg-summary-latest.md`), [
580114
580227
  "Latest KG summary moved to `.omnius/context/kg-summary/latest.md`.",
580115
580228
  "",
580116
580229
  lines.join("\n")
580117
580230
  ].join("\n"), "utf-8");
580118
- writeFileSync90(join178(kgSummaryDir, "index.json"), JSON.stringify({
580231
+ writeFileSync91(join179(kgSummaryDir, "index.json"), JSON.stringify({
580119
580232
  schema: "omnius.kg-summary-index.v1",
580120
580233
  latest: "latest.md",
580121
580234
  latestSessionFile: summaryFilename,
@@ -580127,7 +580240,7 @@ ${this._completionCaveat}` : this._completionCaveat;
580127
580240
  const maxFiles = parseInt(process.env["OMNIUS_KG_SUMMARY_MAX_FILES"] || "60", 10) || 60;
580128
580241
  const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3;
580129
580242
  const summaries = readdirSync59(kgSummaryDir).filter((name10) => name10.startsWith("kg-summary-") && name10.endsWith(".md")).map((name10) => {
580130
- const filePath = join178(kgSummaryDir, name10);
580243
+ const filePath = join179(kgSummaryDir, name10);
580131
580244
  const stat8 = statSync59(filePath);
580132
580245
  return { filePath, mtimeMs: stat8.mtimeMs };
580133
580246
  }).sort((a2, b) => b.mtimeMs - a2.mtimeMs);
@@ -580414,11 +580527,11 @@ ${errOutput}`);
580414
580527
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
580415
580528
  });
580416
580529
  try {
580417
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = __require("node:fs");
580418
- const { join: join178 } = __require("node:path");
580419
- const resultsDir = join178(this.omniusStateDir(), "tool-results");
580420
- mkdirSync105(resultsDir, { recursive: true });
580421
- writeFileSync90(join178(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
580530
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = __require("node:fs");
580531
+ const { join: join179 } = __require("node:path");
580532
+ const resultsDir = join179(this.omniusStateDir(), "tool-results");
580533
+ mkdirSync106(resultsDir, { recursive: true });
580534
+ writeFileSync91(join179(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
580422
580535
  # Turn: ${turn}
580423
580536
  # Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
580424
580537
  # Size: ${result.output.length} chars, ${lineCount} lines
@@ -580811,10 +580924,10 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
580811
580924
  if (!this._workingDirectory)
580812
580925
  return;
580813
580926
  try {
580814
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = __require("node:fs");
580815
- const { join: join178 } = __require("node:path");
580816
- const sessionDir2 = this.options.stateDir ? join178(this.omniusStateDir(), "session", this._sessionId) : join178(this._workingDirectory, ".omnius", "session", this._sessionId);
580817
- mkdirSync105(sessionDir2, { recursive: true });
580927
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = __require("node:fs");
580928
+ const { join: join179 } = __require("node:path");
580929
+ const sessionDir2 = this.options.stateDir ? join179(this.omniusStateDir(), "session", this._sessionId) : join179(this._workingDirectory, ".omnius", "session", this._sessionId);
580930
+ mkdirSync106(sessionDir2, { recursive: true });
580818
580931
  const checkpoint = {
580819
580932
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
580820
580933
  sessionId: this._sessionId,
@@ -580826,7 +580939,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
580826
580939
  memexEntryCount: this._memexArchive.size,
580827
580940
  fileRegistrySize: this._fileRegistry.size
580828
580941
  };
580829
- writeFileSync90(join178(sessionDir2, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
580942
+ writeFileSync91(join179(sessionDir2, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
580830
580943
  } catch {
580831
580944
  }
580832
580945
  }
@@ -581515,8 +581628,8 @@ ${telegramPersonaHead}` : stripped
581515
581628
  let recoveredTokens = 0;
581516
581629
  for (const [filePath, entry] of entries) {
581517
581630
  try {
581518
- const { readFileSync: readFileSync133 } = await import("node:fs");
581519
- const content = readFileSync133(filePath, "utf8");
581631
+ const { readFileSync: readFileSync134 } = await import("node:fs");
581632
+ const content = readFileSync134(filePath, "utf8");
581520
581633
  const tokenEst = Math.ceil(content.length / 4);
581521
581634
  if (recoveredTokens + tokenEst > fileRecoveryBudget)
581522
581635
  break;
@@ -583340,14 +583453,16 @@ ${result}`
583340
583453
  isTransientError(err) {
583341
583454
  if (err instanceof Error && err.fatal)
583342
583455
  return false;
583343
- const msg = err instanceof Error ? err.message : String(err);
583456
+ const msg = flattenErrorText(err);
583457
+ if (this.isRecoverableAuthError(err))
583458
+ return true;
583344
583459
  if (/HTTP 402|402 Payment|payment required|insufficient (credits|funds|balance)/i.test(msg))
583345
583460
  return true;
583346
583461
  if (/HTTP 429|429 Too Many|rate.?limit|too many requests/i.test(msg))
583347
583462
  return true;
583348
583463
  if (/Backend HTTP (502|503|504)/i.test(msg))
583349
583464
  return true;
583350
- if (/fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EPIPE|socket hang up/i.test(msg))
583465
+ if (/fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EPIPE|socket hang up|UND_ERR|other side closed/i.test(msg))
583351
583466
  return true;
583352
583467
  if (/received HTML error page/i.test(msg))
583353
583468
  return true;
@@ -583367,6 +583482,16 @@ ${result}`
583367
583482
  const msg = err instanceof Error ? err.message : String(err);
583368
583483
  return /No GPU slot available after 30s\. All slots occupied\./i.test(msg);
583369
583484
  }
583485
+ /**
583486
+ * Recoverable authentication/session error (HTTP 401/403). Distinguished
583487
+ * from a hard config error: this fires when a previously-working backend
583488
+ * loses its session (e.g. "No cookie auth credentials found" after a socket
583489
+ * reset). The fix is to re-authenticate and retry, not to abort the task.
583490
+ */
583491
+ isRecoverableAuthError(err) {
583492
+ const msg = flattenErrorText(err);
583493
+ return /Backend HTTP 401|Backend HTTP 403|HTTP 401|HTTP 403|\b401\b|\b403\b|No cookie auth|cookie auth credentials|unauthor(?:ized|ised)|session (?:expired|invalid|not found)|invalid session|credentials (?:not found|expired|missing)/i.test(msg);
583494
+ }
583370
583495
  /** Detect 402 payment-required errors that should trigger key rotation */
583371
583496
  isPaymentRequiredError(err) {
583372
583497
  const msg = err instanceof Error ? err.message : String(err);
@@ -583418,17 +583543,17 @@ ${result}`
583418
583543
  let resizedBase64 = null;
583419
583544
  try {
583420
583545
  const { execSync: execSync63 } = await import("node:child_process");
583421
- const { writeFileSync: writeFileSync90, readFileSync: readFileSync133, unlinkSync: unlinkSync35 } = await import("node:fs");
583422
- const { join: join178 } = await import("node:path");
583546
+ const { writeFileSync: writeFileSync91, readFileSync: readFileSync134, unlinkSync: unlinkSync35 } = await import("node:fs");
583547
+ const { join: join179 } = await import("node:path");
583423
583548
  const { tmpdir: tmpdir24 } = await import("node:os");
583424
- const tmpIn = join178(tmpdir24(), `omnius_img_in_${Date.now()}.png`);
583425
- const tmpOut = join178(tmpdir24(), `omnius_img_out_${Date.now()}.jpg`);
583426
- writeFileSync90(tmpIn, buffer2);
583549
+ const tmpIn = join179(tmpdir24(), `omnius_img_in_${Date.now()}.png`);
583550
+ const tmpOut = join179(tmpdir24(), `omnius_img_out_${Date.now()}.jpg`);
583551
+ writeFileSync91(tmpIn, buffer2);
583427
583552
  const pyBin = process.platform === "win32" ? "python" : "python3";
583428
583553
  const escapedIn = tmpIn.replace(/\\/g, "\\\\");
583429
583554
  const escapedOut = tmpOut.replace(/\\/g, "\\\\");
583430
583555
  execSync63(`${pyBin} -c "from PIL import Image; img = Image.open('${escapedIn}'); img.thumbnail((512, 512), Image.LANCZOS); img = img.convert('RGB'); img.save('${escapedOut}', 'JPEG', quality=75)"`, { timeout: 1e4, stdio: "pipe" });
583431
- const resizedBuf = readFileSync133(tmpOut);
583556
+ const resizedBuf = readFileSync134(tmpOut);
583432
583557
  resizedBase64 = `data:image/jpeg;base64,${resizedBuf.toString("base64")}`;
583433
583558
  try {
583434
583559
  unlinkSync35(tmpIn);
@@ -583581,10 +583706,11 @@ ${description}`
583581
583706
  async retryOnTransient(initialErr, chatRequest, turn) {
583582
583707
  if (!this.isTransientError(initialErr))
583583
583708
  return null;
583584
- const errMsg = initialErr instanceof Error ? initialErr.message : String(initialErr);
583585
- const isNetworkError2 = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket hang up/i.test(errMsg);
583709
+ const errMsg = flattenErrorText(initialErr);
583710
+ const isNetworkError2 = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket hang up|UND_ERR|other side closed/i.test(errMsg);
583711
+ const isAuthError = this.isRecoverableAuthError(initialErr);
583586
583712
  const isGpuSlotUnavailable = this.isGpuSlotUnavailableError(initialErr);
583587
- const maxRetries = isNetworkError2 || isGpuSlotUnavailable ? Infinity : 3;
583713
+ const maxRetries = isNetworkError2 || isGpuSlotUnavailable || isAuthError ? Infinity : 3;
583588
583714
  const baseDelayMs = isGpuSlotUnavailable ? 1e3 : isNetworkError2 ? 5e3 : 3e3;
583589
583715
  const maxDelayMs = 6e4;
583590
583716
  const backend = this.backend;
@@ -583623,6 +583749,22 @@ ${description}`
583623
583749
  return null;
583624
583750
  }
583625
583751
  }
583752
+ if (isAuthError) {
583753
+ try {
583754
+ const reauthed = await backend.reauth?.();
583755
+ this.emit({
583756
+ type: "status",
583757
+ content: reauthed === false ? `Session lost (auth) — retrying (re-auth unavailable, re-presenting credentials)` : `Session lost (auth) — re-authenticating and retrying`,
583758
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
583759
+ });
583760
+ } catch {
583761
+ this.emit({
583762
+ type: "status",
583763
+ content: `Session lost (auth) — retrying`,
583764
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
583765
+ });
583766
+ }
583767
+ }
583626
583768
  const delay3 = isGpuSlotUnavailable ? baseDelayMs : Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
583627
583769
  const attemptLabel = maxRetries === Infinity ? `${attempt}` : `${attempt}/${maxRetries}`;
583628
583770
  if (isGpuSlotUnavailable) {
@@ -590482,6 +590624,7 @@ __export(dist_exports3, {
590482
590624
  buildDecompositionDirective: () => buildDecompositionDirective,
590483
590625
  buildDecompositionTodos: () => buildDecompositionTodos,
590484
590626
  buildExplorerBriefs: () => buildExplorerBriefs,
590627
+ buildExplorerPrompt: () => buildExplorerPrompt,
590485
590628
  buildForkPrompt: () => buildForkPrompt,
590486
590629
  buildLessonQuery: () => buildLessonQuery,
590487
590630
  buildMetaCritiquePrompt: () => buildMetaCritiquePrompt,
@@ -590520,6 +590663,7 @@ __export(dist_exports3, {
590520
590663
  decomposeSpec: () => decomposeSpec,
590521
590664
  deleteAgentTaskSidecar: () => deleteAgentTaskSidecar,
590522
590665
  deriveClaimsFromProposedText: () => deriveClaimsFromProposedText,
590666
+ deriveRegions: () => deriveRegions,
590523
590667
  detectExitCodeMisread: () => detectExitCodeMisread,
590524
590668
  detectExplorationIntent: () => detectExplorationIntent,
590525
590669
  detectPressure: () => detectPressure,
@@ -590532,6 +590676,7 @@ __export(dist_exports3, {
590532
590676
  extractConstraint: () => extractConstraint,
590533
590677
  extractLessons: () => extractLessons,
590534
590678
  extractMidTaskSteeringInput: () => extractMidTaskSteeringInput,
590679
+ extractPathFindings: () => extractPathFindings,
590535
590680
  extractTaskCompleteSummary: () => extractTaskCompleteSummary,
590536
590681
  fanoutDirective: () => fanoutDirective,
590537
590682
  findDuplicateGroups: () => findDuplicateGroups,
@@ -590591,6 +590736,7 @@ __export(dist_exports3, {
590591
590736
  noteAfterTask: () => noteAfterTask,
590592
590737
  parseContextReferences: () => parseContextReferences,
590593
590738
  parseCritique: () => parseCritique,
590739
+ parseExplorerDigest: () => parseExplorerDigest,
590594
590740
  parseMetaCritique: () => parseMetaCritique,
590595
590741
  parsePlan: () => parsePlan,
590596
590742
  parseTextToolCalls: () => parseTextToolCalls,
@@ -598618,25 +598764,25 @@ async function fetchOpenAIModels(baseUrl2, apiKey) {
598618
598764
  async function fetchPeerModels(peerId, authKey) {
598619
598765
  try {
598620
598766
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports2));
598621
- const { existsSync: existsSync163, readFileSync: readFileSync133 } = await import("node:fs");
598622
- const { join: join178 } = await import("node:path");
598767
+ const { existsSync: existsSync164, readFileSync: readFileSync134 } = await import("node:fs");
598768
+ const { join: join179 } = await import("node:path");
598623
598769
  const cwd4 = process.cwd();
598624
598770
  const nexusTool = new NexusTool2(cwd4);
598625
598771
  const nexusDir = nexusTool.getNexusDir();
598626
598772
  let isLocalPeer = false;
598627
598773
  try {
598628
- const statusPath = join178(nexusDir, "status.json");
598629
- if (existsSync163(statusPath)) {
598630
- const status = JSON.parse(readFileSync133(statusPath, "utf8"));
598774
+ const statusPath = join179(nexusDir, "status.json");
598775
+ if (existsSync164(statusPath)) {
598776
+ const status = JSON.parse(readFileSync134(statusPath, "utf8"));
598631
598777
  if (status.peerId === peerId) isLocalPeer = true;
598632
598778
  }
598633
598779
  } catch {
598634
598780
  }
598635
598781
  if (isLocalPeer) {
598636
- const pricingPath = join178(nexusDir, "pricing.json");
598637
- if (existsSync163(pricingPath)) {
598782
+ const pricingPath = join179(nexusDir, "pricing.json");
598783
+ if (existsSync164(pricingPath)) {
598638
598784
  try {
598639
- const pricing = JSON.parse(readFileSync133(pricingPath, "utf8"));
598785
+ const pricing = JSON.parse(readFileSync134(pricingPath, "utf8"));
598640
598786
  const localModels = (pricing.models || []).map((m2) => ({
598641
598787
  name: m2.model || "unknown",
598642
598788
  size: m2.parameterSize || "",
@@ -598649,10 +598795,10 @@ async function fetchPeerModels(peerId, authKey) {
598649
598795
  }
598650
598796
  }
598651
598797
  }
598652
- const cachePath2 = join178(nexusDir, "peer-models-cache.json");
598653
- if (existsSync163(cachePath2)) {
598798
+ const cachePath2 = join179(nexusDir, "peer-models-cache.json");
598799
+ if (existsSync164(cachePath2)) {
598654
598800
  try {
598655
- const cache8 = JSON.parse(readFileSync133(cachePath2, "utf8"));
598801
+ const cache8 = JSON.parse(readFileSync134(cachePath2, "utf8"));
598656
598802
  if (cache8.peerId === peerId && cache8.models?.length > 0) {
598657
598803
  const age = Date.now() - new Date(cache8.cachedAt).getTime();
598658
598804
  if (age < 5 * 60 * 1e3) {
@@ -598764,10 +598910,10 @@ async function fetchPeerModels(peerId, authKey) {
598764
598910
  } catch {
598765
598911
  }
598766
598912
  if (isLocalPeer) {
598767
- const pricingPath = join178(nexusDir, "pricing.json");
598768
- if (existsSync163(pricingPath)) {
598913
+ const pricingPath = join179(nexusDir, "pricing.json");
598914
+ if (existsSync164(pricingPath)) {
598769
598915
  try {
598770
- const pricing = JSON.parse(readFileSync133(pricingPath, "utf8"));
598916
+ const pricing = JSON.parse(readFileSync134(pricingPath, "utf8"));
598771
598917
  return (pricing.models || []).map((m2) => ({
598772
598918
  name: m2.model || "unknown",
598773
598919
  size: m2.parameterSize || "",
@@ -610902,6 +611048,28 @@ var init_status_bar = __esm({
610902
611048
  _brailleSpinner = new BrailleSpinner();
610903
611049
  /** Slow refresh timer for monitoring bar when braille spinner is off */
610904
611050
  _monitorTimer = null;
611051
+ /**
611052
+ * Header inference indicator — a small braille glyph that cycles next to the
611053
+ * "Omnius v{version}" identity segment (left of the menu buttons) WHENEVER the
611054
+ * agent is inferencing, so the user can see it's working in the background and
611055
+ * not stalled — including during prompt-processing / cold-load before any
611056
+ * tokens stream. Self-driven on its own timer so it animates even when no
611057
+ * tokens are flowing yet.
611058
+ */
611059
+ static HEADER_SPINNER_FRAMES = [
611060
+ "⠋",
611061
+ "⠙",
611062
+ "⠹",
611063
+ "⠸",
611064
+ "⠼",
611065
+ "⠴",
611066
+ "⠦",
611067
+ "⠧",
611068
+ "⠇",
611069
+ "⠏"
611070
+ ];
611071
+ _headerSpinnerFrame = 0;
611072
+ _headerSpinnerTimer = null;
610905
611073
  /** Current dynamic footer height: box top + input rows + box bottom + optional metrics. */
610906
611074
  _currentFooterHeight = 4;
610907
611075
  // box-top(1) + input(1) + box-bottom(1) + metrics(1)
@@ -611006,6 +611174,14 @@ var init_status_bar = __esm({
611006
611174
  last2.width += 2;
611007
611175
  }
611008
611176
  }
611177
+ if (this._processing) {
611178
+ const glyph = _StatusBar.HEADER_SPINNER_FRAMES[this._headerSpinnerFrame] ?? "";
611179
+ const last2 = parts[parts.length - 1];
611180
+ if (last2 && glyph) {
611181
+ last2.text += `${glyph} `;
611182
+ last2.width += 2;
611183
+ }
611184
+ }
611009
611185
  return parts;
611010
611186
  }
611011
611187
  buildHeaderIdentityRender() {
@@ -611517,10 +611693,35 @@ var init_status_bar = __esm({
611517
611693
  clearInterval(this._monitorTimer);
611518
611694
  this._monitorTimer = null;
611519
611695
  }
611696
+ this._startHeaderSpinner();
611520
611697
  } else {
611698
+ this._stopHeaderSpinner();
611521
611699
  this.ensureMonitorTimer();
611522
611700
  }
611523
611701
  }
611702
+ /**
611703
+ * Start cycling the header inference glyph. Ticks on its own ~110 ms timer
611704
+ * and repaints the header panels so the braille frame advances even while the
611705
+ * model is still processing the prompt (no token stream yet). Idempotent.
611706
+ */
611707
+ _startHeaderSpinner() {
611708
+ if (this._headerSpinnerTimer) return;
611709
+ this._headerSpinnerFrame = 0;
611710
+ if (this.active) this.refreshHeaderPanels();
611711
+ this._headerSpinnerTimer = setInterval(() => {
611712
+ this._headerSpinnerFrame = (this._headerSpinnerFrame + 1) % _StatusBar.HEADER_SPINNER_FRAMES.length;
611713
+ if (this.active) this.refreshHeaderPanels();
611714
+ }, 110);
611715
+ this._headerSpinnerTimer.unref?.();
611716
+ }
611717
+ /** Stop the header inference glyph and repaint once so it disappears cleanly. */
611718
+ _stopHeaderSpinner() {
611719
+ if (this._headerSpinnerTimer) {
611720
+ clearInterval(this._headerSpinnerTimer);
611721
+ this._headerSpinnerTimer = null;
611722
+ }
611723
+ if (this.active) this.refreshHeaderPanels();
611724
+ }
611524
611725
  /**
611525
611726
  * Ensure the monitoring timer is running when the registry has entries
611526
611727
  * and the braille spinner is not active. Refreshes the buffer line
@@ -612081,6 +612282,10 @@ var init_status_bar = __esm({
612081
612282
  this._brailleSpinner.stop();
612082
612283
  this._processing = false;
612083
612284
  }
612285
+ if (this._headerSpinnerTimer) {
612286
+ clearInterval(this._headerSpinnerTimer);
612287
+ this._headerSpinnerTimer = null;
612288
+ }
612084
612289
  this.stopAllMetrics();
612085
612290
  this.termWrite(`\x1B[1;${termRows()}r`);
612086
612291
  }
@@ -632164,9 +632369,9 @@ async function ensureVoiceDeps(ctx3) {
632164
632369
  }
632165
632370
  if (typeof mod3.getVenvPython === "function") {
632166
632371
  const { dirname: dirname54 } = await import("node:path");
632167
- const { existsSync: existsSync163 } = await import("node:fs");
632372
+ const { existsSync: existsSync164 } = await import("node:fs");
632168
632373
  const venvPy = mod3.getVenvPython();
632169
- if (existsSync163(venvPy)) {
632374
+ if (existsSync164(venvPy)) {
632170
632375
  process.env.TRANSCRIBE_PYTHON = venvPy;
632171
632376
  const venvBin = dirname54(venvPy);
632172
632377
  const sep6 = process.platform === "win32" ? ";" : ":";
@@ -633052,10 +633257,10 @@ async function handleSlashCommand(input, ctx3) {
633052
633257
  if (!key) {
633053
633258
  try {
633054
633259
  const { homedir: homedir62 } = await import("node:os");
633055
- const { readFileSync: readFileSync133, existsSync: existsSync163 } = await import("node:fs");
633056
- const { join: join178 } = await import("node:path");
633057
- const p2 = join178(homedir62(), ".omnius", "api.key");
633058
- if (existsSync163(p2)) key = readFileSync133(p2, "utf8").trim();
633260
+ const { readFileSync: readFileSync134, existsSync: existsSync164 } = await import("node:fs");
633261
+ const { join: join179 } = await import("node:path");
633262
+ const p2 = join179(homedir62(), ".omnius", "api.key");
633263
+ if (existsSync164(p2)) key = readFileSync134(p2, "utf8").trim();
633059
633264
  } catch {
633060
633265
  }
633061
633266
  }
@@ -633098,13 +633303,13 @@ async function handleSlashCommand(input, ctx3) {
633098
633303
  try {
633099
633304
  const { randomBytes: randomBytes30 } = await import("node:crypto");
633100
633305
  const { homedir: homedir62 } = await import("node:os");
633101
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = await import("node:fs");
633102
- const { join: join178 } = await import("node:path");
633306
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
633307
+ const { join: join179 } = await import("node:path");
633103
633308
  const newKey = randomBytes30(16).toString("hex");
633104
633309
  process.env["OMNIUS_API_KEY"] = newKey;
633105
- const dir = join178(homedir62(), ".omnius");
633106
- mkdirSync105(dir, { recursive: true });
633107
- writeFileSync90(join178(dir, "api.key"), newKey + "\n", "utf8");
633310
+ const dir = join179(homedir62(), ".omnius");
633311
+ mkdirSync106(dir, { recursive: true });
633312
+ writeFileSync91(join179(dir, "api.key"), newKey + "\n", "utf8");
633108
633313
  renderInfo(`New API key: ${c3.bold(c3.yellow(newKey))}`);
633109
633314
  renderInfo(
633110
633315
  "Restart the daemon to apply if needed. Use /access any to restart quickly."
@@ -633375,11 +633580,11 @@ async function handleSlashCommand(input, ctx3) {
633375
633580
  );
633376
633581
  try {
633377
633582
  const { homedir: homedir63 } = await import("node:os");
633378
- const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
633379
- const { join: join179 } = await import("node:path");
633380
- const dir = join179(homedir63(), ".omnius");
633381
- mkdirSync106(dir, { recursive: true });
633382
- writeFileSync91(join179(dir, "api.key"), apiKey + "\n", "utf8");
633583
+ const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync92 } = await import("node:fs");
633584
+ const { join: join180 } = await import("node:path");
633585
+ const dir = join180(homedir63(), ".omnius");
633586
+ mkdirSync107(dir, { recursive: true });
633587
+ writeFileSync92(join180(dir, "api.key"), apiKey + "\n", "utf8");
633383
633588
  } catch {
633384
633589
  }
633385
633590
  }
@@ -633391,11 +633596,11 @@ async function handleSlashCommand(input, ctx3) {
633391
633596
  const port2 = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
633392
633597
  try {
633393
633598
  const { homedir: homedir63 } = await import("node:os");
633394
- const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
633395
- const { join: join179 } = await import("node:path");
633396
- const dir = join179(homedir63(), ".omnius");
633397
- mkdirSync106(dir, { recursive: true });
633398
- writeFileSync91(join179(dir, "access"), `${val2}
633599
+ const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync92 } = await import("node:fs");
633600
+ const { join: join180 } = await import("node:path");
633601
+ const dir = join180(homedir63(), ".omnius");
633602
+ mkdirSync107(dir, { recursive: true });
633603
+ writeFileSync92(join180(dir, "access"), `${val2}
633399
633604
  `, "utf8");
633400
633605
  } catch {
633401
633606
  }
@@ -633495,11 +633700,11 @@ async function handleSlashCommand(input, ctx3) {
633495
633700
  );
633496
633701
  try {
633497
633702
  const { homedir: homedir63 } = await import("node:os");
633498
- const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
633499
- const { join: join179 } = await import("node:path");
633500
- const dir = join179(homedir63(), ".omnius");
633501
- mkdirSync106(dir, { recursive: true });
633502
- writeFileSync91(join179(dir, "api.key"), apiKey + "\n", "utf8");
633703
+ const { mkdirSync: mkdirSync107, writeFileSync: writeFileSync92 } = await import("node:fs");
633704
+ const { join: join180 } = await import("node:path");
633705
+ const dir = join180(homedir63(), ".omnius");
633706
+ mkdirSync107(dir, { recursive: true });
633707
+ writeFileSync92(join180(dir, "api.key"), apiKey + "\n", "utf8");
633503
633708
  } catch {
633504
633709
  }
633505
633710
  }
@@ -633510,12 +633715,12 @@ async function handleSlashCommand(input, ctx3) {
633510
633715
  }
633511
633716
  const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
633512
633717
  const { homedir: homedir62 } = await import("node:os");
633513
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = await import("node:fs");
633514
- const { join: join178 } = await import("node:path");
633718
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
633719
+ const { join: join179 } = await import("node:path");
633515
633720
  try {
633516
- const dir = join178(homedir62(), ".omnius");
633517
- mkdirSync105(dir, { recursive: true });
633518
- writeFileSync90(join178(dir, "access"), `${val}
633721
+ const dir = join179(homedir62(), ".omnius");
633722
+ mkdirSync106(dir, { recursive: true });
633723
+ writeFileSync91(join179(dir, "access"), `${val}
633519
633724
  `, "utf8");
633520
633725
  } catch (e2) {
633521
633726
  renderWarning(
@@ -642354,7 +642559,7 @@ async function handleVoiceMenu(ctx3, save3, hasLocal) {
642354
642559
  const { basename: basename39, join: pathJoin } = await import("node:path");
642355
642560
  const {
642356
642561
  copyFileSync: copyFileSync8,
642357
- mkdirSync: mkdirSync105,
642562
+ mkdirSync: mkdirSync106,
642358
642563
  existsSync: exists2
642359
642564
  } = await import("node:fs");
642360
642565
  const { homedir: homedir62 } = await import("node:os");
@@ -642369,7 +642574,7 @@ async function handleVoiceMenu(ctx3, save3, hasLocal) {
642369
642574
  "models",
642370
642575
  modelName
642371
642576
  );
642372
- if (!exists2(destDir)) mkdirSync105(destDir, { recursive: true });
642577
+ if (!exists2(destDir)) mkdirSync106(destDir, { recursive: true });
642373
642578
  copyFileSync8(onnxDrop.path, pathJoin(destDir, "model.onnx"));
642374
642579
  copyFileSync8(jsonDrop.path, pathJoin(destDir, "config.json"));
642375
642580
  const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
@@ -644148,13 +644353,13 @@ async function handleSponsoredEndpoint(ctx3, local) {
644148
644353
  sponsors.push(...verified);
644149
644354
  if (verified.length > 0) {
644150
644355
  try {
644151
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = __require("node:fs");
644152
- mkdirSync105(sponsorDir2, { recursive: true });
644356
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = __require("node:fs");
644357
+ mkdirSync106(sponsorDir2, { recursive: true });
644153
644358
  const cached = verified.map((s2) => ({
644154
644359
  ...s2,
644155
644360
  lastVerified: Date.now()
644156
644361
  }));
644157
- writeFileSync90(knownFile, JSON.stringify(cached, null, 2));
644362
+ writeFileSync91(knownFile, JSON.stringify(cached, null, 2));
644158
644363
  } catch {
644159
644364
  }
644160
644365
  }
@@ -644358,16 +644563,16 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
644358
644563
  }
644359
644564
  if (models.length > 0) {
644360
644565
  try {
644361
- const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync105 } = await import("node:fs");
644362
- const { join: join178, dirname: dirname54 } = await import("node:path");
644363
- const cachePath2 = join178(
644566
+ const { writeFileSync: writeFileSync91, mkdirSync: mkdirSync106 } = await import("node:fs");
644567
+ const { join: join179, dirname: dirname54 } = await import("node:path");
644568
+ const cachePath2 = join179(
644364
644569
  ctx3.repoRoot || process.cwd(),
644365
644570
  ".omnius",
644366
644571
  "nexus",
644367
644572
  "peer-models-cache.json"
644368
644573
  );
644369
- mkdirSync105(dirname54(cachePath2), { recursive: true });
644370
- writeFileSync90(
644574
+ mkdirSync106(dirname54(cachePath2), { recursive: true });
644575
+ writeFileSync91(
644371
644576
  cachePath2,
644372
644577
  JSON.stringify(
644373
644578
  {
@@ -644441,16 +644646,16 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
644441
644646
  "Live model probe failed; using sponsor directory model advertisement."
644442
644647
  );
644443
644648
  try {
644444
- const { writeFileSync: writeFileSync90, mkdirSync: mkdirSync105 } = await import("node:fs");
644445
- const { join: join178, dirname: dirname54 } = await import("node:path");
644446
- const cachePath2 = join178(
644649
+ const { writeFileSync: writeFileSync91, mkdirSync: mkdirSync106 } = await import("node:fs");
644650
+ const { join: join179, dirname: dirname54 } = await import("node:path");
644651
+ const cachePath2 = join179(
644447
644652
  ctx3.repoRoot || process.cwd(),
644448
644653
  ".omnius",
644449
644654
  "nexus",
644450
644655
  "peer-models-cache.json"
644451
644656
  );
644452
- mkdirSync105(dirname54(cachePath2), { recursive: true });
644453
- writeFileSync90(
644657
+ mkdirSync106(dirname54(cachePath2), { recursive: true });
644658
+ writeFileSync91(
644454
644659
  cachePath2,
644455
644660
  JSON.stringify(
644456
644661
  {
@@ -645464,17 +645669,17 @@ async function handleUpdate(subcommand, ctx3) {
645464
645669
  try {
645465
645670
  const { createRequire: createRequire11 } = await import("node:module");
645466
645671
  const { fileURLToPath: fileURLToPath23 } = await import("node:url");
645467
- const { dirname: dirname54, join: join178 } = await import("node:path");
645468
- const { existsSync: existsSync163 } = await import("node:fs");
645672
+ const { dirname: dirname54, join: join179 } = await import("node:path");
645673
+ const { existsSync: existsSync164 } = await import("node:fs");
645469
645674
  const req3 = createRequire11(import.meta.url);
645470
645675
  const thisDir = dirname54(fileURLToPath23(import.meta.url));
645471
645676
  const candidates = [
645472
- join178(thisDir, "..", "package.json"),
645473
- join178(thisDir, "..", "..", "package.json"),
645474
- join178(thisDir, "..", "..", "..", "package.json")
645677
+ join179(thisDir, "..", "package.json"),
645678
+ join179(thisDir, "..", "..", "package.json"),
645679
+ join179(thisDir, "..", "..", "..", "package.json")
645475
645680
  ];
645476
645681
  for (const pkgPath of candidates) {
645477
- if (existsSync163(pkgPath)) {
645682
+ if (existsSync164(pkgPath)) {
645478
645683
  const pkg = req3(pkgPath);
645479
645684
  if (pkg.name === "omnius" || pkg.name === "@omnius/cli") {
645480
645685
  currentVersion = pkg.version ?? "0.0.0";
@@ -647148,13 +647353,13 @@ var init_commands = __esm({
647148
647353
  try {
647149
647354
  const { randomBytes: randomBytes30 } = await import("node:crypto");
647150
647355
  const { homedir: homedir62 } = await import("node:os");
647151
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = await import("node:fs");
647152
- const { join: join178 } = await import("node:path");
647356
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
647357
+ const { join: join179 } = await import("node:path");
647153
647358
  const apiKey = randomBytes30(16).toString("hex");
647154
647359
  process.env["OMNIUS_API_KEY"] = apiKey;
647155
- const dir = join178(homedir62(), ".omnius");
647156
- mkdirSync105(dir, { recursive: true });
647157
- writeFileSync90(join178(dir, "api.key"), apiKey + "\n", "utf8");
647360
+ const dir = join179(homedir62(), ".omnius");
647361
+ mkdirSync106(dir, { recursive: true });
647362
+ writeFileSync91(join179(dir, "api.key"), apiKey + "\n", "utf8");
647158
647363
  renderInfo(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
647159
647364
  renderInfo(
647160
647365
  "Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it."
@@ -647173,11 +647378,11 @@ var init_commands = __esm({
647173
647378
  const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
647174
647379
  try {
647175
647380
  const { homedir: homedir62 } = await import("node:os");
647176
- const { mkdirSync: mkdirSync105, writeFileSync: writeFileSync90 } = await import("node:fs");
647177
- const { join: join178 } = await import("node:path");
647178
- const dir = join178(homedir62(), ".omnius");
647179
- mkdirSync105(dir, { recursive: true });
647180
- writeFileSync90(join178(dir, "access"), `${val}
647381
+ const { mkdirSync: mkdirSync106, writeFileSync: writeFileSync91 } = await import("node:fs");
647382
+ const { join: join179 } = await import("node:path");
647383
+ const dir = join179(homedir62(), ".omnius");
647384
+ mkdirSync106(dir, { recursive: true });
647385
+ writeFileSync91(join179(dir, "access"), `${val}
647181
647386
  `, "utf8");
647182
647387
  } catch {
647183
647388
  }
@@ -682380,6 +682585,343 @@ var init_direct_tool_registry = __esm({
682380
682585
  }
682381
682586
  });
682382
682587
 
682588
+ // packages/cli/src/api/external-tool-registry.ts
682589
+ import { existsSync as existsSync152, mkdirSync as mkdirSync95, readFileSync as readFileSync124, writeFileSync as writeFileSync81, renameSync as renameSync14 } from "node:fs";
682590
+ import { join as join163 } from "node:path";
682591
+ function externalToolStorePath(workingDir) {
682592
+ return join163(workingDir, ".omnius", "external-tools.json");
682593
+ }
682594
+ function loadExternalTools(workingDir) {
682595
+ const path12 = externalToolStorePath(workingDir);
682596
+ if (!existsSync152(path12)) return [];
682597
+ try {
682598
+ const parsed = JSON.parse(readFileSync124(path12, "utf-8"));
682599
+ if (!parsed || !Array.isArray(parsed.tools)) return [];
682600
+ return parsed.tools.filter(
682601
+ (t2) => t2 && typeof t2.name === "string" && t2.transport != null
682602
+ );
682603
+ } catch {
682604
+ return [];
682605
+ }
682606
+ }
682607
+ function persist3(workingDir, tools) {
682608
+ const path12 = externalToolStorePath(workingDir);
682609
+ mkdirSync95(join163(workingDir, ".omnius"), { recursive: true });
682610
+ const file = { version: STORE_VERSION, tools };
682611
+ const tmp = `${path12}.tmp`;
682612
+ writeFileSync81(tmp, JSON.stringify(file, null, 2), { mode: 384 });
682613
+ renameSync14(tmp, path12);
682614
+ }
682615
+ function validateManifest2(input, existing) {
682616
+ if (!input || typeof input !== "object") {
682617
+ return { ok: false, error: "Body must be a JSON object." };
682618
+ }
682619
+ const m2 = input;
682620
+ const name10 = typeof m2["name"] === "string" ? m2["name"].trim() : "";
682621
+ if (!NAME_RE.test(name10)) {
682622
+ return {
682623
+ ok: false,
682624
+ error: "`name` must match /^[a-zA-Z][a-zA-Z0-9_]{0,63}$/ (letters, digits, underscore; start with a letter)."
682625
+ };
682626
+ }
682627
+ const description = typeof m2["description"] === "string" ? m2["description"].trim() : "";
682628
+ if (!description) {
682629
+ return { ok: false, error: "`description` is required and must be non-empty." };
682630
+ }
682631
+ const parametersRaw = m2["parameters"];
682632
+ let parameters;
682633
+ if (parametersRaw == null) {
682634
+ parameters = { type: "object", properties: {} };
682635
+ } else if (typeof parametersRaw === "object" && !Array.isArray(parametersRaw)) {
682636
+ parameters = parametersRaw;
682637
+ if (parameters["type"] !== "object") {
682638
+ return {
682639
+ ok: false,
682640
+ error: '`parameters` must be a JSON schema object with `type: "object"`.'
682641
+ };
682642
+ }
682643
+ } else {
682644
+ return { ok: false, error: "`parameters` must be a JSON schema object." };
682645
+ }
682646
+ const transportResult = validateTransport(m2["transport"]);
682647
+ if (!transportResult.ok) return { ok: false, error: transportResult.error };
682648
+ const transport = transportResult.transport;
682649
+ const security = normalizeSecurity(m2["security"], transport);
682650
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
682651
+ const record = {
682652
+ name: name10,
682653
+ description,
682654
+ parameters,
682655
+ security,
682656
+ transport,
682657
+ source: "external",
682658
+ created_at: existing?.created_at ?? now2,
682659
+ updated_at: now2
682660
+ };
682661
+ return { ok: true, record };
682662
+ }
682663
+ function validateTransport(raw) {
682664
+ if (!raw || typeof raw !== "object") {
682665
+ return {
682666
+ ok: false,
682667
+ error: '`transport` is required: {type:"http",callback_url} or {type:"mcp",server,tool}.'
682668
+ };
682669
+ }
682670
+ const t2 = raw;
682671
+ if (t2["type"] === "http") {
682672
+ const url = typeof t2["callback_url"] === "string" ? t2["callback_url"].trim() : "";
682673
+ if (!/^https?:\/\//i.test(url)) {
682674
+ return { ok: false, error: "http transport requires an absolute http(s) `callback_url`." };
682675
+ }
682676
+ const transport = { type: "http", callback_url: url };
682677
+ if (typeof t2["auth_header"] === "string") transport.auth_header = t2["auth_header"];
682678
+ if (t2["headers"] && typeof t2["headers"] === "object") {
682679
+ transport.headers = t2["headers"];
682680
+ }
682681
+ if (typeof t2["timeout_ms"] === "number") transport.timeout_ms = t2["timeout_ms"];
682682
+ if (typeof t2["result_path"] === "string") transport.result_path = t2["result_path"].trim();
682683
+ return { ok: true, transport };
682684
+ }
682685
+ if (t2["type"] === "mcp") {
682686
+ const server2 = typeof t2["server"] === "string" ? t2["server"].trim() : "";
682687
+ const tool = typeof t2["tool"] === "string" ? t2["tool"].trim() : "";
682688
+ if (!server2 || !tool) {
682689
+ return { ok: false, error: "mcp transport requires non-empty `server` and `tool`." };
682690
+ }
682691
+ const transport = { type: "mcp", server: server2, tool };
682692
+ if (t2["connect"] && typeof t2["connect"] === "object") {
682693
+ transport.connect = t2["connect"];
682694
+ }
682695
+ return { ok: true, transport };
682696
+ }
682697
+ return { ok: false, error: '`transport.type` must be "http" or "mcp".' };
682698
+ }
682699
+ function normalizeSecurity(raw, transport) {
682700
+ const s2 = raw && typeof raw === "object" ? raw : {};
682701
+ const categories = Array.isArray(s2["categories"]) ? s2["categories"].filter((c8) => typeof c8 === "string") : ["network"];
682702
+ const risk = ["low", "medium", "high", "critical"].includes(s2["risk"]) ? s2["risk"] : "medium";
682703
+ const requires_scope = ["read", "run", "admin"].includes(s2["requires_scope"]) ? s2["requires_scope"] : "run";
682704
+ const off_device_allowed = s2["off_device_allowed"] === true;
682705
+ const rationale = typeof s2["rationale"] === "string" && s2["rationale"].trim() ? s2["rationale"].trim() : transport.type === "http" ? `External HTTP tool; Omnius forwards args to ${transport.callback_url}.` : `External MCP tool; proxies to ${transport.server}:${transport.tool}.`;
682706
+ return { categories: categories.length ? categories : ["network"], risk, requires_scope, off_device_allowed, rationale };
682707
+ }
682708
+ function upsertExternalTool(workingDir, record) {
682709
+ const tools = loadExternalTools(workingDir);
682710
+ const idx = tools.findIndex((t2) => t2.name === record.name);
682711
+ const replaced = idx >= 0;
682712
+ if (replaced) tools[idx] = record;
682713
+ else tools.push(record);
682714
+ tools.sort((a2, b) => a2.name.localeCompare(b.name));
682715
+ persist3(workingDir, tools);
682716
+ return { replaced };
682717
+ }
682718
+ function removeExternalTool(workingDir, name10) {
682719
+ const tools = loadExternalTools(workingDir);
682720
+ const next = tools.filter((t2) => t2.name !== name10);
682721
+ if (next.length === tools.length) return false;
682722
+ persist3(workingDir, next);
682723
+ return true;
682724
+ }
682725
+ function getExternalTool(workingDir, name10) {
682726
+ return loadExternalTools(workingDir).find((t2) => t2.name === name10) ?? null;
682727
+ }
682728
+ var STORE_VERSION, NAME_RE;
682729
+ var init_external_tool_registry = __esm({
682730
+ "packages/cli/src/api/external-tool-registry.ts"() {
682731
+ "use strict";
682732
+ STORE_VERSION = 1;
682733
+ NAME_RE = /^[a-zA-Z][a-zA-Z0-9_]{0,63}$/;
682734
+ }
682735
+ });
682736
+
682737
+ // packages/cli/src/api/external-tool-dispatch.ts
682738
+ function clampTimeout(ms, def) {
682739
+ if (typeof ms !== "number" || !Number.isFinite(ms)) return def;
682740
+ return Math.min(Math.max(Math.round(ms), 1e3), 12e4);
682741
+ }
682742
+ function readPath(obj, path12) {
682743
+ let cur = obj;
682744
+ for (const seg of path12.split(".")) {
682745
+ if (cur == null || typeof cur !== "object") return void 0;
682746
+ cur = cur[seg];
682747
+ }
682748
+ return cur;
682749
+ }
682750
+ async function dispatchHttp(transport, record, args, sessionId, fetchImpl) {
682751
+ const start2 = performance.now();
682752
+ const controller = new AbortController();
682753
+ const timeout2 = clampTimeout(transport.timeout_ms, 3e4);
682754
+ const timer = setTimeout(() => controller.abort(), timeout2);
682755
+ try {
682756
+ const headers = {
682757
+ "content-type": "application/json",
682758
+ ...transport.headers ?? {}
682759
+ };
682760
+ if (transport.auth_header) headers["authorization"] = transport.auth_header;
682761
+ const resp = await fetchImpl(transport.callback_url, {
682762
+ method: "POST",
682763
+ headers,
682764
+ body: JSON.stringify({ name: record.name, args, session_id: sessionId }),
682765
+ signal: controller.signal
682766
+ });
682767
+ const text2 = await resp.text();
682768
+ if (!resp.ok) {
682769
+ return {
682770
+ success: false,
682771
+ output: "",
682772
+ error: `External tool HTTP ${resp.status}: ${text2.slice(0, 500)}`,
682773
+ durationMs: performance.now() - start2,
682774
+ transport: "http"
682775
+ };
682776
+ }
682777
+ let output = text2;
682778
+ if (transport.result_path) {
682779
+ try {
682780
+ const json = JSON.parse(text2);
682781
+ const extracted = readPath(json, transport.result_path);
682782
+ output = typeof extracted === "string" ? extracted : JSON.stringify(extracted ?? null);
682783
+ } catch {
682784
+ }
682785
+ }
682786
+ return {
682787
+ success: true,
682788
+ output,
682789
+ durationMs: performance.now() - start2,
682790
+ transport: "http"
682791
+ };
682792
+ } catch (err) {
682793
+ const aborted = err instanceof Error && err.name === "AbortError";
682794
+ return {
682795
+ success: false,
682796
+ output: "",
682797
+ error: aborted ? `External tool call timed out after ${timeout2}ms` : `External tool call failed: ${err instanceof Error ? err.message : String(err)}`,
682798
+ durationMs: performance.now() - start2,
682799
+ transport: "http"
682800
+ };
682801
+ } finally {
682802
+ clearTimeout(timer);
682803
+ }
682804
+ }
682805
+ async function dispatchMcp(transport, args, workingDir, deps) {
682806
+ const start2 = performance.now();
682807
+ const mgr = await deps.getMcpManager(workingDir);
682808
+ if (!mgr) {
682809
+ return {
682810
+ success: false,
682811
+ output: "",
682812
+ error: "MCP module unavailable — cannot dispatch mcp transport.",
682813
+ durationMs: performance.now() - start2,
682814
+ transport: "mcp"
682815
+ };
682816
+ }
682817
+ const client = mgr.clients?.get(transport.server);
682818
+ if (!client) {
682819
+ return {
682820
+ success: false,
682821
+ output: "",
682822
+ error: `MCP server '${transport.server}' is not connected.`,
682823
+ durationMs: performance.now() - start2,
682824
+ transport: "mcp"
682825
+ };
682826
+ }
682827
+ try {
682828
+ const result = await client.callTool(transport.tool, args);
682829
+ return {
682830
+ success: true,
682831
+ output: typeof result === "string" ? result : JSON.stringify(result),
682832
+ durationMs: performance.now() - start2,
682833
+ transport: "mcp"
682834
+ };
682835
+ } catch (err) {
682836
+ return {
682837
+ success: false,
682838
+ output: "",
682839
+ error: `MCP tool '${transport.server}:${transport.tool}' failed: ${err instanceof Error ? err.message : String(err)}`,
682840
+ durationMs: performance.now() - start2,
682841
+ transport: "mcp"
682842
+ };
682843
+ }
682844
+ }
682845
+ async function executeExternalTool(record, args, workingDir, sessionId, deps) {
682846
+ const fetchImpl = deps.fetchImpl ?? fetch;
682847
+ if (record.transport.type === "http") {
682848
+ return dispatchHttp(record.transport, record, args, sessionId, fetchImpl);
682849
+ }
682850
+ return dispatchMcp(record.transport, args, workingDir, deps);
682851
+ }
682852
+ var init_external_tool_dispatch = __esm({
682853
+ "packages/cli/src/api/external-tool-dispatch.ts"() {
682854
+ "use strict";
682855
+ }
682856
+ });
682857
+
682858
+ // packages/cli/src/api/external-tool-eval.ts
682859
+ function scoreCase(expect, result) {
682860
+ const failures = [];
682861
+ if (!expect) {
682862
+ if (!result.success) failures.push(`expected success but tool failed: ${result.error ?? "unknown"}`);
682863
+ return failures;
682864
+ }
682865
+ if (typeof expect.success === "boolean" && result.success !== expect.success) {
682866
+ failures.push(`expected success=${expect.success} but got ${result.success}${result.error ? ` (${result.error})` : ""}`);
682867
+ }
682868
+ if (typeof expect.output_contains === "string" && !result.output.includes(expect.output_contains)) {
682869
+ failures.push(`output did not contain ${JSON.stringify(expect.output_contains)}`);
682870
+ }
682871
+ if (typeof expect.output_equals === "string" && result.output.trim() !== expect.output_equals.trim()) {
682872
+ failures.push(`output did not equal ${JSON.stringify(expect.output_equals)}`);
682873
+ }
682874
+ if (typeof expect.output_matches === "string") {
682875
+ let re = null;
682876
+ try {
682877
+ re = new RegExp(expect.output_matches);
682878
+ } catch {
682879
+ failures.push(`invalid output_matches regex ${JSON.stringify(expect.output_matches)}`);
682880
+ }
682881
+ if (re && !re.test(result.output)) {
682882
+ failures.push(`output did not match /${expect.output_matches}/`);
682883
+ }
682884
+ }
682885
+ return failures;
682886
+ }
682887
+ async function evaluateExternalTool(record, cases, workingDir, deps) {
682888
+ const start2 = performance.now();
682889
+ const results = [];
682890
+ for (let i2 = 0; i2 < cases.length; i2++) {
682891
+ const c8 = cases[i2];
682892
+ const result = await executeExternalTool(
682893
+ record,
682894
+ c8.args ?? {},
682895
+ workingDir,
682896
+ null,
682897
+ deps
682898
+ );
682899
+ const failures = scoreCase(c8.expect, result);
682900
+ results.push({
682901
+ name: c8.name ?? `case_${i2 + 1}`,
682902
+ passed: failures.length === 0,
682903
+ failures,
682904
+ result
682905
+ });
682906
+ }
682907
+ const passed = results.filter((r2) => r2.passed).length;
682908
+ return {
682909
+ tool: record.name,
682910
+ total: results.length,
682911
+ passed,
682912
+ failed: results.length - passed,
682913
+ pass_rate: results.length ? passed / results.length : 0,
682914
+ duration_ms: performance.now() - start2,
682915
+ cases: results
682916
+ };
682917
+ }
682918
+ var init_external_tool_eval = __esm({
682919
+ "packages/cli/src/api/external-tool-eval.ts"() {
682920
+ "use strict";
682921
+ init_external_tool_dispatch();
682922
+ }
682923
+ });
682924
+
682383
682925
  // packages/cli/src/api/aiwg.ts
682384
682926
  var aiwg_exports = {};
682385
682927
  __export(aiwg_exports, {
@@ -682392,19 +682934,19 @@ __export(aiwg_exports, {
682392
682934
  resolveAiwgRoot: () => resolveAiwgRoot,
682393
682935
  tryRouteAiwg: () => tryRouteAiwg
682394
682936
  });
682395
- import { existsSync as existsSync152, readFileSync as readFileSync124, readdirSync as readdirSync54, statSync as statSync54 } from "node:fs";
682396
- import { join as join163 } from "node:path";
682937
+ import { existsSync as existsSync153, readFileSync as readFileSync125, readdirSync as readdirSync54, statSync as statSync54 } from "node:fs";
682938
+ import { join as join164 } from "node:path";
682397
682939
  import { homedir as homedir54 } from "node:os";
682398
682940
  import { execSync as execSync58 } from "node:child_process";
682399
682941
  function resolveAiwgRoot() {
682400
682942
  if (_cachedAiwgRoot !== void 0) return _cachedAiwgRoot;
682401
682943
  const envRoot = process.env["OMNIUS_AIWG_ROOT"];
682402
- if (envRoot && existsSync152(join163(envRoot, "package.json"))) {
682944
+ if (envRoot && existsSync153(join164(envRoot, "package.json"))) {
682403
682945
  _cachedAiwgRoot = envRoot;
682404
682946
  return envRoot;
682405
682947
  }
682406
- const shareDir = join163(homedir54(), ".local", "share", "ai-writing-guide");
682407
- if (existsSync152(join163(shareDir, "agentic"))) {
682948
+ const shareDir = join164(homedir54(), ".local", "share", "ai-writing-guide");
682949
+ if (existsSync153(join164(shareDir, "agentic"))) {
682408
682950
  _cachedAiwgRoot = shareDir;
682409
682951
  return shareDir;
682410
682952
  }
@@ -682414,8 +682956,8 @@ function resolveAiwgRoot() {
682414
682956
  timeout: 5e3,
682415
682957
  stdio: ["pipe", "pipe", "pipe"]
682416
682958
  }).trim();
682417
- const candidate = join163(globalRoot, "aiwg");
682418
- if (existsSync152(join163(candidate, "package.json"))) {
682959
+ const candidate = join164(globalRoot, "aiwg");
682960
+ if (existsSync153(join164(candidate, "package.json"))) {
682419
682961
  _cachedAiwgRoot = candidate;
682420
682962
  return candidate;
682421
682963
  }
@@ -682426,22 +682968,22 @@ function resolveAiwgRoot() {
682426
682968
  "/usr/lib/node_modules/aiwg",
682427
682969
  "/opt/homebrew/lib/node_modules/aiwg"
682428
682970
  ]) {
682429
- if (existsSync152(join163(p2, "package.json"))) {
682971
+ if (existsSync153(join164(p2, "package.json"))) {
682430
682972
  _cachedAiwgRoot = p2;
682431
682973
  return p2;
682432
682974
  }
682433
682975
  }
682434
682976
  const versionDirs = [
682435
- join163(homedir54(), ".nvm", "versions", "node"),
682436
- join163(homedir54(), ".local", "share", "fnm", "node-versions")
682977
+ join164(homedir54(), ".nvm", "versions", "node"),
682978
+ join164(homedir54(), ".local", "share", "fnm", "node-versions")
682437
682979
  ];
682438
682980
  for (const vdir of versionDirs) {
682439
- if (!existsSync152(vdir)) continue;
682981
+ if (!existsSync153(vdir)) continue;
682440
682982
  try {
682441
682983
  for (const ver of readdirSync54(vdir)) {
682442
682984
  for (const prefix of ["lib/node_modules/aiwg", "installation/lib/node_modules/aiwg"]) {
682443
- const cand = join163(vdir, ver, prefix);
682444
- if (existsSync152(join163(cand, "package.json"))) {
682985
+ const cand = join164(vdir, ver, prefix);
682986
+ if (existsSync153(join164(cand, "package.json"))) {
682445
682987
  _cachedAiwgRoot = cand;
682446
682988
  return cand;
682447
682989
  }
@@ -682459,11 +683001,11 @@ function resolveAiwgRoot() {
682459
683001
  if (whichAiwg) {
682460
683002
  let cur = whichAiwg;
682461
683003
  for (let i2 = 0; i2 < 8; i2++) {
682462
- cur = join163(cur, "..");
682463
- const pj = join163(cur, "package.json");
682464
- if (existsSync152(pj)) {
683004
+ cur = join164(cur, "..");
683005
+ const pj = join164(cur, "package.json");
683006
+ if (existsSync153(pj)) {
682465
683007
  try {
682466
- const pkg = JSON.parse(readFileSync124(pj, "utf-8"));
683008
+ const pkg = JSON.parse(readFileSync125(pj, "utf-8"));
682467
683009
  if (pkg.name === "aiwg") {
682468
683010
  _cachedAiwgRoot = cur;
682469
683011
  return cur;
@@ -682485,14 +683027,14 @@ function listAiwgFrameworks() {
682485
683027
  _cachedFrameworks = [];
682486
683028
  return _cachedFrameworks;
682487
683029
  }
682488
- const frameworksDir = join163(root, "agentic", "code", "frameworks");
682489
- if (!existsSync152(frameworksDir)) {
683030
+ const frameworksDir = join164(root, "agentic", "code", "frameworks");
683031
+ if (!existsSync153(frameworksDir)) {
682490
683032
  _cachedFrameworks = [];
682491
683033
  return _cachedFrameworks;
682492
683034
  }
682493
683035
  const out = [];
682494
683036
  for (const name10 of readdirSync54(frameworksDir)) {
682495
- const p2 = join163(frameworksDir, name10);
683037
+ const p2 = join164(frameworksDir, name10);
682496
683038
  try {
682497
683039
  const st = statSync54(p2);
682498
683040
  if (!st.isDirectory()) continue;
@@ -682520,7 +683062,7 @@ function aggregateDir(dir, depth = 0) {
682520
683062
  try {
682521
683063
  for (const e2 of readdirSync54(dir, { withFileTypes: true })) {
682522
683064
  if (e2.name.startsWith(".") || e2.name === "node_modules") continue;
682523
- const p2 = join163(dir, e2.name);
683065
+ const p2 = join164(dir, e2.name);
682524
683066
  if (e2.isDirectory()) {
682525
683067
  const sub2 = aggregateDir(p2, depth + 1);
682526
683068
  out.files += sub2.files;
@@ -682550,10 +683092,10 @@ function aggregateDir(dir, depth = 0) {
682550
683092
  }
682551
683093
  function readFirstLineDescription(dir) {
682552
683094
  for (const candidate of ["README.md", "SKILL.md", "INDEX.md"]) {
682553
- const p2 = join163(dir, candidate);
682554
- if (!existsSync152(p2)) continue;
683095
+ const p2 = join164(dir, candidate);
683096
+ if (!existsSync153(p2)) continue;
682555
683097
  try {
682556
- const txt = readFileSync124(p2, "utf-8");
683098
+ const txt = readFileSync125(p2, "utf-8");
682557
683099
  const descMatch = txt.match(/^description:\s*(.+)$/m);
682558
683100
  if (descMatch) return descMatch[1].trim().slice(0, 200);
682559
683101
  for (const line of txt.split("\n")) {
@@ -682575,12 +683117,12 @@ function listAiwgItems() {
682575
683117
  }
682576
683118
  const out = [];
682577
683119
  const walkRoots = [
682578
- join163(root, "agentic", "code", "frameworks"),
682579
- join163(root, "agentic", "code", "addons"),
682580
- join163(root, "plugins")
683120
+ join164(root, "agentic", "code", "frameworks"),
683121
+ join164(root, "agentic", "code", "addons"),
683122
+ join164(root, "plugins")
682581
683123
  ];
682582
683124
  for (const wr of walkRoots) {
682583
- if (!existsSync152(wr)) continue;
683125
+ if (!existsSync153(wr)) continue;
682584
683126
  walkForItems(wr, out, 0);
682585
683127
  }
682586
683128
  _cachedItems = out;
@@ -682591,7 +683133,7 @@ function walkForItems(dir, out, depth) {
682591
683133
  try {
682592
683134
  for (const e2 of readdirSync54(dir, { withFileTypes: true })) {
682593
683135
  if (e2.name.startsWith(".") || e2.name === "node_modules") continue;
682594
- const p2 = join163(dir, e2.name);
683136
+ const p2 = join164(dir, e2.name);
682595
683137
  if (e2.isDirectory()) {
682596
683138
  walkForItems(p2, out, depth + 1);
682597
683139
  } else if (e2.isFile() && e2.name.endsWith(".md")) {
@@ -682604,7 +683146,7 @@ function walkForItems(dir, out, depth) {
682604
683146
  }
682605
683147
  function parseItem(p2) {
682606
683148
  try {
682607
- const raw = readFileSync124(p2, "utf-8");
683149
+ const raw = readFileSync125(p2, "utf-8");
682608
683150
  const header = raw.slice(0, 3e3);
682609
683151
  const nameMatch = header.match(/^name:\s*(.+)$/m);
682610
683152
  const descMatch = header.match(/^description:\s*(.+)$/m);
@@ -682642,8 +683184,8 @@ function deriveSource(p2) {
682642
683184
  }
682643
683185
  function loadAiwgItemContent(path12, maxBytes = 2e4) {
682644
683186
  try {
682645
- if (!existsSync152(path12)) return null;
682646
- const raw = readFileSync124(path12, "utf-8");
683187
+ if (!existsSync153(path12)) return null;
683188
+ const raw = readFileSync125(path12, "utf-8");
682647
683189
  return raw.length > maxBytes ? raw.slice(0, maxBytes) + "\n\n...(truncated for context budget)" : raw;
682648
683190
  } catch {
682649
683191
  return null;
@@ -682656,14 +683198,14 @@ function listAiwgAddons() {
682656
683198
  _cachedAddons = [];
682657
683199
  return _cachedAddons;
682658
683200
  }
682659
- const addonsDir = join163(root, "agentic", "code", "addons");
682660
- if (!existsSync152(addonsDir)) {
683201
+ const addonsDir = join164(root, "agentic", "code", "addons");
683202
+ if (!existsSync153(addonsDir)) {
682661
683203
  _cachedAddons = [];
682662
683204
  return _cachedAddons;
682663
683205
  }
682664
683206
  const out = [];
682665
683207
  for (const name10 of readdirSync54(addonsDir)) {
682666
- const p2 = join163(addonsDir, name10);
683208
+ const p2 = join164(addonsDir, name10);
682667
683209
  try {
682668
683210
  const st = statSync54(p2);
682669
683211
  if (!st.isDirectory()) continue;
@@ -683179,18 +683721,18 @@ __export(runtime_keys_exports, {
683179
683721
  mintKey: () => mintKey,
683180
683722
  revokeByPrefix: () => revokeByPrefix
683181
683723
  });
683182
- import { existsSync as existsSync153, readFileSync as readFileSync125, writeFileSync as writeFileSync81, mkdirSync as mkdirSync95, chmodSync as chmodSync4 } from "node:fs";
683183
- import { join as join164 } from "node:path";
683724
+ import { existsSync as existsSync154, readFileSync as readFileSync126, writeFileSync as writeFileSync82, mkdirSync as mkdirSync96, chmodSync as chmodSync4 } from "node:fs";
683725
+ import { join as join165 } from "node:path";
683184
683726
  import { homedir as homedir55 } from "node:os";
683185
683727
  import { randomBytes as randomBytes27 } from "node:crypto";
683186
683728
  function ensureDir2() {
683187
- const dir = join164(homedir55(), ".omnius");
683188
- if (!existsSync153(dir)) mkdirSync95(dir, { recursive: true });
683729
+ const dir = join165(homedir55(), ".omnius");
683730
+ if (!existsSync154(dir)) mkdirSync96(dir, { recursive: true });
683189
683731
  }
683190
683732
  function loadAll() {
683191
- if (!existsSync153(KEYS_FILE)) return [];
683733
+ if (!existsSync154(KEYS_FILE)) return [];
683192
683734
  try {
683193
- const raw = readFileSync125(KEYS_FILE, "utf-8");
683735
+ const raw = readFileSync126(KEYS_FILE, "utf-8");
683194
683736
  const parsed = JSON.parse(raw);
683195
683737
  if (!Array.isArray(parsed)) return [];
683196
683738
  return parsed;
@@ -683200,7 +683742,7 @@ function loadAll() {
683200
683742
  }
683201
683743
  function persistAll(records) {
683202
683744
  ensureDir2();
683203
- writeFileSync81(KEYS_FILE, JSON.stringify(records, null, 2), "utf-8");
683745
+ writeFileSync82(KEYS_FILE, JSON.stringify(records, null, 2), "utf-8");
683204
683746
  try {
683205
683747
  chmodSync4(KEYS_FILE, 384);
683206
683748
  } catch {
@@ -683265,7 +683807,7 @@ var KEYS_FILE;
683265
683807
  var init_runtime_keys = __esm({
683266
683808
  "packages/cli/src/api/runtime-keys.ts"() {
683267
683809
  "use strict";
683268
- KEYS_FILE = join164(homedir55(), ".omnius", "keys.json");
683810
+ KEYS_FILE = join165(homedir55(), ".omnius", "keys.json");
683269
683811
  }
683270
683812
  });
683271
683813
 
@@ -683276,20 +683818,20 @@ __export(tor_fallback_exports, {
683276
683818
  torIsReachable: () => torIsReachable,
683277
683819
  tunnelViaTor: () => tunnelViaTor
683278
683820
  });
683279
- import { existsSync as existsSync154, readFileSync as readFileSync126 } from "node:fs";
683821
+ import { existsSync as existsSync155, readFileSync as readFileSync127 } from "node:fs";
683280
683822
  import { homedir as homedir56 } from "node:os";
683281
- import { join as join165 } from "node:path";
683823
+ import { join as join166 } from "node:path";
683282
683824
  import { createConnection as createConnection3 } from "node:net";
683283
683825
  function getLocalOnion() {
683284
683826
  const candidates = [
683285
- join165(homedir56(), "hidden_service_hostname"),
683286
- join165(homedir56(), ".omnius", "tor", "hostname"),
683827
+ join166(homedir56(), "hidden_service_hostname"),
683828
+ join166(homedir56(), ".omnius", "tor", "hostname"),
683287
683829
  "/var/lib/tor/hidden_service/hostname"
683288
683830
  ];
683289
683831
  for (const p2 of candidates) {
683290
683832
  try {
683291
- if (existsSync154(p2)) {
683292
- const v = readFileSync126(p2, "utf-8").trim();
683833
+ if (existsSync155(p2)) {
683834
+ const v = readFileSync127(p2, "utf-8").trim();
683293
683835
  if (v && v.endsWith(".onion")) return v;
683294
683836
  }
683295
683837
  } catch {
@@ -683434,8 +683976,8 @@ __export(graphical_sudo_exports, {
683434
683976
  runGraphicalSudo: () => runGraphicalSudo
683435
683977
  });
683436
683978
  import { spawn as spawn31 } from "node:child_process";
683437
- import { existsSync as existsSync155, mkdirSync as mkdirSync96, writeFileSync as writeFileSync82, chmodSync as chmodSync5 } from "node:fs";
683438
- import { join as join166 } from "node:path";
683979
+ import { existsSync as existsSync156, mkdirSync as mkdirSync97, writeFileSync as writeFileSync83, chmodSync as chmodSync5 } from "node:fs";
683980
+ import { join as join167 } from "node:path";
683439
683981
  import { tmpdir as tmpdir22 } from "node:os";
683440
683982
  function detectSudoHelper() {
683441
683983
  if (process.platform === "win32") return null;
@@ -683451,15 +683993,15 @@ function which2(cmd) {
683451
683993
  const path12 = process.env["PATH"] || "/usr/bin:/bin:/usr/local/bin";
683452
683994
  for (const dir of path12.split(":")) {
683453
683995
  if (!dir) continue;
683454
- const full = join166(dir, cmd);
683455
- if (existsSync155(full)) return full;
683996
+ const full = join167(dir, cmd);
683997
+ if (existsSync156(full)) return full;
683456
683998
  }
683457
683999
  return null;
683458
684000
  }
683459
684001
  function ensureAskpassShim(helper, description) {
683460
- const shimDir = join166(tmpdir22(), "omnius-askpass");
683461
- mkdirSync96(shimDir, { recursive: true });
683462
- const shim = join166(shimDir, `${helper}.sh`);
684002
+ const shimDir = join167(tmpdir22(), "omnius-askpass");
684003
+ mkdirSync97(shimDir, { recursive: true });
684004
+ const shim = join167(shimDir, `${helper}.sh`);
683463
684005
  let body;
683464
684006
  if (helper === "zenity") {
683465
684007
  body = `#!/bin/sh
@@ -683470,7 +684012,7 @@ exec zenity --password --title="Omnius needs sudo" --text="${description.replace
683470
684012
  exec kdialog --password "${description.replace(/"/g, '\\"')}" 2>/dev/null
683471
684013
  `;
683472
684014
  }
683473
- writeFileSync82(shim, body, "utf-8");
684015
+ writeFileSync83(shim, body, "utf-8");
683474
684016
  chmodSync5(shim, 493);
683475
684017
  return shim;
683476
684018
  }
@@ -683550,8 +684092,8 @@ var init_graphical_sudo = __esm({
683550
684092
  });
683551
684093
 
683552
684094
  // packages/cli/src/api/routes-v1.ts
683553
- import { existsSync as existsSync156, mkdirSync as mkdirSync97, readFileSync as readFileSync127, readdirSync as readdirSync55, statSync as statSync55 } from "node:fs";
683554
- import { join as join167, resolve as pathResolve3 } from "node:path";
684095
+ import { existsSync as existsSync157, mkdirSync as mkdirSync98, readFileSync as readFileSync128, readdirSync as readdirSync55, statSync as statSync55 } from "node:fs";
684096
+ import { join as join168, resolve as pathResolve3 } from "node:path";
683555
684097
  import { homedir as homedir57 } from "node:os";
683556
684098
  async function tryRouteV1(ctx3) {
683557
684099
  const { pathname, method } = ctx3;
@@ -683659,18 +684201,23 @@ async function tryRouteV1(ctx3) {
683659
684201
  if (pathname === "/v1/tools" && method === "GET") {
683660
684202
  return handleListTools(ctx3);
683661
684203
  }
684204
+ if (pathname === "/v1/tools/register" && method === "POST") {
684205
+ return handleRegisterTool(ctx3);
684206
+ }
683662
684207
  {
683663
- const m2 = /^\/v1\/tools\/([^/]+)(\/call)?$/.exec(pathname);
684208
+ const m2 = /^\/v1\/tools\/([^/]+)(\/call|\/eval)?$/.exec(pathname);
683664
684209
  if (m2) {
683665
684210
  const toolName = decodeURIComponent(m2[1]);
683666
- const isCall = !!m2[2];
683667
- if (isCall && method === "POST") return handleCallTool(ctx3, toolName);
683668
- if (!isCall && method === "GET") return handleGetTool(ctx3, toolName);
684211
+ const suffix = m2[2];
684212
+ if (suffix === "/call" && method === "POST") return handleCallTool(ctx3, toolName);
684213
+ if (suffix === "/eval" && method === "POST") return handleEvalTool(ctx3, toolName);
684214
+ if (!suffix && method === "GET") return handleGetTool(ctx3, toolName);
684215
+ if (!suffix && method === "DELETE") return handleDeleteTool(ctx3, toolName);
683669
684216
  sendProblem(ctx3.res, problemDetails({
683670
684217
  type: P2.methodNotAllowed,
683671
684218
  status: 405,
683672
684219
  title: `Method ${method} not allowed for ${pathname}`,
683673
- detail: isCall ? "POST /v1/tools/{name}/call to execute the tool." : "GET /v1/tools/{name} to fetch its schema.",
684220
+ detail: suffix === "/call" ? "POST /v1/tools/{name}/call to execute the tool." : suffix === "/eval" ? "POST /v1/tools/{name}/eval to evaluate the tool." : "GET /v1/tools/{name} for schema, DELETE to unregister an external tool.",
683674
684221
  instance: ctx3.requestId
683675
684222
  }));
683676
684223
  return true;
@@ -683802,11 +684349,11 @@ async function handleGetSkill(ctx3, name10) {
683802
684349
  async function fallbackDiscoverSkills() {
683803
684350
  return (_root) => {
683804
684351
  const roots = [
683805
- join167(homedir57(), ".local", "share", "ai-writing-guide")
684352
+ join168(homedir57(), ".local", "share", "ai-writing-guide")
683806
684353
  ];
683807
684354
  const out = [];
683808
684355
  for (const root of roots) {
683809
- if (!existsSync156(root)) continue;
684356
+ if (!existsSync157(root)) continue;
683810
684357
  walkForSkills(root, out, 0);
683811
684358
  }
683812
684359
  return out;
@@ -683817,12 +684364,12 @@ function walkForSkills(dir, out, depth) {
683817
684364
  try {
683818
684365
  for (const e2 of readdirSync55(dir, { withFileTypes: true })) {
683819
684366
  if (e2.name.startsWith(".") || e2.name === "node_modules") continue;
683820
- const p2 = join167(dir, e2.name);
684367
+ const p2 = join168(dir, e2.name);
683821
684368
  if (e2.isDirectory()) {
683822
684369
  walkForSkills(p2, out, depth + 1);
683823
684370
  } else if (e2.isFile() && e2.name === "SKILL.md") {
683824
684371
  try {
683825
- const content = readFileSync127(p2, "utf-8").slice(0, 2e3);
684372
+ const content = readFileSync128(p2, "utf-8").slice(0, 2e3);
683826
684373
  const nameMatch = content.match(/^name:\s*(.+)$/m);
683827
684374
  const descMatch = content.match(/^description:\s*(.+)$/m);
683828
684375
  out.push({
@@ -684105,19 +684652,19 @@ async function handleOllamaPoolCleanup(ctx3) {
684105
684652
  }
684106
684653
  }
684107
684654
  function memoryDbPaths2(baseDir = process.cwd()) {
684108
- const dir = join167(baseDir, ".omnius");
684655
+ const dir = join168(baseDir, ".omnius");
684109
684656
  return {
684110
- episodes: join167(dir, "episodes.db"),
684111
- knowledge: join167(dir, "knowledge.db")
684657
+ episodes: join168(dir, "episodes.db"),
684658
+ knowledge: join168(dir, "knowledge.db")
684112
684659
  };
684113
684660
  }
684114
684661
  function unifiedMemoryDbPath(baseDir = process.cwd()) {
684115
- const dir = join167(baseDir, ".omnius");
684662
+ const dir = join168(baseDir, ".omnius");
684116
684663
  try {
684117
- mkdirSync97(dir, { recursive: true });
684664
+ mkdirSync98(dir, { recursive: true });
684118
684665
  } catch {
684119
684666
  }
684120
- return join167(dir, "unified-memory.db");
684667
+ return join168(dir, "unified-memory.db");
684121
684668
  }
684122
684669
  function withUnifiedMemory(fn) {
684123
684670
  const db = initDb(unifiedMemoryDbPath());
@@ -684746,7 +685293,7 @@ async function handleFilesRead(ctx3) {
684746
685293
  }));
684747
685294
  return true;
684748
685295
  }
684749
- if (!existsSync156(resolved)) {
685296
+ if (!existsSync157(resolved)) {
684750
685297
  sendProblem(res, problemDetails({
684751
685298
  type: P2.notFound,
684752
685299
  status: 404,
@@ -684778,7 +685325,7 @@ async function handleFilesRead(ctx3) {
684778
685325
  }));
684779
685326
  return true;
684780
685327
  }
684781
- const content = readFileSync127(resolved, "utf-8");
685328
+ const content = readFileSync128(resolved, "utf-8");
684782
685329
  const offset = typeof body.offset === "number" && body.offset >= 0 ? body.offset : 0;
684783
685330
  const limit = typeof body.limit === "number" && body.limit > 0 ? body.limit : content.length;
684784
685331
  const slice2 = content.slice(offset, offset + limit);
@@ -685011,14 +685558,14 @@ async function handleNexusStatus(ctx3) {
685011
685558
  const { res, requestId } = ctx3;
685012
685559
  try {
685013
685560
  const statePaths = [
685014
- join167(process.cwd(), ".omnius", "nexus-peer-state.json"),
685015
- join167(homedir57(), ".omnius", "nexus-peer-cache.json")
685561
+ join168(process.cwd(), ".omnius", "nexus-peer-state.json"),
685562
+ join168(homedir57(), ".omnius", "nexus-peer-cache.json")
685016
685563
  ];
685017
685564
  const states2 = [];
685018
685565
  for (const p2 of statePaths) {
685019
- if (!existsSync156(p2)) continue;
685566
+ if (!existsSync157(p2)) continue;
685020
685567
  try {
685021
- const raw = readFileSync127(p2, "utf-8");
685568
+ const raw = readFileSync128(p2, "utf-8");
685022
685569
  states2.push({ source: p2, data: JSON.parse(raw) });
685023
685570
  } catch (e2) {
685024
685571
  states2.push({ source: p2, error: String(e2) });
@@ -685045,8 +685592,8 @@ async function handleNexusStatus(ctx3) {
685045
685592
  }
685046
685593
  function loadAgentName() {
685047
685594
  try {
685048
- const p2 = join167(homedir57(), ".omnius", "agent-name");
685049
- if (existsSync156(p2)) return readFileSync127(p2, "utf-8").trim();
685595
+ const p2 = join168(homedir57(), ".omnius", "agent-name");
685596
+ if (existsSync157(p2)) return readFileSync128(p2, "utf-8").trim();
685050
685597
  } catch {
685051
685598
  }
685052
685599
  return null;
@@ -685055,14 +685602,14 @@ async function handleSponsors(ctx3) {
685055
685602
  const { req: req3, res, url, requestId } = ctx3;
685056
685603
  try {
685057
685604
  const candidates = [
685058
- join167(homedir57(), ".omnius", "sponsor-cache.json"),
685059
- join167(homedir57(), ".omnius", "sponsors.json")
685605
+ join168(homedir57(), ".omnius", "sponsor-cache.json"),
685606
+ join168(homedir57(), ".omnius", "sponsors.json")
685060
685607
  ];
685061
685608
  let sponsors = [];
685062
685609
  for (const p2 of candidates) {
685063
- if (!existsSync156(p2)) continue;
685610
+ if (!existsSync157(p2)) continue;
685064
685611
  try {
685065
- const raw = JSON.parse(readFileSync127(p2, "utf-8"));
685612
+ const raw = JSON.parse(readFileSync128(p2, "utf-8"));
685066
685613
  if (Array.isArray(raw)) {
685067
685614
  sponsors = raw;
685068
685615
  break;
@@ -685131,8 +685678,8 @@ async function handleEvaluate(ctx3) {
685131
685678
  }));
685132
685679
  return true;
685133
685680
  }
685134
- const jobPath = join167(process.cwd(), ".omnius", "jobs", `${runId}.json`);
685135
- if (!existsSync156(jobPath)) {
685681
+ const jobPath = join168(process.cwd(), ".omnius", "jobs", `${runId}.json`);
685682
+ if (!existsSync157(jobPath)) {
685136
685683
  sendProblem(res, problemDetails({
685137
685684
  type: P2.notFound,
685138
685685
  status: 404,
@@ -685142,7 +685689,7 @@ async function handleEvaluate(ctx3) {
685142
685689
  }));
685143
685690
  return true;
685144
685691
  }
685145
- const job = JSON.parse(readFileSync127(jobPath, "utf-8"));
685692
+ const job = JSON.parse(readFileSync128(jobPath, "utf-8"));
685146
685693
  sendJson2(res, 200, {
685147
685694
  run_id: runId,
685148
685695
  task: job.task,
@@ -685280,9 +685827,9 @@ async function handleMintKey(ctx3) {
685280
685827
  return true;
685281
685828
  }
685282
685829
  function _readStatusFile(p2) {
685283
- if (!existsSync156(p2)) return null;
685830
+ if (!existsSync157(p2)) return null;
685284
685831
  try {
685285
- const data = JSON.parse(readFileSync127(p2, "utf-8"));
685832
+ const data = JSON.parse(readFileSync128(p2, "utf-8"));
685286
685833
  if (data?.connected && typeof data.peerId === "string" && data.peerId.length > 10) {
685287
685834
  const pid = Number(data.pid);
685288
685835
  if (pid > 0) {
@@ -685305,32 +685852,32 @@ function _readStatusFile(p2) {
685305
685852
  function resolveLocalPeerId() {
685306
685853
  const override = process.env["OMNIUS_NEXUS_DIR"];
685307
685854
  if (override) {
685308
- const r2 = _readStatusFile(join167(override, "status.json"));
685855
+ const r2 = _readStatusFile(join168(override, "status.json"));
685309
685856
  if (r2) return r2;
685310
685857
  }
685311
685858
  const scope = (process.env["OMNIUS_NEXUS_SCOPE"] || "").toLowerCase();
685312
685859
  const projectScopeFlag = (process.env["OMNIUS_NEXUS_PROJECT_SCOPE"] || "").toLowerCase();
685313
685860
  const projectScoped = scope === "project" || scope === "local" || projectScopeFlag === "1" || projectScopeFlag === "true" || projectScopeFlag === "yes";
685314
685861
  const candidates = projectScoped ? [
685315
- join167(process.cwd(), ".omnius", "nexus", "status.json"),
685316
- join167(homedir57(), ".omnius", "nexus", "status.json")
685862
+ join168(process.cwd(), ".omnius", "nexus", "status.json"),
685863
+ join168(homedir57(), ".omnius", "nexus", "status.json")
685317
685864
  ] : [
685318
- join167(homedir57(), ".omnius", "nexus", "status.json"),
685319
- join167(process.cwd(), ".omnius", "nexus", "status.json")
685865
+ join168(homedir57(), ".omnius", "nexus", "status.json"),
685866
+ join168(process.cwd(), ".omnius", "nexus", "status.json")
685320
685867
  ];
685321
685868
  for (const p2 of candidates) {
685322
685869
  const r2 = _readStatusFile(p2);
685323
685870
  if (r2) return r2;
685324
685871
  }
685325
685872
  try {
685326
- const regPath = join167(homedir57(), ".omnius", "nexus-registry.json");
685327
- if (existsSync156(regPath)) {
685328
- const reg = JSON.parse(readFileSync127(regPath, "utf-8"));
685873
+ const regPath = join168(homedir57(), ".omnius", "nexus-registry.json");
685874
+ if (existsSync157(regPath)) {
685875
+ const reg = JSON.parse(readFileSync128(regPath, "utf-8"));
685329
685876
  const entries = Array.isArray(reg?.dirs) ? reg.dirs : [];
685330
685877
  for (const entry of entries) {
685331
685878
  const dir = typeof entry === "string" ? entry : entry?.dir;
685332
685879
  if (typeof dir === "string") {
685333
- const r2 = _readStatusFile(join167(dir, "status.json"));
685880
+ const r2 = _readStatusFile(join168(dir, "status.json"));
685334
685881
  if (r2) return r2;
685335
685882
  }
685336
685883
  }
@@ -685364,21 +685911,21 @@ function locateTorScript(filename) {
685364
685911
  const candidates = [
685365
685912
  // npm-installed layout: build-publish.mjs copies scripts to
685366
685913
  // publish/dist/scripts/tor/ which lands at <install>/dist/scripts/tor/.
685367
- join167(__dirname, "scripts", "tor", filename),
685368
- join167(__dirname, "..", "scripts", "tor", filename),
685369
- join167(__dirname, "..", "..", "scripts", "tor", filename),
685914
+ join168(__dirname, "scripts", "tor", filename),
685915
+ join168(__dirname, "..", "scripts", "tor", filename),
685916
+ join168(__dirname, "..", "..", "scripts", "tor", filename),
685370
685917
  // Workspace dev: cli package's source tree.
685371
- join167(process.cwd(), "packages", "cli", "scripts", "tor", filename),
685372
- join167(process.cwd(), "scripts", "tor", filename)
685918
+ join168(process.cwd(), "packages", "cli", "scripts", "tor", filename),
685919
+ join168(process.cwd(), "scripts", "tor", filename)
685373
685920
  ];
685374
685921
  for (const p2 of candidates) {
685375
- if (existsSync156(p2)) return p2;
685922
+ if (existsSync157(p2)) return p2;
685376
685923
  }
685377
685924
  try {
685378
685925
  const { execSync: execSync63 } = __require("node:child_process");
685379
685926
  const root = execSync63("npm root -g", { encoding: "utf-8", timeout: 5e3 }).trim();
685380
- const p2 = join167(root, "omnius", "dist", "scripts", "tor", filename);
685381
- if (existsSync156(p2)) return p2;
685927
+ const p2 = join168(root, "omnius", "dist", "scripts", "tor", filename);
685928
+ if (existsSync157(p2)) return p2;
685382
685929
  } catch {
685383
685930
  }
685384
685931
  return null;
@@ -685650,15 +686197,15 @@ async function handleRemoteProxy(ctx3) {
685650
686197
  const tunnelScope = (process.env["OMNIUS_NEXUS_SCOPE"] || "").toLowerCase();
685651
686198
  const tunnelProjectScope = tunnelScope === "project" || tunnelScope === "local" || ["1", "true", "yes"].includes((process.env["OMNIUS_NEXUS_PROJECT_SCOPE"] || "").toLowerCase());
685652
686199
  const nexusCandidates = tunnelProjectScope ? [
685653
- join167(process.cwd(), ".omnius", "nexus"),
685654
- join167(homedir57(), ".omnius", "nexus")
686200
+ join168(process.cwd(), ".omnius", "nexus"),
686201
+ join168(homedir57(), ".omnius", "nexus")
685655
686202
  ] : [
685656
- join167(homedir57(), ".omnius", "nexus"),
685657
- join167(process.cwd(), ".omnius", "nexus")
686203
+ join168(homedir57(), ".omnius", "nexus"),
686204
+ join168(process.cwd(), ".omnius", "nexus")
685658
686205
  ];
685659
686206
  let nexusDirPath = null;
685660
686207
  for (const p2 of nexusCandidates) {
685661
- if (existsSync156(join167(p2, "status.json"))) {
686208
+ if (existsSync157(join168(p2, "status.json"))) {
685662
686209
  nexusDirPath = p2;
685663
686210
  break;
685664
686211
  }
@@ -685754,7 +686301,7 @@ async function handleRemoteProxy(ctx3) {
685754
686301
  }));
685755
686302
  return true;
685756
686303
  }
685757
- const streamFile = join167(nexusDirPath, `tunnel-${requestId}-${Date.now()}.jsonl`);
686304
+ const streamFile = join168(nexusDirPath, `tunnel-${requestId}-${Date.now()}.jsonl`);
685758
686305
  try {
685759
686306
  const { writeFileSync: _wfs } = await import("node:fs");
685760
686307
  _wfs(streamFile, "");
@@ -686116,11 +686663,16 @@ async function handleListTools(ctx3) {
686116
686663
  default_exposure: entry.defaultExposure,
686117
686664
  availability: entry.availability,
686118
686665
  direct_callable: entry.directCallable,
686666
+ source: "builtin",
686119
686667
  endpoints: {
686120
686668
  call: `/v1/tools/${encodeURIComponent(entry.name)}/call`,
686121
686669
  schema: `/v1/tools/${encodeURIComponent(entry.name)}`
686122
686670
  }
686123
686671
  }));
686672
+ for (const ext of loadExternalTools(workingDir)) {
686673
+ if (profile.loaded && !isToolAllowed(profile.loaded.profile, ext.name)) continue;
686674
+ tools.push(externalToolToListEntry(ext));
686675
+ }
686124
686676
  tools.sort((a2, b) => a2.name.localeCompare(b.name));
686125
686677
  const filterCat = url.searchParams.get("category");
686126
686678
  const filterScope = url.searchParams.get("scope");
@@ -686184,11 +686736,33 @@ async function handleGetTool(ctx3, name10) {
686184
686736
  }
686185
686737
  const found = registry4.byName.get(name10);
686186
686738
  if (!found) {
686739
+ const ext = getExternalTool(workingDir, name10);
686740
+ if (ext) {
686741
+ if (profile.loaded && !isToolAllowed(profile.loaded.profile, name10)) {
686742
+ sendProblem(res, problemDetails({
686743
+ type: P2.forbidden,
686744
+ status: 403,
686745
+ title: "Tool denied by profile",
686746
+ detail: `Tool '${name10}' is not allowed by profile '${profile.loaded.profile.name}'.`,
686747
+ instance: requestId
686748
+ }));
686749
+ return true;
686750
+ }
686751
+ sendJson2(res, 200, {
686752
+ ...externalToolToListEntry(ext),
686753
+ call_body_shape: {
686754
+ args: "<object matching the `parameters` JSON schema>",
686755
+ session_id: "<optional stable workflow id; also accepted as X-Omnius-Session-Id or env.OMNIUS_SESSION_ID>"
686756
+ },
686757
+ active_profile: profile.loaded ? profileMetadata(profile.loaded, registry4.entries.map((entry) => entry.name)) : null
686758
+ });
686759
+ return true;
686760
+ }
686187
686761
  sendProblem(res, problemDetails({
686188
686762
  type: P2.notFound,
686189
686763
  status: 404,
686190
686764
  title: `Tool '${name10}' not found`,
686191
- detail: "No direct-callable tool with that name is registered.",
686765
+ detail: "No direct-callable or registered external tool with that name.",
686192
686766
  instance: requestId
686193
686767
  }));
686194
686768
  return true;
@@ -686305,6 +686879,10 @@ async function handleCallTool(ctx3, name10) {
686305
686879
  const registry4 = await buildDirectToolRegistry(workingDir);
686306
686880
  const entry = registry4.byName.get(name10);
686307
686881
  if (!entry) {
686882
+ const ext = getExternalTool(workingDir, name10);
686883
+ if (ext) {
686884
+ return callExternalTool(ctx3, ext, args, workingDir, origin, scope, body);
686885
+ }
686308
686886
  sendProblem(res, problemDetails({
686309
686887
  type: P2.notFound,
686310
686888
  status: 404,
@@ -686402,6 +686980,268 @@ async function handleCallTool(ctx3, name10) {
686402
686980
  return true;
686403
686981
  }
686404
686982
  }
686983
+ function externalToolToListEntry(ext) {
686984
+ return {
686985
+ name: ext.name,
686986
+ class: "ExternalTool",
686987
+ description: ext.description,
686988
+ parameters: ext.parameters,
686989
+ security: ext.security,
686990
+ default_exposure: ext.security.off_device_allowed ? "trusted-default" : "local-default",
686991
+ availability: { available: true, cached: false, checkedAt: ext.updated_at },
686992
+ direct_callable: true,
686993
+ source: "external",
686994
+ transport: ext.transport.type,
686995
+ endpoints: {
686996
+ call: `/v1/tools/${encodeURIComponent(ext.name)}/call`,
686997
+ schema: `/v1/tools/${encodeURIComponent(ext.name)}`,
686998
+ eval: `/v1/tools/${encodeURIComponent(ext.name)}/eval`
686999
+ },
687000
+ created_at: ext.created_at,
687001
+ updated_at: ext.updated_at
687002
+ };
687003
+ }
687004
+ function externalDispatchDeps() {
687005
+ return { getMcpManager: (workingDir) => getMcpManager(workingDir) };
687006
+ }
687007
+ async function callExternalTool(ctx3, ext, args, workingDir, origin, scope, body) {
687008
+ const { res, requestId, user } = ctx3;
687009
+ const scopeRank = { read: 0, run: 1, admin: 2 };
687010
+ if (scopeRank[scope] < scopeRank[ext.security.requires_scope]) {
687011
+ sendProblem(res, problemDetails({
687012
+ type: P2.forbidden,
687013
+ status: 403,
687014
+ title: "Tool invocation denied",
687015
+ detail: `Tool '${ext.name}' requires '${ext.security.requires_scope}' scope; caller has '${scope}'.`,
687016
+ instance: requestId
687017
+ }));
687018
+ return true;
687019
+ }
687020
+ if (origin === "remote" && !ext.security.off_device_allowed && scope !== "admin") {
687021
+ sendProblem(res, problemDetails({
687022
+ type: P2.forbidden,
687023
+ status: 403,
687024
+ title: "Tool invocation denied",
687025
+ detail: `Tool '${ext.name}' is not off_device_allowed; remote callers need admin scope.`,
687026
+ instance: requestId
687027
+ }));
687028
+ return true;
687029
+ }
687030
+ const sessionId = resolveDirectToolSessionId(ctx3, body, args);
687031
+ const result = await executeExternalTool(ext, args, workingDir, sessionId, externalDispatchDeps());
687032
+ publishEvent("tool.called", { tool: ext.name, transport: ext.transport.type, source: "external" }, {
687033
+ subject: user ?? "anonymous",
687034
+ aimsControl: "A.6.2.6"
687035
+ // ISO 42001 — AI system operation record
687036
+ });
687037
+ sendJson2(res, result.success ? 200 : 502, {
687038
+ tool: ext.name,
687039
+ class: "ExternalTool",
687040
+ result,
687041
+ security: ext.security,
687042
+ session_id: sessionId ?? null,
687043
+ origin,
687044
+ scope
687045
+ });
687046
+ return true;
687047
+ }
687048
+ async function handleRegisterTool(ctx3) {
687049
+ const { req: req3, res, requestId, user } = ctx3;
687050
+ const scope = requestScope(ctx3);
687051
+ if (scope === "read") {
687052
+ sendProblem(res, problemDetails({
687053
+ type: P2.forbidden,
687054
+ status: 403,
687055
+ title: "run scope required",
687056
+ detail: "Registering a tool requires 'run' or 'admin' scope.",
687057
+ instance: requestId
687058
+ }));
687059
+ return true;
687060
+ }
687061
+ let body;
687062
+ try {
687063
+ body = await parseJsonBodyStrict(req3);
687064
+ } catch {
687065
+ sendProblem(res, problemDetails({
687066
+ type: P2.invalidRequest,
687067
+ status: 400,
687068
+ title: "Body must be JSON",
687069
+ detail: "POST a tool manifest: {name, description, parameters, security?, transport}.",
687070
+ instance: requestId
687071
+ }));
687072
+ return true;
687073
+ }
687074
+ const workingDir = resolveToolWorkingDirFromRequest(ctx3);
687075
+ const origin = requestOrigin(ctx3);
687076
+ if (origin === "remote" && scope !== "admin") {
687077
+ sendProblem(res, problemDetails({
687078
+ type: P2.forbidden,
687079
+ status: 403,
687080
+ title: "Admin scope required",
687081
+ detail: "Remote callers must use admin scope to register tools.",
687082
+ instance: requestId
687083
+ }));
687084
+ return true;
687085
+ }
687086
+ const builtins = await buildDirectToolRegistry(workingDir);
687087
+ const manifestName = typeof body?.name === "string" ? body.name.trim() : "";
687088
+ if (manifestName && builtins.byName.has(manifestName)) {
687089
+ sendProblem(res, problemDetails({
687090
+ type: P2.invalidRequest,
687091
+ status: 409,
687092
+ title: "Name collides with built-in tool",
687093
+ detail: `'${manifestName}' is a built-in tool; choose a different name.`,
687094
+ instance: requestId
687095
+ }));
687096
+ return true;
687097
+ }
687098
+ const existing = getExternalTool(workingDir, manifestName) ?? void 0;
687099
+ const validation = validateManifest2(body, existing);
687100
+ if (!validation.ok || !validation.record) {
687101
+ sendProblem(res, problemDetails({
687102
+ type: P2.invalidRequest,
687103
+ status: 400,
687104
+ title: "Invalid tool manifest",
687105
+ detail: validation.error ?? "Manifest failed validation.",
687106
+ instance: requestId
687107
+ }));
687108
+ return true;
687109
+ }
687110
+ const record = validation.record;
687111
+ if (record.transport.type === "mcp" && record.transport.connect?.url) {
687112
+ try {
687113
+ const mgr = await getMcpManager(workingDir);
687114
+ if (mgr && typeof mgr.addServer === "function") {
687115
+ const c8 = record.transport.connect;
687116
+ await mgr.addServer(record.transport.server, {
687117
+ transport: c8.transport ?? "streamable-http",
687118
+ url: c8.url,
687119
+ headers: c8.headers,
687120
+ command: c8.command,
687121
+ args: c8.args
687122
+ });
687123
+ }
687124
+ } catch (err) {
687125
+ sendProblem(res, problemDetails({
687126
+ type: P2.upstreamFailure,
687127
+ status: 502,
687128
+ title: "MCP server connect failed",
687129
+ detail: `Registered tool but could not connect MCP server '${record.transport.server}': ${err instanceof Error ? err.message : String(err)}`,
687130
+ instance: requestId
687131
+ }));
687132
+ return true;
687133
+ }
687134
+ }
687135
+ const { replaced } = upsertExternalTool(workingDir, record);
687136
+ publishEvent("tool.registered", { tool: record.name, transport: record.transport.type, replaced }, {
687137
+ subject: user ?? "anonymous",
687138
+ aimsControl: "A.6.2.4"
687139
+ // ISO 42001 — AI system change/control record
687140
+ });
687141
+ sendJson2(res, replaced ? 200 : 201, {
687142
+ registered: record.name,
687143
+ replaced,
687144
+ working_directory: workingDir,
687145
+ tool: externalToolToListEntry(record)
687146
+ });
687147
+ return true;
687148
+ }
687149
+ async function handleDeleteTool(ctx3, name10) {
687150
+ const { res, requestId, user } = ctx3;
687151
+ const scope = requestScope(ctx3);
687152
+ if (scope === "read") {
687153
+ sendProblem(res, problemDetails({
687154
+ type: P2.forbidden,
687155
+ status: 403,
687156
+ title: "run scope required",
687157
+ detail: "Unregistering a tool requires 'run' or 'admin' scope.",
687158
+ instance: requestId
687159
+ }));
687160
+ return true;
687161
+ }
687162
+ const workingDir = resolveToolWorkingDirFromRequest(ctx3);
687163
+ const removed = removeExternalTool(workingDir, name10);
687164
+ if (!removed) {
687165
+ sendProblem(res, problemDetails({
687166
+ type: P2.notFound,
687167
+ status: 404,
687168
+ title: `External tool '${name10}' not found`,
687169
+ detail: "Only externally-registered tools can be deleted; built-ins are immutable.",
687170
+ instance: requestId
687171
+ }));
687172
+ return true;
687173
+ }
687174
+ publishEvent("tool.unregistered", { tool: name10 }, {
687175
+ subject: user ?? "anonymous",
687176
+ aimsControl: "A.6.2.4"
687177
+ });
687178
+ sendJson2(res, 200, { unregistered: name10, working_directory: workingDir });
687179
+ return true;
687180
+ }
687181
+ async function handleEvalTool(ctx3, name10) {
687182
+ const { req: req3, res, requestId } = ctx3;
687183
+ const scope = requestScope(ctx3);
687184
+ if (scope === "read") {
687185
+ sendProblem(res, problemDetails({
687186
+ type: P2.forbidden,
687187
+ status: 403,
687188
+ title: "run scope required",
687189
+ detail: "Evaluating a tool requires 'run' or 'admin' scope.",
687190
+ instance: requestId
687191
+ }));
687192
+ return true;
687193
+ }
687194
+ let body;
687195
+ try {
687196
+ body = await parseJsonBodyStrict(req3);
687197
+ } catch {
687198
+ sendProblem(res, problemDetails({
687199
+ type: P2.invalidRequest,
687200
+ status: 400,
687201
+ title: "Body must be JSON",
687202
+ detail: "POST {cases: [{name?, args, expect?}]}.",
687203
+ instance: requestId
687204
+ }));
687205
+ return true;
687206
+ }
687207
+ const cases = Array.isArray(body?.cases) ? body.cases : null;
687208
+ if (!cases || cases.length === 0) {
687209
+ sendProblem(res, problemDetails({
687210
+ type: P2.invalidRequest,
687211
+ status: 400,
687212
+ title: "Missing 'cases'",
687213
+ detail: "Provide a non-empty `cases` array: [{args, expect?}].",
687214
+ instance: requestId
687215
+ }));
687216
+ return true;
687217
+ }
687218
+ const workingDir = resolveToolWorkingDirFromRequest(ctx3);
687219
+ const ext = getExternalTool(workingDir, name10);
687220
+ if (!ext) {
687221
+ sendProblem(res, problemDetails({
687222
+ type: P2.notFound,
687223
+ status: 404,
687224
+ title: `External tool '${name10}' not found`,
687225
+ detail: "Tool-level eval is available for externally-registered tools.",
687226
+ instance: requestId
687227
+ }));
687228
+ return true;
687229
+ }
687230
+ try {
687231
+ const report2 = await evaluateExternalTool(ext, cases, workingDir, externalDispatchDeps());
687232
+ sendJson2(res, 200, report2);
687233
+ return true;
687234
+ } catch (err) {
687235
+ sendProblem(res, problemDetails({
687236
+ type: P2.internalError,
687237
+ status: 500,
687238
+ title: "Tool eval failed",
687239
+ detail: err instanceof Error ? err.message : String(err),
687240
+ instance: requestId
687241
+ }));
687242
+ return true;
687243
+ }
687244
+ }
686405
687245
  async function handleListHooks(ctx3) {
686406
687246
  const { res } = ctx3;
686407
687247
  sendJson2(res, 200, {
@@ -686449,14 +687289,14 @@ async function handleListEngines(ctx3) {
686449
687289
  const home = homedir57();
686450
687290
  sendJson2(res, 200, {
686451
687291
  engines: [
686452
- { name: "dream", state_file: join167(process.cwd(), ".omnius", "dreams"), controllable_via: "SSE + slash commands" },
686453
- { name: "bless", state_file: join167(process.cwd(), ".omnius", "bless-state.json"), controllable_via: "slash commands" },
686454
- { name: "call", state_file: join167(process.cwd(), ".omnius", "call-state.json"), controllable_via: "slash commands" },
686455
- { name: "listen", state_file: join167(process.cwd(), ".omnius", "listen-state.json"), controllable_via: "slash commands" },
686456
- { name: "telegram", state_file: join167(home, ".omnius", "telegram-state.json"), controllable_via: "slash commands" },
686457
- { name: "expose", state_file: join167(process.cwd(), ".omnius", "expose-state.json"), controllable_via: "/expose commands" },
686458
- { name: "nexus", state_file: join167(home, ".omnius", "nexus-peer-cache.json"), controllable_via: "/nexus commands" },
686459
- { name: "ipfs", state_file: join167(process.cwd(), ".omnius", "ipfs"), controllable_via: "slash commands" }
687292
+ { name: "dream", state_file: join168(process.cwd(), ".omnius", "dreams"), controllable_via: "SSE + slash commands" },
687293
+ { name: "bless", state_file: join168(process.cwd(), ".omnius", "bless-state.json"), controllable_via: "slash commands" },
687294
+ { name: "call", state_file: join168(process.cwd(), ".omnius", "call-state.json"), controllable_via: "slash commands" },
687295
+ { name: "listen", state_file: join168(process.cwd(), ".omnius", "listen-state.json"), controllable_via: "slash commands" },
687296
+ { name: "telegram", state_file: join168(home, ".omnius", "telegram-state.json"), controllable_via: "slash commands" },
687297
+ { name: "expose", state_file: join168(process.cwd(), ".omnius", "expose-state.json"), controllable_via: "/expose commands" },
687298
+ { name: "nexus", state_file: join168(home, ".omnius", "nexus-peer-cache.json"), controllable_via: "/nexus commands" },
687299
+ { name: "ipfs", state_file: join168(process.cwd(), ".omnius", "ipfs"), controllable_via: "slash commands" }
686460
687300
  ],
686461
687301
  note: "Engine instrumentation lives in the running TUI process. Full status + control requires the daemon↔TUI bridge (PT-07). See parity audit WO-PARITY-04."
686462
687302
  });
@@ -686539,21 +687379,21 @@ async function tryAimsRoute(ctx3) {
686539
687379
  return false;
686540
687380
  }
686541
687381
  function aimsDir() {
686542
- return join167(homedir57(), ".omnius", "aims");
687382
+ return join168(homedir57(), ".omnius", "aims");
686543
687383
  }
686544
687384
  function readAimsFile(name10, fallback) {
686545
687385
  try {
686546
- const p2 = join167(aimsDir(), name10);
686547
- if (existsSync156(p2)) return JSON.parse(readFileSync127(p2, "utf-8"));
687386
+ const p2 = join168(aimsDir(), name10);
687387
+ if (existsSync157(p2)) return JSON.parse(readFileSync128(p2, "utf-8"));
686548
687388
  } catch {
686549
687389
  }
686550
687390
  return fallback;
686551
687391
  }
686552
687392
  function writeAimsFile(name10, data) {
686553
687393
  const dir = aimsDir();
686554
- const { mkdirSync: mkdirSync105, writeFileSync: wf, renameSync: rn } = __require("node:fs");
686555
- mkdirSync105(dir, { recursive: true });
686556
- const finalPath = join167(dir, name10);
687394
+ const { mkdirSync: mkdirSync106, writeFileSync: wf, renameSync: rn } = __require("node:fs");
687395
+ mkdirSync106(dir, { recursive: true });
687396
+ const finalPath = join168(dir, name10);
686557
687397
  const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
686558
687398
  try {
686559
687399
  wf(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
@@ -686916,12 +687756,12 @@ async function handleAimsSuppliers(ctx3) {
686916
687756
  }
686917
687757
  ];
686918
687758
  const sponsorPaths = [
686919
- join167(homedir57(), ".omnius", "sponsor-cache.json")
687759
+ join168(homedir57(), ".omnius", "sponsor-cache.json")
686920
687760
  ];
686921
687761
  for (const p2 of sponsorPaths) {
686922
- if (!existsSync156(p2)) continue;
687762
+ if (!existsSync157(p2)) continue;
686923
687763
  try {
686924
- const raw = JSON.parse(readFileSync127(p2, "utf-8"));
687764
+ const raw = JSON.parse(readFileSync128(p2, "utf-8"));
686925
687765
  const list = Array.isArray(raw) ? raw : raw?.sponsors ?? [];
686926
687766
  for (const s2 of list) {
686927
687767
  suppliers.push({
@@ -687074,6 +687914,9 @@ var init_routes_v1 = __esm({
687074
687914
  init_command_registry();
687075
687915
  init_profiles();
687076
687916
  init_direct_tool_registry();
687917
+ init_external_tool_registry();
687918
+ init_external_tool_dispatch();
687919
+ init_external_tool_eval();
687077
687920
  init_dist();
687078
687921
  PROBLEM_BASE2 = "https://omnius.nexus/problems";
687079
687922
  P2 = {
@@ -697682,15 +698525,55 @@ function getOpenApiSpec() {
697682
698525
  responses: { 200: { description: "Paginated tools with security metadata" } }
697683
698526
  }
697684
698527
  },
698528
+ "/v1/tools/register": {
698529
+ post: {
698530
+ summary: "Register an application-specific external tool (run scope)",
698531
+ tags: ["Tools"],
698532
+ description: 'Unified registration contract for agents integrating Omnius into their stack. Body: {name, description, parameters (JSON schema, type:object), security?, transport}. `transport` is discriminated: {type:"http", callback_url, auth_header?, headers?, timeout_ms?, result_path?} — Omnius POSTs {name, args, session_id} to callback_url; OR {type:"mcp", server, tool, connect?:{url, transport, headers}} — proxies to a named tool on an MCP server, auto-connecting when `connect` is supplied. Registered tools are persisted per working directory (.omnius/external-tools.json) and appear in GET /v1/tools alongside built-ins. Names that collide with built-ins are rejected (409). Remote callers require admin scope.',
698533
+ responses: {
698534
+ 201: { description: "Registered (new)" },
698535
+ 200: { description: "Registered (replaced existing)" },
698536
+ 400: { description: "Invalid manifest" },
698537
+ 403: { description: "Forbidden — run/admin scope required" },
698538
+ 409: { description: "Name collides with a built-in tool" },
698539
+ 502: { description: "MCP server connect failed" }
698540
+ }
698541
+ }
698542
+ },
697685
698543
  "/v1/tools/{name}": {
697686
698544
  get: {
697687
698545
  summary: "Single tool schema + security policy",
697688
698546
  tags: ["Tools"],
697689
698547
  parameters: [{ name: "name", in: "path", required: true, schema: { type: "string" }, description: "Tool name (snake_case, e.g. file_read)" }],
697690
698548
  responses: {
697691
- 200: { description: "Tool entry with security info" },
698549
+ 200: { description: "Tool entry with security info (built-in or external)" },
697692
698550
  404: { description: "Unknown tool name" }
697693
698551
  }
698552
+ },
698553
+ delete: {
698554
+ summary: "Unregister an external tool (run scope)",
698555
+ tags: ["Tools"],
698556
+ description: "Removes an externally-registered tool from the per-working-directory registry. Built-in tools are immutable and return 404.",
698557
+ parameters: [{ name: "name", in: "path", required: true, schema: { type: "string" } }],
698558
+ responses: {
698559
+ 200: { description: "Unregistered" },
698560
+ 403: { description: "Forbidden — run/admin scope required" },
698561
+ 404: { description: "No external tool with that name" }
698562
+ }
698563
+ }
698564
+ },
698565
+ "/v1/tools/{name}/eval": {
698566
+ post: {
698567
+ summary: "Evaluate an external tool against test cases (dev cycle)",
698568
+ tags: ["Tools"],
698569
+ description: "Runs the registered tool for each case and scores it — the dev-cycle complement to /v1/evaluate (which scores agent runs). Body: {cases: [{name?, args, expect?}]}. `expect` supports {success, output_contains, output_equals, output_matches}. Returns per-case pass/fail plus {total, passed, failed, pass_rate, duration_ms}.",
698570
+ parameters: [{ name: "name", in: "path", required: true, schema: { type: "string" } }],
698571
+ responses: {
698572
+ 200: { description: "Eval report" },
698573
+ 400: { description: "Missing/empty cases" },
698574
+ 403: { description: "Forbidden — run/admin scope required" },
698575
+ 404: { description: "No external tool with that name" }
698576
+ }
697694
698577
  }
697695
698578
  },
697696
698579
  "/v1/tools/{name}/call": {
@@ -698165,15 +699048,15 @@ var init_auth_oidc = __esm({
698165
699048
  });
698166
699049
 
698167
699050
  // packages/cli/src/api/usage-tracker.ts
698168
- import { mkdirSync as mkdirSync98, readFileSync as readFileSync128, writeFileSync as writeFileSync83, existsSync as existsSync157 } from "node:fs";
698169
- import { join as join168 } from "node:path";
699051
+ import { mkdirSync as mkdirSync99, readFileSync as readFileSync129, writeFileSync as writeFileSync84, existsSync as existsSync158 } from "node:fs";
699052
+ import { join as join169 } from "node:path";
698170
699053
  function initUsageTracker(omniusDir) {
698171
- const dir = join168(omniusDir, "usage");
698172
- mkdirSync98(dir, { recursive: true });
698173
- usageFile = join168(dir, "token-usage.json");
699054
+ const dir = join169(omniusDir, "usage");
699055
+ mkdirSync99(dir, { recursive: true });
699056
+ usageFile = join169(dir, "token-usage.json");
698174
699057
  try {
698175
- if (existsSync157(usageFile)) {
698176
- store = JSON.parse(readFileSync128(usageFile, "utf-8"));
699058
+ if (existsSync158(usageFile)) {
699059
+ store = JSON.parse(readFileSync129(usageFile, "utf-8"));
698177
699060
  }
698178
699061
  } catch {
698179
699062
  store = { providers: {}, lastSaved: "" };
@@ -698209,7 +699092,7 @@ function flush2() {
698209
699092
  if (!initialized2 || !dirty) return;
698210
699093
  try {
698211
699094
  store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
698212
- writeFileSync83(usageFile, JSON.stringify(store, null, 2), "utf-8");
699095
+ writeFileSync84(usageFile, JSON.stringify(store, null, 2), "utf-8");
698213
699096
  dirty = false;
698214
699097
  } catch {
698215
699098
  }
@@ -698384,23 +699267,23 @@ var init_chat_followup = __esm({
698384
699267
 
698385
699268
  // packages/cli/src/docker.ts
698386
699269
  import { execSync as execSync59, spawn as spawn32 } from "node:child_process";
698387
- import { existsSync as existsSync158, mkdirSync as mkdirSync99, writeFileSync as writeFileSync84 } from "node:fs";
698388
- import { join as join169, resolve as resolve65, dirname as dirname50 } from "node:path";
699270
+ import { existsSync as existsSync159, mkdirSync as mkdirSync100, writeFileSync as writeFileSync85 } from "node:fs";
699271
+ import { join as join170, resolve as resolve65, dirname as dirname50 } from "node:path";
698389
699272
  import { homedir as homedir58 } from "node:os";
698390
699273
  import { fileURLToPath as fileURLToPath19 } from "node:url";
698391
699274
  function getDockerDir() {
698392
699275
  try {
698393
699276
  if (typeof __dirname !== "undefined") {
698394
- return join169(__dirname, "..", "..", "..", "docker");
699277
+ return join170(__dirname, "..", "..", "..", "docker");
698395
699278
  }
698396
699279
  } catch {
698397
699280
  }
698398
699281
  try {
698399
699282
  const thisDir = dirname50(fileURLToPath19(import.meta.url));
698400
- return join169(thisDir, "..", "..", "..", "docker");
699283
+ return join170(thisDir, "..", "..", "..", "docker");
698401
699284
  } catch {
698402
699285
  }
698403
- return join169(process.cwd(), "docker");
699286
+ return join170(process.cwd(), "docker");
698404
699287
  }
698405
699288
  function isDockerAvailable() {
698406
699289
  try {
@@ -698531,11 +699414,11 @@ async function ensureOmniusImage(force = false) {
698531
699414
  }
698532
699415
  let buildContext;
698533
699416
  const dockerDir = getDockerDir();
698534
- if (existsSync158(join169(dockerDir, "Dockerfile"))) {
699417
+ if (existsSync159(join170(dockerDir, "Dockerfile"))) {
698535
699418
  buildContext = dockerDir;
698536
699419
  } else {
698537
- buildContext = join169(homedir58(), ".omnius", "docker-build");
698538
- mkdirSync99(buildContext, { recursive: true });
699420
+ buildContext = join170(homedir58(), ".omnius", "docker-build");
699421
+ mkdirSync100(buildContext, { recursive: true });
698539
699422
  writeDockerfiles(buildContext);
698540
699423
  }
698541
699424
  try {
@@ -698609,8 +699492,8 @@ chown -R node:node /workspace /home/node/.omnius 2>/dev/null || true
698609
699492
  if [ "$1" = "omnius" ]; then shift; exec su - node -c "cd /workspace && omnius $*"; fi
698610
699493
  exec "$@"
698611
699494
  `;
698612
- writeFileSync84(join169(dir, "Dockerfile"), dockerfile);
698613
- writeFileSync84(join169(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
699495
+ writeFileSync85(join170(dir, "Dockerfile"), dockerfile);
699496
+ writeFileSync85(join170(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
698614
699497
  }
698615
699498
  function hasNvidiaGpu() {
698616
699499
  try {
@@ -698683,7 +699566,7 @@ __export(embedding_workers_exports, {
698683
699566
  startEmbeddingWorkers: () => startEmbeddingWorkers,
698684
699567
  stopEmbeddingWorkers: () => stopEmbeddingWorkers
698685
699568
  });
698686
- import { basename as basename38, join as join170 } from "node:path";
699569
+ import { basename as basename38, join as join171 } from "node:path";
698687
699570
  function startEmbeddingWorkers(opts) {
698688
699571
  if (_running) return;
698689
699572
  _running = true;
@@ -698749,8 +699632,8 @@ async function runEmbeddingTask(modality, episodeId, taskId, opts) {
698749
699632
  try {
698750
699633
  if (!_aligner) {
698751
699634
  const stateRoot = process.env.OMNIUS_DIR || process.cwd();
698752
- const omniusDir = basename38(stateRoot) === ".omnius" ? stateRoot : join170(stateRoot, ".omnius");
698753
- const memDir = join170(omniusDir, "memory");
699635
+ const omniusDir = basename38(stateRoot) === ".omnius" ? stateRoot : join171(stateRoot, ".omnius");
699636
+ const memDir = join171(omniusDir, "memory");
698754
699637
  _aligner = new EmbeddingAligner(
698755
699638
  `${modality}-${emb.length}`,
698756
699639
  // e.g. "visual-512"
@@ -698865,18 +699748,18 @@ import * as http5 from "node:http";
698865
699748
  import * as https3 from "node:https";
698866
699749
  import { createRequire as createRequire8 } from "node:module";
698867
699750
  import { fileURLToPath as fileURLToPath20 } from "node:url";
698868
- import { dirname as dirname51, join as join171, resolve as resolve66 } from "node:path";
699751
+ import { dirname as dirname51, join as join172, resolve as resolve66 } from "node:path";
698869
699752
  import { homedir as homedir59 } from "node:os";
698870
699753
  import { spawn as spawn33, execSync as execSync60 } from "node:child_process";
698871
699754
  import {
698872
699755
  createReadStream as createReadStream2,
698873
- mkdirSync as mkdirSync100,
698874
- writeFileSync as writeFileSync85,
698875
- readFileSync as readFileSync129,
699756
+ mkdirSync as mkdirSync101,
699757
+ writeFileSync as writeFileSync86,
699758
+ readFileSync as readFileSync130,
698876
699759
  readdirSync as readdirSync56,
698877
- existsSync as existsSync159,
699760
+ existsSync as existsSync160,
698878
699761
  watch as fsWatch4,
698879
- renameSync as renameSync14,
699762
+ renameSync as renameSync15,
698880
699763
  unlinkSync as unlinkSync34,
698881
699764
  statSync as statSync56,
698882
699765
  openSync as openSync6,
@@ -698886,25 +699769,25 @@ import {
698886
699769
  import { randomBytes as randomBytes28, randomUUID as randomUUID21, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
698887
699770
  import { createHash as createHash43 } from "node:crypto";
698888
699771
  function memoryDbPaths3(baseDir = process.cwd()) {
698889
- const dir = join171(baseDir, ".omnius");
699772
+ const dir = join172(baseDir, ".omnius");
698890
699773
  return {
698891
699774
  dir,
698892
- episodes: join171(dir, "episodes.db"),
698893
- knowledge: join171(dir, "knowledge.db")
699775
+ episodes: join172(dir, "episodes.db"),
699776
+ knowledge: join172(dir, "knowledge.db")
698894
699777
  };
698895
699778
  }
698896
699779
  function getVersion3() {
698897
699780
  try {
698898
699781
  const thisDir = dirname51(fileURLToPath20(import.meta.url));
698899
699782
  const candidates = [
698900
- join171(thisDir, "..", "package.json"),
698901
- join171(thisDir, "..", "..", "package.json"),
698902
- join171(thisDir, "..", "..", "..", "package.json")
699783
+ join172(thisDir, "..", "package.json"),
699784
+ join172(thisDir, "..", "..", "package.json"),
699785
+ join172(thisDir, "..", "..", "..", "package.json")
698903
699786
  ];
698904
699787
  for (const pkgPath of candidates) {
698905
699788
  try {
698906
- if (!existsSync159(pkgPath)) continue;
698907
- const pkg = JSON.parse(readFileSync129(pkgPath, "utf8"));
699789
+ if (!existsSync160(pkgPath)) continue;
699790
+ const pkg = JSON.parse(readFileSync130(pkgPath, "utf8"));
698908
699791
  if (pkg.name === "omnius" || pkg.name === "@omnius/cli" || pkg.name === "@omnius/monorepo") {
698909
699792
  return pkg.version ?? "0.0.0";
698910
699793
  }
@@ -699318,9 +700201,9 @@ function isOriginAllowed(origin) {
699318
700201
  if (!origin) return true;
699319
700202
  let accessMode = (process.env["OMNIUS_ACCESS"] || "").toLowerCase().trim();
699320
700203
  try {
699321
- const accessFile = join171(homedir59(), ".omnius", "access");
699322
- if (existsSync159(accessFile)) {
699323
- const persisted = readFileSync129(accessFile, "utf8").trim().toLowerCase();
700204
+ const accessFile = join172(homedir59(), ".omnius", "access");
700205
+ if (existsSync160(accessFile)) {
700206
+ const persisted = readFileSync130(accessFile, "utf8").trim().toLowerCase();
699324
700207
  if (persisted === "any" || persisted === "lan" || persisted === "loopback") {
699325
700208
  accessMode = persisted;
699326
700209
  }
@@ -700164,28 +701047,28 @@ function ollamaStream(ollamaUrl, path12, method, body, onData, onEnd, onError, t
700164
701047
  }
700165
701048
  function jobsDir() {
700166
701049
  const root = resolve66(process.cwd());
700167
- const dir = join171(root, ".omnius", "jobs");
700168
- mkdirSync100(dir, { recursive: true });
701050
+ const dir = join172(root, ".omnius", "jobs");
701051
+ mkdirSync101(dir, { recursive: true });
700169
701052
  return dir;
700170
701053
  }
700171
701054
  function loadJob(id) {
700172
- const file = join171(jobsDir(), `${id}.json`);
700173
- if (!existsSync159(file)) return null;
701055
+ const file = join172(jobsDir(), `${id}.json`);
701056
+ if (!existsSync160(file)) return null;
700174
701057
  try {
700175
- return JSON.parse(readFileSync129(file, "utf-8"));
701058
+ return JSON.parse(readFileSync130(file, "utf-8"));
700176
701059
  } catch {
700177
701060
  return null;
700178
701061
  }
700179
701062
  }
700180
701063
  function listJobs2() {
700181
701064
  const dir = jobsDir();
700182
- if (!existsSync159(dir)) return [];
701065
+ if (!existsSync160(dir)) return [];
700183
701066
  const files = readdirSync56(dir).filter((f2) => f2.endsWith(".json")).sort();
700184
701067
  const jobs = [];
700185
701068
  for (const file of files) {
700186
701069
  try {
700187
701070
  jobs.push(
700188
- JSON.parse(readFileSync129(join171(dir, file), "utf-8"))
701071
+ JSON.parse(readFileSync130(join172(dir, file), "utf-8"))
700189
701072
  );
700190
701073
  } catch {
700191
701074
  }
@@ -700196,14 +701079,14 @@ function pruneOldJobs() {
700196
701079
  const retentionH = parseFloat(process.env["OMNIUS_RUN_RETENTION_H"] || "24");
700197
701080
  const cutoffMs = Date.now() - (Number.isFinite(retentionH) && retentionH > 0 ? retentionH : 24) * 36e5;
700198
701081
  const dir = jobsDir();
700199
- if (!existsSync159(dir)) return { pruned: 0, kept: 0 };
701082
+ if (!existsSync160(dir)) return { pruned: 0, kept: 0 };
700200
701083
  let pruned = 0;
700201
701084
  let kept = 0;
700202
701085
  for (const file of readdirSync56(dir)) {
700203
701086
  if (!file.endsWith(".json")) continue;
700204
- const path12 = join171(dir, file);
701087
+ const path12 = join172(dir, file);
700205
701088
  try {
700206
- const job = JSON.parse(readFileSync129(path12, "utf-8"));
701089
+ const job = JSON.parse(readFileSync130(path12, "utf-8"));
700207
701090
  if (job.status === "running") {
700208
701091
  kept++;
700209
701092
  continue;
@@ -700216,7 +701099,7 @@ function pruneOldJobs() {
700216
701099
  } catch {
700217
701100
  }
700218
701101
  const outFile = path12.replace(/\.json$/, ".output");
700219
- if (existsSync159(outFile)) {
701102
+ if (existsSync160(outFile)) {
700220
701103
  try {
700221
701104
  unlinkSync34(outFile);
700222
701105
  } catch {
@@ -700529,14 +701412,14 @@ function autoSeedTodosFromPrompt(prompt) {
700529
701412
  return [];
700530
701413
  }
700531
701414
  function atomicJobWrite(dir, id, job) {
700532
- const finalPath = join171(dir, `${id}.json`);
701415
+ const finalPath = join172(dir, `${id}.json`);
700533
701416
  const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
700534
701417
  try {
700535
- writeFileSync85(tmpPath, JSON.stringify(job, null, 2), "utf-8");
700536
- renameSync14(tmpPath, finalPath);
701418
+ writeFileSync86(tmpPath, JSON.stringify(job, null, 2), "utf-8");
701419
+ renameSync15(tmpPath, finalPath);
700537
701420
  } catch {
700538
701421
  try {
700539
- writeFileSync85(finalPath, JSON.stringify(job, null, 2), "utf-8");
701422
+ writeFileSync86(finalPath, JSON.stringify(job, null, 2), "utf-8");
700540
701423
  } catch {
700541
701424
  }
700542
701425
  try {
@@ -702348,28 +703231,28 @@ ${task}` : task;
702348
703231
  });
702349
703232
  }
702350
703233
  function updateStateFile() {
702351
- return join171(homedir59(), ".omnius", "update-state.json");
703234
+ return join172(homedir59(), ".omnius", "update-state.json");
702352
703235
  }
702353
703236
  function updateLogPath() {
702354
- return join171(homedir59(), ".omnius", "update.log");
703237
+ return join172(homedir59(), ".omnius", "update.log");
702355
703238
  }
702356
703239
  function readUpdateState() {
702357
703240
  try {
702358
703241
  const p2 = updateStateFile();
702359
- if (!existsSync159(p2)) return null;
702360
- return JSON.parse(readFileSync129(p2, "utf-8"));
703242
+ if (!existsSync160(p2)) return null;
703243
+ return JSON.parse(readFileSync130(p2, "utf-8"));
702361
703244
  } catch {
702362
703245
  return null;
702363
703246
  }
702364
703247
  }
702365
703248
  function writeUpdateState(state) {
702366
703249
  try {
702367
- const dir = join171(homedir59(), ".omnius");
702368
- mkdirSync100(dir, { recursive: true });
703250
+ const dir = join172(homedir59(), ".omnius");
703251
+ mkdirSync101(dir, { recursive: true });
702369
703252
  const finalPath = updateStateFile();
702370
703253
  const tmpPath = `${finalPath}.tmp.${process.pid}`;
702371
- writeFileSync85(tmpPath, JSON.stringify(state, null, 2), "utf-8");
702372
- renameSync14(tmpPath, finalPath);
703254
+ writeFileSync86(tmpPath, JSON.stringify(state, null, 2), "utf-8");
703255
+ renameSync15(tmpPath, finalPath);
702373
703256
  } catch {
702374
703257
  }
702375
703258
  }
@@ -702416,15 +703299,15 @@ async function handleV1Update(req3, res, requestId) {
702416
703299
  const { execSync: es } = require4("node:child_process");
702417
703300
  const isWin2 = process.platform === "win32";
702418
703301
  let npmBin = "";
702419
- for (const candidate of isWin2 ? [join171(nodeDir, "npm.cmd"), join171(nodeDir, "npm")] : [join171(nodeDir, "npm"), "/usr/local/bin/npm", "/usr/bin/npm"]) {
702420
- if (existsSync159(candidate)) {
703302
+ for (const candidate of isWin2 ? [join172(nodeDir, "npm.cmd"), join172(nodeDir, "npm")] : [join172(nodeDir, "npm"), "/usr/local/bin/npm", "/usr/bin/npm"]) {
703303
+ if (existsSync160(candidate)) {
702421
703304
  npmBin = candidate;
702422
703305
  break;
702423
703306
  }
702424
703307
  }
702425
703308
  if (!npmBin) npmBin = isWin2 ? "npm.cmd" : "npm";
702426
703309
  const pkgSpec = `omnius@${targetVersion}`;
702427
- const dir = join171(homedir59(), ".omnius");
703310
+ const dir = join172(homedir59(), ".omnius");
702428
703311
  fs11.mkdirSync(dir, { recursive: true });
702429
703312
  const logFd = fs11.openSync(logPath3, "w");
702430
703313
  const npmPrefix = dirname51(nodeDir);
@@ -702438,7 +703321,7 @@ async function handleV1Update(req3, res, requestId) {
702438
703321
  }).trim();
702439
703322
  } else {
702440
703323
  const npmCliCandidates = [
702441
- join171(
703324
+ join172(
702442
703325
  nodeDir,
702443
703326
  "..",
702444
703327
  "lib",
@@ -702447,7 +703330,7 @@ async function handleV1Update(req3, res, requestId) {
702447
703330
  "bin",
702448
703331
  "npm-cli.js"
702449
703332
  ),
702450
- join171(
703333
+ join172(
702451
703334
  npmBin,
702452
703335
  "..",
702453
703336
  "..",
@@ -702461,7 +703344,7 @@ async function handleV1Update(req3, res, requestId) {
702461
703344
  let npmCli = "";
702462
703345
  for (const c8 of npmCliCandidates) {
702463
703346
  try {
702464
- if (existsSync159(c8)) {
703347
+ if (existsSync160(c8)) {
702465
703348
  npmCli = c8;
702466
703349
  break;
702467
703350
  }
@@ -702506,8 +703389,8 @@ async function handleV1Update(req3, res, requestId) {
702506
703389
  );
702507
703390
  } else {
702508
703391
  const npmCliCandidates = [
702509
- join171(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
702510
- join171(
703392
+ join172(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
703393
+ join172(
702511
703394
  npmBin,
702512
703395
  "..",
702513
703396
  "..",
@@ -702521,7 +703404,7 @@ async function handleV1Update(req3, res, requestId) {
702521
703404
  let npmCli = "";
702522
703405
  for (const c8 of npmCliCandidates) {
702523
703406
  try {
702524
- if (existsSync159(c8)) {
703407
+ if (existsSync160(c8)) {
702525
703408
  npmCli = c8;
702526
703409
  break;
702527
703410
  }
@@ -702661,8 +703544,8 @@ function handleV1UpdateStatus(res) {
702661
703544
  let logTail = "";
702662
703545
  let exitCode = null;
702663
703546
  try {
702664
- if (existsSync159(logPath3)) {
702665
- const raw = readFileSync129(logPath3, "utf-8");
703547
+ if (existsSync160(logPath3)) {
703548
+ const raw = readFileSync130(logPath3, "utf-8");
702666
703549
  const m2 = raw.match(/__EXIT_CODE=(\d+)/);
702667
703550
  if (m2) exitCode = parseInt(m2[1], 10);
702668
703551
  logTail = raw.slice(-2e3);
@@ -702786,8 +703669,8 @@ async function handleV1Run(req3, res) {
702786
703669
  if (workingDir) {
702787
703670
  cwd4 = resolve66(workingDir);
702788
703671
  } else if (isolate) {
702789
- const wsDir = join171(dir, "..", "workspaces", id);
702790
- mkdirSync100(wsDir, { recursive: true });
703672
+ const wsDir = join172(dir, "..", "workspaces", id);
703673
+ mkdirSync101(wsDir, { recursive: true });
702791
703674
  cwd4 = wsDir;
702792
703675
  } else {
702793
703676
  cwd4 = resolve66(process.cwd());
@@ -703022,7 +703905,7 @@ async function handleV1Run(req3, res) {
703022
703905
  let output = "";
703023
703906
  let tailBytes = 0;
703024
703907
  const TAIL_BUDGET = 1048576;
703025
- const outputWriter = new DiskTaskOutput(join171(dir, `${id}.output`));
703908
+ const outputWriter = new DiskTaskOutput(join172(dir, `${id}.output`));
703026
703909
  job.outputFile = outputWriter.path;
703027
703910
  atomicJobWrite(dir, id, job);
703028
703911
  child.stdout?.on("data", (chunk) => {
@@ -703248,7 +704131,7 @@ function handleV1RunsById(res, id) {
703248
704131
  }
703249
704132
  const outputFile = job.outputFile;
703250
704133
  const enriched = { ...job };
703251
- if (outputFile && existsSync159(outputFile)) {
704134
+ if (outputFile && existsSync160(outputFile)) {
703252
704135
  try {
703253
704136
  const size = statSync56(outputFile).size;
703254
704137
  const tailSize = Math.min(size, 4096);
@@ -704219,7 +705102,7 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
704219
705102
  }
704220
705103
  try {
704221
705104
  const target = resolve66(rawPath);
704222
- if (!existsSync159(target)) {
705105
+ if (!existsSync160(target)) {
704223
705106
  jsonResponse(res, 404, { error: "File not found", path: target });
704224
705107
  return;
704225
705108
  }
@@ -704446,12 +705329,12 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
704446
705329
  }
704447
705330
  for (const e2 of entries) {
704448
705331
  if (!e2.isDirectory()) continue;
704449
- const child = join171(dir, e2.name);
704450
- const omniusDir = join171(child, ".omnius");
705332
+ const child = join172(dir, e2.name);
705333
+ const omniusDir = join172(child, ".omnius");
704451
705334
  try {
704452
705335
  if (statSync56(omniusDir).isDirectory()) {
704453
705336
  const name10 = e2.name;
704454
- const prefsFile = join171(omniusDir, "config.json");
705337
+ const prefsFile = join172(omniusDir, "config.json");
704455
705338
  let lastSeen = 0;
704456
705339
  try {
704457
705340
  lastSeen = statSync56(prefsFile).mtimeMs;
@@ -704505,12 +705388,12 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
704505
705388
  }
704506
705389
  for (const e2 of entries) {
704507
705390
  if (!e2.isDirectory()) continue;
704508
- const child = join171(dir, e2.name);
704509
- const omniusDir = join171(child, ".omnius");
705391
+ const child = join172(dir, e2.name);
705392
+ const omniusDir = join172(child, ".omnius");
704510
705393
  try {
704511
705394
  if (statSync56(omniusDir).isDirectory()) {
704512
705395
  const name10 = e2.name;
704513
- const prefsFile = join171(omniusDir, "config.json");
705396
+ const prefsFile = join172(omniusDir, "config.json");
704514
705397
  let lastSeen = 0;
704515
705398
  try {
704516
705399
  lastSeen = statSync56(prefsFile).mtimeMs;
@@ -704718,13 +705601,13 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
704718
705601
  return;
704719
705602
  }
704720
705603
  const { tmpdir: tmpdir24 } = await import("node:os");
704721
- const { writeFileSync: writeFileSync90, unlinkSync: unlinkSync35 } = await import("node:fs");
705604
+ const { writeFileSync: writeFileSync91, unlinkSync: unlinkSync35 } = await import("node:fs");
704722
705605
  const { join: pjoin } = await import("node:path");
704723
705606
  const tmpPath = pjoin(
704724
705607
  tmpdir24(),
704725
705608
  `omnius-clone-upload-${Date.now()}-${safeName3}`
704726
705609
  );
704727
- writeFileSync90(tmpPath, buf);
705610
+ writeFileSync91(tmpPath, buf);
704728
705611
  try {
704729
705612
  const ve = getVoiceEngine();
704730
705613
  const msg = await ve.setCloneVoice(tmpPath);
@@ -705448,7 +706331,7 @@ data: ${JSON.stringify(data)}
705448
706331
  }
705449
706332
  for (const f2 of seenFiles) {
705450
706333
  try {
705451
- writeFileSync85(f2, JSON.stringify({ tasks: [] }, null, 2));
706334
+ writeFileSync86(f2, JSON.stringify({ tasks: [] }, null, 2));
705452
706335
  deleted++;
705453
706336
  } catch {
705454
706337
  }
@@ -707124,7 +708007,7 @@ ${historyLines}
707124
708007
  function getScheduleRoots() {
707125
708008
  const rootsEnv = process.env["OMNIUS_SCHEDULE_ROOTS"] || "";
707126
708009
  const roots = rootsEnv.split(rootsEnv.includes(";") ? ";" : ":").filter(Boolean);
707127
- const defaults3 = [process.cwd(), join171(homedir59(), "Documents")];
708010
+ const defaults3 = [process.cwd(), join172(homedir59(), "Documents")];
707128
708011
  const set = /* @__PURE__ */ new Set([...defaults3, ...roots]);
707129
708012
  return [...set];
707130
708013
  }
@@ -707139,10 +708022,10 @@ function listScheduledTasks() {
707139
708022
  root,
707140
708023
  0,
707141
708024
  (dir) => {
707142
- if (dir.endsWith(`${join171(".omnius", "scheduled")}`) || dir.includes(`${join171(".omnius", "scheduled")}`)) {
707143
- const file = join171(dir, "tasks.json");
708025
+ if (dir.endsWith(`${join172(".omnius", "scheduled")}`) || dir.includes(`${join172(".omnius", "scheduled")}`)) {
708026
+ const file = join172(dir, "tasks.json");
707144
708027
  try {
707145
- const raw = readFileSync129(file, "utf-8");
708028
+ const raw = readFileSync130(file, "utf-8");
707146
708029
  const json = JSON.parse(raw);
707147
708030
  const tasks = Array.isArray(json?.tasks) ? json.tasks : Array.isArray(json) ? json : [];
707148
708031
  tasks.forEach((t2, i2) => {
@@ -707231,7 +708114,7 @@ function walk(dir, depth, onDir, maxDepth) {
707231
708114
  if (e2.name === "node_modules" || e2.name.startsWith(".")) {
707232
708115
  if (e2.name !== ".omnius") continue;
707233
708116
  }
707234
- const child = join171(dir, e2.name);
708117
+ const child = join172(dir, e2.name);
707235
708118
  walk(child, depth + 1, onDir, maxDepth);
707236
708119
  }
707237
708120
  }
@@ -707240,18 +708123,18 @@ function setScheduledEnabled(id, enabled2) {
707240
708123
  const target = tasks.find((t2) => t2.id === id);
707241
708124
  if (!target) return false;
707242
708125
  try {
707243
- const raw = readFileSync129(target.file, "utf-8");
708126
+ const raw = readFileSync130(target.file, "utf-8");
707244
708127
  const json = JSON.parse(raw);
707245
708128
  const arr = Array.isArray(json?.tasks) ? json.tasks : Array.isArray(json) ? json : [];
707246
708129
  if (!arr[target.index]) return false;
707247
708130
  arr[target.index].enabled = enabled2;
707248
708131
  if (Array.isArray(json?.tasks)) {
707249
708132
  json.tasks = arr;
707250
- writeFileSync85(target.file, JSON.stringify(json, null, 2));
708133
+ writeFileSync86(target.file, JSON.stringify(json, null, 2));
707251
708134
  } else if (Array.isArray(json)) {
707252
- writeFileSync85(target.file, JSON.stringify(arr, null, 2));
708135
+ writeFileSync86(target.file, JSON.stringify(arr, null, 2));
707253
708136
  } else {
707254
- writeFileSync85(target.file, JSON.stringify({ tasks: arr }, null, 2));
708137
+ writeFileSync86(target.file, JSON.stringify({ tasks: arr }, null, 2));
707255
708138
  }
707256
708139
  if (!enabled2) {
707257
708140
  try {
@@ -707273,7 +708156,7 @@ function deleteScheduledById(id) {
707273
708156
  const target = tasks.find((t2) => t2.id === id);
707274
708157
  if (!target) return false;
707275
708158
  try {
707276
- const raw = readFileSync129(target.file, "utf-8");
708159
+ const raw = readFileSync130(target.file, "utf-8");
707277
708160
  const json = JSON.parse(raw);
707278
708161
  const arr = Array.isArray(json?.tasks) ? json.tasks : Array.isArray(json) ? json : [];
707279
708162
  if (!arr[target.index]) return false;
@@ -707281,11 +708164,11 @@ function deleteScheduledById(id) {
707281
708164
  arr.splice(target.index, 1);
707282
708165
  if (Array.isArray(json?.tasks)) {
707283
708166
  json.tasks = arr;
707284
- writeFileSync85(target.file, JSON.stringify(json, null, 2));
708167
+ writeFileSync86(target.file, JSON.stringify(json, null, 2));
707285
708168
  } else if (Array.isArray(json)) {
707286
- writeFileSync85(target.file, JSON.stringify(arr, null, 2));
708169
+ writeFileSync86(target.file, JSON.stringify(arr, null, 2));
707287
708170
  } else {
707288
- writeFileSync85(target.file, JSON.stringify({ tasks: arr }, null, 2));
708171
+ writeFileSync86(target.file, JSON.stringify({ tasks: arr }, null, 2));
707289
708172
  }
707290
708173
  const candidates = [];
707291
708174
  if (id) candidates.push(id);
@@ -707494,11 +708377,11 @@ function reconcileScheduledTasks(apply) {
707494
708377
  const errors = [];
707495
708378
  for (const f2 of found) {
707496
708379
  const wdir = f2.workingDir || process.cwd();
707497
- const file = join171(wdir, ".omnius", "scheduled", "tasks.json");
708380
+ const file = join172(wdir, ".omnius", "scheduled", "tasks.json");
707498
708381
  try {
707499
708382
  let json = { tasks: [] };
707500
708383
  try {
707501
- const raw = readFileSync129(file, "utf-8");
708384
+ const raw = readFileSync130(file, "utf-8");
707502
708385
  json = JSON.parse(raw);
707503
708386
  } catch {
707504
708387
  }
@@ -707515,11 +708398,11 @@ function reconcileScheduledTasks(apply) {
707515
708398
  };
707516
708399
  arr.push(entry);
707517
708400
  const toWrite = Array.isArray(json?.tasks) ? { ...json, tasks: arr } : Array.isArray(json) ? arr : { tasks: arr };
707518
- mkdirSync100(join171(wdir, ".omnius", "scheduled"), { recursive: true });
707519
- mkdirSync100(join171(wdir, ".omnius", "scheduled", "logs"), {
708401
+ mkdirSync101(join172(wdir, ".omnius", "scheduled"), { recursive: true });
708402
+ mkdirSync101(join172(wdir, ".omnius", "scheduled", "logs"), {
707520
708403
  recursive: true
707521
708404
  });
707522
- writeFileSync85(file, JSON.stringify(toWrite, null, 2));
708405
+ writeFileSync86(file, JSON.stringify(toWrite, null, 2));
707523
708406
  adopted.push({ file, index: arr.length - 1 });
707524
708407
  }
707525
708408
  } else {
@@ -707592,32 +708475,32 @@ function writeCrontabLines(lines) {
707592
708475
  }
707593
708476
  function canonicalCronLine(rec) {
707594
708477
  const omniusBin = findOmniusBinary4();
707595
- const logDir = join171(rec.workingDir, ".omnius", "scheduled", "logs");
707596
- const logFile = join171(logDir, `${rec.id}.log`);
707597
- const storeFile = join171(rec.workingDir, ".omnius", "scheduled", "tasks.json");
708478
+ const logDir = join172(rec.workingDir, ".omnius", "scheduled", "logs");
708479
+ const logFile = join172(logDir, `${rec.id}.log`);
708480
+ const storeFile = join172(rec.workingDir, ".omnius", "scheduled", "tasks.json");
707598
708481
  const taskEsc = rec.task.replace(/'/g, "'\\''");
707599
- const lockDir = join171(rec.workingDir, ".omnius", "run");
707600
- const lockPath = join171(lockDir, `${rec.id}.lock`);
708482
+ const lockDir = join172(rec.workingDir, ".omnius", "run");
708483
+ const lockPath = join172(lockDir, `${rec.id}.lock`);
707601
708484
  const wrapper = [
707602
708485
  `cd ${JSON.stringify(rec.workingDir)}`,
707603
708486
  `mkdir -p ${JSON.stringify(logDir)}`,
707604
708487
  `mkdir -p ${JSON.stringify(lockDir)}`,
707605
708488
  `if mkdir ${JSON.stringify(lockPath)} 2>/dev/null; then`,
707606
- ` echo $$ > ${JSON.stringify(join171(lockPath, "pid"))}`,
708489
+ ` echo $$ > ${JSON.stringify(join172(lockPath, "pid"))}`,
707607
708490
  ` trap 'rm -rf ${lockPath}' EXIT`,
707608
708491
  `else`,
707609
- ` if [ -f ${JSON.stringify(join171(lockPath, "pid"))} ]; then`,
707610
- ` oldpid=$(cat ${JSON.stringify(join171(lockPath, "pid"))} 2>/dev/null || echo)`,
708492
+ ` if [ -f ${JSON.stringify(join172(lockPath, "pid"))} ]; then`,
708493
+ ` oldpid=$(cat ${JSON.stringify(join172(lockPath, "pid"))} 2>/dev/null || echo)`,
707611
708494
  ` if [ -n "$oldpid" ] && kill -0 "$oldpid" 2>/dev/null; then`,
707612
708495
  ` echo "[omnius-scheduler] ${rec.id} already running as PID $oldpid; skipping" >> ${JSON.stringify(logFile)}`,
707613
708496
  ` exit 0`,
707614
708497
  ` else`,
707615
708498
  ` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
707616
- ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join171(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
708499
+ ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join172(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
707617
708500
  ` fi`,
707618
708501
  ` else`,
707619
708502
  ` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
707620
- ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join171(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
708503
+ ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join172(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
707621
708504
  ` fi`,
707622
708505
  `fi`,
707623
708506
  `lease_id="cron-agent-$(date +%s)-$$"`,
@@ -707659,9 +708542,9 @@ function fixupOrMigrateScheduled(mode, dryRun) {
707659
708542
  try {
707660
708543
  if (!f2.workingDir || !f2.task) continue;
707661
708544
  const unitBase = `omnius-${f2.id}`;
707662
- const unitDir = join171(homedir59(), ".config", "systemd", "user");
707663
- const svc = join171(unitDir, `${unitBase}.service`);
707664
- const tim = join171(unitDir, `${unitBase}.timer`);
708545
+ const unitDir = join172(homedir59(), ".config", "systemd", "user");
708546
+ const svc = join172(unitDir, `${unitBase}.service`);
708547
+ const tim = join172(unitDir, `${unitBase}.timer`);
707665
708548
  const omniusBin = findOmniusBinary4();
707666
708549
  const rec = {
707667
708550
  id: f2.id,
@@ -707696,9 +708579,9 @@ Persistent=true
707696
708579
  WantedBy=timers.target
707697
708580
  `;
707698
708581
  if (!dryRun) {
707699
- mkdirSync100(unitDir, { recursive: true });
707700
- writeFileSync85(svc, svcText);
707701
- writeFileSync85(tim, timText);
708582
+ mkdirSync101(unitDir, { recursive: true });
708583
+ writeFileSync86(svc, svcText);
708584
+ writeFileSync86(tim, timText);
707702
708585
  try {
707703
708586
  const { execSync: es } = require4("node:child_process");
707704
708587
  es("systemctl --user daemon-reload", { stdio: "pipe" });
@@ -707813,8 +708696,8 @@ function startApiServer(options2 = {}) {
707813
708696
  const config = loadConfig();
707814
708697
  const ollamaUrl = options2.ollamaUrl ?? config.backendUrl;
707815
708698
  const cwd4 = process.cwd();
707816
- initAuditLog(join171(cwd4, ".omnius"));
707817
- initUsageTracker(join171(cwd4, ".omnius"));
708699
+ initAuditLog(join172(cwd4, ".omnius"));
708700
+ initUsageTracker(join172(cwd4, ".omnius"));
707818
708701
  try {
707819
708702
  const taskMgr = getSharedTaskManager();
707820
708703
  taskMgr.setEventPublisher((type, data, opts) => {
@@ -707867,7 +708750,7 @@ function startApiServer(options2 = {}) {
707867
708750
  try {
707868
708751
  const dir = todoDir();
707869
708752
  try {
707870
- mkdirSync100(dir, { recursive: true });
708753
+ mkdirSync101(dir, { recursive: true });
707871
708754
  } catch {
707872
708755
  }
707873
708756
  const cache8 = /* @__PURE__ */ new Map();
@@ -707877,7 +708760,7 @@ function startApiServer(options2 = {}) {
707877
708760
  const sid = f2.replace(/\.json$/, "");
707878
708761
  try {
707879
708762
  const items = JSON.parse(
707880
- readFileSync129(join171(dir, f2), "utf-8")
708763
+ readFileSync130(join172(dir, f2), "utf-8")
707881
708764
  );
707882
708765
  if (Array.isArray(items)) {
707883
708766
  cache8.set(sid, new Map(items.map((t2) => [t2.id, t2])));
@@ -707891,10 +708774,10 @@ function startApiServer(options2 = {}) {
707891
708774
  if (!fname || !fname.endsWith(".json") || fname.includes(".tmp."))
707892
708775
  return;
707893
708776
  const sid = fname.replace(/\.json$/, "");
707894
- const fp = join171(dir, fname);
708777
+ const fp = join172(dir, fname);
707895
708778
  let next = [];
707896
708779
  try {
707897
- if (!existsSync159(fp)) {
708780
+ if (!existsSync160(fp)) {
707898
708781
  const old = cache8.get(sid);
707899
708782
  if (old) {
707900
708783
  for (const t2 of old.values()) {
@@ -707911,7 +708794,7 @@ function startApiServer(options2 = {}) {
707911
708794
  }
707912
708795
  return;
707913
708796
  }
707914
- next = JSON.parse(readFileSync129(fp, "utf-8"));
708797
+ next = JSON.parse(readFileSync130(fp, "utf-8"));
707915
708798
  if (!Array.isArray(next)) return;
707916
708799
  } catch {
707917
708800
  return;
@@ -707967,14 +708850,14 @@ function startApiServer(options2 = {}) {
707967
708850
  );
707968
708851
  if (!apiTestMode && retentionDays > 0) {
707969
708852
  try {
707970
- const jobsDir3 = join171(cwd4, ".omnius", "jobs");
707971
- if (existsSync159(jobsDir3)) {
708853
+ const jobsDir3 = join172(cwd4, ".omnius", "jobs");
708854
+ if (existsSync160(jobsDir3)) {
707972
708855
  const cutoff = Date.now() - retentionDays * 864e5;
707973
708856
  for (const f2 of readdirSync56(jobsDir3)) {
707974
708857
  if (!f2.endsWith(".json")) continue;
707975
708858
  try {
707976
- const jobPath = join171(jobsDir3, f2);
707977
- const job = JSON.parse(readFileSync129(jobPath, "utf-8"));
708859
+ const jobPath = join172(jobsDir3, f2);
708860
+ const job = JSON.parse(readFileSync130(jobPath, "utf-8"));
707978
708861
  const jobTime = new Date(
707979
708862
  job.startedAt ?? job.completedAt ?? 0
707980
708863
  ).getTime();
@@ -707996,8 +708879,8 @@ function startApiServer(options2 = {}) {
707996
708879
  if (useTls) {
707997
708880
  try {
707998
708881
  tlsOpts = {
707999
- cert: readFileSync129(resolve66(tlsCert)),
708000
- key: readFileSync129(resolve66(tlsKey))
708882
+ cert: readFileSync130(resolve66(tlsCert)),
708883
+ key: readFileSync130(resolve66(tlsKey))
708001
708884
  };
708002
708885
  } catch (e2) {
708003
708886
  log22(`
@@ -708008,9 +708891,9 @@ function startApiServer(options2 = {}) {
708008
708891
  }
708009
708892
  let runtimeAccessMode = resolveAccessMode(process.env["OMNIUS_ACCESS"], host);
708010
708893
  try {
708011
- const accessFile = join171(homedir59(), ".omnius", "access");
708012
- if (existsSync159(accessFile)) {
708013
- const persisted = readFileSync129(accessFile, "utf8").trim();
708894
+ const accessFile = join172(homedir59(), ".omnius", "access");
708895
+ if (existsSync160(accessFile)) {
708896
+ const persisted = readFileSync130(accessFile, "utf8").trim();
708014
708897
  const resolved = resolveAccessMode(persisted, host);
708015
708898
  if (resolved) runtimeAccessMode = resolved;
708016
708899
  }
@@ -708080,10 +708963,10 @@ function startApiServer(options2 = {}) {
708080
708963
  const previous = runtimeAccessMode;
708081
708964
  runtimeAccessMode = requested;
708082
708965
  try {
708083
- const dir = join171(homedir59(), ".omnius");
708084
- mkdirSync100(dir, { recursive: true });
708085
- writeFileSync85(
708086
- join171(dir, "access"),
708966
+ const dir = join172(homedir59(), ".omnius");
708967
+ mkdirSync101(dir, { recursive: true });
708968
+ writeFileSync86(
708969
+ join172(dir, "access"),
708087
708970
  `${runtimeAccessMode}
708088
708971
  `,
708089
708972
  "utf8"
@@ -708439,9 +709322,9 @@ function startApiServer(options2 = {}) {
708439
709322
  try {
708440
709323
  const here = dirname51(fileURLToPath20(import.meta.url));
708441
709324
  for (const rel of ["../package.json", "../../package.json", "../../../package.json", "../../../../package.json"]) {
708442
- const p2 = join171(here, rel);
708443
- if (existsSync159(p2)) {
708444
- const pkg = JSON.parse(readFileSync129(p2, "utf8"));
709325
+ const p2 = join172(here, rel);
709326
+ if (existsSync160(p2)) {
709327
+ const pkg = JSON.parse(readFileSync130(p2, "utf8"));
708445
709328
  if (pkg.name === "omnius" || pkg.name === "@omnius/cli" || pkg.name === "@omnius/monorepo") {
708446
709329
  return pkg.version ?? null;
708447
709330
  }
@@ -708495,8 +709378,8 @@ function startApiServer(options2 = {}) {
708495
709378
  }
708496
709379
  try {
708497
709380
  const {
708498
- writeFileSync: writeFileSync90,
708499
- mkdirSync: mkdirSync105,
709381
+ writeFileSync: writeFileSync91,
709382
+ mkdirSync: mkdirSync106,
708500
709383
  existsSync: _exists,
708501
709384
  readFileSync: _rfs
708502
709385
  } = require4("node:fs");
@@ -708533,8 +709416,8 @@ function startApiServer(options2 = {}) {
708533
709416
  let written = 0;
708534
709417
  for (const dir of dirSet) {
708535
709418
  try {
708536
- if (!_exists(dir)) mkdirSync105(dir, { recursive: true });
708537
- writeFileSync90(_join(dir, "api-port.json"), apiHint);
709419
+ if (!_exists(dir)) mkdirSync106(dir, { recursive: true });
709420
+ writeFileSync91(_join(dir, "api-port.json"), apiHint);
708538
709421
  written++;
708539
709422
  } catch {
708540
709423
  }
@@ -708897,13 +709780,13 @@ async function handleChatAttachmentUpload(req3, res) {
708897
709780
  return;
708898
709781
  }
708899
709782
  const safeName3 = filename.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 180) || `attachment-${Date.now()}.bin`;
708900
- const dir = join171(process.cwd(), ".omnius", "gui-attachments");
708901
- mkdirSync100(dir, { recursive: true });
708902
- const localPath = join171(
709783
+ const dir = join172(process.cwd(), ".omnius", "gui-attachments");
709784
+ mkdirSync101(dir, { recursive: true });
709785
+ const localPath = join172(
708903
709786
  dir,
708904
709787
  `${Date.now()}-${randomUUID21().slice(0, 8)}-${safeName3}`
708905
709788
  );
708906
- writeFileSync85(localPath, Buffer.from(base642, "base64"));
709789
+ writeFileSync86(localPath, Buffer.from(base642, "base64"));
708907
709790
  const mimeType = typeof b.mimeType === "string" ? b.mimeType : typeof b.mime_type === "string" ? b.mime_type : "";
708908
709791
  const isImage = mimeType.toLowerCase().startsWith("image/") || /\.(png|jpe?g|gif|webp|bmp|tiff?)$/i.test(safeName3);
708909
709792
  const sessionId = typeof b.sessionId === "string" ? b.sessionId : typeof b.session_id === "string" ? b.session_id : void 0;
@@ -709389,15 +710272,15 @@ __export(clipboard_media_exports, {
709389
710272
  pasteClipboardImageToFile: () => pasteClipboardImageToFile
709390
710273
  });
709391
710274
  import { execFileSync as execFileSync11, execSync as execSync61 } from "node:child_process";
709392
- import { mkdirSync as mkdirSync101, readFileSync as readFileSync130, rmSync as rmSync13, writeFileSync as writeFileSync86 } from "node:fs";
709393
- import { join as join172 } from "node:path";
710275
+ import { mkdirSync as mkdirSync102, readFileSync as readFileSync131, rmSync as rmSync13, writeFileSync as writeFileSync87 } from "node:fs";
710276
+ import { join as join173 } from "node:path";
709394
710277
  function pasteClipboardImageToFile(repoRoot) {
709395
710278
  const image = readClipboardImage();
709396
710279
  if (!image) return null;
709397
- const dir = join172(repoRoot, ".omnius", "clipboard");
709398
- mkdirSync101(dir, { recursive: true });
709399
- const path12 = join172(dir, `clipboard-${Date.now()}${image.ext}`);
709400
- writeFileSync86(path12, image.buffer);
710280
+ const dir = join173(repoRoot, ".omnius", "clipboard");
710281
+ mkdirSync102(dir, { recursive: true });
710282
+ const path12 = join173(dir, `clipboard-${Date.now()}${image.ext}`);
710283
+ writeFileSync87(path12, image.buffer);
709401
710284
  return { path: path12, buffer: image.buffer, mime: image.mime };
709402
710285
  }
709403
710286
  function readClipboardImage() {
@@ -709406,7 +710289,7 @@ function readClipboardImage() {
709406
710289
  execSync61("command -v pngpaste", { stdio: "ignore", timeout: 1e3 });
709407
710290
  const tmp = `/tmp/omnius-clipboard-${Date.now()}.png`;
709408
710291
  execFileSync11("pngpaste", [tmp], { timeout: 3e3 });
709409
- const buffer2 = readFileSync130(tmp);
710292
+ const buffer2 = readFileSync131(tmp);
709410
710293
  try {
709411
710294
  rmSync13(tmp);
709412
710295
  } catch {
@@ -709461,19 +710344,19 @@ var init_clipboard_media = __esm({
709461
710344
 
709462
710345
  // packages/cli/src/tui/interactive.ts
709463
710346
  import { cwd } from "node:process";
709464
- import { resolve as resolve67, join as join173, dirname as dirname52, extname as extname22, relative as relative17, sep as sep5 } from "node:path";
710347
+ import { resolve as resolve67, join as join174, dirname as dirname52, extname as extname22, relative as relative17, sep as sep5 } from "node:path";
709465
710348
  import { createRequire as createRequire9 } from "node:module";
709466
710349
  import { fileURLToPath as fileURLToPath21 } from "node:url";
709467
710350
  import {
709468
- readFileSync as readFileSync131,
709469
- writeFileSync as writeFileSync87,
710351
+ readFileSync as readFileSync132,
710352
+ writeFileSync as writeFileSync88,
709470
710353
  appendFileSync as appendFileSync17,
709471
710354
  rmSync as rmSync14,
709472
710355
  readdirSync as readdirSync57,
709473
710356
  statSync as statSync57,
709474
- mkdirSync as mkdirSync102
710357
+ mkdirSync as mkdirSync103
709475
710358
  } from "node:fs";
709476
- import { existsSync as existsSync160 } from "node:fs";
710359
+ import { existsSync as existsSync161 } from "node:fs";
709477
710360
  import { execSync as execSync62 } from "node:child_process";
709478
710361
  import { homedir as homedir60 } from "node:os";
709479
710362
  function formatTimeAgo2(date) {
@@ -709491,12 +710374,12 @@ function getVersion4() {
709491
710374
  const require5 = createRequire9(import.meta.url);
709492
710375
  const thisDir = dirname52(fileURLToPath21(import.meta.url));
709493
710376
  const candidates = [
709494
- join173(thisDir, "..", "package.json"),
709495
- join173(thisDir, "..", "..", "package.json"),
709496
- join173(thisDir, "..", "..", "..", "package.json")
710377
+ join174(thisDir, "..", "package.json"),
710378
+ join174(thisDir, "..", "..", "package.json"),
710379
+ join174(thisDir, "..", "..", "..", "package.json")
709497
710380
  ];
709498
710381
  for (const pkgPath of candidates) {
709499
- if (existsSync160(pkgPath)) {
710382
+ if (existsSync161(pkgPath)) {
709500
710383
  const pkg = require5(pkgPath);
709501
710384
  if (pkg.name === "omnius" || pkg.name === "@omnius/cli" || pkg.name === "@omnius/monorepo") {
709502
710385
  return pkg.version ?? "0.0.0";
@@ -710212,6 +711095,9 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier2) {
710212
711095
  // MCP tools (dynamic — from connected MCP servers, WO-MCP-01)
710213
711096
  ..._mcpTools.map(adaptTool6),
710214
711097
  createSubAgentTool(config, repoRoot, contextWindowSize),
711098
+ // Active exploration fan-out — one call spawns parallel read-only explorers
711099
+ // and returns a merged digest (Workstream B).
711100
+ createFanoutExploreTool(config, repoRoot, contextWindowSize),
710215
711101
  // Self-critique plan mode (WO-TP2)
710216
711102
  createPlanModeTool(config, repoRoot, contextWindowSize),
710217
711103
  createTaskCompleteTool(modelTier2, repoRoot)
@@ -710478,6 +711364,151 @@ Use task_status(task_id="${taskId}") or task_output(task_id="${taskId}") to chec
710478
711364
  };
710479
711365
  return tool;
710480
711366
  }
711367
+ function createFanoutExploreTool(config, repoRoot, ctxWindowSize) {
711368
+ return {
711369
+ name: "fanout_explore",
711370
+ description: "Discover where something lives across a large/multi-package codebase by fanning out parallel READ-ONLY explorer sub-agents — one per region — and returning a single merged, distilled map of the relevant files. Use this ONCE for broad 'where/how is X handled across the codebase' questions instead of grepping the whole repo serially. For a single-file or narrow lookup, use grep_search/file_read directly instead.",
711371
+ parameters: {
711372
+ type: "object",
711373
+ properties: {
711374
+ objective: {
711375
+ type: "string",
711376
+ description: "What to find, e.g. 'where authentication is handled' or 'all places that read the media store path'."
711377
+ },
711378
+ regions: {
711379
+ type: "array",
711380
+ items: { type: "string" },
711381
+ description: "Optional explicit regions (dirs/packages) to split across. If omitted, regions are derived from the repo (packages/* or top-level dirs)."
711382
+ },
711383
+ max_regions: {
711384
+ type: "number",
711385
+ description: "Cap on the number of parallel explorers (default 6)."
711386
+ }
711387
+ },
711388
+ required: ["objective"]
711389
+ },
711390
+ async execute(args) {
711391
+ const objective = String(
711392
+ args["objective"] ?? args["task"] ?? args["query"] ?? ""
711393
+ ).trim();
711394
+ if (!objective) {
711395
+ return { success: false, output: "", error: "objective is required" };
711396
+ }
711397
+ const maxRegions = typeof args["max_regions"] === "number" && args["max_regions"] > 0 ? Math.min(8, Math.floor(args["max_regions"])) : 6;
711398
+ let regions = Array.isArray(args["regions"]) ? args["regions"].map((r2) => String(r2)).filter(Boolean) : [];
711399
+ if (regions.length === 0) {
711400
+ const listDir = (rel) => {
711401
+ try {
711402
+ return readdirSync57(join174(repoRoot, rel), { withFileTypes: true }).map(
711403
+ (d2) => ({ name: d2.name, isDir: d2.isDirectory() })
711404
+ );
711405
+ } catch {
711406
+ return [];
711407
+ }
711408
+ };
711409
+ regions = deriveRegions(listDir("."), listDir("packages"), {
711410
+ max: maxRegions
711411
+ });
711412
+ } else {
711413
+ regions = regions.slice(0, maxRegions);
711414
+ }
711415
+ if (regions.length < 2) {
711416
+ return {
711417
+ success: false,
711418
+ output: "",
711419
+ error: "fanout_explore needs ≥2 regions to be worthwhile; for a narrow search use grep_search/file_read directly."
711420
+ };
711421
+ }
711422
+ const briefs = buildExplorerBriefs(objective, regions);
711423
+ const subTier = getModelTier(config.model);
711424
+ const compaction = subTier === "small" ? 12e3 : subTier === "medium" ? 24e3 : 4e4;
711425
+ const debug = process.env["OMNIUS_FANOUT_DEBUG"] === "1";
711426
+ const rawReturns = [];
711427
+ const digests = await Promise.all(
711428
+ briefs.map(async (brief) => {
711429
+ try {
711430
+ const backend = new OllamaAgenticBackend(
711431
+ config.backendUrl,
711432
+ config.model,
711433
+ config.apiKey
711434
+ );
711435
+ const runner = new AgenticRunner(backend, {
711436
+ maxTurns: 10,
711437
+ maxTokens: 4096,
711438
+ temperature: 0,
711439
+ requestTimeoutMs: config.timeoutMs,
711440
+ taskTimeoutMs: config.timeoutMs * 2,
711441
+ compactionThreshold: compaction,
711442
+ contextWindowSize: ctxWindowSize ?? 0,
711443
+ modelTier: subTier,
711444
+ toolProfile: getRuntimeToolProfilePolicy(repoRoot)
711445
+ });
711446
+ const roTools = [
711447
+ new FileReadTool(repoRoot),
711448
+ new GrepSearchTool(repoRoot),
711449
+ new GlobFindTool(repoRoot),
711450
+ new ListDirectoryTool(repoRoot)
711451
+ ].map(adaptTool6);
711452
+ roTools.push(createTaskCompleteTool(subTier, repoRoot));
711453
+ for (const t2 of roTools) runner.registerTool(t2);
711454
+ const result = await runner.run(
711455
+ buildExplorerPrompt(brief),
711456
+ `Working directory: ${repoRoot}`
711457
+ );
711458
+ const raw = result.summary || "";
711459
+ if (debug) rawReturns.push({ region: brief.scope, raw });
711460
+ return parseExplorerDigest(brief.scope, raw);
711461
+ } catch (err) {
711462
+ if (debug)
711463
+ rawReturns.push({
711464
+ region: brief.scope,
711465
+ raw: `[explorer error] ${err instanceof Error ? err.message : String(err)}`
711466
+ });
711467
+ return { region: brief.scope, relevant: false, findings: [], summary: "" };
711468
+ }
711469
+ })
711470
+ );
711471
+ if (debug) {
711472
+ try {
711473
+ writeFileSync88(
711474
+ join174(repoRoot, ".omnius", "fanout-debug.json"),
711475
+ JSON.stringify({ objective, regions, rawReturns, digests }, null, 2)
711476
+ );
711477
+ } catch {
711478
+ }
711479
+ }
711480
+ const merged = mergeDigests(digests);
711481
+ if (merged.paths.length === 0) {
711482
+ return {
711483
+ success: true,
711484
+ output: `[fanout_explore] ${objective}
711485
+ ${merged.synthesis}
711486
+ Explored regions: ${regions.join(", ")}
711487
+ No relevant files found — broaden the objective or search specific paths directly.`
711488
+ };
711489
+ }
711490
+ const lines = [
711491
+ `[fanout_explore] ${objective}`,
711492
+ merged.synthesis,
711493
+ "",
711494
+ "Relevant files (deduped):",
711495
+ ...merged.paths.map((p2) => ` - ${p2}`),
711496
+ "",
711497
+ "By region:"
711498
+ ];
711499
+ for (const d2 of merged.digests) {
711500
+ lines.push(`## ${d2.region}${d2.summary ? ` — ${d2.summary}` : ""}`);
711501
+ for (const f2 of d2.findings) {
711502
+ lines.push(` - ${f2.path} — ${f2.whyRelevant}`);
711503
+ }
711504
+ }
711505
+ if (merged.emptyRegions.length > 0) {
711506
+ lines.push("", `Empty regions (covered, nothing found): ${merged.emptyRegions.join(", ")}`);
711507
+ }
711508
+ return { success: true, output: lines.join("\n") };
711509
+ }
711510
+ };
711511
+ }
710481
711512
  function createPlanModeTool(config, repoRoot, ctxWindowSize) {
710482
711513
  return {
710483
711514
  name: "enter_plan_mode",
@@ -710700,14 +711731,14 @@ Meta-critique: quality ${meta.quality}/5, thorough: ${meta.thorough}`;
710700
711731
  function gatherMemorySnippets(root) {
710701
711732
  const snippets = [];
710702
711733
  const dirs = [
710703
- join173(root, ".omnius", "memory"),
710704
- join173(root, ".omnius", "memory")
711734
+ join174(root, ".omnius", "memory"),
711735
+ join174(root, ".omnius", "memory")
710705
711736
  ];
710706
711737
  for (const dir of dirs) {
710707
- if (!existsSync160(dir)) continue;
711738
+ if (!existsSync161(dir)) continue;
710708
711739
  try {
710709
711740
  for (const f2 of readdirSync57(dir).filter((f3) => f3.endsWith(".json"))) {
710710
- const data = JSON.parse(readFileSync131(join173(dir, f2), "utf-8"));
711741
+ const data = JSON.parse(readFileSync132(join174(dir, f2), "utf-8"));
710711
711742
  for (const val of Object.values(data)) {
710712
711743
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
710713
711744
  if (v.length > 10) snippets.push(v);
@@ -710963,7 +711994,7 @@ function extractGeneratedAudioPath(output, repoRoot) {
710963
711994
  const match = output.match(/(?:Sound|Music|TTS) generated:\s+([^\n\r]+)/i);
710964
711995
  const raw = match?.[1]?.trim().replace(/^["']|["']$/g, "");
710965
711996
  if (!raw) return null;
710966
- return raw.startsWith("/") || raw.startsWith("~") ? raw.replace(/^~(?=\/)/, homedir60()) : join173(repoRoot, raw);
711997
+ return raw.startsWith("/") || raw.startsWith("~") ? raw.replace(/^~(?=\/)/, homedir60()) : join174(repoRoot, raw);
710967
711998
  }
710968
711999
  async function playGeneratedAudioForToolResult(toolName, output, repoRoot, writer) {
710969
712000
  if (!toolName || !["generate_audio", "generate_tts", "audio_playback"].includes(toolName) || !output)
@@ -711141,9 +712172,9 @@ ${metabolismMemories}
711141
712172
  }
711142
712173
  if (!realtimeEnabled)
711143
712174
  try {
711144
- const archeFile = join173(repoRoot, ".omnius", "arche", "variants.json");
711145
- if (existsSync160(archeFile)) {
711146
- const variants = JSON.parse(readFileSync131(archeFile, "utf8"));
712175
+ const archeFile = join174(repoRoot, ".omnius", "arche", "variants.json");
712176
+ if (existsSync161(archeFile)) {
712177
+ const variants = JSON.parse(readFileSync132(archeFile, "utf8"));
711147
712178
  if (variants.length > 0) {
711148
712179
  let filtered = variants;
711149
712180
  if (taskType) {
@@ -711393,14 +712424,14 @@ RULES:
711393
712424
  const compactionThreshold = Number.isFinite(envOverride) && envOverride > 0 ? envOverride : modelTier2 === "small" ? 12e3 : modelTier2 === "medium" ? 24e3 : 4e4;
711394
712425
  let identityInjection = "";
711395
712426
  try {
711396
- const ikStateFile = join173(
712427
+ const ikStateFile = join174(
711397
712428
  repoRoot,
711398
712429
  ".omnius",
711399
712430
  "identity",
711400
712431
  "self-state.json"
711401
712432
  );
711402
- if (existsSync160(ikStateFile)) {
711403
- const selfState = JSON.parse(readFileSync131(ikStateFile, "utf8"));
712433
+ if (existsSync161(ikStateFile)) {
712434
+ const selfState = JSON.parse(readFileSync132(ikStateFile, "utf8"));
711404
712435
  const lines = [
711405
712436
  `[Identity State v${selfState.version}]`,
711406
712437
  `Self: ${selfState.narrative_summary}`,
@@ -711738,17 +712769,17 @@ Review its full output via sub_agent(action='output', id='${id}')`
711738
712769
  }
711739
712770
  }
711740
712771
  try {
711741
- const { readdirSync: readdirSync59, readFileSync: readFileSync133, existsSync: existsSync163 } = await import("node:fs");
712772
+ const { readdirSync: readdirSync59, readFileSync: readFileSync134, existsSync: existsSync164 } = await import("node:fs");
711742
712773
  const { join: pathJoin } = await import("node:path");
711743
712774
  const chunksDir = pathJoin(cwd(), ".omnius", "todo-chunks");
711744
- if (existsSync163(chunksDir)) {
712775
+ if (existsSync164(chunksDir)) {
711745
712776
  const files = readdirSync59(chunksDir).filter(
711746
712777
  (f2) => f2.endsWith(".json")
711747
712778
  );
711748
712779
  for (const f2 of files) {
711749
712780
  try {
711750
712781
  const data = JSON.parse(
711751
- readFileSync133(pathJoin(chunksDir, f2), "utf-8")
712782
+ readFileSync134(pathJoin(chunksDir, f2), "utf-8")
711752
712783
  );
711753
712784
  if (data._deleted) continue;
711754
712785
  if ((data.functionalSummary || "").toLowerCase().includes(q) || (data.detailSummary || "").toLowerCase().includes(q) || (data.keyFiles || []).some(
@@ -711814,11 +712845,11 @@ ${lines.join("\n")}`
711814
712845
  const expand2 = args.expand === true;
711815
712846
  if (expand2 && id.startsWith("todo-ctx-")) {
711816
712847
  try {
711817
- const { readFileSync: readFileSync133, existsSync: existsSync163 } = await import("node:fs");
712848
+ const { readFileSync: readFileSync134, existsSync: existsSync164 } = await import("node:fs");
711818
712849
  const { join: pathJoin } = await import("node:path");
711819
712850
  const chunksDir = pathJoin(cwd(), ".omnius", "todo-chunks");
711820
712851
  const todoIdSuffix = id.replace("todo-ctx-", "");
711821
- const files = existsSync163(chunksDir) ? (await import("node:fs")).readdirSync(chunksDir).filter((f2) => f2.endsWith(".json")) : [];
712852
+ const files = existsSync164(chunksDir) ? (await import("node:fs")).readdirSync(chunksDir).filter((f2) => f2.endsWith(".json")) : [];
711822
712853
  let chunkData = null;
711823
712854
  for (const f2 of files) {
711824
712855
  try {
@@ -712819,13 +713850,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
712819
713850
  });
712820
713851
  }
712821
713852
  try {
712822
- const ikDir = join173(repoRoot, ".omnius", "identity");
712823
- const ikFile = join173(ikDir, "self-state.json");
713853
+ const ikDir = join174(repoRoot, ".omnius", "identity");
713854
+ const ikFile = join174(ikDir, "self-state.json");
712824
713855
  let ikState;
712825
- if (existsSync160(ikFile)) {
712826
- ikState = JSON.parse(readFileSync131(ikFile, "utf8"));
713856
+ if (existsSync161(ikFile)) {
713857
+ ikState = JSON.parse(readFileSync132(ikFile, "utf8"));
712827
713858
  } else {
712828
- mkdirSync102(ikDir, { recursive: true });
713859
+ mkdirSync103(ikDir, { recursive: true });
712829
713860
  const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
712830
713861
  ikState = {
712831
713862
  self_id: `omnius-${machineId}`,
@@ -712941,7 +713972,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
712941
713972
  }
712942
713973
  ikState.session_count = (ikState.session_count || 0) + 1;
712943
713974
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
712944
- writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
713975
+ writeFileSync88(ikFile, JSON.stringify(ikState, null, 2));
712945
713976
  } catch (ikErr) {
712946
713977
  try {
712947
713978
  console.error("[IK-OBSERVE]", ikErr);
@@ -712973,14 +714004,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
712973
714004
  tokens
712974
714005
  );
712975
714006
  try {
712976
- const ikFile = join173(
714007
+ const ikFile = join174(
712977
714008
  repoRoot,
712978
714009
  ".omnius",
712979
714010
  "identity",
712980
714011
  "self-state.json"
712981
714012
  );
712982
- if (existsSync160(ikFile)) {
712983
- const ikState = JSON.parse(readFileSync131(ikFile, "utf8"));
714013
+ if (existsSync161(ikFile)) {
714014
+ const ikState = JSON.parse(readFileSync132(ikFile, "utf8"));
712984
714015
  if (!ikState.stats) ikState.stats = { queries_served: 0 };
712985
714016
  ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
712986
714017
  ikState.homeostasis.uncertainty = Math.min(
@@ -713002,7 +714033,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
713002
714033
  ikState.version_history = ikState.version_history.slice(-200);
713003
714034
  ikState.session_count = (ikState.session_count || 0) + 1;
713004
714035
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
713005
- writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
714036
+ writeFileSync88(ikFile, JSON.stringify(ikState, null, 2));
713006
714037
  }
713007
714038
  } catch {
713008
714039
  }
@@ -713302,10 +714333,10 @@ async function startInteractive(config, repoPath2) {
713302
714333
  process.stdin.pause();
713303
714334
  }
713304
714335
  try {
713305
- const omniusDir = join173(repoRoot, ".omnius");
713306
- const nexusPidFile = join173(omniusDir, "nexus", "daemon.pid");
713307
- if (existsSync160(nexusPidFile)) {
713308
- const pid = parseInt(readFileSync131(nexusPidFile, "utf8").trim(), 10);
714336
+ const omniusDir = join174(repoRoot, ".omnius");
714337
+ const nexusPidFile = join174(omniusDir, "nexus", "daemon.pid");
714338
+ if (existsSync161(nexusPidFile)) {
714339
+ const pid = parseInt(readFileSync132(nexusPidFile, "utf8").trim(), 10);
713309
714340
  if (pid > 0) {
713310
714341
  try {
713311
714342
  process.kill(pid, 0);
@@ -714024,7 +715055,7 @@ ${result.summary}`
714024
715055
  let p2pGateway = null;
714025
715056
  let peerMesh = null;
714026
715057
  let inferenceRouter = null;
714027
- const secretVault = new SecretVault(join173(repoRoot, ".omnius", "vault.enc"));
715058
+ const secretVault = new SecretVault(join174(repoRoot, ".omnius", "vault.enc"));
714028
715059
  let adminSessionKey = null;
714029
715060
  const callSubAgents = /* @__PURE__ */ new Map();
714030
715061
  void Promise.resolve().then(() => (init_syntax_highlight(), syntax_highlight_exports)).then((m2) => m2.prewarm()).catch(() => {
@@ -714347,22 +715378,22 @@ Respond to the scoped Telegram target when complete.`
714347
715378
  const out = [];
714348
715379
  const pushJsonFiles = (dir, prefix) => {
714349
715380
  try {
714350
- if (!existsSync160(dir)) return;
715381
+ if (!existsSync161(dir)) return;
714351
715382
  for (const file of readdirSync57(dir)) {
714352
715383
  if (!file.endsWith(".json")) continue;
714353
715384
  const id = file.replace(/\.json$/, "");
714354
- out.push({ id: `${prefix}:${id}`, label: id, path: join173(dir, file) });
715385
+ out.push({ id: `${prefix}:${id}`, label: id, path: join174(dir, file) });
714355
715386
  }
714356
715387
  } catch {
714357
715388
  }
714358
715389
  };
714359
- pushJsonFiles(join173(repoRoot, ".omnius", "checkpoints"), "turn");
715390
+ pushJsonFiles(join174(repoRoot, ".omnius", "checkpoints"), "turn");
714360
715391
  try {
714361
- const sessionDir2 = join173(repoRoot, ".omnius", "session");
714362
- if (existsSync160(sessionDir2)) {
715392
+ const sessionDir2 = join174(repoRoot, ".omnius", "session");
715393
+ if (existsSync161(sessionDir2)) {
714363
715394
  for (const entry of readdirSync57(sessionDir2)) {
714364
- const cp2 = join173(sessionDir2, entry, "checkpoint.json");
714365
- if (existsSync160(cp2))
715395
+ const cp2 = join174(sessionDir2, entry, "checkpoint.json");
715396
+ if (existsSync161(cp2))
714366
715397
  out.push({ id: `session:${entry}`, label: entry, path: cp2 });
714367
715398
  }
714368
715399
  }
@@ -714452,9 +715483,9 @@ This is an independent background session started from /background.`
714452
715483
  return id;
714453
715484
  };
714454
715485
  try {
714455
- const titleFile = join173(repoRoot, ".omnius", "session-title");
714456
- if (existsSync160(titleFile))
714457
- sessionTitle = readFileSync131(titleFile, "utf8").trim() || null;
715486
+ const titleFile = join174(repoRoot, ".omnius", "session-title");
715487
+ if (existsSync161(titleFile))
715488
+ sessionTitle = readFileSync132(titleFile, "utf8").trim() || null;
714458
715489
  } catch {
714459
715490
  }
714460
715491
  let carouselRetired = isResumed;
@@ -714532,7 +715563,7 @@ This is an independent background session started from /background.`
714532
715563
  const completions = [];
714533
715564
  for (const entry of entries) {
714534
715565
  if (!entry.startsWith(partialName)) continue;
714535
- const full = join173(searchDir, entry);
715566
+ const full = join174(searchDir, entry);
714536
715567
  try {
714537
715568
  const st = statSync57(full);
714538
715569
  const suffix = st.isDirectory() ? "/" : "";
@@ -714563,13 +715594,13 @@ This is an independent background session started from /background.`
714563
715594
  );
714564
715595
  return [hits, line];
714565
715596
  }
714566
- const HISTORY_DIR = join173(homedir60(), ".omnius");
714567
- const HISTORY_FILE = join173(HISTORY_DIR, "repl-history");
715597
+ const HISTORY_DIR = join174(homedir60(), ".omnius");
715598
+ const HISTORY_FILE = join174(HISTORY_DIR, "repl-history");
714568
715599
  const MAX_HISTORY_LINES = 500;
714569
715600
  let savedHistory = [];
714570
715601
  try {
714571
- if (existsSync160(HISTORY_FILE)) {
714572
- const raw = readFileSync131(HISTORY_FILE, "utf8").trim();
715602
+ if (existsSync161(HISTORY_FILE)) {
715603
+ const raw = readFileSync132(HISTORY_FILE, "utf8").trim();
714573
715604
  if (raw) savedHistory = raw.split("\n").reverse();
714574
715605
  }
714575
715606
  } catch {
@@ -714721,12 +715752,12 @@ This is an independent background session started from /background.`
714721
715752
  function persistHistoryLine(line) {
714722
715753
  if (!line.trim()) return;
714723
715754
  try {
714724
- mkdirSync102(HISTORY_DIR, { recursive: true });
715755
+ mkdirSync103(HISTORY_DIR, { recursive: true });
714725
715756
  appendFileSync17(HISTORY_FILE, line + "\n", "utf8");
714726
715757
  if (Math.random() < 0.02) {
714727
- const all2 = readFileSync131(HISTORY_FILE, "utf8").trim().split("\n");
715758
+ const all2 = readFileSync132(HISTORY_FILE, "utf8").trim().split("\n");
714728
715759
  if (all2.length > MAX_HISTORY_LINES) {
714729
- writeFileSync87(
715760
+ writeFileSync88(
714730
715761
  HISTORY_FILE,
714731
715762
  all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n",
714732
715763
  "utf8"
@@ -714935,10 +715966,10 @@ This is an independent background session started from /background.`
714935
715966
  const { unlinkSync: _rmStale } = await import("node:fs");
714936
715967
  const { homedir: _hdir } = await import("node:os");
714937
715968
  for (const dp of [
714938
- join173(repoRoot, ".omnius", "nexus", "nexus-daemon.mjs"),
714939
- join173(_hdir(), ".omnius", "nexus", "nexus-daemon.mjs")
715969
+ join174(repoRoot, ".omnius", "nexus", "nexus-daemon.mjs"),
715970
+ join174(_hdir(), ".omnius", "nexus", "nexus-daemon.mjs")
714940
715971
  ]) {
714941
- if (existsSync160(dp))
715972
+ if (existsSync161(dp))
714942
715973
  try {
714943
715974
  _rmStale(dp);
714944
715975
  } catch {
@@ -714950,10 +715981,10 @@ This is an independent background session started from /background.`
714950
715981
  const autoNexus = new NexusTool(repoRoot);
714951
715982
  const _registerNexusDaemon = () => {
714952
715983
  try {
714953
- const nexusPidFile = join173(autoNexus.getNexusDir(), "daemon.pid");
714954
- if (existsSync160(nexusPidFile)) {
715984
+ const nexusPidFile = join174(autoNexus.getNexusDir(), "daemon.pid");
715985
+ if (existsSync161(nexusPidFile)) {
714955
715986
  const nPid = parseInt(
714956
- readFileSync131(nexusPidFile, "utf8").trim(),
715987
+ readFileSync132(nexusPidFile, "utf8").trim(),
714957
715988
  10
714958
715989
  );
714959
715990
  if (nPid > 0 && !registry2.daemons.has("Nexus")) {
@@ -714984,7 +716015,7 @@ This is an independent background session started from /background.`
714984
716015
  await new Promise((r3) => setTimeout(r3, 5e3));
714985
716016
  return _tryNexusConnect(attempt + 1);
714986
716017
  }
714987
- const nexusLogPath = join173(autoNexus.getNexusDir(), "daemon.err");
716018
+ const nexusLogPath = join174(autoNexus.getNexusDir(), "daemon.err");
714988
716019
  const visibleOut = out.length > 1200 ? `${out.slice(0, 1200)}...` : out;
714989
716020
  writeContent(
714990
716021
  () => renderWarning(
@@ -715027,7 +716058,7 @@ Log: ${nexusLogPath}`
715027
716058
  } catch {
715028
716059
  }
715029
716060
  try {
715030
- const omniusDir = join173(repoRoot, ".omnius");
716061
+ const omniusDir = join174(repoRoot, ".omnius");
715031
716062
  const reconnected = await ExposeGateway.checkAndReconnect(omniusDir, {
715032
716063
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
715033
716064
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -715066,7 +716097,7 @@ Log: ${nexusLogPath}`
715066
716097
  } catch {
715067
716098
  }
715068
716099
  try {
715069
- const omniusDir = join173(repoRoot, ".omnius");
716100
+ const omniusDir = join174(repoRoot, ".omnius");
715070
716101
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(
715071
716102
  omniusDir,
715072
716103
  new NexusTool(repoRoot),
@@ -715131,11 +716162,11 @@ Log: ${nexusLogPath}`
715131
716162
  hostname: _hn,
715132
716163
  userInfo: _ui
715133
716164
  } = await import("node:os");
715134
- const globalNamePath = join173(_hd(), ".omnius", "agent-name");
716165
+ const globalNamePath = join174(_hd(), ".omnius", "agent-name");
715135
716166
  let agName = "";
715136
716167
  try {
715137
- if (existsSync160(globalNamePath))
715138
- agName = readFileSync131(globalNamePath, "utf8").trim();
716168
+ if (existsSync161(globalNamePath))
716169
+ agName = readFileSync132(globalNamePath, "utf8").trim();
715139
716170
  } catch {
715140
716171
  }
715141
716172
  if (!agName) {
@@ -715166,7 +716197,7 @@ Log: ${nexusLogPath}`
715166
716197
  }
715167
716198
  if (!ollamaAlive) {
715168
716199
  try {
715169
- const savedSponsorsPath = join173(
716200
+ const savedSponsorsPath = join174(
715170
716201
  repoRoot,
715171
716202
  ".omnius",
715172
716203
  "sponsor",
@@ -715174,9 +716205,9 @@ Log: ${nexusLogPath}`
715174
716205
  );
715175
716206
  let savedSponsors = [];
715176
716207
  try {
715177
- if (existsSync160(savedSponsorsPath)) {
716208
+ if (existsSync161(savedSponsorsPath)) {
715178
716209
  savedSponsors = JSON.parse(
715179
- readFileSync131(savedSponsorsPath, "utf8")
716210
+ readFileSync132(savedSponsorsPath, "utf8")
715180
716211
  );
715181
716212
  const oneHourAgo = Date.now() - 36e5;
715182
716213
  savedSponsors = savedSponsors.filter(
@@ -715666,9 +716697,9 @@ Log: ${nexusLogPath}`
715666
716697
  setSessionTitle(title) {
715667
716698
  sessionTitle = title.trim() || null;
715668
716699
  try {
715669
- mkdirSync102(join173(repoRoot, ".omnius"), { recursive: true });
715670
- writeFileSync87(
715671
- join173(repoRoot, ".omnius", "session-title"),
716700
+ mkdirSync103(join174(repoRoot, ".omnius"), { recursive: true });
716701
+ writeFileSync88(
716702
+ join174(repoRoot, ".omnius", "session-title"),
715672
716703
  `${sessionTitle ?? ""}
715673
716704
  `,
715674
716705
  "utf8"
@@ -717060,10 +718091,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717060
718091
  if (name10 === "voice_list_files") {
717061
718092
  const baseDir = String(args?.dir ?? ".");
717062
718093
  const { readdirSync: readdirSync59, statSync: statSync59 } = __require("node:fs");
717063
- const { join: join178, resolve: resolve71 } = __require("node:path");
717064
- const base3 = baseDir.startsWith("/") ? baseDir : resolve71(join178(repoRoot, baseDir));
718094
+ const { join: join179, resolve: resolve71 } = __require("node:path");
718095
+ const base3 = baseDir.startsWith("/") ? baseDir : resolve71(join179(repoRoot, baseDir));
717065
718096
  const items = readdirSync59(base3).slice(0, 200).map((f2) => {
717066
- const s2 = statSync59(join178(base3, f2));
718097
+ const s2 = statSync59(join179(base3, f2));
717067
718098
  return { name: f2, dir: s2.isDirectory(), size: s2.size };
717068
718099
  });
717069
718100
  return JSON.stringify({ dir: base3, items }, null, 2);
@@ -717166,7 +718197,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717166
718197
  kind,
717167
718198
  targetUrl,
717168
718199
  authKey,
717169
- stateDir: join173(repoRoot, ".omnius"),
718200
+ stateDir: join174(repoRoot, ".omnius"),
717170
718201
  passthrough: passthrough ?? false,
717171
718202
  loadbalance: loadbalance ?? false,
717172
718203
  endpointAuth: passthrough ? endpointAuth ?? currentConfig.apiKey : void 0,
@@ -717222,7 +718253,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717222
718253
  targetUrl,
717223
718254
  authKey,
717224
718255
  fullAccess,
717225
- stateDir: join173(repoRoot, ".omnius"),
718256
+ stateDir: join174(repoRoot, ".omnius"),
717226
718257
  endpointAuth: endpointAuth ?? (passthrough ? currentConfig.apiKey : void 0)
717227
718258
  });
717228
718259
  newTunnel.on("stats", (stats) => {
@@ -717314,9 +718345,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717314
718345
  });
717315
718346
  if (!result.success) throw new Error(result.error || "Connect failed");
717316
718347
  try {
717317
- const nexusPidFile = join173(nexusTool.getNexusDir(), "daemon.pid");
717318
- if (existsSync160(nexusPidFile)) {
717319
- const pid = parseInt(readFileSync131(nexusPidFile, "utf8").trim(), 10);
718348
+ const nexusPidFile = join174(nexusTool.getNexusDir(), "daemon.pid");
718349
+ if (existsSync161(nexusPidFile)) {
718350
+ const pid = parseInt(readFileSync132(nexusPidFile, "utf8").trim(), 10);
717320
718351
  if (pid > 0) {
717321
718352
  registry2.register({
717322
718353
  name: "Nexus",
@@ -717526,10 +718557,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717526
718557
  );
717527
718558
  }
717528
718559
  try {
717529
- const nexusDir = join173(repoRoot, OMNIUS_DIR, "nexus");
717530
- const pidFile = join173(nexusDir, "daemon.pid");
717531
- if (existsSync160(pidFile)) {
717532
- const pid = parseInt(readFileSync131(pidFile, "utf8").trim(), 10);
718560
+ const nexusDir = join174(repoRoot, OMNIUS_DIR, "nexus");
718561
+ const pidFile = join174(nexusDir, "daemon.pid");
718562
+ if (existsSync161(pidFile)) {
718563
+ const pid = parseInt(readFileSync132(pidFile, "utf8").trim(), 10);
717533
718564
  if (pid > 0) {
717534
718565
  try {
717535
718566
  if (process.platform === "win32") {
@@ -717556,13 +718587,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717556
718587
  } catch {
717557
718588
  }
717558
718589
  try {
717559
- const voiceDir3 = join173(homedir60(), ".omnius", "voice");
718590
+ const voiceDir3 = join174(homedir60(), ".omnius", "voice");
717560
718591
  const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
717561
718592
  for (const pf of voicePidFiles) {
717562
- const pidPath = join173(voiceDir3, pf);
717563
- if (existsSync160(pidPath)) {
718593
+ const pidPath = join174(voiceDir3, pf);
718594
+ if (existsSync161(pidPath)) {
717564
718595
  try {
717565
- const pid = parseInt(readFileSync131(pidPath, "utf8").trim(), 10);
718596
+ const pid = parseInt(readFileSync132(pidPath, "utf8").trim(), 10);
717566
718597
  if (pid > 0) {
717567
718598
  if (process.platform === "win32") {
717568
718599
  try {
@@ -717592,8 +718623,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717592
718623
  );
717593
718624
  } catch {
717594
718625
  }
717595
- const omniusPath = join173(repoRoot, OMNIUS_DIR);
717596
- if (existsSync160(omniusPath)) {
718626
+ const omniusPath = join174(repoRoot, OMNIUS_DIR);
718627
+ if (existsSync161(omniusPath)) {
717597
718628
  let deleted = false;
717598
718629
  for (let attempt = 0; attempt < 3; attempt++) {
717599
718630
  try {
@@ -717704,23 +718735,23 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717704
718735
  try {
717705
718736
  const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
717706
718737
  if (isPersonaPlexRunning2()) {
717707
- const ppPidFile = join173(
718738
+ const ppPidFile = join174(
717708
718739
  homedir60(),
717709
718740
  ".omnius",
717710
718741
  "voice",
717711
718742
  "personaplex",
717712
718743
  "daemon.pid"
717713
718744
  );
717714
- const ppPortFile = join173(
718745
+ const ppPortFile = join174(
717715
718746
  homedir60(),
717716
718747
  ".omnius",
717717
718748
  "voice",
717718
718749
  "personaplex",
717719
718750
  "daemon.port"
717720
718751
  );
717721
- if (existsSync160(ppPidFile)) {
717722
- const ppPid = parseInt(readFileSync131(ppPidFile, "utf8").trim(), 10);
717723
- const ppPort = existsSync160(ppPortFile) ? parseInt(readFileSync131(ppPortFile, "utf8").trim(), 10) : void 0;
718752
+ if (existsSync161(ppPidFile)) {
718753
+ const ppPid = parseInt(readFileSync132(ppPidFile, "utf8").trim(), 10);
718754
+ const ppPort = existsSync161(ppPortFile) ? parseInt(readFileSync132(ppPortFile, "utf8").trim(), 10) : void 0;
717724
718755
  if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
717725
718756
  registry2.register({
717726
718757
  name: "PersonaPlex",
@@ -717732,12 +718763,12 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
717732
718763
  }
717733
718764
  }
717734
718765
  }
717735
- const nexusPidFile = join173(
718766
+ const nexusPidFile = join174(
717736
718767
  new NexusTool(repoRoot).getNexusDir(),
717737
718768
  "daemon.pid"
717738
718769
  );
717739
- if (existsSync160(nexusPidFile)) {
717740
- const nPid = parseInt(readFileSync131(nexusPidFile, "utf8").trim(), 10);
718770
+ if (existsSync161(nexusPidFile)) {
718771
+ const nPid = parseInt(readFileSync132(nexusPidFile, "utf8").trim(), 10);
717741
718772
  if (nPid > 0 && !registry2.daemons.has("Nexus")) {
717742
718773
  try {
717743
718774
  process.kill(nPid, 0);
@@ -718167,9 +719198,9 @@ Execute this skill now. Follow the behavioral guidance above.`;
718167
719198
  }
718168
719199
  }
718169
719200
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
718170
- const isImage = isImagePath(cleanPath) && existsSync160(resolve67(repoRoot, cleanPath));
718171
- const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync160(resolve67(repoRoot, cleanPath));
718172
- const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) && existsSync160(resolve67(repoRoot, cleanPath));
719201
+ const isImage = isImagePath(cleanPath) && existsSync161(resolve67(repoRoot, cleanPath));
719202
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync161(resolve67(repoRoot, cleanPath));
719203
+ const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) && existsSync161(resolve67(repoRoot, cleanPath));
718173
719204
  if (activeTask) {
718174
719205
  if ((isImage || isMedia) && activeTask.runner.isPaused) {
718175
719206
  activeTask.runner.resume();
@@ -718178,7 +719209,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
718178
719209
  if (isImage) {
718179
719210
  try {
718180
719211
  const imgPath = resolve67(repoRoot, cleanPath);
718181
- const imgBuffer = readFileSync131(imgPath);
719212
+ const imgBuffer = readFileSync132(imgPath);
718182
719213
  const base642 = imgBuffer.toString("base64");
718183
719214
  const ext = extname22(cleanPath).toLowerCase();
718184
719215
  const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
@@ -718411,7 +719442,7 @@ Read it with image_read or vision if more detail is needed. Describe what you se
718411
719442
  if (isMarkdown && fullInput === input) {
718412
719443
  try {
718413
719444
  const mdPath = resolve67(repoRoot, cleanPath);
718414
- const mdContent = readFileSync131(mdPath, "utf8");
719445
+ const mdContent = readFileSync132(mdPath, "utf8");
718415
719446
  const { parseMcpMarkdown: parseMcpMarkdown2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports2));
718416
719447
  const result = parseMcpMarkdown2(mdContent);
718417
719448
  if (result.servers.length > 0) {
@@ -719048,13 +720079,13 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
719048
720079
  const handle2 = startTask(task, config, repoRoot);
719049
720080
  await handle2.promise;
719050
720081
  try {
719051
- const ikDir = join173(repoRoot, ".omnius", "identity");
719052
- const ikFile = join173(ikDir, "self-state.json");
720082
+ const ikDir = join174(repoRoot, ".omnius", "identity");
720083
+ const ikFile = join174(ikDir, "self-state.json");
719053
720084
  let ikState;
719054
- if (existsSync160(ikFile)) {
719055
- ikState = JSON.parse(readFileSync131(ikFile, "utf8"));
720085
+ if (existsSync161(ikFile)) {
720086
+ ikState = JSON.parse(readFileSync132(ikFile, "utf8"));
719056
720087
  } else {
719057
- mkdirSync102(ikDir, { recursive: true });
720088
+ mkdirSync103(ikDir, { recursive: true });
719058
720089
  ikState = {
719059
720090
  self_id: `omnius-${Date.now().toString(36)}`,
719060
720091
  version: 1,
@@ -719107,7 +720138,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
719107
720138
  );
719108
720139
  ikState.session_count = (ikState.session_count || 0) + 1;
719109
720140
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
719110
- writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
720141
+ writeFileSync88(ikFile, JSON.stringify(ikState, null, 2));
719111
720142
  } catch (ikErr) {
719112
720143
  }
719113
720144
  try {
@@ -719120,12 +720151,12 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
719120
720151
  );
719121
720152
  } catch {
719122
720153
  try {
719123
- const archeDir = join173(repoRoot, ".omnius", "arche");
719124
- const archeFile = join173(archeDir, "variants.json");
720154
+ const archeDir = join174(repoRoot, ".omnius", "arche");
720155
+ const archeFile = join174(archeDir, "variants.json");
719125
720156
  let variants = [];
719126
720157
  try {
719127
- if (existsSync160(archeFile))
719128
- variants = JSON.parse(readFileSync131(archeFile, "utf8"));
720158
+ if (existsSync161(archeFile))
720159
+ variants = JSON.parse(readFileSync132(archeFile, "utf8"));
719129
720160
  } catch {
719130
720161
  }
719131
720162
  variants.push({
@@ -719139,21 +720170,21 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
719139
720170
  tags: ["general"]
719140
720171
  });
719141
720172
  if (variants.length > 50) variants = variants.slice(-50);
719142
- mkdirSync102(archeDir, { recursive: true });
719143
- writeFileSync87(archeFile, JSON.stringify(variants, null, 2));
720173
+ mkdirSync103(archeDir, { recursive: true });
720174
+ writeFileSync88(archeFile, JSON.stringify(variants, null, 2));
719144
720175
  } catch {
719145
720176
  }
719146
720177
  }
719147
720178
  try {
719148
- const metaFile2 = join173(
720179
+ const metaFile2 = join174(
719149
720180
  repoRoot,
719150
720181
  ".omnius",
719151
720182
  "memory",
719152
720183
  "metabolism",
719153
720184
  "store.json"
719154
720185
  );
719155
- if (existsSync160(metaFile2)) {
719156
- const store2 = JSON.parse(readFileSync131(metaFile2, "utf8"));
720186
+ if (existsSync161(metaFile2)) {
720187
+ const store2 = JSON.parse(readFileSync132(metaFile2, "utf8"));
719157
720188
  const surfaced = store2.filter(
719158
720189
  (m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15
719159
720190
  ).sort(
@@ -719171,7 +720202,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
719171
720202
  updated = true;
719172
720203
  }
719173
720204
  if (updated) {
719174
- writeFileSync87(metaFile2, JSON.stringify(store2, null, 2));
720205
+ writeFileSync88(metaFile2, JSON.stringify(store2, null, 2));
719175
720206
  }
719176
720207
  }
719177
720208
  } catch {
@@ -719229,9 +720260,9 @@ Rules:
719229
720260
  try {
719230
720261
  const { initDb: initDb2 } = __require("@omnius/memory");
719231
720262
  const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@omnius/memory");
719232
- const dbDir = join173(repoRoot, ".omnius", "memory");
719233
- mkdirSync102(dbDir, { recursive: true });
719234
- const db = initDb2(join173(dbDir, "structured.db"));
720263
+ const dbDir = join174(repoRoot, ".omnius", "memory");
720264
+ mkdirSync103(dbDir, { recursive: true });
720265
+ const db = initDb2(join174(dbDir, "structured.db"));
719235
720266
  const memStore = new ProceduralMemoryStore2(db);
719236
720267
  memStore.createWithEmbedding(
719237
720268
  {
@@ -719251,12 +720282,12 @@ Rules:
719251
720282
  db.close();
719252
720283
  } catch {
719253
720284
  }
719254
- const metaDir = join173(repoRoot, ".omnius", "memory", "metabolism");
719255
- const storeFile = join173(metaDir, "store.json");
720285
+ const metaDir = join174(repoRoot, ".omnius", "memory", "metabolism");
720286
+ const storeFile = join174(metaDir, "store.json");
719256
720287
  let store2 = [];
719257
720288
  try {
719258
- if (existsSync160(storeFile))
719259
- store2 = JSON.parse(readFileSync131(storeFile, "utf8"));
720289
+ if (existsSync161(storeFile))
720290
+ store2 = JSON.parse(readFileSync132(storeFile, "utf8"));
719260
720291
  } catch {
719261
720292
  }
719262
720293
  store2.push({
@@ -719279,32 +720310,32 @@ Rules:
719279
720310
  accessCount: 0
719280
720311
  });
719281
720312
  if (store2.length > 100) store2 = store2.slice(-100);
719282
- mkdirSync102(metaDir, { recursive: true });
719283
- writeFileSync87(storeFile, JSON.stringify(store2, null, 2));
720313
+ mkdirSync103(metaDir, { recursive: true });
720314
+ writeFileSync88(storeFile, JSON.stringify(store2, null, 2));
719284
720315
  }
719285
720316
  }
719286
720317
  } catch {
719287
720318
  }
719288
720319
  try {
719289
- const cohereSettingsFile = join173(repoRoot, ".omnius", "settings.json");
720320
+ const cohereSettingsFile = join174(repoRoot, ".omnius", "settings.json");
719290
720321
  let cohereActive = false;
719291
720322
  try {
719292
- if (existsSync160(cohereSettingsFile)) {
719293
- const settings = JSON.parse(readFileSync131(cohereSettingsFile, "utf8"));
720323
+ if (existsSync161(cohereSettingsFile)) {
720324
+ const settings = JSON.parse(readFileSync132(cohereSettingsFile, "utf8"));
719294
720325
  cohereActive = settings.cohere === true;
719295
720326
  }
719296
720327
  } catch {
719297
720328
  }
719298
720329
  if (cohereActive) {
719299
- const metaFile2 = join173(
720330
+ const metaFile2 = join174(
719300
720331
  repoRoot,
719301
720332
  ".omnius",
719302
720333
  "memory",
719303
720334
  "metabolism",
719304
720335
  "store.json"
719305
720336
  );
719306
- if (existsSync160(metaFile2)) {
719307
- const store2 = JSON.parse(readFileSync131(metaFile2, "utf8"));
720337
+ if (existsSync161(metaFile2)) {
720338
+ const store2 = JSON.parse(readFileSync132(metaFile2, "utf8"));
719308
720339
  const latest = store2.filter(
719309
720340
  (m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction"
719310
720341
  ).slice(-1)[0];
@@ -719331,9 +720362,9 @@ Rules:
719331
720362
  }
719332
720363
  } catch (err) {
719333
720364
  try {
719334
- const ikFile = join173(repoRoot, ".omnius", "identity", "self-state.json");
719335
- if (existsSync160(ikFile)) {
719336
- const ikState = JSON.parse(readFileSync131(ikFile, "utf8"));
720365
+ const ikFile = join174(repoRoot, ".omnius", "identity", "self-state.json");
720366
+ if (existsSync161(ikFile)) {
720367
+ const ikState = JSON.parse(readFileSync132(ikFile, "utf8"));
719337
720368
  ikState.homeostasis.uncertainty = Math.min(
719338
720369
  1,
719339
720370
  ikState.homeostasis.uncertainty + 0.1
@@ -719344,17 +720375,17 @@ Rules:
719344
720375
  );
719345
720376
  ikState.session_count = (ikState.session_count || 0) + 1;
719346
720377
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
719347
- writeFileSync87(ikFile, JSON.stringify(ikState, null, 2));
720378
+ writeFileSync88(ikFile, JSON.stringify(ikState, null, 2));
719348
720379
  }
719349
- const metaFile2 = join173(
720380
+ const metaFile2 = join174(
719350
720381
  repoRoot,
719351
720382
  ".omnius",
719352
720383
  "memory",
719353
720384
  "metabolism",
719354
720385
  "store.json"
719355
720386
  );
719356
- if (existsSync160(metaFile2)) {
719357
- const store2 = JSON.parse(readFileSync131(metaFile2, "utf8"));
720387
+ if (existsSync161(metaFile2)) {
720388
+ const store2 = JSON.parse(readFileSync132(metaFile2, "utf8"));
719358
720389
  const surfaced = store2.filter(
719359
720390
  (m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15
719360
720391
  ).sort(
@@ -719372,15 +720403,15 @@ Rules:
719372
720403
  (item.scores.confidence || 0.5) - 0.02
719373
720404
  );
719374
720405
  }
719375
- writeFileSync87(metaFile2, JSON.stringify(store2, null, 2));
720406
+ writeFileSync88(metaFile2, JSON.stringify(store2, null, 2));
719376
720407
  }
719377
720408
  try {
719378
- const archeDir = join173(repoRoot, ".omnius", "arche");
719379
- const archeFile = join173(archeDir, "variants.json");
720409
+ const archeDir = join174(repoRoot, ".omnius", "arche");
720410
+ const archeFile = join174(archeDir, "variants.json");
719380
720411
  let variants = [];
719381
720412
  try {
719382
- if (existsSync160(archeFile))
719383
- variants = JSON.parse(readFileSync131(archeFile, "utf8"));
720413
+ if (existsSync161(archeFile))
720414
+ variants = JSON.parse(readFileSync132(archeFile, "utf8"));
719384
720415
  } catch {
719385
720416
  }
719386
720417
  variants.push({
@@ -719394,8 +720425,8 @@ Rules:
719394
720425
  tags: ["general"]
719395
720426
  });
719396
720427
  if (variants.length > 50) variants = variants.slice(-50);
719397
- mkdirSync102(archeDir, { recursive: true });
719398
- writeFileSync87(archeFile, JSON.stringify(variants, null, 2));
720428
+ mkdirSync103(archeDir, { recursive: true });
720429
+ writeFileSync88(archeFile, JSON.stringify(variants, null, 2));
719399
720430
  } catch {
719400
720431
  }
719401
720432
  } catch {
@@ -719506,18 +720537,18 @@ __export(run_exports, {
719506
720537
  import { resolve as resolve68 } from "node:path";
719507
720538
  import { spawn as spawn34 } from "node:child_process";
719508
720539
  import {
719509
- mkdirSync as mkdirSync103,
719510
- writeFileSync as writeFileSync88,
719511
- readFileSync as readFileSync132,
720540
+ mkdirSync as mkdirSync104,
720541
+ writeFileSync as writeFileSync89,
720542
+ readFileSync as readFileSync133,
719512
720543
  readdirSync as readdirSync58,
719513
- existsSync as existsSync161
720544
+ existsSync as existsSync162
719514
720545
  } from "node:fs";
719515
720546
  import { randomBytes as randomBytes29 } from "node:crypto";
719516
- import { join as join174 } from "node:path";
720547
+ import { join as join175 } from "node:path";
719517
720548
  function jobsDir2(repoPath2) {
719518
720549
  const root = resolve68(repoPath2 ?? process.cwd());
719519
- const dir = join174(root, ".omnius", "jobs");
719520
- mkdirSync103(dir, { recursive: true });
720550
+ const dir = join175(root, ".omnius", "jobs");
720551
+ mkdirSync104(dir, { recursive: true });
719521
720552
  return dir;
719522
720553
  }
719523
720554
  async function runCommand2(opts, config) {
@@ -719647,7 +720678,7 @@ async function runBackground(task, config, opts) {
719647
720678
  }
719648
720679
  });
719649
720680
  job.pid = child.pid ?? 0;
719650
- writeFileSync88(join174(dir, `${id}.json`), JSON.stringify(job, null, 2));
720681
+ writeFileSync89(join175(dir, `${id}.json`), JSON.stringify(job, null, 2));
719651
720682
  let output = "";
719652
720683
  child.stdout?.on("data", (chunk) => {
719653
720684
  output += chunk.toString();
@@ -719663,7 +720694,7 @@ async function runBackground(task, config, opts) {
719663
720694
  job.summary = result.summary;
719664
720695
  job.durationMs = result.durationMs;
719665
720696
  job.error = result.error;
719666
- writeFileSync88(join174(dir, `${id}.json`), JSON.stringify(job, null, 2));
720697
+ writeFileSync89(join175(dir, `${id}.json`), JSON.stringify(job, null, 2));
719667
720698
  } catch {
719668
720699
  }
719669
720700
  });
@@ -719679,13 +720710,13 @@ async function runBackground(task, config, opts) {
719679
720710
  }
719680
720711
  function statusCommand(jobId, repoPath2) {
719681
720712
  const dir = jobsDir2(repoPath2);
719682
- const file = join174(dir, `${jobId}.json`);
719683
- if (!existsSync161(file)) {
720713
+ const file = join175(dir, `${jobId}.json`);
720714
+ if (!existsSync162(file)) {
719684
720715
  console.error(`Job not found: ${jobId}`);
719685
720716
  console.log(`Available jobs: omnius jobs`);
719686
720717
  process.exit(1);
719687
720718
  }
719688
- const job = JSON.parse(readFileSync132(file, "utf-8"));
720719
+ const job = JSON.parse(readFileSync133(file, "utf-8"));
719689
720720
  const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
719690
720721
  const icon = job.status === "completed" ? "✓" : job.status === "failed" ? "✗" : "●";
719691
720722
  console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
@@ -719707,7 +720738,7 @@ function jobsCommand(repoPath2) {
719707
720738
  console.log("Jobs:");
719708
720739
  for (const file of files) {
719709
720740
  try {
719710
- const job = JSON.parse(readFileSync132(join174(dir, file), "utf-8"));
720741
+ const job = JSON.parse(readFileSync133(join175(dir, file), "utf-8"));
719711
720742
  const icon = job.status === "completed" ? "✓" : job.status === "failed" ? "✗" : "●";
719712
720743
  const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
719713
720744
  const cleanListTask = cleanForStorage(job.task) || job.task;
@@ -719734,13 +720765,13 @@ __export(index_repo_exports, {
719734
720765
  indexRepoCommand: () => indexRepoCommand
719735
720766
  });
719736
720767
  import { resolve as resolve69 } from "node:path";
719737
- import { existsSync as existsSync162, statSync as statSync58 } from "node:fs";
720768
+ import { existsSync as existsSync163, statSync as statSync58 } from "node:fs";
719738
720769
  import { cwd as cwd2 } from "node:process";
719739
720770
  async function indexRepoCommand(opts, _config3) {
719740
720771
  const repoRoot = resolve69(opts.repoPath ?? cwd2());
719741
720772
  printHeader("Index Repository");
719742
720773
  printInfo(`Indexing: ${repoRoot}`);
719743
- if (!existsSync162(repoRoot)) {
720774
+ if (!existsSync163(repoRoot)) {
719744
720775
  printError(`Path does not exist: ${repoRoot}`);
719745
720776
  process.exit(1);
719746
720777
  }
@@ -719992,7 +721023,7 @@ var config_exports2 = {};
719992
721023
  __export(config_exports2, {
719993
721024
  configCommand: () => configCommand
719994
721025
  });
719995
- import { join as join175, resolve as resolve70 } from "node:path";
721026
+ import { join as join176, resolve as resolve70 } from "node:path";
719996
721027
  import { homedir as homedir61 } from "node:os";
719997
721028
  import { cwd as cwd3 } from "node:process";
719998
721029
  function redactIfSensitive(key, value2) {
@@ -720076,7 +721107,7 @@ function handleShow(opts, config) {
720076
721107
  }
720077
721108
  }
720078
721109
  printSection("Config File");
720079
- printInfo(`~/.omnius/config.json (${join175(homedir61(), ".omnius", "config.json")})`);
721110
+ printInfo(`~/.omnius/config.json (${join176(homedir61(), ".omnius", "config.json")})`);
720080
721111
  printSection("Priority Chain");
720081
721112
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
720082
721113
  printInfo(" 2. Project .omnius/settings.json (--local)");
@@ -720115,7 +721146,7 @@ function handleSet(opts, _config3) {
720115
721146
  const coerced = coerceForSettings(key, value2);
720116
721147
  saveProjectSettings(repoRoot, { [key]: coerced });
720117
721148
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value2)}`);
720118
- printInfo(`Saved to ${join175(repoRoot, ".omnius", "settings.json")}`);
721149
+ printInfo(`Saved to ${join176(repoRoot, ".omnius", "settings.json")}`);
720119
721150
  printInfo("This override applies only when running in this workspace.");
720120
721151
  } catch (err) {
720121
721152
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -720302,8 +721333,8 @@ __export(eval_exports, {
720302
721333
  evalCommand: () => evalCommand
720303
721334
  });
720304
721335
  import { tmpdir as tmpdir23 } from "node:os";
720305
- import { mkdirSync as mkdirSync104, writeFileSync as writeFileSync89 } from "node:fs";
720306
- import { join as join176 } from "node:path";
721336
+ import { mkdirSync as mkdirSync105, writeFileSync as writeFileSync90 } from "node:fs";
721337
+ import { join as join177 } from "node:path";
720307
721338
  async function evalCommand(opts, config) {
720308
721339
  const suiteName = opts.suite ?? "basic";
720309
721340
  const suite = SUITES[suiteName];
@@ -720432,10 +721463,10 @@ async function evalCommand(opts, config) {
720432
721463
  process.exit(failed > 0 ? 1 : 0);
720433
721464
  }
720434
721465
  function createTempEvalRepo() {
720435
- const dir = join176(tmpdir23(), `omnius-eval-${Date.now()}`);
720436
- mkdirSync104(dir, { recursive: true });
720437
- writeFileSync89(
720438
- join176(dir, "package.json"),
721466
+ const dir = join177(tmpdir23(), `omnius-eval-${Date.now()}`);
721467
+ mkdirSync105(dir, { recursive: true });
721468
+ writeFileSync90(
721469
+ join177(dir, "package.json"),
720439
721470
  JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
720440
721471
  "utf8"
720441
721472
  );
@@ -720510,7 +721541,7 @@ init_typed_node_events();
720510
721541
  init_dist5();
720511
721542
  import { parseArgs as nodeParseArgs2 } from "node:util";
720512
721543
  import { fileURLToPath as fileURLToPath22 } from "node:url";
720513
- import { dirname as dirname53, join as join177 } from "node:path";
721544
+ import { dirname as dirname53, join as join178 } from "node:path";
720514
721545
  import { createRequire as createRequire10 } from "node:module";
720515
721546
 
720516
721547
  // packages/cli/src/cli.ts
@@ -720658,7 +721689,7 @@ init_output();
720658
721689
  function getVersion5() {
720659
721690
  try {
720660
721691
  const require5 = createRequire10(import.meta.url);
720661
- const pkgPath = join177(dirname53(fileURLToPath22(import.meta.url)), "..", "package.json");
721692
+ const pkgPath = join178(dirname53(fileURLToPath22(import.meta.url)), "..", "package.json");
720662
721693
  const pkg = require5(pkgPath);
720663
721694
  return pkg.version;
720664
721695
  } catch {
@@ -721040,12 +722071,12 @@ function crashLog(label, err) {
721040
722071
  const logLine = `[${timestamp}] ${label}: ${msg}
721041
722072
  `;
721042
722073
  try {
721043
- const { appendFileSync: appendFileSync18, mkdirSync: mkdirSync105 } = __require("node:fs");
721044
- const { join: join178 } = __require("node:path");
722074
+ const { appendFileSync: appendFileSync18, mkdirSync: mkdirSync106 } = __require("node:fs");
722075
+ const { join: join179 } = __require("node:path");
721045
722076
  const { homedir: homedir62 } = __require("node:os");
721046
- const logDir = join178(homedir62(), ".omnius");
721047
- mkdirSync105(logDir, { recursive: true });
721048
- appendFileSync18(join178(logDir, "crash.log"), logLine);
722077
+ const logDir = join179(homedir62(), ".omnius");
722078
+ mkdirSync106(logDir, { recursive: true });
722079
+ appendFileSync18(join179(logDir, "crash.log"), logLine);
721049
722080
  } catch {
721050
722081
  }
721051
722082
  try {