omnius 1.0.199 → 1.0.201

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
@@ -23044,6 +23044,13 @@ function deleteRepoFromCache(repo) {
23044
23044
  }
23045
23045
  return removed;
23046
23046
  }
23047
+ function deleteCachedModel(repo) {
23048
+ const bytesFreed = deleteRepoFromCache(repo);
23049
+ const meta = readMeta();
23050
+ meta.entries = meta.entries.filter((entry) => entry.repo !== repo);
23051
+ writeMeta(meta);
23052
+ return { repo, bytesFreed };
23053
+ }
23047
23054
  function evictModelsToFreeSpace(args) {
23048
23055
  const safetyMargin = args.safetyMarginBytes ?? 1 * 1024 ** 3;
23049
23056
  const target = args.neededBytes + safetyMargin;
@@ -258378,9 +258385,9 @@ print("${sentinel}")
258378
258385
  if (!this.proc || this.proc.killed) {
258379
258386
  return { success: false, path: "" };
258380
258387
  }
258381
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = await import("node:fs");
258388
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
258382
258389
  const sessionDir2 = join36(this.cwd, ".omnius", "rlm");
258383
- mkdirSync88(sessionDir2, { recursive: true });
258390
+ mkdirSync89(sessionDir2, { recursive: true });
258384
258391
  const sessionPath2 = join36(sessionDir2, "session.json");
258385
258392
  try {
258386
258393
  const inspectCode = `
@@ -258404,7 +258411,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
258404
258411
  trajectoryCount: this.trajectory.length,
258405
258412
  subCallCount: this.subCallCount
258406
258413
  };
258407
- writeFileSync79(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
258414
+ writeFileSync80(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
258408
258415
  return { success: true, path: sessionPath2 };
258409
258416
  }
258410
258417
  } catch {
@@ -259013,7 +259020,7 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
259013
259020
  /** Update memory scores based on task outcome. Called after task completion.
259014
259021
  * Memories used in successful tasks get boosted. Memories present during failures get decayed. */
259015
259022
  updateFromOutcomeSync(surfacedMemoryText, succeeded) {
259016
- const { readFileSync: readFileSync117, writeFileSync: writeFileSync79, existsSync: existsSync144, mkdirSync: mkdirSync88 } = __require("node:fs");
259023
+ const { readFileSync: readFileSync117, writeFileSync: writeFileSync80, existsSync: existsSync144, mkdirSync: mkdirSync89 } = __require("node:fs");
259017
259024
  const metaDir = join37(this.cwd, ".omnius", "memory", "metabolism");
259018
259025
  const storeFile = join37(metaDir, "store.json");
259019
259026
  if (!existsSync144(storeFile))
@@ -259044,8 +259051,8 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
259044
259051
  updated = true;
259045
259052
  }
259046
259053
  if (updated) {
259047
- mkdirSync88(metaDir, { recursive: true });
259048
- writeFileSync79(storeFile, JSON.stringify(store2, null, 2));
259054
+ mkdirSync89(metaDir, { recursive: true });
259055
+ writeFileSync80(storeFile, JSON.stringify(store2, null, 2));
259049
259056
  }
259050
259057
  }
259051
259058
  // ── Storage ──────────────────────────────────────────────────────────
@@ -259491,7 +259498,7 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
259491
259498
  }
259492
259499
  /** Archive a strategy variant synchronously (for task completion path) */
259493
259500
  archiveVariantSync(strategy, outcome, tags = []) {
259494
- const { readFileSync: readFileSync117, writeFileSync: writeFileSync79, existsSync: existsSync144, mkdirSync: mkdirSync88 } = __require("node:fs");
259501
+ const { readFileSync: readFileSync117, writeFileSync: writeFileSync80, existsSync: existsSync144, mkdirSync: mkdirSync89 } = __require("node:fs");
259495
259502
  const dir = join39(this.cwd, ".omnius", "arche");
259496
259503
  const archiveFile = join39(dir, "variants.json");
259497
259504
  let variants = [];
@@ -259512,8 +259519,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
259512
259519
  });
259513
259520
  if (variants.length > 50)
259514
259521
  variants = variants.slice(-50);
259515
- mkdirSync88(dir, { recursive: true });
259516
- writeFileSync79(archiveFile, JSON.stringify(variants, null, 2));
259522
+ mkdirSync89(dir, { recursive: true });
259523
+ writeFileSync80(archiveFile, JSON.stringify(variants, null, 2));
259517
259524
  }
259518
259525
  async saveArchive(variants) {
259519
259526
  const dir = join39(this.cwd, ".omnius", "arche");
@@ -534863,6 +534870,7 @@ __export(dist_exports, {
534863
534870
  createWorktree: () => createWorktree2,
534864
534871
  defaultExposureForTool: () => defaultExposureForTool,
534865
534872
  defaultExtensionForMime: () => defaultExtensionForMime,
534873
+ deleteCachedModel: () => deleteCachedModel,
534866
534874
  deleteMediaModelAdapter: () => deleteMediaModelAdapter,
534867
534875
  deleteTodos: () => deleteTodos,
534868
534876
  detectCudaDevices: () => detectCudaDevices,
@@ -550158,12 +550166,12 @@ var init_reflectionBuffer = __esm({
550158
550166
  if (!this.persistPath)
550159
550167
  return;
550160
550168
  try {
550161
- const { writeFileSync: writeFileSync79, mkdirSync: mkdirSync88, existsSync: existsSync144 } = __require("node:fs");
550169
+ const { writeFileSync: writeFileSync80, mkdirSync: mkdirSync89, existsSync: existsSync144 } = __require("node:fs");
550162
550170
  const { join: join160 } = __require("node:path");
550163
550171
  const dir = join160(this.persistPath, "..");
550164
550172
  if (!existsSync144(dir))
550165
- mkdirSync88(dir, { recursive: true });
550166
- writeFileSync79(this.persistPath, JSON.stringify(this.state, null, 2));
550173
+ mkdirSync89(dir, { recursive: true });
550174
+ writeFileSync80(this.persistPath, JSON.stringify(this.state, null, 2));
550167
550175
  } catch {
550168
550176
  }
550169
550177
  }
@@ -550377,15 +550385,17 @@ function loadMessagePairsFromLog(omniusDir, opts) {
550377
550385
  const now = Date.now();
550378
550386
  const norm = (s2) => s2.toLowerCase().replace(/\s+/g, " ").replace(/[.!?,;:]+$/g, "").trim();
550379
550387
  const taskNorm = norm(opts.currentTask.slice(0, 500));
550388
+ const eligible = records.filter((rec) => now - rec.recordedAt <= ttl && norm(rec.handoff.priorGoal) !== taskNorm);
550389
+ const signature = (rec) => `${norm(rec.handoff.priorGoal)}|${[...rec.handoff.filesTouched].sort().join(",")}`;
550390
+ const lastIndexBySig = /* @__PURE__ */ new Map();
550391
+ eligible.forEach((rec, i2) => lastIndexBySig.set(signature(rec), i2));
550380
550392
  const out = [];
550381
- for (const rec of records) {
550382
- if (now - rec.recordedAt > ttl)
550383
- continue;
550384
- if (norm(rec.handoff.priorGoal) === taskNorm)
550385
- continue;
550393
+ eligible.forEach((rec, i2) => {
550394
+ if (lastIndexBySig.get(signature(rec)) !== i2)
550395
+ return;
550386
550396
  const pair = buildHandoffMessagePair(rec.handoff);
550387
550397
  out.push(pair[0], pair[1]);
550388
- }
550398
+ });
550389
550399
  return out;
550390
550400
  }
550391
550401
  function trimLog(omniusDir) {
@@ -554695,7 +554705,8 @@ var init_agenticRunner = __esm({
554695
554705
  // Phase 4 — sub-agent isolation flag (defaults false). When true, this
554696
554706
  // runner skips cross-task handoff inheritance from the parent's
554697
554707
  // session.
554698
- subAgent: options2?.subAgent ?? false
554708
+ subAgent: options2?.subAgent ?? false,
554709
+ skipCrossTaskHandoff: options2?.skipCrossTaskHandoff ?? false
554699
554710
  };
554700
554711
  this._observerMode = this.options.observerMode;
554701
554712
  }
@@ -558451,6 +558462,10 @@ TASK: ${scrubbedTask}` : scrubbedTask;
558451
558462
  try {
558452
558463
  if (this.options.subAgent)
558453
558464
  throw "skip-handoff-subagent";
558465
+ if (this.options.skipCrossTaskHandoff)
558466
+ throw "skip-handoff-caller-optout";
558467
+ if (/<task-handoff>|<session-recap>/.test(task))
558468
+ throw "skip-handoff-restore-supplied";
558454
558469
  if (process.env["OMNIUS_FRESH_SESSION"] === "1")
558455
558470
  throw "skip-handoff-fresh";
558456
558471
  const omniusDir = this._workingDirectory ? _pathJoin(this._workingDirectory, ".omnius") : _pathJoin(process.cwd(), ".omnius");
@@ -563799,10 +563814,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
563799
563814
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
563800
563815
  });
563801
563816
  try {
563802
- const { mkdirSync: mkdirSync88, readdirSync: readdirSync53, statSync: statSync53, unlinkSync: unlinkSync31, writeFileSync: writeFileSync79 } = __require("node:fs");
563817
+ const { mkdirSync: mkdirSync89, readdirSync: readdirSync53, statSync: statSync53, unlinkSync: unlinkSync31, writeFileSync: writeFileSync80 } = __require("node:fs");
563803
563818
  const { join: join160 } = __require("node:path");
563804
563819
  const contextDir = join160(this._workingDirectory || process.cwd(), ".omnius", "context");
563805
- mkdirSync88(contextDir, { recursive: true });
563820
+ mkdirSync89(contextDir, { recursive: true });
563806
563821
  const topEntities = this._temporalGraph.nodesByType("entity", 3);
563807
563822
  const topFiles = this._temporalGraph.nodesByType("file", 3);
563808
563823
  const topConcepts = this._temporalGraph.nodesByType("concept", 3);
@@ -563843,17 +563858,17 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
563843
563858
  section("Top Concepts", topConcepts);
563844
563859
  lines.push("(Use file_read on this file for quick recall. See provenance JSON for full edge detail.)");
563845
563860
  const kgSummaryDir = join160(contextDir, "kg-summary");
563846
- mkdirSync88(kgSummaryDir, { recursive: true });
563861
+ mkdirSync89(kgSummaryDir, { recursive: true });
563847
563862
  const summaryFilename = `kg-summary-${this._sessionId}.md`;
563848
563863
  const outPath = join160(kgSummaryDir, summaryFilename);
563849
- writeFileSync79(outPath, lines.join("\n"), "utf-8");
563850
- writeFileSync79(join160(kgSummaryDir, "latest.md"), lines.join("\n"), "utf-8");
563851
- writeFileSync79(join160(contextDir, `kg-summary-latest.md`), [
563864
+ writeFileSync80(outPath, lines.join("\n"), "utf-8");
563865
+ writeFileSync80(join160(kgSummaryDir, "latest.md"), lines.join("\n"), "utf-8");
563866
+ writeFileSync80(join160(contextDir, `kg-summary-latest.md`), [
563852
563867
  "Latest KG summary moved to `.omnius/context/kg-summary/latest.md`.",
563853
563868
  "",
563854
563869
  lines.join("\n")
563855
563870
  ].join("\n"), "utf-8");
563856
- writeFileSync79(join160(kgSummaryDir, "index.json"), JSON.stringify({
563871
+ writeFileSync80(join160(kgSummaryDir, "index.json"), JSON.stringify({
563857
563872
  schema: "omnius.kg-summary-index.v1",
563858
563873
  latest: "latest.md",
563859
563874
  latestSessionFile: summaryFilename,
@@ -564143,11 +564158,11 @@ ${errOutput}`);
564143
564158
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
564144
564159
  });
564145
564160
  try {
564146
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = __require("node:fs");
564161
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = __require("node:fs");
564147
564162
  const { join: join160 } = __require("node:path");
564148
564163
  const resultsDir = join160(this.omniusStateDir(), "tool-results");
564149
- mkdirSync88(resultsDir, { recursive: true });
564150
- writeFileSync79(join160(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
564164
+ mkdirSync89(resultsDir, { recursive: true });
564165
+ writeFileSync80(join160(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
564151
564166
  # Turn: ${turn}
564152
564167
  # Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
564153
564168
  # Size: ${result.output.length} chars, ${lineCount} lines
@@ -564540,10 +564555,10 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
564540
564555
  if (!this._workingDirectory)
564541
564556
  return;
564542
564557
  try {
564543
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = __require("node:fs");
564558
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = __require("node:fs");
564544
564559
  const { join: join160 } = __require("node:path");
564545
564560
  const sessionDir2 = this.options.stateDir ? join160(this.omniusStateDir(), "session", this._sessionId) : join160(this._workingDirectory, ".omnius", "session", this._sessionId);
564546
- mkdirSync88(sessionDir2, { recursive: true });
564561
+ mkdirSync89(sessionDir2, { recursive: true });
564547
564562
  const checkpoint = {
564548
564563
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
564549
564564
  sessionId: this._sessionId,
@@ -564555,7 +564570,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
564555
564570
  memexEntryCount: this._memexArchive.size,
564556
564571
  fileRegistrySize: this._fileRegistry.size
564557
564572
  };
564558
- writeFileSync79(join160(sessionDir2, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
564573
+ writeFileSync80(join160(sessionDir2, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
564559
564574
  } catch {
564560
564575
  }
564561
564576
  }
@@ -566968,12 +566983,12 @@ ${result}`
566968
566983
  let resizedBase64 = null;
566969
566984
  try {
566970
566985
  const { execSync: execSync62 } = await import("node:child_process");
566971
- const { writeFileSync: writeFileSync79, readFileSync: readFileSync117, unlinkSync: unlinkSync31 } = await import("node:fs");
566986
+ const { writeFileSync: writeFileSync80, readFileSync: readFileSync117, unlinkSync: unlinkSync31 } = await import("node:fs");
566972
566987
  const { join: join160 } = await import("node:path");
566973
566988
  const { tmpdir: tmpdir23 } = await import("node:os");
566974
566989
  const tmpIn = join160(tmpdir23(), `omnius_img_in_${Date.now()}.png`);
566975
566990
  const tmpOut = join160(tmpdir23(), `omnius_img_out_${Date.now()}.jpg`);
566976
- writeFileSync79(tmpIn, buffer2);
566991
+ writeFileSync80(tmpIn, buffer2);
566977
566992
  const pyBin = process.platform === "win32" ? "python" : "python3";
566978
566993
  const escapedIn = tmpIn.replace(/\\/g, "\\\\");
566979
566994
  const escapedOut = tmpOut.replace(/\\/g, "\\\\");
@@ -609728,13 +609743,13 @@ async function handleSlashCommand(input, ctx3) {
609728
609743
  try {
609729
609744
  const { randomBytes: randomBytes29 } = await import("node:crypto");
609730
609745
  const { homedir: homedir56 } = await import("node:os");
609731
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = await import("node:fs");
609746
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
609732
609747
  const { join: join160 } = await import("node:path");
609733
609748
  const newKey = randomBytes29(16).toString("hex");
609734
609749
  process.env["OMNIUS_API_KEY"] = newKey;
609735
609750
  const dir = join160(homedir56(), ".omnius");
609736
- mkdirSync88(dir, { recursive: true });
609737
- writeFileSync79(join160(dir, "api.key"), newKey + "\n", "utf8");
609751
+ mkdirSync89(dir, { recursive: true });
609752
+ writeFileSync80(join160(dir, "api.key"), newKey + "\n", "utf8");
609738
609753
  renderInfo(`New API key: ${c3.bold(c3.yellow(newKey))}`);
609739
609754
  renderInfo(
609740
609755
  "Restart the daemon to apply if needed. Use /access any to restart quickly."
@@ -609999,11 +610014,11 @@ async function handleSlashCommand(input, ctx3) {
609999
610014
  );
610000
610015
  try {
610001
610016
  const { homedir: homedir57 } = await import("node:os");
610002
- const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
610017
+ const { mkdirSync: mkdirSync90, writeFileSync: writeFileSync81 } = await import("node:fs");
610003
610018
  const { join: join161 } = await import("node:path");
610004
610019
  const dir = join161(homedir57(), ".omnius");
610005
- mkdirSync89(dir, { recursive: true });
610006
- writeFileSync80(join161(dir, "api.key"), apiKey + "\n", "utf8");
610020
+ mkdirSync90(dir, { recursive: true });
610021
+ writeFileSync81(join161(dir, "api.key"), apiKey + "\n", "utf8");
610007
610022
  } catch {
610008
610023
  }
610009
610024
  }
@@ -610015,11 +610030,11 @@ async function handleSlashCommand(input, ctx3) {
610015
610030
  const port2 = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
610016
610031
  try {
610017
610032
  const { homedir: homedir57 } = await import("node:os");
610018
- const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
610033
+ const { mkdirSync: mkdirSync90, writeFileSync: writeFileSync81 } = await import("node:fs");
610019
610034
  const { join: join161 } = await import("node:path");
610020
610035
  const dir = join161(homedir57(), ".omnius");
610021
- mkdirSync89(dir, { recursive: true });
610022
- writeFileSync80(join161(dir, "access"), `${val2}
610036
+ mkdirSync90(dir, { recursive: true });
610037
+ writeFileSync81(join161(dir, "access"), `${val2}
610023
610038
  `, "utf8");
610024
610039
  } catch {
610025
610040
  }
@@ -610119,11 +610134,11 @@ async function handleSlashCommand(input, ctx3) {
610119
610134
  );
610120
610135
  try {
610121
610136
  const { homedir: homedir57 } = await import("node:os");
610122
- const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
610137
+ const { mkdirSync: mkdirSync90, writeFileSync: writeFileSync81 } = await import("node:fs");
610123
610138
  const { join: join161 } = await import("node:path");
610124
610139
  const dir = join161(homedir57(), ".omnius");
610125
- mkdirSync89(dir, { recursive: true });
610126
- writeFileSync80(join161(dir, "api.key"), apiKey + "\n", "utf8");
610140
+ mkdirSync90(dir, { recursive: true });
610141
+ writeFileSync81(join161(dir, "api.key"), apiKey + "\n", "utf8");
610127
610142
  } catch {
610128
610143
  }
610129
610144
  }
@@ -610134,12 +610149,12 @@ async function handleSlashCommand(input, ctx3) {
610134
610149
  }
610135
610150
  const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
610136
610151
  const { homedir: homedir56 } = await import("node:os");
610137
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = await import("node:fs");
610152
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
610138
610153
  const { join: join160 } = await import("node:path");
610139
610154
  try {
610140
610155
  const dir = join160(homedir56(), ".omnius");
610141
- mkdirSync88(dir, { recursive: true });
610142
- writeFileSync79(join160(dir, "access"), `${val}
610156
+ mkdirSync89(dir, { recursive: true });
610157
+ writeFileSync80(join160(dir, "access"), `${val}
610143
610158
  `, "utf8");
610144
610159
  } catch (e2) {
610145
610160
  renderWarning(
@@ -618103,7 +618118,7 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
618103
618118
  const { basename: basename38, join: pathJoin } = await import("node:path");
618104
618119
  const {
618105
618120
  copyFileSync: copyFileSync5,
618106
- mkdirSync: mkdirSync88,
618121
+ mkdirSync: mkdirSync89,
618107
618122
  existsSync: exists2
618108
618123
  } = await import("node:fs");
618109
618124
  const { homedir: homedir56 } = await import("node:os");
@@ -618118,7 +618133,7 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
618118
618133
  "models",
618119
618134
  modelName
618120
618135
  );
618121
- if (!exists2(destDir)) mkdirSync88(destDir, { recursive: true });
618136
+ if (!exists2(destDir)) mkdirSync89(destDir, { recursive: true });
618122
618137
  copyFileSync5(onnxDrop.path, pathJoin(destDir, "model.onnx"));
618123
618138
  copyFileSync5(jsonDrop.path, pathJoin(destDir, "config.json"));
618124
618139
  const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
@@ -619589,13 +619604,13 @@ async function handleSponsoredEndpoint(ctx3, local) {
619589
619604
  sponsors.push(...verified);
619590
619605
  if (verified.length > 0) {
619591
619606
  try {
619592
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = __require("node:fs");
619593
- mkdirSync88(sponsorDir2, { recursive: true });
619607
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = __require("node:fs");
619608
+ mkdirSync89(sponsorDir2, { recursive: true });
619594
619609
  const cached = verified.map((s2) => ({
619595
619610
  ...s2,
619596
619611
  lastVerified: Date.now()
619597
619612
  }));
619598
- writeFileSync79(knownFile, JSON.stringify(cached, null, 2));
619613
+ writeFileSync80(knownFile, JSON.stringify(cached, null, 2));
619599
619614
  } catch {
619600
619615
  }
619601
619616
  }
@@ -619799,7 +619814,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
619799
619814
  }
619800
619815
  if (models.length > 0) {
619801
619816
  try {
619802
- const { writeFileSync: writeFileSync79, mkdirSync: mkdirSync88 } = await import("node:fs");
619817
+ const { writeFileSync: writeFileSync80, mkdirSync: mkdirSync89 } = await import("node:fs");
619803
619818
  const { join: join160, dirname: dirname46 } = await import("node:path");
619804
619819
  const cachePath = join160(
619805
619820
  ctx3.repoRoot || process.cwd(),
@@ -619807,8 +619822,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
619807
619822
  "nexus",
619808
619823
  "peer-models-cache.json"
619809
619824
  );
619810
- mkdirSync88(dirname46(cachePath), { recursive: true });
619811
- writeFileSync79(
619825
+ mkdirSync89(dirname46(cachePath), { recursive: true });
619826
+ writeFileSync80(
619812
619827
  cachePath,
619813
619828
  JSON.stringify(
619814
619829
  {
@@ -619880,7 +619895,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
619880
619895
  }));
619881
619896
  renderWarning("Live model probe failed; using sponsor directory model advertisement.");
619882
619897
  try {
619883
- const { writeFileSync: writeFileSync79, mkdirSync: mkdirSync88 } = await import("node:fs");
619898
+ const { writeFileSync: writeFileSync80, mkdirSync: mkdirSync89 } = await import("node:fs");
619884
619899
  const { join: join160, dirname: dirname46 } = await import("node:path");
619885
619900
  const cachePath = join160(
619886
619901
  ctx3.repoRoot || process.cwd(),
@@ -619888,8 +619903,8 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
619888
619903
  "nexus",
619889
619904
  "peer-models-cache.json"
619890
619905
  );
619891
- mkdirSync88(dirname46(cachePath), { recursive: true });
619892
- writeFileSync79(
619906
+ mkdirSync89(dirname46(cachePath), { recursive: true });
619907
+ writeFileSync80(
619893
619908
  cachePath,
619894
619909
  JSON.stringify({
619895
619910
  peerId,
@@ -622491,13 +622506,13 @@ var init_commands = __esm({
622491
622506
  try {
622492
622507
  const { randomBytes: randomBytes29 } = await import("node:crypto");
622493
622508
  const { homedir: homedir56 } = await import("node:os");
622494
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = await import("node:fs");
622509
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
622495
622510
  const { join: join160 } = await import("node:path");
622496
622511
  const apiKey = randomBytes29(16).toString("hex");
622497
622512
  process.env["OMNIUS_API_KEY"] = apiKey;
622498
622513
  const dir = join160(homedir56(), ".omnius");
622499
- mkdirSync88(dir, { recursive: true });
622500
- writeFileSync79(join160(dir, "api.key"), apiKey + "\n", "utf8");
622514
+ mkdirSync89(dir, { recursive: true });
622515
+ writeFileSync80(join160(dir, "api.key"), apiKey + "\n", "utf8");
622501
622516
  renderInfo(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
622502
622517
  renderInfo(
622503
622518
  "Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it."
@@ -622516,11 +622531,11 @@ var init_commands = __esm({
622516
622531
  const port = parseInt(process.env["OMNIUS_PORT"] || "11435", 10);
622517
622532
  try {
622518
622533
  const { homedir: homedir56 } = await import("node:os");
622519
- const { mkdirSync: mkdirSync88, writeFileSync: writeFileSync79 } = await import("node:fs");
622534
+ const { mkdirSync: mkdirSync89, writeFileSync: writeFileSync80 } = await import("node:fs");
622520
622535
  const { join: join160 } = await import("node:path");
622521
622536
  const dir = join160(homedir56(), ".omnius");
622522
- mkdirSync88(dir, { recursive: true });
622523
- writeFileSync79(join160(dir, "access"), `${val}
622537
+ mkdirSync89(dir, { recursive: true });
622538
+ writeFileSync80(join160(dir, "access"), `${val}
622524
622539
  `, "utf8");
622525
622540
  } catch {
622526
622541
  }
@@ -622811,22 +622826,47 @@ function loadMemoryContext(repoRoot) {
622811
622826
  }
622812
622827
  const buckets = /* @__PURE__ */ new Map();
622813
622828
  for (const e2 of deduped) {
622814
- const key = `${e2.scope}/${e2.topic}`;
622815
- const arr = buckets.get(key) ?? [];
622816
- arr.push(e2);
622817
- buckets.set(key, arr);
622829
+ const family = topicFamily(e2.topic);
622830
+ const bucketKey = `${e2.scope}/${family}`;
622831
+ const bucket = buckets.get(bucketKey) ?? { family, multiTopic: false, entries: [] };
622832
+ if (bucket.entries.length > 0 && bucket.entries[0].topic !== e2.topic) bucket.multiTopic = true;
622833
+ bucket.entries.push(e2);
622834
+ buckets.set(bucketKey, bucket);
622818
622835
  }
622819
622836
  const lines = [];
622820
- for (const [bucketKey, entries] of buckets) {
622821
- const sorted = entries.sort((a2, b) => b.ts.localeCompare(a2.ts)).slice(0, 5);
622822
- if (sorted.length === 0) continue;
622823
- lines.push(`[${bucketKey}]`);
622837
+ for (const [bucketKey, bucket] of buckets) {
622838
+ const sorted = bucket.entries.sort((a2, b) => b.ts.localeCompare(a2.ts));
622839
+ const seenValues = /* @__PURE__ */ new Set();
622840
+ const kept = [];
622824
622841
  for (const e2 of sorted) {
622825
- lines.push(` ${e2.key}: ${truncateProjectContextText(e2.value, 200, "")}`);
622842
+ const sig = normalizeValueSignature(e2.value);
622843
+ if (seenValues.has(sig)) continue;
622844
+ seenValues.add(sig);
622845
+ kept.push(e2);
622846
+ if (kept.length >= 5) break;
622847
+ }
622848
+ if (kept.length === 0) continue;
622849
+ const dropped = bucket.entries.length - kept.length;
622850
+ const header = bucket.multiTopic ? `[${bucketKey}* (${bucket.entries.length} entries in series${dropped > 0 ? `, ${dropped} redundant collapsed` : ""})]` : `[${bucketKey}]`;
622851
+ lines.push(header);
622852
+ for (const e2 of kept) {
622853
+ const label = bucket.multiTopic ? `${e2.topic}.${e2.key}` : e2.key;
622854
+ lines.push(` ${label}: ${truncateProjectContextText(trimMemoryValueMetadata(e2.value), 200, "")}`);
622826
622855
  }
622827
622856
  }
622828
622857
  return lines.join("\n");
622829
622858
  }
622859
+ function topicFamily(topic) {
622860
+ const m2 = topic.match(/^(.*?)[_-]?\d+$/);
622861
+ if (!m2 || !m2[1]) return topic;
622862
+ return m2[1].length >= 3 ? m2[1] : topic;
622863
+ }
622864
+ function normalizeValueSignature(value2) {
622865
+ return value2.toLowerCase().replace(/\d+(\.\d+)?/g, "#").replace(/\s+/g, " ").trim().slice(0, 160);
622866
+ }
622867
+ function trimMemoryValueMetadata(value2) {
622868
+ return value2.replace(/\b(?:confidence|weight|salience|score|noise_score|relevance)\s*[=:]\s*\d*\.?\d+\b/gi, "").replace(/\b(?:evidence|sources?|refs?)\s*[=:]\s*[\d,\s]+\b/gi, "").replace(/\bvalue_?hash\s*[=:]\s*[0-9a-f]{8,}\b/gi, "").replace(/[ \t]{2,}/g, " ").replace(/\s+([,.;])/g, "$1").trim();
622869
+ }
622830
622870
  function loadSessionHistory2(repoRoot) {
622831
622871
  const sessions3 = loadRecentSessions(repoRoot, 5);
622832
622872
  const lines = ["Recent tasks in this project:"];
@@ -626226,18 +626266,471 @@ var init_edit_history = __esm({
626226
626266
  }
626227
626267
  });
626228
626268
 
626269
+ // packages/cli/src/tui/snr-engine.ts
626270
+ import { existsSync as existsSync120, readdirSync as readdirSync42, readFileSync as readFileSync96, writeFileSync as writeFileSync61, mkdirSync as mkdirSync69, rmSync as rmSync7 } from "node:fs";
626271
+ import { join as join133, basename as basename31 } from "node:path";
626272
+ function computeDPrime(signalScores, noiseScores) {
626273
+ if (signalScores.length === 0 || noiseScores.length === 0) return 0;
626274
+ const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
626275
+ const variance = (arr, mu) => arr.reduce((s2, v) => s2 + (v - mu) ** 2, 0) / Math.max(1, arr.length - 1);
626276
+ const muSignal = mean(signalScores);
626277
+ const muNoise = mean(noiseScores);
626278
+ const varSignal = variance(signalScores, muSignal);
626279
+ const varNoise = variance(noiseScores, muNoise);
626280
+ const pooledStd = Math.sqrt((varSignal + varNoise) / 2);
626281
+ if (pooledStd === 0) return muSignal > muNoise ? 3 : 0;
626282
+ return (muSignal - muNoise) / pooledStd;
626283
+ }
626284
+ function computeSparsity(entries) {
626285
+ if (entries.length <= 1) return 1;
626286
+ const ngramSets = entries.map((e2) => {
626287
+ const words = e2.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
626288
+ const ngrams = /* @__PURE__ */ new Set();
626289
+ for (let i2 = 0; i2 < words.length - 1; i2++) {
626290
+ ngrams.add(`${words[i2]} ${words[i2 + 1]}`);
626291
+ }
626292
+ return ngrams;
626293
+ });
626294
+ let totalPairs = 0;
626295
+ let totalJaccard = 0;
626296
+ for (let i2 = 0; i2 < ngramSets.length; i2++) {
626297
+ for (let j = i2 + 1; j < ngramSets.length; j++) {
626298
+ const a2 = ngramSets[i2];
626299
+ const b = ngramSets[j];
626300
+ if (a2.size === 0 && b.size === 0) continue;
626301
+ const intersection = new Set([...a2].filter((x) => b.has(x)));
626302
+ const union = /* @__PURE__ */ new Set([...a2, ...b]);
626303
+ totalJaccard += union.size > 0 ? intersection.size / union.size : 0;
626304
+ totalPairs++;
626305
+ }
626306
+ }
626307
+ if (totalPairs === 0) return 1;
626308
+ const avgOverlap = totalJaccard / totalPairs;
626309
+ return Math.max(0, Math.min(1, 1 - avgOverlap));
626310
+ }
626311
+ function adaptTool2(tool) {
626312
+ return {
626313
+ name: tool.name,
626314
+ description: tool.description,
626315
+ parameters: tool.parameters,
626316
+ async execute(args) {
626317
+ const result = await tool.execute(args);
626318
+ return { success: result.success, output: result.output, error: result.error };
626319
+ }
626320
+ };
626321
+ }
626322
+ var SNREngine;
626323
+ var init_snr_engine = __esm({
626324
+ "packages/cli/src/tui/snr-engine.ts"() {
626325
+ "use strict";
626326
+ init_dist8();
626327
+ init_dist5();
626328
+ init_project_context();
626329
+ init_render();
626330
+ SNREngine = class {
626331
+ constructor(config, repoRoot) {
626332
+ this.config = config;
626333
+ this.repoRoot = repoRoot;
626334
+ }
626335
+ config;
626336
+ repoRoot;
626337
+ lastScore = null;
626338
+ evaluationCount = 0;
626339
+ get score() {
626340
+ return this.lastScore;
626341
+ }
626342
+ /**
626343
+ * Quick local-only SNR estimation (no LLM calls, fast).
626344
+ * @param contextSlots — total context window tokens (for Hopfield capacity warning)
626345
+ */
626346
+ computeLocalSNR(currentTask, contextEntries, contextSlots) {
626347
+ if (contextEntries.length === 0) {
626348
+ return this.makeScore(1, 3, 0, 0, 0, 1, ["local-empty"]);
626349
+ }
626350
+ const taskTerms = new Set(
626351
+ currentTask.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""))
626352
+ );
626353
+ const scores = contextEntries.map((entry) => {
626354
+ const entryTerms = entry.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""));
626355
+ const matchCount = entryTerms.filter((t2) => taskTerms.has(t2)).length;
626356
+ const score2 = entryTerms.length > 0 ? matchCount / Math.sqrt(entryTerms.length) : 0;
626357
+ return { entry, score: score2 };
626358
+ });
626359
+ const allScores = scores.map((s2) => s2.score);
626360
+ const mean = allScores.reduce((a2, b) => a2 + b, 0) / allScores.length;
626361
+ const std = Math.sqrt(allScores.reduce((a2, v) => a2 + (v - mean) ** 2, 0) / allScores.length);
626362
+ const threshold = mean + 0.5 * std;
626363
+ const signalScores = allScores.filter((s2) => s2 >= threshold);
626364
+ const noiseScores = allScores.filter((s2) => s2 < threshold);
626365
+ const dPrime = computeDPrime(
626366
+ signalScores.length > 0 ? signalScores : [mean],
626367
+ noiseScores.length > 0 ? noiseScores : [0]
626368
+ );
626369
+ const sparsity = computeSparsity(contextEntries);
626370
+ const signalProportion = signalScores.length / allScores.length;
626371
+ const dPrimeNorm = Math.min(1, Math.max(0, dPrime / 3));
626372
+ const ratio = 0.5 * signalProportion + 0.3 * dPrimeNorm + 0.2 * sparsity;
626373
+ const capacityWarning = contextSlots ? contextEntries.length > Math.floor(contextSlots * 0.138) : false;
626374
+ const score = this.makeScore(
626375
+ ratio,
626376
+ dPrime,
626377
+ contextEntries.length,
626378
+ signalScores.length,
626379
+ noiseScores.length,
626380
+ sparsity,
626381
+ ["local-keyword"],
626382
+ capacityWarning
626383
+ );
626384
+ this.lastScore = score;
626385
+ this.evaluationCount++;
626386
+ return score;
626387
+ }
626388
+ /**
626389
+ * Full SNR evaluation using parallel LLM evaluator agents.
626390
+ * Mirrors PFC gating + multi-agent debate (Du et al. 2023).
626391
+ *
626392
+ * Spawns 2 lightweight agents with different evaluation perspectives:
626393
+ * - "Relevance Evaluator" — scores entries by task relevance (PFC role)
626394
+ * - "Noise Detector" — identifies redundant/stale/irrelevant entries (DG role)
626395
+ *
626396
+ * Their consensus determines the final SNR.
626397
+ */
626398
+ async evaluateWithAgents(currentTask, memoryTopics, onEvent) {
626399
+ const entries = this.loadMemoryEntries(memoryTopics);
626400
+ if (entries.length === 0) {
626401
+ const score2 = this.makeScore(1, 3, 0, 0, 0, 1, ["agents-empty"]);
626402
+ this.lastScore = score2;
626403
+ return score2;
626404
+ }
626405
+ const entrySummaries = entries.map(
626406
+ (e2, i2) => `[${i2}] topic=${e2.topic} key=${e2.key}: ${e2.value.slice(0, 200)}${e2.value.length > 200 ? "..." : ""}`
626407
+ );
626408
+ const entriesBlock = entrySummaries.join("\n");
626409
+ const [relevanceResult, noiseResult] = await Promise.allSettled([
626410
+ this.runEvaluatorAgent(
626411
+ "relevance",
626412
+ `You are a Prefrontal Cortex Gating Evaluator. Your role is to assess which
626413
+ memory entries are RELEVANT to the current task.
626414
+
626415
+ CURRENT TASK: ${currentTask}
626416
+
626417
+ MEMORY ENTRIES TO EVALUATE:
626418
+ ${entriesBlock}
626419
+
626420
+ For each entry, output a JSON array of objects:
626421
+ [{"index": 0, "score": 0.8, "reason": "directly related to task"}, ...]
626422
+
626423
+ Score 0-1 where:
626424
+ - 1.0 = directly relevant to the current task
626425
+ - 0.7 = supporting context (useful background)
626426
+ - 0.4 = marginally relevant
626427
+ - 0.1 = not relevant to current task
626428
+
626429
+ Call task_complete with the JSON array when done.`,
626430
+ onEvent
626431
+ ),
626432
+ this.runEvaluatorAgent(
626433
+ "noise",
626434
+ `You are a Dentate Gyrus Pattern Separation Evaluator. Your role is to identify
626435
+ NOISE in the memory context — entries that are redundant, stale, or interfering.
626436
+
626437
+ CURRENT TASK: ${currentTask}
626438
+
626439
+ MEMORY ENTRIES TO EVALUATE:
626440
+ ${entriesBlock}
626441
+
626442
+ For each entry, output a JSON array of objects:
626443
+ [{"index": 0, "noise_score": 0.2, "reason": "unique, not redundant"}, ...]
626444
+
626445
+ Noise score 0-1 where:
626446
+ - 1.0 = pure noise (completely redundant, stale, or interfering with task)
626447
+ - 0.7 = mostly noise (outdated or largely redundant with another entry)
626448
+ - 0.4 = moderate noise (some overlap with other entries)
626449
+ - 0.1 = clean signal (unique, fresh, non-interfering)
626450
+
626451
+ Look for: duplicate information, outdated facts, entries that contradict
626452
+ newer entries, entries about completely unrelated topics.
626453
+
626454
+ Call task_complete with the JSON array when done.`,
626455
+ onEvent
626456
+ )
626457
+ ]);
626458
+ const relevanceScores = this.parseEvaluatorResult(
626459
+ relevanceResult.status === "fulfilled" ? relevanceResult.value : "",
626460
+ entries.length,
626461
+ 0.5
626462
+ // default relevance
626463
+ );
626464
+ const noiseScores = this.parseEvaluatorResult(
626465
+ noiseResult.status === "fulfilled" ? noiseResult.value : "",
626466
+ entries.length,
626467
+ 0.5
626468
+ // default noise
626469
+ );
626470
+ const combinedScores = entries.map((_, i2) => {
626471
+ const rel = relevanceScores[i2] ?? 0.5;
626472
+ const noise2 = noiseScores[i2] ?? 0.5;
626473
+ const votes = [rel, 1 - noise2].sort((a2, b) => a2 - b);
626474
+ return (votes[0] + votes[1]) / 2;
626475
+ });
626476
+ const mean = combinedScores.reduce((a2, b) => a2 + b, 0) / combinedScores.length;
626477
+ const std = Math.sqrt(combinedScores.reduce((a2, v) => a2 + (v - mean) ** 2, 0) / combinedScores.length);
626478
+ const threshold = Math.max(0.3, mean);
626479
+ const signalEntries = combinedScores.filter((s2) => s2 >= threshold);
626480
+ const noiseEntries = combinedScores.filter((s2) => s2 < threshold);
626481
+ const dPrime = computeDPrime(
626482
+ signalEntries.length > 0 ? signalEntries : [mean],
626483
+ noiseEntries.length > 0 ? noiseEntries : [0.1]
626484
+ );
626485
+ const sparsity = computeSparsity(entries.map((e2) => e2.value));
626486
+ const signalProportion = signalEntries.length / combinedScores.length;
626487
+ const dPrimeNorm = Math.min(1, Math.max(0, dPrime / 3));
626488
+ const ratio = 0.5 * signalProportion + 0.3 * dPrimeNorm + 0.2 * sparsity;
626489
+ const evaluators = [
626490
+ relevanceResult.status === "fulfilled" ? "relevance-agent" : "relevance-failed",
626491
+ noiseResult.status === "fulfilled" ? "noise-agent" : "noise-failed"
626492
+ ];
626493
+ const score = this.makeScore(
626494
+ ratio,
626495
+ dPrime,
626496
+ entries.length,
626497
+ signalEntries.length,
626498
+ noiseEntries.length,
626499
+ sparsity,
626500
+ evaluators
626501
+ );
626502
+ this.lastScore = score;
626503
+ this.evaluationCount++;
626504
+ return score;
626505
+ }
626506
+ // ── Evaluator agent ──────────────────────────────────────────────────
626507
+ async runEvaluatorAgent(name10, prompt, onEvent) {
626508
+ const backend = new OllamaAgenticBackend(
626509
+ this.config.backendUrl,
626510
+ this.config.model,
626511
+ this.config.apiKey
626512
+ );
626513
+ const modelTier = getModelTier(this.config.model);
626514
+ const runner = new AgenticRunner(backend, {
626515
+ maxTurns: 5,
626516
+ // Evaluators are very focused — 5 turns max
626517
+ maxTokens: 4096,
626518
+ temperature: 0,
626519
+ // Deterministic scoring
626520
+ requestTimeoutMs: this.config.timeoutMs,
626521
+ taskTimeoutMs: this.config.timeoutMs,
626522
+ compactionThreshold: modelTier === "small" ? 8e3 : 16e3,
626523
+ modelTier
626524
+ });
626525
+ const tools = [
626526
+ new MemoryReadTool(this.repoRoot),
626527
+ new MemorySearchTool(this.repoRoot)
626528
+ ];
626529
+ runner.registerTools([
626530
+ ...tools.map(adaptTool2),
626531
+ {
626532
+ name: "task_complete",
626533
+ description: "Signal evaluation is complete with your scored results.",
626534
+ parameters: {
626535
+ type: "object",
626536
+ properties: {
626537
+ summary: { type: "string", description: "JSON array of scored entries" }
626538
+ },
626539
+ required: ["summary"]
626540
+ },
626541
+ async execute(args) {
626542
+ return { success: true, output: args["summary"] || "[]" };
626543
+ }
626544
+ }
626545
+ ]);
626546
+ if (onEvent) runner.onEvent(onEvent);
626547
+ const result = await runner.run(
626548
+ prompt,
626549
+ `SNR Evaluator (${name10}). Working directory: ${this.repoRoot}`
626550
+ );
626551
+ return result.summary || "[]";
626552
+ }
626553
+ // ── Memory loading ───────────────────────────────────────────────────
626554
+ loadMemoryEntries(topics) {
626555
+ const entries = [];
626556
+ const dirs = [.../* @__PURE__ */ new Set([
626557
+ join133(this.repoRoot, ".omnius", "memory")
626558
+ ])];
626559
+ for (const dir of dirs) {
626560
+ if (!existsSync120(dir)) continue;
626561
+ try {
626562
+ const files = readdirSync42(dir).filter((f2) => f2.endsWith(".json"));
626563
+ for (const f2 of files) {
626564
+ const topic = basename31(f2, ".json");
626565
+ if (topics.length > 0 && !topics.includes(topic)) continue;
626566
+ try {
626567
+ const data = JSON.parse(readFileSync96(join133(dir, f2), "utf-8"));
626568
+ for (const [key, val] of Object.entries(data)) {
626569
+ const value2 = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
626570
+ entries.push({ topic, key, value: value2 });
626571
+ }
626572
+ } catch {
626573
+ }
626574
+ }
626575
+ } catch {
626576
+ }
626577
+ }
626578
+ return entries;
626579
+ }
626580
+ // ── Result parsing ───────────────────────────────────────────────────
626581
+ parseEvaluatorResult(summary, entryCount, defaultScore) {
626582
+ const scores = new Array(entryCount).fill(defaultScore);
626583
+ try {
626584
+ const jsonMatch = summary.match(/\[[\s\S]*\]/);
626585
+ if (!jsonMatch) return scores;
626586
+ const parsed = JSON.parse(jsonMatch[0]);
626587
+ for (const item of parsed) {
626588
+ const idx = typeof item.index === "number" ? item.index : -1;
626589
+ const score = typeof item.score === "number" ? item.score : typeof item.noise_score === "number" ? item.noise_score : defaultScore;
626590
+ if (idx >= 0 && idx < entryCount) {
626591
+ scores[idx] = Math.max(0, Math.min(1, score));
626592
+ }
626593
+ }
626594
+ } catch {
626595
+ }
626596
+ return scores;
626597
+ }
626598
+ // ── Memory pruning recommendations ──────────────────────────────────
626599
+ /**
626600
+ * Identify low-SNR memory entries that should be pruned.
626601
+ * Mirrors synaptic downscaling during slow-wave sleep — weak connections
626602
+ * (low-relevance, high-redundancy entries) are depotentiated.
626603
+ *
626604
+ * Returns topics+keys of entries scoring below the noise threshold.
626605
+ * Does NOT delete anything — the caller decides what to do with the list.
626606
+ */
626607
+ getPruningCandidates(currentTask, noiseThreshold = 0.3) {
626608
+ const entries = this.loadMemoryEntries([]);
626609
+ if (entries.length === 0) return [];
626610
+ const taskTerms = new Set(
626611
+ currentTask.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""))
626612
+ );
626613
+ const candidates = [];
626614
+ for (const entry of entries) {
626615
+ const entryTerms = entry.value.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""));
626616
+ const matchCount = entryTerms.filter((t2) => taskTerms.has(t2)).length;
626617
+ const relevance = entryTerms.length > 0 ? matchCount / Math.sqrt(entryTerms.length) : 0;
626618
+ if (relevance < noiseThreshold) {
626619
+ candidates.push({
626620
+ topic: entry.topic,
626621
+ key: entry.key,
626622
+ score: relevance,
626623
+ reason: relevance === 0 ? "no keyword overlap with current task" : `low relevance (${(relevance * 100).toFixed(0)}% < ${(noiseThreshold * 100).toFixed(0)}% threshold)`
626624
+ });
626625
+ }
626626
+ }
626627
+ return candidates.sort((a2, b) => a2.score - b.score);
626628
+ }
626629
+ /**
626630
+ * Act on the pruning recommendations: move low-SNR entries OUT of the active
626631
+ * memory topic files and into `.omnius/memory/.archive/<topic>.json`.
626632
+ *
626633
+ * This is the missing half of the Dentate Gyrus loop — `getPruningCandidates`
626634
+ * only ever produced a list that nothing consumed, so flagged-noise entries
626635
+ * kept loading into every context window (agent self-audit 2026-05-28).
626636
+ *
626637
+ * Safety properties:
626638
+ * - Reversible: entries are moved to an archive file, never deleted.
626639
+ * - Bounded: at most `maxArchive` entries removed per call.
626640
+ * - Guarded: refuses to run against a trivial focus string (which would
626641
+ * score every entry as irrelevant and archive the whole store).
626642
+ * - Conservative threshold (0.15) — only entries with near-zero relevance
626643
+ * to the focus are eligible.
626644
+ *
626645
+ * Intended caller: the deliberate slow-wave consolidation cycle, passing the
626646
+ * consolidation summary as `focus` (what the agent just decided matters).
626647
+ */
626648
+ archiveNoiseEntries(focus, opts = {}) {
626649
+ const noiseThreshold = opts.noiseThreshold ?? 0.15;
626650
+ const maxArchive = opts.maxArchive ?? 25;
626651
+ const focusTerms = focus.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
626652
+ if (focusTerms.length < 3) return { archived: 0, topics: [] };
626653
+ const candidates = this.getPruningCandidates(focus, noiseThreshold).slice(0, maxArchive);
626654
+ if (candidates.length === 0) return { archived: 0, topics: [] };
626655
+ const byTopic = /* @__PURE__ */ new Map();
626656
+ for (const cand of candidates) {
626657
+ const set = byTopic.get(cand.topic) ?? /* @__PURE__ */ new Set();
626658
+ set.add(cand.key);
626659
+ byTopic.set(cand.topic, set);
626660
+ }
626661
+ const memDir = join133(this.repoRoot, ".omnius", "memory");
626662
+ const archiveDir = join133(memDir, ".archive");
626663
+ let archived = 0;
626664
+ const touchedTopics = [];
626665
+ for (const [topic, keys] of byTopic) {
626666
+ const file = join133(memDir, `${topic}.json`);
626667
+ if (!existsSync120(file)) continue;
626668
+ try {
626669
+ const data = JSON.parse(readFileSync96(file, "utf-8"));
626670
+ const moved = {};
626671
+ for (const key of keys) {
626672
+ if (key in data) {
626673
+ moved[key] = data[key];
626674
+ delete data[key];
626675
+ archived++;
626676
+ }
626677
+ }
626678
+ if (Object.keys(moved).length === 0) continue;
626679
+ mkdirSync69(archiveDir, { recursive: true });
626680
+ const archiveFile = join133(archiveDir, `${topic}.json`);
626681
+ let archiveData = {};
626682
+ if (existsSync120(archiveFile)) {
626683
+ try {
626684
+ archiveData = JSON.parse(readFileSync96(archiveFile, "utf-8"));
626685
+ } catch {
626686
+ }
626687
+ }
626688
+ Object.assign(archiveData, moved);
626689
+ writeFileSync61(archiveFile, JSON.stringify(archiveData, null, 2));
626690
+ if (Object.keys(data).length === 0) {
626691
+ try {
626692
+ rmSync7(file);
626693
+ } catch {
626694
+ }
626695
+ } else {
626696
+ writeFileSync61(file, JSON.stringify(data, null, 2));
626697
+ }
626698
+ touchedTopics.push(topic);
626699
+ } catch {
626700
+ }
626701
+ }
626702
+ return { archived, topics: touchedTopics };
626703
+ }
626704
+ // ── Helpers ──────────────────────────────────────────────────────────
626705
+ makeScore(ratio, dPrime, total, signal, noise2, sparsity, evaluators, capacityWarning = false) {
626706
+ return {
626707
+ ratio: Math.max(0, Math.min(1, ratio)),
626708
+ dPrime: Math.max(0, dPrime),
626709
+ entriesEvaluated: total,
626710
+ signalCount: signal,
626711
+ noiseCount: noise2,
626712
+ sparsity: Math.max(0, Math.min(1, sparsity)),
626713
+ evaluatedAt: (/* @__PURE__ */ new Date()).toISOString(),
626714
+ evaluators,
626715
+ capacityWarning
626716
+ };
626717
+ }
626718
+ };
626719
+ }
626720
+ });
626721
+
626229
626722
  // packages/cli/src/tui/promptLoader.ts
626230
- import { readFileSync as readFileSync96, existsSync as existsSync120 } from "node:fs";
626231
- import { join as join133, dirname as dirname38 } from "node:path";
626723
+ import { readFileSync as readFileSync97, existsSync as existsSync121 } from "node:fs";
626724
+ import { join as join134, dirname as dirname38 } from "node:path";
626232
626725
  import { fileURLToPath as fileURLToPath17 } from "node:url";
626233
626726
  function loadPrompt3(promptPath, vars) {
626234
626727
  let content = cache7.get(promptPath);
626235
626728
  if (content === void 0) {
626236
- const fullPath = join133(PROMPTS_DIR3, promptPath);
626237
- if (!existsSync120(fullPath)) {
626729
+ const fullPath = join134(PROMPTS_DIR3, promptPath);
626730
+ if (!existsSync121(fullPath)) {
626238
626731
  throw new Error(`Prompt file not found: ${fullPath}`);
626239
626732
  }
626240
- content = readFileSync96(fullPath, "utf-8");
626733
+ content = readFileSync97(fullPath, "utf-8");
626241
626734
  cache7.set(promptPath, content);
626242
626735
  }
626243
626736
  if (!vars) return content;
@@ -626249,16 +626742,16 @@ var init_promptLoader3 = __esm({
626249
626742
  "use strict";
626250
626743
  __filename5 = fileURLToPath17(import.meta.url);
626251
626744
  __dirname6 = dirname38(__filename5);
626252
- devPath2 = join133(__dirname6, "..", "..", "prompts");
626253
- publishedPath2 = join133(__dirname6, "..", "prompts");
626254
- PROMPTS_DIR3 = existsSync120(devPath2) ? devPath2 : publishedPath2;
626745
+ devPath2 = join134(__dirname6, "..", "..", "prompts");
626746
+ publishedPath2 = join134(__dirname6, "..", "prompts");
626747
+ PROMPTS_DIR3 = existsSync121(devPath2) ? devPath2 : publishedPath2;
626255
626748
  cache7 = /* @__PURE__ */ new Map();
626256
626749
  }
626257
626750
  });
626258
626751
 
626259
626752
  // packages/cli/src/tui/dream-engine.ts
626260
- import { mkdirSync as mkdirSync69, writeFileSync as writeFileSync61, readFileSync as readFileSync97, existsSync as existsSync121, readdirSync as readdirSync42 } from "node:fs";
626261
- import { join as join134, basename as basename31 } from "node:path";
626753
+ import { mkdirSync as mkdirSync70, writeFileSync as writeFileSync62, readFileSync as readFileSync98, existsSync as existsSync122, readdirSync as readdirSync43 } from "node:fs";
626754
+ import { join as join135, basename as basename32 } from "node:path";
626262
626755
  import { execSync as execSync56 } from "node:child_process";
626263
626756
  function setDreamWriteContent(fn) {
626264
626757
  _dreamWriteContent = fn;
@@ -626271,10 +626764,10 @@ function dreamWrite(fn) {
626271
626764
  }
626272
626765
  }
626273
626766
  function loadAutoresearchMemory(repoRoot) {
626274
- const memoryPath = join134(repoRoot, ".omnius", "memory", "autoresearch.json");
626275
- if (!existsSync121(memoryPath)) return "";
626767
+ const memoryPath = join135(repoRoot, ".omnius", "memory", "autoresearch.json");
626768
+ if (!existsSync122(memoryPath)) return "";
626276
626769
  try {
626277
- const raw = readFileSync97(memoryPath, "utf-8");
626770
+ const raw = readFileSync98(memoryPath, "utf-8");
626278
626771
  const data = JSON.parse(raw);
626279
626772
  const sections = [];
626280
626773
  for (const key of AUTORESEARCH_MEMORY_KEYS) {
@@ -626293,7 +626786,7 @@ ${sections.join("\n\n")}`;
626293
626786
  return "";
626294
626787
  }
626295
626788
  }
626296
- function adaptTool2(tool) {
626789
+ function adaptTool3(tool) {
626297
626790
  return {
626298
626791
  name: tool.name,
626299
626792
  description: tool.description,
@@ -626440,6 +626933,7 @@ var init_dream_engine = __esm({
626440
626933
  init_dist8();
626441
626934
  init_dist5();
626442
626935
  init_project_context();
626936
+ init_snr_engine();
626443
626937
  init_setup();
626444
626938
  init_render();
626445
626939
  init_promptLoader3();
@@ -626471,14 +626965,14 @@ var init_dream_engine = __esm({
626471
626965
  const rawPath = String(args["path"] ?? "");
626472
626966
  const content = String(args["content"] ?? "");
626473
626967
  if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
626474
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join134(this.autoresearchDir, basename31(rawPath)) : join134(this.autoresearchDir, rawPath);
626968
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join135(this.autoresearchDir, basename32(rawPath)) : join135(this.autoresearchDir, rawPath);
626475
626969
  if (!targetPath.startsWith(this.autoresearchDir)) {
626476
626970
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .omnius/autoresearch/", durationMs: Date.now() - start2 };
626477
626971
  }
626478
626972
  try {
626479
- const dir = join134(targetPath, "..");
626480
- mkdirSync69(dir, { recursive: true });
626481
- writeFileSync61(targetPath, content, "utf-8");
626973
+ const dir = join135(targetPath, "..");
626974
+ mkdirSync70(dir, { recursive: true });
626975
+ writeFileSync62(targetPath, content, "utf-8");
626482
626976
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
626483
626977
  } catch (err) {
626484
626978
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
@@ -626506,20 +627000,20 @@ var init_dream_engine = __esm({
626506
627000
  const rawPath = String(args["path"] ?? "");
626507
627001
  const oldStr = String(args["old_string"] ?? "");
626508
627002
  const newStr = String(args["new_string"] ?? "");
626509
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join134(this.autoresearchDir, basename31(rawPath)) : join134(this.autoresearchDir, rawPath);
627003
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join135(this.autoresearchDir, basename32(rawPath)) : join135(this.autoresearchDir, rawPath);
626510
627004
  if (!targetPath.startsWith(this.autoresearchDir)) {
626511
627005
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .omnius/autoresearch/", durationMs: Date.now() - start2 };
626512
627006
  }
626513
627007
  try {
626514
- if (!existsSync121(targetPath)) {
627008
+ if (!existsSync122(targetPath)) {
626515
627009
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
626516
627010
  }
626517
- let content = readFileSync97(targetPath, "utf-8");
627011
+ let content = readFileSync98(targetPath, "utf-8");
626518
627012
  if (!content.includes(oldStr)) {
626519
627013
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start2 };
626520
627014
  }
626521
627015
  content = content.replace(oldStr, newStr);
626522
- writeFileSync61(targetPath, content, "utf-8");
627016
+ writeFileSync62(targetPath, content, "utf-8");
626523
627017
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start2 };
626524
627018
  } catch (err) {
626525
627019
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
@@ -626559,14 +627053,14 @@ var init_dream_engine = __esm({
626559
627053
  const rawPath = String(args["path"] ?? "");
626560
627054
  const content = String(args["content"] ?? "");
626561
627055
  if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
626562
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join134(this.dreamsDir, basename31(rawPath)) : join134(this.dreamsDir, rawPath);
627056
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join135(this.dreamsDir, basename32(rawPath)) : join135(this.dreamsDir, rawPath);
626563
627057
  if (!targetPath.startsWith(this.dreamsDir)) {
626564
627058
  return { success: false, output: "", error: "Dream mode: writes are confined to .omnius/dreams/", durationMs: Date.now() - start2 };
626565
627059
  }
626566
627060
  try {
626567
- const dir = join134(targetPath, "..");
626568
- mkdirSync69(dir, { recursive: true });
626569
- writeFileSync61(targetPath, content, "utf-8");
627061
+ const dir = join135(targetPath, "..");
627062
+ mkdirSync70(dir, { recursive: true });
627063
+ writeFileSync62(targetPath, content, "utf-8");
626570
627064
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start2 };
626571
627065
  } catch (err) {
626572
627066
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
@@ -626594,20 +627088,20 @@ var init_dream_engine = __esm({
626594
627088
  const rawPath = String(args["path"] ?? "");
626595
627089
  const oldStr = String(args["old_string"] ?? "");
626596
627090
  const newStr = String(args["new_string"] ?? "");
626597
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join134(this.dreamsDir, basename31(rawPath)) : join134(this.dreamsDir, rawPath);
627091
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join135(this.dreamsDir, basename32(rawPath)) : join135(this.dreamsDir, rawPath);
626598
627092
  if (!targetPath.startsWith(this.dreamsDir)) {
626599
627093
  return { success: false, output: "", error: "Dream mode: edits are confined to .omnius/dreams/", durationMs: Date.now() - start2 };
626600
627094
  }
626601
627095
  try {
626602
- if (!existsSync121(targetPath)) {
627096
+ if (!existsSync122(targetPath)) {
626603
627097
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start2 };
626604
627098
  }
626605
- let content = readFileSync97(targetPath, "utf-8");
627099
+ let content = readFileSync98(targetPath, "utf-8");
626606
627100
  if (!content.includes(oldStr)) {
626607
627101
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start2 };
626608
627102
  }
626609
627103
  content = content.replace(oldStr, newStr);
626610
- writeFileSync61(targetPath, content, "utf-8");
627104
+ writeFileSync62(targetPath, content, "utf-8");
626611
627105
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start2 };
626612
627106
  } catch (err) {
626613
627107
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start2 };
@@ -626656,7 +627150,7 @@ var init_dream_engine = __esm({
626656
627150
  constructor(config, repoRoot) {
626657
627151
  this.config = config;
626658
627152
  this.repoRoot = repoRoot;
626659
- this.dreamsDir = join134(repoRoot, ".omnius", "dreams");
627153
+ this.dreamsDir = join135(repoRoot, ".omnius", "dreams");
626660
627154
  this.state = {
626661
627155
  mode: "default",
626662
627156
  active: false,
@@ -626695,7 +627189,7 @@ var init_dream_engine = __esm({
626695
627189
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
626696
627190
  results: []
626697
627191
  };
626698
- mkdirSync69(this.dreamsDir, { recursive: true });
627192
+ mkdirSync70(this.dreamsDir, { recursive: true });
626699
627193
  this.saveDreamState();
626700
627194
  try {
626701
627195
  for (let cycle = 1; cycle <= totalCycles; cycle++) {
@@ -626767,8 +627261,8 @@ ${result.summary}`;
626767
627261
  if (mode !== "default" || cycle === totalCycles) {
626768
627262
  renderDreamContraction(cycle);
626769
627263
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
626770
- const summaryPath = join134(this.dreamsDir, `cycle-${cycle}-summary.md`);
626771
- writeFileSync61(summaryPath, cycleSummary, "utf-8");
627264
+ const summaryPath = join135(this.dreamsDir, `cycle-${cycle}-summary.md`);
627265
+ writeFileSync62(summaryPath, cycleSummary, "utf-8");
626772
627266
  }
626773
627267
  if (mode === "lucid" && !this.abortController.signal.aborted) {
626774
627268
  this.saveVersionCheckpoint(cycle);
@@ -627007,7 +627501,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
627007
627501
  }
627008
627502
  /** Build role-specific tool sets for swarm agents */
627009
627503
  buildSwarmTools(role, _workspace) {
627010
- const autoresearchDir = join134(this.repoRoot, ".omnius", "autoresearch");
627504
+ const autoresearchDir = join135(this.repoRoot, ".omnius", "autoresearch");
627011
627505
  const taskComplete = this.createSwarmTaskCompleteTool(role);
627012
627506
  switch (role) {
627013
627507
  case "researcher": {
@@ -627022,7 +627516,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
627022
627516
  new MemorySearchTool(this.repoRoot),
627023
627517
  new MemoryWriteTool(this.repoRoot)
627024
627518
  ];
627025
- return [...tools.map(adaptTool2), this.createDreamTodoWriteTool(), this.createDreamWorkingNotesTool(), taskComplete];
627519
+ return [...tools.map(adaptTool3), this.createDreamTodoWriteTool(), this.createDreamWorkingNotesTool(), taskComplete];
627026
627520
  }
627027
627521
  case "monitor": {
627028
627522
  const tools = [
@@ -627033,7 +627527,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
627033
627527
  // status-only in prompt
627034
627528
  new MemoryReadTool(this.repoRoot)
627035
627529
  ];
627036
- return [...tools.map(adaptTool2), this.createDreamTodoWriteTool(), taskComplete];
627530
+ return [...tools.map(adaptTool3), this.createDreamTodoWriteTool(), taskComplete];
627037
627531
  }
627038
627532
  case "evaluator": {
627039
627533
  const tools = [
@@ -627045,7 +627539,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
627045
627539
  new MemoryWriteTool(this.repoRoot),
627046
627540
  new GrepSearchTool(this.repoRoot)
627047
627541
  ];
627048
- return [...tools.map(adaptTool2), this.createDreamTodoWriteTool(), this.createDreamWorkingNotesTool(), taskComplete];
627542
+ return [...tools.map(adaptTool3), this.createDreamTodoWriteTool(), this.createDreamWorkingNotesTool(), taskComplete];
627049
627543
  }
627050
627544
  case "critic": {
627051
627545
  const tools = [
@@ -627054,7 +627548,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
627054
627548
  new MemorySearchTool(this.repoRoot),
627055
627549
  new GrepSearchTool(this.repoRoot)
627056
627550
  ];
627057
- return [...tools.map(adaptTool2), this.createDreamTodoWriteTool(), taskComplete];
627551
+ return [...tools.map(adaptTool3), this.createDreamTodoWriteTool(), taskComplete];
627058
627552
  }
627059
627553
  case "flow_maintainer": {
627060
627554
  const tools = [
@@ -627062,7 +627556,7 @@ After synthesis, call task_complete with the final prioritized summary.`,
627062
627556
  new MemoryWriteTool(this.repoRoot),
627063
627557
  new MemorySearchTool(this.repoRoot)
627064
627558
  ];
627065
- return [...tools.map(adaptTool2), this.createDreamTodoWriteTool(), this.createDreamWorkingNotesTool(), taskComplete];
627559
+ return [...tools.map(adaptTool3), this.createDreamTodoWriteTool(), this.createDreamWorkingNotesTool(), taskComplete];
627066
627560
  }
627067
627561
  }
627068
627562
  }
@@ -627408,7 +627902,7 @@ Call task_complete with a human-readable summary of the autoresearch session.`,
627408
627902
  workspace,
627409
627903
  onEvent
627410
627904
  );
627411
- const reportPath = join134(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
627905
+ const reportPath = join135(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
627412
627906
  const report2 = `# Autoresearch Swarm Report — Cycle ${cycleNum}
627413
627907
 
627414
627908
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -627430,8 +627924,8 @@ ${summaryResult}
627430
627924
  *Generated by omnius autoresearch swarm*
627431
627925
  `;
627432
627926
  try {
627433
- mkdirSync69(this.dreamsDir, { recursive: true });
627434
- writeFileSync61(reportPath, report2, "utf-8");
627927
+ mkdirSync70(this.dreamsDir, { recursive: true });
627928
+ writeFileSync62(reportPath, report2, "utf-8");
627435
627929
  } catch {
627436
627930
  }
627437
627931
  renderSwarmComplete(workspace);
@@ -627443,7 +627937,7 @@ ${summaryResult}
627443
627937
  new MemoryReadTool(this.repoRoot),
627444
627938
  new MemoryWriteTool(this.repoRoot),
627445
627939
  new MemorySearchTool(this.repoRoot)
627446
- ].map(adaptTool2);
627940
+ ].map(adaptTool3);
627447
627941
  const todoWriteTool = this.createDreamTodoWriteTool();
627448
627942
  const workingNotesTool = this.createDreamWorkingNotesTool();
627449
627943
  if (toolMode === "full") {
@@ -627462,7 +627956,7 @@ ${summaryResult}
627462
627956
  new WebSearchTool()
627463
627957
  ];
627464
627958
  return [
627465
- ...tools.map(adaptTool2),
627959
+ ...tools.map(adaptTool3),
627466
627960
  ...memoryAndPlanTools,
627467
627961
  todoWriteTool,
627468
627962
  workingNotesTool,
@@ -627484,8 +627978,8 @@ ${summaryResult}
627484
627978
  new DreamShellTool(this.repoRoot)
627485
627979
  ];
627486
627980
  return [
627487
- ...readTools.map(adaptTool2),
627488
- ...dreamWriteTools.map(adaptTool2),
627981
+ ...readTools.map(adaptTool3),
627982
+ ...dreamWriteTools.map(adaptTool3),
627489
627983
  ...memoryAndPlanTools,
627490
627984
  todoWriteTool,
627491
627985
  workingNotesTool,
@@ -627494,7 +627988,7 @@ ${summaryResult}
627494
627988
  }
627495
627989
  /** Dream-scoped todo_write — persists to .omnius/dreams/todo-state.json */
627496
627990
  createDreamTodoWriteTool() {
627497
- const todoPath3 = join134(this.dreamsDir, "todo-state.json");
627991
+ const todoPath3 = join135(this.dreamsDir, "todo-state.json");
627498
627992
  return {
627499
627993
  name: "todo_write",
627500
627994
  description: "Update the task checklist for this dream session. Mark items in_progress/completed/pending as you work through stages.",
@@ -627523,7 +628017,7 @@ ${summaryResult}
627523
628017
  return { success: false, output: "", error: "todos must be an array" };
627524
628018
  }
627525
628019
  try {
627526
- writeFileSync61(todoPath3, JSON.stringify({ todos, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
628020
+ writeFileSync62(todoPath3, JSON.stringify({ todos, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
627527
628021
  const summary = todos.map(
627528
628022
  (t2, i2) => ` ${t2.status === "completed" ? "✓" : t2.status === "in_progress" ? "▶" : "◯"} ${i2 + 1}: ${t2.content || "(untitled)"}`
627529
628023
  ).join("\n");
@@ -627537,7 +628031,7 @@ ${summary}` };
627537
628031
  }
627538
628032
  /** Dream-scoped working_notes — persists to .omnius/dreams/working-notes.json */
627539
628033
  createDreamWorkingNotesTool() {
627540
- const notesPath = join134(this.dreamsDir, "working-notes.json");
628034
+ const notesPath = join135(this.dreamsDir, "working-notes.json");
627541
628035
  return {
627542
628036
  name: "working_notes",
627543
628037
  description: "Track discoveries, decisions, and findings across dream stages. Notes persist within this dream session.",
@@ -627561,8 +628055,8 @@ ${summary}` };
627561
628055
  const action = args["action"] || "list";
627562
628056
  try {
627563
628057
  let notes = [];
627564
- if (existsSync121(notesPath)) {
627565
- notes = JSON.parse(readFileSync97(notesPath, "utf-8"));
628058
+ if (existsSync122(notesPath)) {
628059
+ notes = JSON.parse(readFileSync98(notesPath, "utf-8"));
627566
628060
  }
627567
628061
  if (action === "add") {
627568
628062
  const note = {
@@ -627571,11 +628065,11 @@ ${summary}` };
627571
628065
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
627572
628066
  };
627573
628067
  notes.push(note);
627574
- writeFileSync61(notesPath, JSON.stringify(notes, null, 2), "utf-8");
628068
+ writeFileSync62(notesPath, JSON.stringify(notes, null, 2), "utf-8");
627575
628069
  return { success: true, output: `Note added: [${note.category}] ${note.content.slice(0, 80)}` };
627576
628070
  }
627577
628071
  if (action === "clear") {
627578
- writeFileSync61(notesPath, "[]", "utf-8");
628072
+ writeFileSync62(notesPath, "[]", "utf-8");
627579
628073
  return { success: true, output: "All notes cleared." };
627580
628074
  }
627581
628075
  if (action === "search") {
@@ -627611,9 +628105,9 @@ ${summary}` };
627611
628105
  }
627612
628106
  /** Save workspace backup for lucid mode */
627613
628107
  saveVersionCheckpoint(cycle) {
627614
- const checkpointDir3 = join134(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
628108
+ const checkpointDir3 = join135(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
627615
628109
  try {
627616
- mkdirSync69(checkpointDir3, { recursive: true });
628110
+ mkdirSync70(checkpointDir3, { recursive: true });
627617
628111
  try {
627618
628112
  const gitStatus = execSync56("git status --porcelain", {
627619
628113
  cwd: this.repoRoot,
@@ -627630,11 +628124,11 @@ ${summary}` };
627630
628124
  encoding: "utf-8",
627631
628125
  timeout: 5e3
627632
628126
  }).trim();
627633
- writeFileSync61(join134(checkpointDir3, "git-status.txt"), gitStatus, "utf-8");
627634
- writeFileSync61(join134(checkpointDir3, "git-diff.patch"), gitDiff, "utf-8");
627635
- writeFileSync61(join134(checkpointDir3, "git-hash.txt"), gitHash, "utf-8");
627636
- writeFileSync61(
627637
- join134(checkpointDir3, "checkpoint.json"),
628127
+ writeFileSync62(join135(checkpointDir3, "git-status.txt"), gitStatus, "utf-8");
628128
+ writeFileSync62(join135(checkpointDir3, "git-diff.patch"), gitDiff, "utf-8");
628129
+ writeFileSync62(join135(checkpointDir3, "git-hash.txt"), gitHash, "utf-8");
628130
+ writeFileSync62(
628131
+ join135(checkpointDir3, "checkpoint.json"),
627638
628132
  JSON.stringify({
627639
628133
  cycle,
627640
628134
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -627645,8 +628139,8 @@ ${summary}` };
627645
628139
  );
627646
628140
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
627647
628141
  } catch {
627648
- writeFileSync61(
627649
- join134(checkpointDir3, "checkpoint.json"),
628142
+ writeFileSync62(
628143
+ join135(checkpointDir3, "checkpoint.json"),
627650
628144
  JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2),
627651
628145
  "utf-8"
627652
628146
  );
@@ -627686,7 +628180,7 @@ Each proposal includes implementation entrypoints and estimated effort.
627686
628180
  /** Update the master proposal index */
627687
628181
  updateProposalIndex() {
627688
628182
  try {
627689
- const files = readdirSync42(this.dreamsDir).filter((f2) => f2.endsWith(".md") && f2 !== "PROPOSAL-INDEX.md" && f2 !== "dream-state.json").sort();
628183
+ const files = readdirSync43(this.dreamsDir).filter((f2) => f2.endsWith(".md") && f2 !== "PROPOSAL-INDEX.md" && f2 !== "dream-state.json").sort();
627690
628184
  const index = `# Dream Proposals Index
627691
628185
 
627692
628186
  **Last updated**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -627707,7 +628201,7 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
627707
628201
  ---
627708
628202
  *Auto-generated by omnius dream engine*
627709
628203
  `;
627710
- writeFileSync61(join134(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
628204
+ writeFileSync62(join135(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
627711
628205
  } catch {
627712
628206
  }
627713
628207
  }
@@ -627728,8 +628222,8 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
627728
628222
  results: []
627729
628223
  };
627730
628224
  renderInfo("Memory consolidation starting — Phase 1: Orient → Phase 2: Gather → Phase 3: Consolidate → Phase 4: Prune");
627731
- const memoryDir = join134(this.repoRoot, ".omnius", "memory");
627732
- mkdirSync69(memoryDir, { recursive: true });
628225
+ const memoryDir = join135(this.repoRoot, ".omnius", "memory");
628226
+ mkdirSync70(memoryDir, { recursive: true });
627733
628227
  let prompt;
627734
628228
  try {
627735
628229
  prompt = loadPrompt3("tui/dream-consolidate.md", {
@@ -627795,14 +628289,25 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
627795
628289
  durationMs
627796
628290
  });
627797
628291
  try {
627798
- writeFileSync61(
627799
- join134(memoryDir, ".last-consolidation"),
628292
+ writeFileSync62(
628293
+ join135(memoryDir, ".last-consolidation"),
627800
628294
  JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), summary: result.summary?.slice(0, 500) }) + "\n"
627801
628295
  );
627802
628296
  } catch {
627803
628297
  }
627804
628298
  renderInfo(`Consolidation complete: ${result.turns} turns, ${result.toolCalls} tool calls, ${(durationMs / 1e3).toFixed(1)}s`);
627805
628299
  if (result.summary) renderInfo(`Summary: ${result.summary.slice(0, 200)}`);
628300
+ if (result.summary && result.summary.trim().length > 40) {
628301
+ try {
628302
+ const snr = new SNREngine(this.config, this.repoRoot);
628303
+ const { archived, topics } = snr.archiveNoiseEntries(result.summary);
628304
+ if (archived > 0) {
628305
+ renderInfo(`Pruned ${archived} low-SNR memory entr${archived === 1 ? "y" : "ies"} to .archive (topics: ${topics.join(", ")})`);
628306
+ }
628307
+ } catch (pruneErr) {
628308
+ renderWarning(`Noise pruning skipped: ${pruneErr instanceof Error ? pruneErr.message : String(pruneErr)}`);
628309
+ }
628310
+ }
627806
628311
  } catch (err) {
627807
628312
  renderWarning(`Consolidation failed: ${err instanceof Error ? err.message : String(err)}`);
627808
628313
  }
@@ -627813,8 +628318,8 @@ ${files.map((f2) => `- [\`${f2}\`](./${f2})`).join("\n")}
627813
628318
  /** Save dream state for resume/inspection */
627814
628319
  saveDreamState() {
627815
628320
  try {
627816
- writeFileSync61(
627817
- join134(this.dreamsDir, "dream-state.json"),
628321
+ writeFileSync62(
628322
+ join135(this.dreamsDir, "dream-state.json"),
627818
628323
  JSON.stringify(this.state, null, 2) + "\n",
627819
628324
  "utf-8"
627820
628325
  );
@@ -628194,8 +628699,8 @@ var init_bless_engine = __esm({
628194
628699
  });
628195
628700
 
628196
628701
  // packages/cli/src/tui/dmn-engine.ts
628197
- import { existsSync as existsSync122, readFileSync as readFileSync98, writeFileSync as writeFileSync62, mkdirSync as mkdirSync70, readdirSync as readdirSync43, unlinkSync as unlinkSync24 } from "node:fs";
628198
- import { join as join135, basename as basename32 } from "node:path";
628702
+ import { existsSync as existsSync123, readFileSync as readFileSync99, writeFileSync as writeFileSync63, mkdirSync as mkdirSync71, readdirSync as readdirSync44, unlinkSync as unlinkSync24 } from "node:fs";
628703
+ import { join as join136, basename as basename33 } from "node:path";
628199
628704
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
628200
628705
  const competenceReport = competence.length > 0 ? competence.map((c8) => {
628201
628706
  const rate = c8.attempts > 0 ? Math.round(c8.successes / c8.attempts * 100) : 0;
@@ -628219,7 +628724,7 @@ ${competenceReport}
628219
628724
  Reflect on what went well and what could improve.`;
628220
628725
  }
628221
628726
  }
628222
- function adaptTool3(tool) {
628727
+ function adaptTool4(tool) {
628223
628728
  return {
628224
628729
  name: tool.name,
628225
628730
  description: tool.description,
@@ -628300,9 +628805,9 @@ var init_dmn_engine = __esm({
628300
628805
  constructor(config, repoRoot) {
628301
628806
  this.config = config;
628302
628807
  this.repoRoot = repoRoot;
628303
- this.stateDir = join135(repoRoot, ".omnius", "dmn");
628304
- this.historyDir = join135(repoRoot, ".omnius", "dmn", "cycles");
628305
- mkdirSync70(this.historyDir, { recursive: true });
628808
+ this.stateDir = join136(repoRoot, ".omnius", "dmn");
628809
+ this.historyDir = join136(repoRoot, ".omnius", "dmn", "cycles");
628810
+ mkdirSync71(this.historyDir, { recursive: true });
628306
628811
  this.loadState();
628307
628812
  }
628308
628813
  config;
@@ -628517,7 +629022,7 @@ DMN state directory: ${this.stateDir}`
628517
629022
  new ShellTool(this.repoRoot)
628518
629023
  ];
628519
629024
  return [
628520
- ...tools.map(adaptTool3),
629025
+ ...tools.map(adaptTool4),
628521
629026
  this.createTaskCompleteTool()
628522
629027
  ];
628523
629028
  }
@@ -628794,7 +629299,7 @@ OUTPUT: Call task_complete with JSON:
628794
629299
  ];
628795
629300
  tools.push(new MemoryWriteTool(this.repoRoot));
628796
629301
  runner.registerTools([
628797
- ...tools.map(adaptTool3),
629302
+ ...tools.map(adaptTool4),
628798
629303
  {
628799
629304
  name: "task_complete",
628800
629305
  description: `Signal that the ${role} analysis is complete.`,
@@ -628938,15 +629443,15 @@ OUTPUT: Call task_complete with JSON:
628938
629443
  async gatherMemoryTopics() {
628939
629444
  const topics = [];
628940
629445
  const dirs = [
628941
- join135(this.repoRoot, ".omnius", "memory"),
628942
- join135(this.repoRoot, ".omnius", "memory")
629446
+ join136(this.repoRoot, ".omnius", "memory"),
629447
+ join136(this.repoRoot, ".omnius", "memory")
628943
629448
  ];
628944
629449
  for (const dir of dirs) {
628945
- if (!existsSync122(dir)) continue;
629450
+ if (!existsSync123(dir)) continue;
628946
629451
  try {
628947
- const files = readdirSync43(dir).filter((f2) => f2.endsWith(".json"));
629452
+ const files = readdirSync44(dir).filter((f2) => f2.endsWith(".json"));
628948
629453
  for (const f2 of files) {
628949
- const topic = basename32(f2, ".json");
629454
+ const topic = basename33(f2, ".json");
628950
629455
  if (!topics.includes(topic)) topics.push(topic);
628951
629456
  }
628952
629457
  } catch {
@@ -628956,18 +629461,18 @@ OUTPUT: Call task_complete with JSON:
628956
629461
  }
628957
629462
  // ── State persistence ─────────────────────────────────────────────────
628958
629463
  loadState() {
628959
- const path12 = join135(this.stateDir, "state.json");
628960
- if (existsSync122(path12)) {
629464
+ const path12 = join136(this.stateDir, "state.json");
629465
+ if (existsSync123(path12)) {
628961
629466
  try {
628962
- this.state = JSON.parse(readFileSync98(path12, "utf-8"));
629467
+ this.state = JSON.parse(readFileSync99(path12, "utf-8"));
628963
629468
  } catch {
628964
629469
  }
628965
629470
  }
628966
629471
  }
628967
629472
  saveState() {
628968
629473
  try {
628969
- writeFileSync62(
628970
- join135(this.stateDir, "state.json"),
629474
+ writeFileSync63(
629475
+ join136(this.stateDir, "state.json"),
628971
629476
  JSON.stringify(this.state, null, 2) + "\n",
628972
629477
  "utf-8"
628973
629478
  );
@@ -628977,8 +629482,8 @@ OUTPUT: Call task_complete with JSON:
628977
629482
  saveCycleResult(result) {
628978
629483
  try {
628979
629484
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
628980
- writeFileSync62(
628981
- join135(this.historyDir, filename),
629485
+ writeFileSync63(
629486
+ join136(this.historyDir, filename),
628982
629487
  JSON.stringify(result, null, 2) + "\n",
628983
629488
  "utf-8"
628984
629489
  );
@@ -628987,13 +629492,13 @@ OUTPUT: Call task_complete with JSON:
628987
629492
  }
628988
629493
  }
628989
629494
  pruneCycleHistory() {
628990
- const files = readdirSync43(this.historyDir).filter((f2) => f2.startsWith("cycle-") && f2.endsWith(".json")).sort();
629495
+ const files = readdirSync44(this.historyDir).filter((f2) => f2.startsWith("cycle-") && f2.endsWith(".json")).sort();
628991
629496
  if (files.length <= 2) return;
628992
629497
  const keep = /* @__PURE__ */ new Set([files[0], files[files.length - 1]]);
628993
629498
  const latestByFingerprint = /* @__PURE__ */ new Map();
628994
629499
  for (const file of files) {
628995
629500
  try {
628996
- const parsed = JSON.parse(readFileSync98(join135(this.historyDir, file), "utf-8"));
629501
+ const parsed = JSON.parse(readFileSync99(join136(this.historyDir, file), "utf-8"));
628997
629502
  latestByFingerprint.set(this.fingerprintCycle(parsed), file);
628998
629503
  } catch {
628999
629504
  keep.add(file);
@@ -629011,7 +629516,7 @@ OUTPUT: Call task_complete with JSON:
629011
629516
  for (const file of files) {
629012
629517
  if (!keep.has(file)) {
629013
629518
  try {
629014
- unlinkSync24(join135(this.historyDir, file));
629519
+ unlinkSync24(join136(this.historyDir, file));
629015
629520
  } catch {
629016
629521
  }
629017
629522
  }
@@ -629037,385 +629542,6 @@ ${result.reasoning}`).toLowerCase().replace(/\d+/g, "#").replace(/\s+/g, " ").tr
629037
629542
  }
629038
629543
  });
629039
629544
 
629040
- // packages/cli/src/tui/snr-engine.ts
629041
- import { existsSync as existsSync123, readdirSync as readdirSync44, readFileSync as readFileSync99 } from "node:fs";
629042
- import { join as join136, basename as basename33 } from "node:path";
629043
- function computeDPrime(signalScores, noiseScores) {
629044
- if (signalScores.length === 0 || noiseScores.length === 0) return 0;
629045
- const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
629046
- const variance = (arr, mu) => arr.reduce((s2, v) => s2 + (v - mu) ** 2, 0) / Math.max(1, arr.length - 1);
629047
- const muSignal = mean(signalScores);
629048
- const muNoise = mean(noiseScores);
629049
- const varSignal = variance(signalScores, muSignal);
629050
- const varNoise = variance(noiseScores, muNoise);
629051
- const pooledStd = Math.sqrt((varSignal + varNoise) / 2);
629052
- if (pooledStd === 0) return muSignal > muNoise ? 3 : 0;
629053
- return (muSignal - muNoise) / pooledStd;
629054
- }
629055
- function computeSparsity(entries) {
629056
- if (entries.length <= 1) return 1;
629057
- const ngramSets = entries.map((e2) => {
629058
- const words = e2.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
629059
- const ngrams = /* @__PURE__ */ new Set();
629060
- for (let i2 = 0; i2 < words.length - 1; i2++) {
629061
- ngrams.add(`${words[i2]} ${words[i2 + 1]}`);
629062
- }
629063
- return ngrams;
629064
- });
629065
- let totalPairs = 0;
629066
- let totalJaccard = 0;
629067
- for (let i2 = 0; i2 < ngramSets.length; i2++) {
629068
- for (let j = i2 + 1; j < ngramSets.length; j++) {
629069
- const a2 = ngramSets[i2];
629070
- const b = ngramSets[j];
629071
- if (a2.size === 0 && b.size === 0) continue;
629072
- const intersection = new Set([...a2].filter((x) => b.has(x)));
629073
- const union = /* @__PURE__ */ new Set([...a2, ...b]);
629074
- totalJaccard += union.size > 0 ? intersection.size / union.size : 0;
629075
- totalPairs++;
629076
- }
629077
- }
629078
- if (totalPairs === 0) return 1;
629079
- const avgOverlap = totalJaccard / totalPairs;
629080
- return Math.max(0, Math.min(1, 1 - avgOverlap));
629081
- }
629082
- function adaptTool4(tool) {
629083
- return {
629084
- name: tool.name,
629085
- description: tool.description,
629086
- parameters: tool.parameters,
629087
- async execute(args) {
629088
- const result = await tool.execute(args);
629089
- return { success: result.success, output: result.output, error: result.error };
629090
- }
629091
- };
629092
- }
629093
- var SNREngine;
629094
- var init_snr_engine = __esm({
629095
- "packages/cli/src/tui/snr-engine.ts"() {
629096
- "use strict";
629097
- init_dist8();
629098
- init_dist5();
629099
- init_project_context();
629100
- init_render();
629101
- SNREngine = class {
629102
- constructor(config, repoRoot) {
629103
- this.config = config;
629104
- this.repoRoot = repoRoot;
629105
- }
629106
- config;
629107
- repoRoot;
629108
- lastScore = null;
629109
- evaluationCount = 0;
629110
- get score() {
629111
- return this.lastScore;
629112
- }
629113
- /**
629114
- * Quick local-only SNR estimation (no LLM calls, fast).
629115
- * @param contextSlots — total context window tokens (for Hopfield capacity warning)
629116
- */
629117
- computeLocalSNR(currentTask, contextEntries, contextSlots) {
629118
- if (contextEntries.length === 0) {
629119
- return this.makeScore(1, 3, 0, 0, 0, 1, ["local-empty"]);
629120
- }
629121
- const taskTerms = new Set(
629122
- currentTask.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""))
629123
- );
629124
- const scores = contextEntries.map((entry) => {
629125
- const entryTerms = entry.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""));
629126
- const matchCount = entryTerms.filter((t2) => taskTerms.has(t2)).length;
629127
- const score2 = entryTerms.length > 0 ? matchCount / Math.sqrt(entryTerms.length) : 0;
629128
- return { entry, score: score2 };
629129
- });
629130
- const allScores = scores.map((s2) => s2.score);
629131
- const mean = allScores.reduce((a2, b) => a2 + b, 0) / allScores.length;
629132
- const std = Math.sqrt(allScores.reduce((a2, v) => a2 + (v - mean) ** 2, 0) / allScores.length);
629133
- const threshold = mean + 0.5 * std;
629134
- const signalScores = allScores.filter((s2) => s2 >= threshold);
629135
- const noiseScores = allScores.filter((s2) => s2 < threshold);
629136
- const dPrime = computeDPrime(
629137
- signalScores.length > 0 ? signalScores : [mean],
629138
- noiseScores.length > 0 ? noiseScores : [0]
629139
- );
629140
- const sparsity = computeSparsity(contextEntries);
629141
- const signalProportion = signalScores.length / allScores.length;
629142
- const dPrimeNorm = Math.min(1, Math.max(0, dPrime / 3));
629143
- const ratio = 0.5 * signalProportion + 0.3 * dPrimeNorm + 0.2 * sparsity;
629144
- const capacityWarning = contextSlots ? contextEntries.length > Math.floor(contextSlots * 0.138) : false;
629145
- const score = this.makeScore(
629146
- ratio,
629147
- dPrime,
629148
- contextEntries.length,
629149
- signalScores.length,
629150
- noiseScores.length,
629151
- sparsity,
629152
- ["local-keyword"],
629153
- capacityWarning
629154
- );
629155
- this.lastScore = score;
629156
- this.evaluationCount++;
629157
- return score;
629158
- }
629159
- /**
629160
- * Full SNR evaluation using parallel LLM evaluator agents.
629161
- * Mirrors PFC gating + multi-agent debate (Du et al. 2023).
629162
- *
629163
- * Spawns 2 lightweight agents with different evaluation perspectives:
629164
- * - "Relevance Evaluator" — scores entries by task relevance (PFC role)
629165
- * - "Noise Detector" — identifies redundant/stale/irrelevant entries (DG role)
629166
- *
629167
- * Their consensus determines the final SNR.
629168
- */
629169
- async evaluateWithAgents(currentTask, memoryTopics, onEvent) {
629170
- const entries = this.loadMemoryEntries(memoryTopics);
629171
- if (entries.length === 0) {
629172
- const score2 = this.makeScore(1, 3, 0, 0, 0, 1, ["agents-empty"]);
629173
- this.lastScore = score2;
629174
- return score2;
629175
- }
629176
- const entrySummaries = entries.map(
629177
- (e2, i2) => `[${i2}] topic=${e2.topic} key=${e2.key}: ${e2.value.slice(0, 200)}${e2.value.length > 200 ? "..." : ""}`
629178
- );
629179
- const entriesBlock = entrySummaries.join("\n");
629180
- const [relevanceResult, noiseResult] = await Promise.allSettled([
629181
- this.runEvaluatorAgent(
629182
- "relevance",
629183
- `You are a Prefrontal Cortex Gating Evaluator. Your role is to assess which
629184
- memory entries are RELEVANT to the current task.
629185
-
629186
- CURRENT TASK: ${currentTask}
629187
-
629188
- MEMORY ENTRIES TO EVALUATE:
629189
- ${entriesBlock}
629190
-
629191
- For each entry, output a JSON array of objects:
629192
- [{"index": 0, "score": 0.8, "reason": "directly related to task"}, ...]
629193
-
629194
- Score 0-1 where:
629195
- - 1.0 = directly relevant to the current task
629196
- - 0.7 = supporting context (useful background)
629197
- - 0.4 = marginally relevant
629198
- - 0.1 = not relevant to current task
629199
-
629200
- Call task_complete with the JSON array when done.`,
629201
- onEvent
629202
- ),
629203
- this.runEvaluatorAgent(
629204
- "noise",
629205
- `You are a Dentate Gyrus Pattern Separation Evaluator. Your role is to identify
629206
- NOISE in the memory context — entries that are redundant, stale, or interfering.
629207
-
629208
- CURRENT TASK: ${currentTask}
629209
-
629210
- MEMORY ENTRIES TO EVALUATE:
629211
- ${entriesBlock}
629212
-
629213
- For each entry, output a JSON array of objects:
629214
- [{"index": 0, "noise_score": 0.2, "reason": "unique, not redundant"}, ...]
629215
-
629216
- Noise score 0-1 where:
629217
- - 1.0 = pure noise (completely redundant, stale, or interfering with task)
629218
- - 0.7 = mostly noise (outdated or largely redundant with another entry)
629219
- - 0.4 = moderate noise (some overlap with other entries)
629220
- - 0.1 = clean signal (unique, fresh, non-interfering)
629221
-
629222
- Look for: duplicate information, outdated facts, entries that contradict
629223
- newer entries, entries about completely unrelated topics.
629224
-
629225
- Call task_complete with the JSON array when done.`,
629226
- onEvent
629227
- )
629228
- ]);
629229
- const relevanceScores = this.parseEvaluatorResult(
629230
- relevanceResult.status === "fulfilled" ? relevanceResult.value : "",
629231
- entries.length,
629232
- 0.5
629233
- // default relevance
629234
- );
629235
- const noiseScores = this.parseEvaluatorResult(
629236
- noiseResult.status === "fulfilled" ? noiseResult.value : "",
629237
- entries.length,
629238
- 0.5
629239
- // default noise
629240
- );
629241
- const combinedScores = entries.map((_, i2) => {
629242
- const rel = relevanceScores[i2] ?? 0.5;
629243
- const noise2 = noiseScores[i2] ?? 0.5;
629244
- const votes = [rel, 1 - noise2].sort((a2, b) => a2 - b);
629245
- return (votes[0] + votes[1]) / 2;
629246
- });
629247
- const mean = combinedScores.reduce((a2, b) => a2 + b, 0) / combinedScores.length;
629248
- const std = Math.sqrt(combinedScores.reduce((a2, v) => a2 + (v - mean) ** 2, 0) / combinedScores.length);
629249
- const threshold = Math.max(0.3, mean);
629250
- const signalEntries = combinedScores.filter((s2) => s2 >= threshold);
629251
- const noiseEntries = combinedScores.filter((s2) => s2 < threshold);
629252
- const dPrime = computeDPrime(
629253
- signalEntries.length > 0 ? signalEntries : [mean],
629254
- noiseEntries.length > 0 ? noiseEntries : [0.1]
629255
- );
629256
- const sparsity = computeSparsity(entries.map((e2) => e2.value));
629257
- const signalProportion = signalEntries.length / combinedScores.length;
629258
- const dPrimeNorm = Math.min(1, Math.max(0, dPrime / 3));
629259
- const ratio = 0.5 * signalProportion + 0.3 * dPrimeNorm + 0.2 * sparsity;
629260
- const evaluators = [
629261
- relevanceResult.status === "fulfilled" ? "relevance-agent" : "relevance-failed",
629262
- noiseResult.status === "fulfilled" ? "noise-agent" : "noise-failed"
629263
- ];
629264
- const score = this.makeScore(
629265
- ratio,
629266
- dPrime,
629267
- entries.length,
629268
- signalEntries.length,
629269
- noiseEntries.length,
629270
- sparsity,
629271
- evaluators
629272
- );
629273
- this.lastScore = score;
629274
- this.evaluationCount++;
629275
- return score;
629276
- }
629277
- // ── Evaluator agent ──────────────────────────────────────────────────
629278
- async runEvaluatorAgent(name10, prompt, onEvent) {
629279
- const backend = new OllamaAgenticBackend(
629280
- this.config.backendUrl,
629281
- this.config.model,
629282
- this.config.apiKey
629283
- );
629284
- const modelTier = getModelTier(this.config.model);
629285
- const runner = new AgenticRunner(backend, {
629286
- maxTurns: 5,
629287
- // Evaluators are very focused — 5 turns max
629288
- maxTokens: 4096,
629289
- temperature: 0,
629290
- // Deterministic scoring
629291
- requestTimeoutMs: this.config.timeoutMs,
629292
- taskTimeoutMs: this.config.timeoutMs,
629293
- compactionThreshold: modelTier === "small" ? 8e3 : 16e3,
629294
- modelTier
629295
- });
629296
- const tools = [
629297
- new MemoryReadTool(this.repoRoot),
629298
- new MemorySearchTool(this.repoRoot)
629299
- ];
629300
- runner.registerTools([
629301
- ...tools.map(adaptTool4),
629302
- {
629303
- name: "task_complete",
629304
- description: "Signal evaluation is complete with your scored results.",
629305
- parameters: {
629306
- type: "object",
629307
- properties: {
629308
- summary: { type: "string", description: "JSON array of scored entries" }
629309
- },
629310
- required: ["summary"]
629311
- },
629312
- async execute(args) {
629313
- return { success: true, output: args["summary"] || "[]" };
629314
- }
629315
- }
629316
- ]);
629317
- if (onEvent) runner.onEvent(onEvent);
629318
- const result = await runner.run(
629319
- prompt,
629320
- `SNR Evaluator (${name10}). Working directory: ${this.repoRoot}`
629321
- );
629322
- return result.summary || "[]";
629323
- }
629324
- // ── Memory loading ───────────────────────────────────────────────────
629325
- loadMemoryEntries(topics) {
629326
- const entries = [];
629327
- const dirs = [
629328
- join136(this.repoRoot, ".omnius", "memory"),
629329
- join136(this.repoRoot, ".omnius", "memory")
629330
- ];
629331
- for (const dir of dirs) {
629332
- if (!existsSync123(dir)) continue;
629333
- try {
629334
- const files = readdirSync44(dir).filter((f2) => f2.endsWith(".json"));
629335
- for (const f2 of files) {
629336
- const topic = basename33(f2, ".json");
629337
- if (topics.length > 0 && !topics.includes(topic)) continue;
629338
- try {
629339
- const data = JSON.parse(readFileSync99(join136(dir, f2), "utf-8"));
629340
- for (const [key, val] of Object.entries(data)) {
629341
- const value2 = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
629342
- entries.push({ topic, key, value: value2 });
629343
- }
629344
- } catch {
629345
- }
629346
- }
629347
- } catch {
629348
- }
629349
- }
629350
- return entries;
629351
- }
629352
- // ── Result parsing ───────────────────────────────────────────────────
629353
- parseEvaluatorResult(summary, entryCount, defaultScore) {
629354
- const scores = new Array(entryCount).fill(defaultScore);
629355
- try {
629356
- const jsonMatch = summary.match(/\[[\s\S]*\]/);
629357
- if (!jsonMatch) return scores;
629358
- const parsed = JSON.parse(jsonMatch[0]);
629359
- for (const item of parsed) {
629360
- const idx = typeof item.index === "number" ? item.index : -1;
629361
- const score = typeof item.score === "number" ? item.score : typeof item.noise_score === "number" ? item.noise_score : defaultScore;
629362
- if (idx >= 0 && idx < entryCount) {
629363
- scores[idx] = Math.max(0, Math.min(1, score));
629364
- }
629365
- }
629366
- } catch {
629367
- }
629368
- return scores;
629369
- }
629370
- // ── Memory pruning recommendations ──────────────────────────────────
629371
- /**
629372
- * Identify low-SNR memory entries that should be pruned.
629373
- * Mirrors synaptic downscaling during slow-wave sleep — weak connections
629374
- * (low-relevance, high-redundancy entries) are depotentiated.
629375
- *
629376
- * Returns topics+keys of entries scoring below the noise threshold.
629377
- * Does NOT delete anything — the caller decides what to do with the list.
629378
- */
629379
- getPruningCandidates(currentTask, noiseThreshold = 0.3) {
629380
- const entries = this.loadMemoryEntries([]);
629381
- if (entries.length === 0) return [];
629382
- const taskTerms = new Set(
629383
- currentTask.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""))
629384
- );
629385
- const candidates = [];
629386
- for (const entry of entries) {
629387
- const entryTerms = entry.value.toLowerCase().split(/\s+/).filter((w) => w.length > 3).map((w) => w.replace(/[^a-z0-9]/g, ""));
629388
- const matchCount = entryTerms.filter((t2) => taskTerms.has(t2)).length;
629389
- const relevance = entryTerms.length > 0 ? matchCount / Math.sqrt(entryTerms.length) : 0;
629390
- if (relevance < noiseThreshold) {
629391
- candidates.push({
629392
- topic: entry.topic,
629393
- key: entry.key,
629394
- score: relevance,
629395
- reason: relevance === 0 ? "no keyword overlap with current task" : `low relevance (${(relevance * 100).toFixed(0)}% < ${(noiseThreshold * 100).toFixed(0)}% threshold)`
629396
- });
629397
- }
629398
- }
629399
- return candidates.sort((a2, b) => a2.score - b.score);
629400
- }
629401
- // ── Helpers ──────────────────────────────────────────────────────────
629402
- makeScore(ratio, dPrime, total, signal, noise2, sparsity, evaluators, capacityWarning = false) {
629403
- return {
629404
- ratio: Math.max(0, Math.min(1, ratio)),
629405
- dPrime: Math.max(0, dPrime),
629406
- entriesEvaluated: total,
629407
- signalCount: signal,
629408
- noiseCount: noise2,
629409
- sparsity: Math.max(0, Math.min(1, sparsity)),
629410
- evaluatedAt: (/* @__PURE__ */ new Date()).toISOString(),
629411
- evaluators,
629412
- capacityWarning
629413
- };
629414
- }
629415
- };
629416
- }
629417
- });
629418
-
629419
629545
  // packages/cli/src/tui/emotion-engine.ts
629420
629546
  function labelFromCoordinates(valence, arousal) {
629421
629547
  if (valence > 0.6 && arousal > 0.6) return { label: "exhilarated", emoji: "🤩" };
@@ -630825,9 +630951,14 @@ function buildTelegramCommandMenuItems(scope) {
630825
630951
  seen.add(cmd.name);
630826
630952
  items.push({
630827
630953
  label: `/${cmd.name}`,
630828
- command: `/${cmd.name}`,
630829
630954
  description: cmd.signatures[0]?.description ?? signature,
630830
- adminOnly: scope === "admin"
630955
+ adminOnly: scope === "admin",
630956
+ action: {
630957
+ type: "command_detail",
630958
+ command: `/${cmd.name}`,
630959
+ label: `/${cmd.name}`,
630960
+ description: cmd.signatures.map((sig) => `${sig.signature} - ${sig.description}`).join("\n")
630961
+ }
630831
630962
  });
630832
630963
  }
630833
630964
  return items.sort((a2, b) => a2.label.localeCompare(b.label));
@@ -630835,10 +630966,18 @@ function buildTelegramCommandMenuItems(scope) {
630835
630966
  function buildTelegramGenerativeMenuItems(commandName) {
630836
630967
  const name10 = commandName.replace(/^\//, "").toLowerCase();
630837
630968
  if (!GENERATIVE_COMMANDS.has(name10)) return [];
630969
+ if (name10 === "models") {
630970
+ return [
630971
+ { label: "CAD models", description: "Browse text-to-CAD adapters.", action: { type: "models", generation: "cad" } },
630972
+ { label: "3D models", description: "Browse 3D mesh/reconstruction adapters.", action: { type: "models", generation: "model3d" } },
630973
+ { label: "Model store", command: "/models", description: "Show unified model store status.", action: { type: "command", command: "/models" } }
630974
+ ];
630975
+ }
630838
630976
  const title = name10[0].toUpperCase() + name10.slice(1);
630977
+ const generation = name10 === "sound" ? "sound" : name10 === "music" ? "music" : name10;
630839
630978
  return [
630840
- { label: `${title} models`, command: `/${name10} list`, description: `List available ${name10} models and hardware fit.` },
630841
- { label: `${title} setup`, command: `/${name10} setup`, description: `Show setup commands for the ${name10} backend.` }
630979
+ { label: `${title} models`, description: `Browse selectable ${name10} models, metadata, cache state, and actions.`, action: { type: "models", generation } },
630980
+ { label: `${title} setup`, description: `Show setup commands for the ${name10} backend.`, action: { type: "setup_generation", generation } }
630842
630981
  ];
630843
630982
  }
630844
630983
  function encodeTelegramCommandMenuCallback(action, value2) {
@@ -630848,43 +630987,85 @@ function encodeTelegramCommandMenuCallback(action, value2) {
630848
630987
  function decodeTelegramCommandMenuCallback(data) {
630849
630988
  const parts = data.split(":");
630850
630989
  if (parts.length !== 3 || parts[0] !== CALLBACK_PREFIX2) return null;
630851
- const action = parts[1] === "p" ? "page" : parts[1] === "r" ? "run" : parts[1] === "c" ? "close" : null;
630990
+ const action = parts[1] === "p" ? "page" : parts[1] === "r" ? "run" : parts[1] === "c" ? "close" : parts[1] === "b" ? "back" : null;
630852
630991
  if (!action) return null;
630853
630992
  return { action, value: parts[2] ?? "" };
630854
630993
  }
630994
+ function pushTelegramCommandMenuState(state, next) {
630995
+ const crumb = {
630996
+ kind: state.kind,
630997
+ title: state.title,
630998
+ subtitle: state.subtitle,
630999
+ body: state.body,
631000
+ page: state.page,
631001
+ items: state.items
631002
+ };
631003
+ return {
631004
+ ...state,
631005
+ kind: next.kind ?? state.kind,
631006
+ title: next.title,
631007
+ subtitle: next.subtitle,
631008
+ body: next.body,
631009
+ page: next.page ?? 0,
631010
+ items: next.items,
631011
+ breadcrumbs: [...state.breadcrumbs ?? [], crumb]
631012
+ };
631013
+ }
631014
+ function popTelegramCommandMenuState(state) {
631015
+ const stack = state.breadcrumbs ?? [];
631016
+ const previous = stack.at(-1);
631017
+ if (!previous) return null;
631018
+ return {
631019
+ ...state,
631020
+ kind: previous.kind,
631021
+ title: previous.title,
631022
+ subtitle: previous.subtitle,
631023
+ body: previous.body,
631024
+ page: previous.page,
631025
+ items: previous.items,
631026
+ breadcrumbs: stack.slice(0, -1)
631027
+ };
631028
+ }
630855
631029
  function renderTelegramCommandMenu(state) {
630856
631030
  const totalPages = Math.max(1, Math.ceil(state.items.length / PAGE_SIZE2));
630857
631031
  const page2 = Math.max(0, Math.min(state.page, totalPages - 1));
630858
631032
  const start2 = page2 * PAGE_SIZE2;
630859
631033
  const visible = state.items.slice(start2, start2 + PAGE_SIZE2);
630860
- const title = state.kind === "generative" ? "Generative command" : "Commands";
631034
+ const title = state.title || (state.kind === "generative" ? "Generative command" : state.kind === "models" ? "Models" : "Commands");
630861
631035
  const scope = state.scope === "admin" ? "admin" : "public";
630862
631036
  const lines = [
630863
631037
  `<b>${escapeHTML3(title)}</b>`,
630864
631038
  `<i>${escapeHTML3(scope)} scope - page ${page2 + 1}/${totalPages}</i>`,
631039
+ state.subtitle ? escapeHTML3(state.subtitle) : "",
631040
+ state.body ? `<blockquote expandable>${escapeHTML3(state.body)}</blockquote>` : "",
630865
631041
  "",
630866
631042
  ...visible.flatMap((item) => [
630867
- `<code>${escapeHTML3(item.command)}</code>`,
631043
+ item.command ? `<code>${escapeHTML3(item.command)}</code>` : `<b>${escapeHTML3(item.label)}</b>`,
630868
631044
  escapeHTML3(item.description)
630869
631045
  ])
630870
- ];
631046
+ ].filter((line) => line !== "");
630871
631047
  const keyboard = visible.map((item, offset) => [{
630872
631048
  text: item.label.slice(0, 32),
630873
631049
  callback_data: encodeTelegramCommandMenuCallback("run", start2 + offset)
630874
631050
  }]);
630875
631051
  const nav = [];
630876
631052
  nav.push({ text: "Close", callback_data: encodeTelegramCommandMenuCallback("close", 0) });
631053
+ if ((state.breadcrumbs ?? []).length > 0) nav.push({ text: "Back", callback_data: encodeTelegramCommandMenuCallback("back", 0) });
630877
631054
  if (page2 > 0) nav.push({ text: "Prev", callback_data: encodeTelegramCommandMenuCallback("page", page2 - 1) });
630878
631055
  nav.push({ text: `${page2 + 1}/${totalPages}`, callback_data: encodeTelegramCommandMenuCallback("page", page2) });
630879
631056
  if (page2 < totalPages - 1) nav.push({ text: "Next", callback_data: encodeTelegramCommandMenuCallback("page", page2 + 1) });
630880
631057
  keyboard.push(nav);
630881
- return { text: lines.join("\n"), reply_markup: { inline_keyboard: keyboard } };
631058
+ return { text: truncateTelegramMenuText(lines.join("\n")), reply_markup: { inline_keyboard: keyboard } };
630882
631059
  }
630883
631060
  function handleTelegramCommandMenuCallback(data, state, now = Date.now()) {
630884
631061
  const decoded = decodeTelegramCommandMenuCallback(data);
630885
631062
  if (!decoded) return null;
630886
631063
  if (state.expiresAt <= now) return null;
630887
631064
  if (decoded.action === "close") return { close: true };
631065
+ if (decoded.action === "back") {
631066
+ const newState = popTelegramCommandMenuState(state);
631067
+ return newState ? { newState, render: renderTelegramCommandMenu(newState) } : null;
631068
+ }
630888
631069
  if (decoded.action === "page") {
630889
631070
  const totalPages = Math.max(1, Math.ceil(state.items.length / PAGE_SIZE2));
630890
631071
  const page2 = Math.max(0, Math.min(Number.parseInt(decoded.value, 10) || 0, totalPages - 1));
@@ -630893,21 +631074,28 @@ function handleTelegramCommandMenuCallback(data, state, now = Date.now()) {
630893
631074
  }
630894
631075
  const index = Number.parseInt(decoded.value, 10);
630895
631076
  const item = Number.isFinite(index) ? state.items[index] : void 0;
630896
- return item ? { command: item.command } : null;
631077
+ if (!item) return null;
631078
+ return item.command ? { command: item.command, item } : { item };
630897
631079
  }
630898
631080
  function escapeHTML3(text) {
630899
631081
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
630900
631082
  }
631083
+ function truncateTelegramMenuText(text) {
631084
+ if (text.length <= 3900) return text;
631085
+ return `${text.slice(0, 3820)}
631086
+
631087
+ <i>... menu page clipped; use buttons to narrow this view.</i>`;
631088
+ }
630901
631089
  var CALLBACK_PREFIX2, PAGE_SIZE2, TTL_MS, MAX_CALLBACK_DATA_BYTES, GENERATIVE_COMMANDS, TelegramCommandMenuStateStore;
630902
631090
  var init_telegram_command_menu = __esm({
630903
631091
  "packages/cli/src/tui/telegram-command-menu.ts"() {
630904
631092
  "use strict";
630905
631093
  init_command_registry();
630906
631094
  CALLBACK_PREFIX2 = "ocm";
630907
- PAGE_SIZE2 = 8;
631095
+ PAGE_SIZE2 = 7;
630908
631096
  TTL_MS = 10 * 60 * 1e3;
630909
631097
  MAX_CALLBACK_DATA_BYTES = 64;
630910
- GENERATIVE_COMMANDS = /* @__PURE__ */ new Set(["image", "video", "sound", "music"]);
631098
+ GENERATIVE_COMMANDS = /* @__PURE__ */ new Set(["image", "video", "sound", "music", "models"]);
630911
631099
  TelegramCommandMenuStateStore = class {
630912
631100
  states = /* @__PURE__ */ new Map();
630913
631101
  key(chatId, messageId) {
@@ -630916,6 +631104,7 @@ var init_telegram_command_menu = __esm({
630916
631104
  create(input, now = Date.now()) {
630917
631105
  return {
630918
631106
  ...input,
631107
+ breadcrumbs: input.breadcrumbs ?? [],
630919
631108
  createdAt: now,
630920
631109
  expiresAt: now + TTL_MS
630921
631110
  };
@@ -630951,11 +631140,11 @@ var init_telegram_command_menu = __esm({
630951
631140
  import { createCipheriv as createCipheriv5, createDecipheriv as createDecipheriv5, randomBytes as randomBytes24 } from "node:crypto";
630952
631141
  import {
630953
631142
  existsSync as existsSync124,
630954
- mkdirSync as mkdirSync71,
631143
+ mkdirSync as mkdirSync72,
630955
631144
  readFileSync as readFileSync100,
630956
631145
  statSync as statSync45,
630957
631146
  unlinkSync as unlinkSync25,
630958
- writeFileSync as writeFileSync63
631147
+ writeFileSync as writeFileSync64
630959
631148
  } from "node:fs";
630960
631149
  import { mkdir as mkdir20 } from "node:fs/promises";
630961
631150
  import {
@@ -630972,7 +631161,7 @@ function telegramCreativeWorkspaceRoot(repoRoot, chatId) {
630972
631161
  const raw = chatId === void 0 ? "unknown" : String(chatId);
630973
631162
  const key = raw.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 96) || "unknown";
630974
631163
  const root = join137(repoRoot, ".omnius", "telegram-creative", key);
630975
- mkdirSync71(root, { recursive: true });
631164
+ mkdirSync72(root, { recursive: true });
630976
631165
  return root;
630977
631166
  }
630978
631167
  function formatTelegramCreativeWorkspacePrompt(root) {
@@ -631145,8 +631334,8 @@ function scopedTool(base3, root, mode) {
631145
631334
  if (mode === "edit" && !existsSync124(guarded.path.abs)) {
631146
631335
  const materialized = materializeTelegramCreativeArtifactForSend(rootAbs, guarded.path.rel);
631147
631336
  if (!materialized.ok) return denied(materialized.error);
631148
- mkdirSync71(dirname39(guarded.path.abs), { recursive: true });
631149
- writeFileSync63(guarded.path.abs, readFileSync100(materialized.path));
631337
+ mkdirSync72(dirname39(guarded.path.abs), { recursive: true });
631338
+ writeFileSync64(guarded.path.abs, readFileSync100(materialized.path));
631150
631339
  materialized.cleanup?.();
631151
631340
  restoredEditPath = guarded.path.abs;
631152
631341
  }
@@ -631238,10 +631427,10 @@ function manifestPath(root) {
631238
631427
  return join137(root, MANIFEST_FILE);
631239
631428
  }
631240
631429
  function ensureManifest(root) {
631241
- mkdirSync71(root, { recursive: true });
631430
+ mkdirSync72(root, { recursive: true });
631242
631431
  const path12 = manifestPath(root);
631243
631432
  if (!existsSync124(path12)) {
631244
- writeFileSync63(path12, JSON.stringify({ files: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2) + "\n", "utf8");
631433
+ writeFileSync64(path12, JSON.stringify({ files: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2) + "\n", "utf8");
631245
631434
  }
631246
631435
  }
631247
631436
  function readManifest(root) {
@@ -631267,7 +631456,7 @@ function readManifest(root) {
631267
631456
  }
631268
631457
  function writeManifest(root, manifest) {
631269
631458
  ensureManifest(root);
631270
- writeFileSync63(manifestPath(root), JSON.stringify(manifest, null, 2) + "\n", "utf8");
631459
+ writeFileSync64(manifestPath(root), JSON.stringify(manifest, null, 2) + "\n", "utf8");
631271
631460
  }
631272
631461
  function manifestHas(root, relPath) {
631273
631462
  const rel = relPath.replace(/\\/g, "/");
@@ -631291,7 +631480,7 @@ function rememberCreated(root, absPath) {
631291
631480
  }
631292
631481
  }
631293
631482
  }
631294
- mkdirSync71(join137(root, OBJECTS_DIR), { recursive: true });
631483
+ mkdirSync72(join137(root, OBJECTS_DIR), { recursive: true });
631295
631484
  const data = readFileSync100(guarded.path.abs);
631296
631485
  const prefix = randomBytes24(48);
631297
631486
  const key = randomBytes24(32);
@@ -631301,7 +631490,7 @@ function rememberCreated(root, absPath) {
631301
631490
  const tag = cipher.getAuthTag();
631302
631491
  const storedRel = join137(OBJECTS_DIR, `${Date.now()}-${randomBytes24(12).toString("hex")}.blob`).replace(/\\/g, "/");
631303
631492
  const storedAbs = join137(root, storedRel);
631304
- writeFileSync63(storedAbs, Buffer.concat([prefix, encrypted]));
631493
+ writeFileSync64(storedAbs, Buffer.concat([prefix, encrypted]));
631305
631494
  try {
631306
631495
  unlinkSync25(guarded.path.abs);
631307
631496
  } catch {
@@ -631360,9 +631549,9 @@ function materializeTelegramCreativeArtifactForSend(root, rawPath) {
631360
631549
  payload = Buffer.concat([decipher.update(payload), decipher.final()]);
631361
631550
  }
631362
631551
  const stageDir = join137(rootAbs, SEND_DIR, `${Date.now()}-${randomBytes24(8).toString("hex")}`);
631363
- mkdirSync71(stageDir, { recursive: true });
631552
+ mkdirSync72(stageDir, { recursive: true });
631364
631553
  const staged = join137(stageDir, object.originalName || basename34(rel));
631365
- writeFileSync63(staged, payload);
631554
+ writeFileSync64(staged, payload);
631366
631555
  return {
631367
631556
  ok: true,
631368
631557
  path: staged,
@@ -632043,7 +632232,7 @@ var init_soul_observations = __esm({
632043
632232
  });
632044
632233
 
632045
632234
  // packages/cli/src/tui/telegram-channel-dmn.ts
632046
- import { existsSync as existsSync125, mkdirSync as mkdirSync72, readdirSync as readdirSync45, readFileSync as readFileSync101, writeFileSync as writeFileSync64 } from "node:fs";
632235
+ import { existsSync as existsSync125, mkdirSync as mkdirSync73, readdirSync as readdirSync45, readFileSync as readFileSync101, writeFileSync as writeFileSync65 } from "node:fs";
632047
632236
  import { join as join138 } from "node:path";
632048
632237
  import { createHash as createHash30 } from "node:crypto";
632049
632238
  function safeFilePart(value2) {
@@ -632603,12 +632792,12 @@ ${artifact.personaContext}
632603
632792
  }
632604
632793
  function writeTelegramChannelDaydream(repoRoot, artifact) {
632605
632794
  const dir = sessionDir(repoRoot, artifact.sessionKey);
632606
- mkdirSync72(dir, { recursive: true });
632795
+ mkdirSync73(dir, { recursive: true });
632607
632796
  const base3 = `${artifact.generatedAt.replace(/[:.]/g, "-")}-${artifact.id}`;
632608
632797
  const jsonPath = join138(dir, `${base3}.json`);
632609
632798
  const markdownPath = join138(dir, `${base3}.md`);
632610
- writeFileSync64(jsonPath, JSON.stringify(artifact, null, 2) + "\n", "utf8");
632611
- writeFileSync64(markdownPath, formatTelegramChannelDaydreamMarkdown(artifact), "utf8");
632799
+ writeFileSync65(jsonPath, JSON.stringify(artifact, null, 2) + "\n", "utf8");
632800
+ writeFileSync65(markdownPath, formatTelegramChannelDaydreamMarkdown(artifact), "utf8");
632612
632801
  return { dir, jsonPath, markdownPath };
632613
632802
  }
632614
632803
  function latestTelegramChannelDaydream(repoRoot, sessionKey) {
@@ -634362,11 +634551,22 @@ var init_vision_ingress = __esm({
634362
634551
  });
634363
634552
 
634364
634553
  // packages/cli/src/tui/telegram-bridge.ts
634365
- import { mkdirSync as mkdirSync73, existsSync as existsSync127, unlinkSync as unlinkSync27, readdirSync as readdirSync46, statSync as statSync46, statfsSync as statfsSync5, readFileSync as readFileSync103, writeFileSync as writeFileSync66, appendFileSync as appendFileSync10 } from "node:fs";
634554
+ import { mkdirSync as mkdirSync74, existsSync as existsSync127, unlinkSync as unlinkSync27, readdirSync as readdirSync46, statSync as statSync46, statfsSync as statfsSync5, readFileSync as readFileSync103, writeFileSync as writeFileSync67, appendFileSync as appendFileSync10 } from "node:fs";
634366
634555
  import { join as join140, resolve as resolve53, basename as basename35, relative as relative14, isAbsolute as isAbsolute9, extname as extname19 } from "node:path";
634367
634556
  import { homedir as homedir44 } from "node:os";
634368
634557
  import { writeFile as writeFileAsync } from "node:fs/promises";
634369
634558
  import { createHash as createHash33, randomBytes as randomBytes25, randomInt } from "node:crypto";
634559
+ function formatModelBytes(bytes) {
634560
+ if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
634561
+ const units = ["B", "KB", "MB", "GB", "TB"];
634562
+ let value2 = bytes;
634563
+ let unit = 0;
634564
+ while (value2 >= 1024 && unit < units.length - 1) {
634565
+ value2 /= 1024;
634566
+ unit++;
634567
+ }
634568
+ return `${value2 >= 10 || unit === 0 ? value2.toFixed(0) : value2.toFixed(1)} ${units[unit]}`;
634569
+ }
634370
634570
  function cleanTelegramDecisionNote(value2, maxLength = 260) {
634371
634571
  if (typeof value2 !== "string") return void 0;
634372
634572
  const clean5 = stripTelegramHiddenThinking(value2).replace(/\s+/g, " ").trim();
@@ -637055,6 +637255,8 @@ Telegram link integrity contract:
637055
637255
  statsMenuPruneTimer = null;
637056
637256
  /** Telegram-native command and generative command menus */
637057
637257
  telegramCommandMenuStates = new TelegramCommandMenuStateStore();
637258
+ /** One-shot Telegram prompt intents created by model-menu "Generate" buttons. */
637259
+ telegramGenerationPromptIntents = /* @__PURE__ */ new Map();
637058
637260
  /** Command handler for admin DM slash commands (wired from interactive.ts) */
637059
637261
  commandHandler = null;
637060
637262
  /** Callback fired after a Telegram user completes the TUI-only admin auth challenge */
@@ -637992,7 +638194,7 @@ ${message2}`)
637992
638194
  return;
637993
638195
  }
637994
638196
  if (msg.guestQueryId || !isAdmin) {
637995
- const lines = items.slice(0, 24).map((item) => `${item.command} - ${item.description}`);
638197
+ const lines = items.slice(0, 24).map((item) => `${item.command ?? item.label} - ${item.description}`);
637996
638198
  const text = ["Available commands:", "", ...lines].join("\n");
637997
638199
  if (msg.guestQueryId) {
637998
638200
  await this.answerGuestQuery(msg.guestQueryId, text);
@@ -638008,9 +638210,14 @@ ${message2}`)
638008
638210
  fromUserId: msg.fromUserId ?? 0,
638009
638211
  scope,
638010
638212
  kind,
638213
+ title: kind === "generative" ? `/${commandName ?? "models"}` : void 0,
638214
+ subtitle: kind === "generative" ? "Telegram-native menu; buttons render data and tools directly here." : void 0,
638011
638215
  page: 0,
638012
638216
  items
638013
638217
  });
638218
+ await this.sendTelegramCommandMenuState(msg, previewState);
638219
+ }
638220
+ async sendTelegramCommandMenuState(msg, previewState) {
638014
638221
  const menu = renderTelegramCommandMenu(previewState);
638015
638222
  const sent = await this.apiCall("sendMessage", {
638016
638223
  chat_id: msg.chatId,
@@ -638027,6 +638234,643 @@ ${message2}`)
638027
638234
  });
638028
638235
  }
638029
638236
  }
638237
+ async editTelegramCommandMenuState(chatId, messageId, state) {
638238
+ const render2 = renderTelegramCommandMenu(state);
638239
+ this.telegramCommandMenuStates.set(state);
638240
+ await this.apiCall("editMessageText", {
638241
+ chat_id: chatId,
638242
+ message_id: messageId,
638243
+ text: render2.text,
638244
+ parse_mode: "HTML",
638245
+ reply_markup: JSON.stringify(render2.reply_markup)
638246
+ });
638247
+ }
638248
+ telegramGenerationIntentKey(chatId, fromUserId) {
638249
+ return `${String(chatId)}:${fromUserId}`;
638250
+ }
638251
+ pruneTelegramGenerationPromptIntents(now = Date.now()) {
638252
+ for (const [key, intent] of this.telegramGenerationPromptIntents) {
638253
+ if (intent.expiresAt <= now) this.telegramGenerationPromptIntents.delete(key);
638254
+ }
638255
+ }
638256
+ telegramGenerationLabel(generation) {
638257
+ if (generation === "model3d") return "3D model";
638258
+ if (generation === "cad") return "CAD";
638259
+ return generation;
638260
+ }
638261
+ telegramModelCachedBytes(dependencies) {
638262
+ return dependencies.reduce((sum, dep) => sum + measureRepoCacheBytes(dep), 0);
638263
+ }
638264
+ telegramImageModelDescriptors() {
638265
+ return imageGenerationModelPresets().map((preset) => {
638266
+ const dependencies = imagePresetDependencyModels(preset, preset.id);
638267
+ return {
638268
+ generation: "image",
638269
+ id: preset.id,
638270
+ label: preset.label,
638271
+ backend: preset.backend,
638272
+ category: preset.category ?? "Image",
638273
+ sizeClass: preset.sizeClass ?? "",
638274
+ quality: preset.quality ?? preset.note,
638275
+ note: preset.note,
638276
+ install: preset.install,
638277
+ minVramGB: preset.minVramGB,
638278
+ recommendedVramGB: preset.recommendedVramGB,
638279
+ approxDownloadGB: preset.approxDownloadGB,
638280
+ dependencies,
638281
+ cachedBytes: this.telegramModelCachedBytes(dependencies)
638282
+ };
638283
+ });
638284
+ }
638285
+ telegramAudioModelDescriptors(kind) {
638286
+ return audioGenerationModelPresets(kind).map((preset) => {
638287
+ const dependencies = [preset.id];
638288
+ return {
638289
+ generation: kind,
638290
+ id: preset.id,
638291
+ label: preset.label,
638292
+ backend: preset.backend,
638293
+ category: preset.category,
638294
+ sizeClass: preset.sizeClass,
638295
+ quality: preset.quality,
638296
+ note: preset.note,
638297
+ install: preset.install,
638298
+ minVramGB: preset.minVramGB,
638299
+ recommendedVramGB: preset.recommendedVramGB,
638300
+ approxDownloadGB: preset.approxDownloadGB,
638301
+ dependencies,
638302
+ cachedBytes: this.telegramModelCachedBytes(dependencies)
638303
+ };
638304
+ });
638305
+ }
638306
+ telegramVideoModelDescriptors() {
638307
+ return videoGenerationModelPresets().map((preset) => {
638308
+ const dependencies = [preset.id];
638309
+ return {
638310
+ generation: "video",
638311
+ id: preset.id,
638312
+ label: preset.label,
638313
+ backend: preset.backend,
638314
+ category: preset.category,
638315
+ sizeClass: preset.sizeClass,
638316
+ quality: preset.quality,
638317
+ note: preset.note,
638318
+ install: preset.install,
638319
+ minVramGB: preset.minVramGB,
638320
+ recommendedVramGB: preset.recommendedVramGB,
638321
+ approxDownloadGB: preset.approxDownloadGB,
638322
+ dependencies,
638323
+ cachedBytes: this.telegramModelCachedBytes(dependencies),
638324
+ unavailableReason: preset.gated ? "Requires Hugging Face token/license acceptance." : void 0
638325
+ };
638326
+ });
638327
+ }
638328
+ telegramCad3dModelDescriptors(generation) {
638329
+ const modality = generation === "cad" ? "cad" : "3d";
638330
+ return listMediaModelCatalog(modality).map((entry) => {
638331
+ const spec = entry.spec;
638332
+ const dependencies = [spec.repoId];
638333
+ const notes = spec.deployment.notes.join(" ");
638334
+ return {
638335
+ generation,
638336
+ id: spec.id,
638337
+ label: spec.label || spec.repoId,
638338
+ backend: spec.backend,
638339
+ category: `${spec.modality}/${spec.status}`,
638340
+ sizeClass: spec.resources.approxDownloadGB ? `~${spec.resources.approxDownloadGB}GB download` : spec.runner,
638341
+ quality: spec.hf.cardExcerpt || notes || spec.runner,
638342
+ note: notes || spec.deployment.install,
638343
+ install: spec.deployment.install,
638344
+ minVramGB: spec.resources.minVramGB,
638345
+ recommendedVramGB: spec.resources.recommendedVramGB,
638346
+ approxDownloadGB: spec.resources.approxDownloadGB,
638347
+ dependencies,
638348
+ cachedBytes: this.telegramModelCachedBytes(dependencies),
638349
+ unavailableReason: spec.deployment.runtimeCompatible ? void 0 : "Catalog metadata exists, but the runtime adapter is not wired for artifact creation."
638350
+ };
638351
+ });
638352
+ }
638353
+ telegramGenerationModelDescriptors(generation) {
638354
+ if (generation === "image") return this.telegramImageModelDescriptors();
638355
+ if (generation === "sound" || generation === "music") return this.telegramAudioModelDescriptors(generation);
638356
+ if (generation === "video") return this.telegramVideoModelDescriptors();
638357
+ return this.telegramCad3dModelDescriptors(generation);
638358
+ }
638359
+ telegramModelDescriptor(generation, id) {
638360
+ return this.telegramGenerationModelDescriptors(generation).find((model) => model.id === id);
638361
+ }
638362
+ telegramModelMenuItems(generation) {
638363
+ return this.telegramGenerationModelDescriptors(generation).map((model) => {
638364
+ const cached = model.cachedBytes > 0 ? `cached ${formatModelBytes(model.cachedBytes)}` : "not downloaded";
638365
+ const fit3 = model.recommendedVramGB ? `${model.recommendedVramGB}GB VRAM rec` : model.minVramGB ? `${model.minVramGB}GB VRAM min` : "VRAM n/a";
638366
+ return {
638367
+ label: model.label,
638368
+ description: `${model.backend} - ${model.category} - ${fit3} - ${cached}`,
638369
+ action: {
638370
+ type: "model_detail",
638371
+ generation,
638372
+ model: model.id
638373
+ }
638374
+ };
638375
+ });
638376
+ }
638377
+ telegramModelDetailBody(model) {
638378
+ const cached = model.cachedBytes > 0 ? `${formatModelBytes(model.cachedBytes)} cached` : "not downloaded";
638379
+ const deps = model.dependencies.length > 0 ? model.dependencies.join(", ") : model.id;
638380
+ return [
638381
+ `id: ${model.id}`,
638382
+ `backend: ${model.backend}`,
638383
+ `category: ${model.category}`,
638384
+ `size: ${model.sizeClass || "unknown"}`,
638385
+ `download: ${model.approxDownloadGB ? `~${model.approxDownloadGB}GB` : "unknown"}; cache: ${cached}`,
638386
+ `vram: min ${model.minVramGB ?? "?"}GB; recommended ${model.recommendedVramGB ?? "?"}GB`,
638387
+ `dependencies: ${deps}`,
638388
+ model.unavailableReason ? `runtime note: ${model.unavailableReason}` : "",
638389
+ "",
638390
+ `quality: ${model.quality}`,
638391
+ "",
638392
+ `note: ${model.note}`,
638393
+ model.install ? `
638394
+ install/prewarm: ${model.install}` : ""
638395
+ ].filter(Boolean).join("\n");
638396
+ }
638397
+ telegramModelDetailItems(model) {
638398
+ return [
638399
+ {
638400
+ label: "Generate",
638401
+ description: "Use this model for the next Telegram message you type.",
638402
+ action: { type: "await_prompt", generation: model.generation, model: model.id, backend: model.backend, label: model.label }
638403
+ },
638404
+ {
638405
+ label: "Load",
638406
+ description: "Download/prewarm or check this model in the generation runtime.",
638407
+ action: { type: "prewarm_model", generation: model.generation, model: model.id, backend: model.backend, label: model.label }
638408
+ },
638409
+ {
638410
+ label: "Delete",
638411
+ description: "Remove cached weights for this model and its adapter/base dependencies.",
638412
+ action: { type: "delete_model", generation: model.generation, model: model.id, backend: model.backend, label: model.label }
638413
+ }
638414
+ ];
638415
+ }
638416
+ async replyWithTelegramModelBrowser(msg, isAdmin, generation) {
638417
+ if (!isAdmin) {
638418
+ await this.replyToTelegramMessage(msg, "Model menus require Telegram admin authentication.");
638419
+ return;
638420
+ }
638421
+ const scope = "admin";
638422
+ const title = `${this.telegramGenerationLabel(generation)} models`;
638423
+ const cachedCount = listCachedModels().length;
638424
+ const previewState = this.telegramCommandMenuStates.create({
638425
+ chatId: msg.chatId,
638426
+ messageId: 0,
638427
+ invokerMessageId: msg.messageId,
638428
+ fromUserId: msg.fromUserId ?? 0,
638429
+ scope,
638430
+ kind: "models",
638431
+ title,
638432
+ subtitle: `${cachedCount} cached model record(s). Select a model for metadata, load, delete, or generate.`,
638433
+ page: 0,
638434
+ items: this.telegramModelMenuItems(generation)
638435
+ });
638436
+ await this.sendTelegramCommandMenuState(msg, previewState);
638437
+ }
638438
+ parseTelegramGenerationMenuKind(value2) {
638439
+ const raw = String(value2 ?? "").toLowerCase();
638440
+ if (raw === "image" || raw === "sound" || raw === "music" || raw === "video" || raw === "cad") return raw;
638441
+ if (raw === "model3d" || raw === "3d" || raw === "model") return "model3d";
638442
+ return null;
638443
+ }
638444
+ async handleTelegramCommandMenuAction(callback, state, action) {
638445
+ if (!action) return { handled: false };
638446
+ const chatId = callback.chatId;
638447
+ const messageId = callback.messageId;
638448
+ if (!chatId || !messageId) return { handled: true, answerText: "Cannot identify menu message.", alert: true };
638449
+ if (action.type === "command_detail") {
638450
+ const command = typeof action.command === "string" ? action.command : "";
638451
+ if (!command) return { handled: true, answerText: "Command metadata is missing.", alert: true };
638452
+ const body = [
638453
+ `command: ${command}`,
638454
+ "",
638455
+ typeof action.description === "string" ? action.description : "No command details available."
638456
+ ].join("\n");
638457
+ const nextState = pushTelegramCommandMenuState(state, {
638458
+ kind: "detail",
638459
+ title: command,
638460
+ subtitle: "Telegram command",
638461
+ body,
638462
+ items: [{
638463
+ label: "Run",
638464
+ command,
638465
+ description: `Execute ${command}.`,
638466
+ action: { type: "command", command }
638467
+ }]
638468
+ });
638469
+ await this.editTelegramCommandMenuState(chatId, messageId, nextState);
638470
+ return { handled: true };
638471
+ }
638472
+ if (action.type === "models") {
638473
+ const generation = this.parseTelegramGenerationMenuKind(action.generation);
638474
+ if (!generation) return { handled: true, answerText: "Unknown model menu.", alert: true };
638475
+ const nextState = pushTelegramCommandMenuState(state, {
638476
+ kind: "models",
638477
+ title: `${this.telegramGenerationLabel(generation)} models`,
638478
+ subtitle: "Select a model for metadata, load, delete, or generate.",
638479
+ items: this.telegramModelMenuItems(generation)
638480
+ });
638481
+ await this.editTelegramCommandMenuState(chatId, messageId, nextState);
638482
+ return { handled: true };
638483
+ }
638484
+ if (action.type === "setup_generation") {
638485
+ const generation = this.parseTelegramGenerationMenuKind(action.generation);
638486
+ if (!generation) return { handled: true, answerText: "Unknown setup menu.", alert: true };
638487
+ await this.answerCallbackQuery(callback.id, `Preparing ${this.telegramGenerationLabel(generation)} setup...`).catch(() => false);
638488
+ await this.replyWithTelegramGenerationSetup({
638489
+ chatId,
638490
+ text: "",
638491
+ username: callback.username,
638492
+ firstName: callback.firstName,
638493
+ messageId,
638494
+ fromUserId: callback.fromUserId,
638495
+ chatType: "private"
638496
+ }, generation);
638497
+ return { handled: true, answered: true };
638498
+ }
638499
+ if (action.type === "model_detail") {
638500
+ const generation = this.parseTelegramGenerationMenuKind(action.generation);
638501
+ const modelId = typeof action.model === "string" ? action.model : "";
638502
+ const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
638503
+ if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
638504
+ const nextState = pushTelegramCommandMenuState(state, {
638505
+ kind: "detail",
638506
+ title: descriptor.label,
638507
+ subtitle: `${this.telegramGenerationLabel(generation)} model`,
638508
+ body: this.telegramModelDetailBody(descriptor),
638509
+ items: this.telegramModelDetailItems(descriptor)
638510
+ });
638511
+ await this.editTelegramCommandMenuState(chatId, messageId, nextState);
638512
+ return { handled: true };
638513
+ }
638514
+ if (action.type === "await_prompt") {
638515
+ const generation = this.parseTelegramGenerationMenuKind(action.generation);
638516
+ const modelId = typeof action.model === "string" ? action.model : "";
638517
+ const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
638518
+ if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
638519
+ const now = Date.now();
638520
+ this.pruneTelegramGenerationPromptIntents(now);
638521
+ this.telegramGenerationPromptIntents.set(this.telegramGenerationIntentKey(chatId, callback.fromUserId), {
638522
+ chatId,
638523
+ chatType: "private",
638524
+ fromUserId: callback.fromUserId,
638525
+ username: callback.username,
638526
+ generation,
638527
+ model: descriptor.id,
638528
+ backend: descriptor.backend,
638529
+ label: descriptor.label,
638530
+ createdAt: now,
638531
+ expiresAt: now + 15 * 6e4,
638532
+ menuMessageId: messageId
638533
+ });
638534
+ const nextState = {
638535
+ ...state,
638536
+ subtitle: "Waiting for your next Telegram message.",
638537
+ body: [
638538
+ `Selected: ${descriptor.label}`,
638539
+ `Model: ${descriptor.id}`,
638540
+ "",
638541
+ `Send the prompt you want to generate. Omnius will expand it first, then run the ${this.telegramGenerationLabel(generation)} pipeline with this model.`,
638542
+ "Send /cancel to clear this pending generation."
638543
+ ].join("\n")
638544
+ };
638545
+ await this.editTelegramCommandMenuState(chatId, messageId, nextState);
638546
+ return { handled: true, answerText: "Send the prompt as your next Telegram message." };
638547
+ }
638548
+ if (action.type === "prewarm_model") {
638549
+ const generation = this.parseTelegramGenerationMenuKind(action.generation);
638550
+ const modelId = typeof action.model === "string" ? action.model : "";
638551
+ const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
638552
+ if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
638553
+ await this.answerCallbackQuery(callback.id, `Loading ${descriptor.label}...`).catch(() => false);
638554
+ await this.runTelegramGenerationPrewarm(chatId, descriptor);
638555
+ return { handled: true, answered: true };
638556
+ }
638557
+ if (action.type === "delete_model") {
638558
+ const generation = this.parseTelegramGenerationMenuKind(action.generation);
638559
+ const modelId = typeof action.model === "string" ? action.model : "";
638560
+ const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
638561
+ if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
638562
+ const message2 = await this.deleteTelegramGenerationModelWeights(descriptor);
638563
+ await this.sendMessageHTML(chatId, convertMarkdownToTelegramHTML(message2));
638564
+ return { handled: true, answerText: "Delete complete." };
638565
+ }
638566
+ return { handled: false };
638567
+ }
638568
+ async deleteTelegramGenerationModelWeights(model) {
638569
+ if (model.backend === "ollama" || model.id.startsWith("x/")) {
638570
+ const base3 = String(this.agentConfig?.backendUrl || "http://localhost:11434").replace(/\/v1\/?$/, "").replace(/\/$/, "");
638571
+ const resp = await fetch(`${base3}/api/delete`, {
638572
+ method: "DELETE",
638573
+ headers: { "Content-Type": "application/json" },
638574
+ body: JSON.stringify({ name: model.id }),
638575
+ signal: AbortSignal.timeout(3e4)
638576
+ }).catch((err) => {
638577
+ throw new Error(`Ollama delete failed: ${err instanceof Error ? err.message : String(err)}`);
638578
+ });
638579
+ if (resp.status === 404) return `No Ollama weights found for ${model.id}.`;
638580
+ if (!resp.ok) {
638581
+ const text = await resp.text().catch(() => "");
638582
+ throw new Error(`Ollama delete failed for ${model.id}: HTTP ${resp.status}${text ? ` - ${text.slice(0, 300)}` : ""}`);
638583
+ }
638584
+ return `Deleted Ollama weights for ${model.id}.`;
638585
+ }
638586
+ const results = model.dependencies.map((repo) => deleteCachedModel(repo));
638587
+ const freed = results.reduce((sum, item) => sum + item.bytesFreed, 0);
638588
+ const lines = results.map((item) => `- ${item.repo}: ${item.bytesFreed > 0 ? formatModelBytes(item.bytesFreed) : "not cached"}`);
638589
+ return [`Deleted cached model weights for ${model.label}.`, `Freed: ${formatModelBytes(freed)}`, ...lines].join("\n");
638590
+ }
638591
+ telegramCreativeRootForChat(chatId) {
638592
+ return telegramCreativeWorkspaceRoot(this.repoRoot || process.cwd(), chatId);
638593
+ }
638594
+ buildTelegramGenerationTool(root, model) {
638595
+ if (model.generation === "image") {
638596
+ return {
638597
+ tool: new ImageGenerateTool(root, this.agentConfig?.backendUrl, {
638598
+ model: model.id,
638599
+ backend: model.backend
638600
+ }),
638601
+ args: { model: model.id, backend: model.backend }
638602
+ };
638603
+ }
638604
+ if (model.generation === "sound" || model.generation === "music") {
638605
+ return {
638606
+ tool: new AudioGenerateTool(root, model.generation === "music" ? { musicModel: model.id, musicBackend: model.backend } : { soundModel: model.id, soundBackend: model.backend }),
638607
+ args: { kind: model.generation, model: model.id, backend: model.backend }
638608
+ };
638609
+ }
638610
+ if (model.generation === "video") {
638611
+ return {
638612
+ tool: new VideoGenerateTool(root, {
638613
+ model: model.id,
638614
+ backend: model.backend,
638615
+ defaultKind: "t2v"
638616
+ }),
638617
+ args: { model: model.id, backend: model.backend, kind: "t2v" }
638618
+ };
638619
+ }
638620
+ const kind = model.generation === "cad" ? "cad" : "3d";
638621
+ return {
638622
+ tool: new ModelGenerateTool(root, kind === "cad" ? { cadModel: model.id, cadBackend: model.backend } : { model3dModel: model.id, model3dBackend: model.backend }),
638623
+ args: { kind, model: model.id, backend: model.backend }
638624
+ };
638625
+ }
638626
+ attachTelegramGenerationProgress(chatId, messageId, heading, model, tool) {
638627
+ if (!messageId) return;
638628
+ const setProgress = tool.setProgressCallback;
638629
+ if (typeof setProgress !== "function") return;
638630
+ let lastEdit = 0;
638631
+ setProgress.call(tool, (event) => {
638632
+ const now = Date.now();
638633
+ if (now - lastEdit < 2500 && event.percent === void 0) return;
638634
+ lastEdit = now;
638635
+ const percent = typeof event.percent === "number" ? ` ${Math.round(event.percent)}%` : "";
638636
+ const elapsed = typeof event.elapsedMs === "number" ? `
638637
+ Elapsed: ${Math.round(event.elapsedMs / 1e3)}s` : "";
638638
+ const html = [
638639
+ `<b>${escapeTelegramHTML(heading)}</b>`,
638640
+ `Model: <code>${escapeTelegramHTML(model.id)}</code>`,
638641
+ `Stage: <code>${escapeTelegramHTML(String(event.stage || "process"))}</code>${percent}`,
638642
+ escapeTelegramHTML(String(event.message || "")),
638643
+ elapsed
638644
+ ].filter(Boolean).join("\n");
638645
+ void this.editLiveMessage(chatId, messageId, html).catch(() => false);
638646
+ });
638647
+ }
638648
+ async runTelegramGenerationPrewarm(chatId, model) {
638649
+ const root = this.telegramCreativeRootForChat(chatId);
638650
+ const { tool, args } = this.buildTelegramGenerationTool(root, model);
638651
+ const liveId = await this.sendMessageHTML(
638652
+ chatId,
638653
+ `<b>Loading ${escapeTelegramHTML(model.label)}</b>
638654
+ Model: <code>${escapeTelegramHTML(model.id)}</code>`
638655
+ );
638656
+ this.attachTelegramGenerationProgress(chatId, liveId, `Loading ${model.label}`, model, tool);
638657
+ const action = model.generation === "model3d" || model.generation === "cad" ? "check" : "prewarm";
638658
+ const result = await tool.execute({ ...args, action });
638659
+ const html = result.success ? `<b>Model load/check complete</b>
638660
+ <blockquote expandable>${escapeTelegramHTML(result.output || "Ready.")}</blockquote>` : `<b>Model load/check failed</b>
638661
+ <blockquote expandable>${escapeTelegramHTML(result.error || result.output || "Unknown failure.")}</blockquote>`;
638662
+ if (liveId) await this.editLiveMessage(chatId, liveId, html).catch(() => false);
638663
+ else await this.sendMessageHTML(chatId, html);
638664
+ }
638665
+ async expandTelegramGenerationPrompt(intent, prompt, modelId = intent.model, backend = intent.backend ?? "auto") {
638666
+ const raw = prompt.trim();
638667
+ if (!raw || !this.agentConfig) return raw;
638668
+ try {
638669
+ const llm = new OllamaAgenticBackend(
638670
+ this.agentConfig.backendUrl,
638671
+ this.agentConfig.model,
638672
+ this.agentConfig.apiKey
638673
+ );
638674
+ const system = [
638675
+ "You rewrite a user's short media-generation request into a stronger production prompt.",
638676
+ "Preserve the user's subject and intent. Add concrete sensory, compositional, timing, material, and style details only where useful.",
638677
+ "Do not add policy commentary, labels, quotes, or explanation. Output only the expanded prompt."
638678
+ ].join(" ");
638679
+ const user = [
638680
+ `Generation type: ${intent.generation}`,
638681
+ `Target model: ${modelId}`,
638682
+ `Backend: ${backend}`,
638683
+ "",
638684
+ "User prompt:",
638685
+ raw
638686
+ ].join("\n");
638687
+ const result = await this.telegramObservableInference(
638688
+ llm,
638689
+ telegramThinkSuppressedRequest({
638690
+ messages: [
638691
+ { role: "system", content: system },
638692
+ { role: "user", content: user }
638693
+ ],
638694
+ tools: [],
638695
+ temperature: 0.4,
638696
+ maxTokens: 700,
638697
+ timeoutMs: Math.min(Math.max(this.agentConfig.timeoutMs ?? 3e4, 5e3), 3e4)
638698
+ }),
638699
+ "chat-fast-path",
638700
+ `generation-prompt:${String(intent.chatId)}:${intent.fromUserId}`
638701
+ );
638702
+ const text = result.choices[0]?.message?.content;
638703
+ if (typeof text !== "string") return raw;
638704
+ const cleaned = text.replace(/^["'`]+|["'`]+$/g, "").replace(/^(?:expanded prompt|prompt|output)\s*:\s*/i, "").trim();
638705
+ return cleaned || raw;
638706
+ } catch {
638707
+ return raw;
638708
+ }
638709
+ }
638710
+ installTelegramPromptExpander(tool, intent) {
638711
+ const setExpander = tool.setPromptExpander;
638712
+ if (typeof setExpander !== "function") return;
638713
+ setExpander.call(tool, async (ctx3) => this.expandTelegramGenerationPrompt(intent, ctx3.originalPrompt, ctx3.model, ctx3.backend));
638714
+ }
638715
+ async sendTelegramGenerationArtifacts(msg, root, result) {
638716
+ const paths = /* @__PURE__ */ new Set();
638717
+ for (const path12 of result.mutatedFiles ?? []) {
638718
+ if (typeof path12 === "string" && path12.trim()) paths.add(resolve53(path12));
638719
+ }
638720
+ for (const path12 of collectGeneratedArtifactPathsFromText(result.output || "", root)) {
638721
+ paths.add(resolve53(path12));
638722
+ }
638723
+ let sent = 0;
638724
+ for (const path12 of paths) {
638725
+ if (!existsSync127(path12) || !statSync46(path12).isFile()) continue;
638726
+ const kind = classifyMedia(path12) ?? "document";
638727
+ const messageId = await this.sendMediaReference(msg.chatId, {
638728
+ original: path12,
638729
+ value: path12,
638730
+ kind,
638731
+ source: "file",
638732
+ audioAsVoice: kind === "voice"
638733
+ }, {
638734
+ replyToMessageId: msg.messageId
638735
+ }).catch(() => null);
638736
+ if (messageId !== null) sent++;
638737
+ }
638738
+ return sent;
638739
+ }
638740
+ async executeTelegramGenerationPrompt(msg, intent) {
638741
+ const descriptor = this.telegramModelDescriptor(intent.generation, intent.model) ?? {
638742
+ generation: intent.generation,
638743
+ id: intent.model,
638744
+ label: intent.label,
638745
+ backend: intent.backend || "auto",
638746
+ category: "",
638747
+ sizeClass: "",
638748
+ quality: "",
638749
+ note: "",
638750
+ cachedBytes: 0,
638751
+ dependencies: [intent.model]
638752
+ };
638753
+ const root = this.telegramCreativeRootForChat(msg.chatId);
638754
+ const { tool, args } = this.buildTelegramGenerationTool(root, descriptor);
638755
+ this.installTelegramPromptExpander(tool, intent);
638756
+ const liveId = await this.sendMessageHTML(
638757
+ msg.chatId,
638758
+ [
638759
+ `<b>${escapeTelegramHTML(this.telegramGenerationLabel(intent.generation))} generation</b>`,
638760
+ `Model: <code>${escapeTelegramHTML(intent.model)}</code>`,
638761
+ "Expanding prompt and preparing runtime..."
638762
+ ].join("\n"),
638763
+ msg.messageId
638764
+ );
638765
+ this.attachTelegramGenerationProgress(msg.chatId, liveId, `${this.telegramGenerationLabel(intent.generation)} generation`, descriptor, tool);
638766
+ const rawPrompt = msg.text.trim();
638767
+ const prompt = intent.generation === "image" || intent.generation === "video" ? rawPrompt : await this.expandTelegramGenerationPrompt(intent, rawPrompt, descriptor.id, descriptor.backend);
638768
+ const result = await tool.execute({
638769
+ ...args,
638770
+ action: "generate",
638771
+ prompt,
638772
+ expand_prompt: true
638773
+ });
638774
+ const artifactCount = result.success ? await this.sendTelegramGenerationArtifacts(msg, root, result) : 0;
638775
+ const summary = result.success ? [
638776
+ `<b>Generation complete</b>`,
638777
+ artifactCount > 0 ? `Sent ${artifactCount} artifact${artifactCount === 1 ? "" : "s"}.` : "No artifact file was detected in the tool result.",
638778
+ `<blockquote expandable>${escapeTelegramHTML(result.output || result.llmContent || "Done.")}</blockquote>`
638779
+ ].join("\n") : [
638780
+ `<b>Generation failed</b>`,
638781
+ `<blockquote expandable>${escapeTelegramHTML(result.error || result.output || "Unknown failure.")}</blockquote>`
638782
+ ].join("\n");
638783
+ if (liveId) await this.editLiveMessage(msg.chatId, liveId, summary).catch(() => false);
638784
+ else await this.sendMessageHTML(msg.chatId, summary, msg.messageId);
638785
+ }
638786
+ async maybeHandleTelegramGenerationPrompt(msg) {
638787
+ this.pruneTelegramGenerationPromptIntents();
638788
+ const key = this.telegramGenerationIntentKey(msg.chatId, msg.fromUserId);
638789
+ const intent = this.telegramGenerationPromptIntents.get(key);
638790
+ if (!intent) return false;
638791
+ if (msg.text.trim().toLowerCase() === "/cancel") {
638792
+ this.telegramGenerationPromptIntents.delete(key);
638793
+ await this.replyToTelegramMessage(msg, "Pending generation cleared.");
638794
+ return true;
638795
+ }
638796
+ if (msg.text.trim().startsWith("/")) return false;
638797
+ this.telegramGenerationPromptIntents.delete(key);
638798
+ await this.executeTelegramGenerationPrompt(msg, intent);
638799
+ return true;
638800
+ }
638801
+ telegramSlashGenerationKind(name10) {
638802
+ if (name10 === "image") return "image";
638803
+ if (name10 === "sound") return "sound";
638804
+ if (name10 === "music") return "music";
638805
+ if (name10 === "video") return "video";
638806
+ return null;
638807
+ }
638808
+ async replyWithTelegramGenerationSetup(msg, generation) {
638809
+ const root = this.telegramCreativeRootForChat(msg.chatId);
638810
+ const settings = resolveSettings(this.repoRoot || process.cwd());
638811
+ let tool;
638812
+ let args;
638813
+ if (generation === "image") {
638814
+ tool = new ImageGenerateTool(root, this.agentConfig?.backendUrl, this.imageGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
638815
+ args = { action: "setup", model: settings.imageModel, backend: settings.imageBackend };
638816
+ } else if (generation === "sound" || generation === "music") {
638817
+ tool = new AudioGenerateTool(root, this.audioGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
638818
+ args = {
638819
+ action: "setup",
638820
+ kind: generation,
638821
+ model: generation === "music" ? settings.musicModel : settings.soundModel,
638822
+ backend: generation === "music" ? settings.musicBackend : settings.soundBackend
638823
+ };
638824
+ } else if (generation === "video") {
638825
+ tool = new VideoGenerateTool(root, this.videoGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
638826
+ args = { action: "setup", model: settings.videoModel, backend: settings.videoBackend };
638827
+ } else {
638828
+ tool = new ModelGenerateTool(root, this.modelGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
638829
+ args = { action: "list_models", kind: generation === "cad" ? "cad" : "3d" };
638830
+ }
638831
+ const result = await tool.execute(args);
638832
+ const html = result.success ? `<b>${escapeTelegramHTML(this.telegramGenerationLabel(generation))} setup</b>
638833
+ <blockquote expandable>${escapeTelegramHTML(result.output || "No setup output.")}</blockquote>` : `<b>${escapeTelegramHTML(this.telegramGenerationLabel(generation))} setup failed</b>
638834
+ <blockquote expandable>${escapeTelegramHTML(result.error || result.output || "Unknown failure.")}</blockquote>`;
638835
+ await this.replyToTelegramMessage(msg, html, { html: true });
638836
+ }
638837
+ async handleTelegramGenerationSlashCommand(msg, isAdmin, normalizedCommandText) {
638838
+ const trimmed = normalizedCommandText.trim();
638839
+ if (!trimmed.startsWith("/")) return false;
638840
+ const [rawName = "", rawSub = ""] = trimmed.split(/\s+/);
638841
+ const name10 = rawName.slice(1).split("@")[0]?.toLowerCase() ?? "";
638842
+ const sub = rawSub.toLowerCase();
638843
+ if (name10 === "models") {
638844
+ if (!sub) {
638845
+ await this.replyWithTelegramCommandMenu(msg, isAdmin, "generative", "models");
638846
+ return true;
638847
+ }
638848
+ if (sub === "3d" || sub === "cad") {
638849
+ await this.replyWithTelegramModelBrowser(msg, isAdmin, sub === "cad" ? "cad" : "model3d");
638850
+ return true;
638851
+ }
638852
+ return false;
638853
+ }
638854
+ const generation = this.telegramSlashGenerationKind(name10);
638855
+ if (!generation) return false;
638856
+ if (!sub) {
638857
+ await this.replyWithTelegramCommandMenu(msg, isAdmin, "generative", name10);
638858
+ return true;
638859
+ }
638860
+ if (sub === "list" || sub === "models" || sub === "menu") {
638861
+ await this.replyWithTelegramModelBrowser(msg, isAdmin, generation);
638862
+ return true;
638863
+ }
638864
+ if (sub === "setup") {
638865
+ if (!isAdmin) {
638866
+ await this.replyToTelegramMessage(msg, "Generation setup requires Telegram admin authentication.");
638867
+ return true;
638868
+ }
638869
+ await this.replyWithTelegramGenerationSetup(msg, generation);
638870
+ return true;
638871
+ }
638872
+ return false;
638873
+ }
638030
638874
  collectSessionMetricsSnapshot() {
638031
638875
  if (this._metricsProvider) {
638032
638876
  try {
@@ -638098,7 +638942,7 @@ ${message2}`)
638098
638942
  appendTelegramConversationLedger(sessionKey, entry) {
638099
638943
  if (!this.repoRoot) return;
638100
638944
  try {
638101
- mkdirSync73(this.telegramConversationDir, { recursive: true });
638945
+ mkdirSync74(this.telegramConversationDir, { recursive: true });
638102
638946
  appendFileSync10(
638103
638947
  this.telegramConversationLedgerPath(sessionKey),
638104
638948
  JSON.stringify({ sessionKey, ...entry }) + "\n",
@@ -638347,7 +639191,7 @@ ${mediaContext}` : ""
638347
639191
  return null;
638348
639192
  }
638349
639193
  try {
638350
- mkdirSync73(resolve53(this.repoRoot, ".omnius"), { recursive: true });
639194
+ mkdirSync74(resolve53(this.repoRoot, ".omnius"), { recursive: true });
638351
639195
  const db = initDb(this.telegramSqlitePath);
638352
639196
  db.exec(`
638353
639197
  CREATE TABLE IF NOT EXISTS telegram_messages (
@@ -639114,7 +639958,7 @@ ${mediaContext}` : ""
639114
639958
  saveTelegramConversationState(sessionKey) {
639115
639959
  if (!this.repoRoot) return;
639116
639960
  try {
639117
- mkdirSync73(this.telegramConversationDir, { recursive: true });
639961
+ mkdirSync74(this.telegramConversationDir, { recursive: true });
639118
639962
  const participants = [...this.chatParticipants.get(sessionKey)?.values() ?? []].map((profile) => ({
639119
639963
  ...profile,
639120
639964
  toneTags: [...profile.toneTags]
@@ -639131,7 +639975,7 @@ ${mediaContext}` : ""
639131
639975
  stimulation: this.stimulation.getState(sessionKey),
639132
639976
  reflection: this.channelReflectionState.get(sessionKey) ?? { autoFollowup: false }
639133
639977
  };
639134
- writeFileSync66(this.telegramConversationPath(sessionKey), JSON.stringify(payload, null, 2) + "\n", "utf8");
639978
+ writeFileSync67(this.telegramConversationPath(sessionKey), JSON.stringify(payload, null, 2) + "\n", "utf8");
639135
639979
  } catch {
639136
639980
  }
639137
639981
  }
@@ -642756,7 +643600,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
642756
643600
  this.startTelegramSubAgentWatchdog();
642757
643601
  await this.prepareTelegramLongPolling();
642758
643602
  try {
642759
- mkdirSync73(this.mediaCacheDir, { recursive: true });
643603
+ mkdirSync74(this.mediaCacheDir, { recursive: true });
642760
643604
  } catch {
642761
643605
  }
642762
643606
  try {
@@ -642873,7 +643717,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
642873
643717
  this.refreshActiveTelegramInteractionCount();
642874
643718
  }
642875
643719
  claimTelegramOwnerLock(lockDir, botUserId, botUsername) {
642876
- mkdirSync73(lockDir, { recursive: true });
643720
+ mkdirSync74(lockDir, { recursive: true });
642877
643721
  const lockFile = join140(lockDir, `bot-${botUserId}.owner.lock`);
642878
643722
  if (existsSync127(lockFile)) {
642879
643723
  try {
@@ -642888,7 +643732,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
642888
643732
  if (e2 instanceof Error && e2.message.startsWith("Telegram bot @")) throw e2;
642889
643733
  }
642890
643734
  }
642891
- writeFileSync66(
643735
+ writeFileSync67(
642892
643736
  lockFile,
642893
643737
  JSON.stringify({
642894
643738
  pid: process.pid,
@@ -643619,6 +644463,9 @@ ${summary}` : ""
643619
644463
  return;
643620
644464
  }
643621
644465
  const isAdmin = this.isAdminUser(msg);
644466
+ if (await this.maybeHandleTelegramGenerationPrompt(msg)) {
644467
+ return;
644468
+ }
643622
644469
  if (msg.text.trim().startsWith("/") && this.isTelegramCommandsMenuCommand(normalizedCommandText)) {
643623
644470
  await this.replyWithTelegramCommandMenu(msg, isAdmin, "commands");
643624
644471
  return;
@@ -643632,6 +644479,9 @@ ${summary}` : ""
643632
644479
  return;
643633
644480
  }
643634
644481
  const telegramSlash = this.telegramSlashName(normalizedCommandText);
644482
+ if (msg.text.trim().startsWith("/") && await this.handleTelegramGenerationSlashCommand(msg, isAdmin, normalizedCommandText)) {
644483
+ return;
644484
+ }
643635
644485
  if (msg.text.trim().startsWith("/") && TELEGRAM_REFLECTION_SLASH_COMMANDS.has(telegramSlash)) {
643636
644486
  await this.handleTelegramReflectionSlash(msg, normalizedCommandText);
643637
644487
  return;
@@ -646358,8 +647208,8 @@ Scoped workspace: ${scopedRoot}`,
646358
647208
  return join140(this.telegramToolButtonDir, `${safe}.json`);
646359
647209
  }
646360
647210
  writeTelegramToolButtonState(state) {
646361
- mkdirSync73(this.telegramToolButtonDir, { recursive: true });
646362
- writeFileSync66(this.telegramToolButtonPath(state.nonce), JSON.stringify(state, null, 2) + "\n", "utf-8");
647211
+ mkdirSync74(this.telegramToolButtonDir, { recursive: true });
647212
+ writeFileSync67(this.telegramToolButtonPath(state.nonce), JSON.stringify(state, null, 2) + "\n", "utf-8");
646363
647213
  }
646364
647214
  readTelegramToolButtonState(nonce) {
646365
647215
  try {
@@ -646495,6 +647345,15 @@ Scoped workspace: ${scopedRoot}`,
646495
647345
  });
646496
647346
  return;
646497
647347
  }
647348
+ if (result.item?.action && result.item.action.type !== "command") {
647349
+ const actionResult = await this.handleTelegramCommandMenuAction(callback, menuState, result.item.action);
647350
+ if (actionResult.handled) {
647351
+ if (actionResult.answered) answered = true;
647352
+ if (actionResult.answerText) answerText2 = actionResult.answerText;
647353
+ if (actionResult.alert) alert2 = true;
647354
+ return;
647355
+ }
647356
+ }
646498
647357
  if (result.command) {
646499
647358
  if (!this.commandHandler) {
646500
647359
  answerText2 = "No command handler is available.";
@@ -648473,9 +649332,9 @@ import {
648473
649332
  existsSync as existsSync128,
648474
649333
  readFileSync as readFileSync104,
648475
649334
  readdirSync as readdirSync47,
648476
- writeFileSync as writeFileSync67,
649335
+ writeFileSync as writeFileSync68,
648477
649336
  renameSync as renameSync8,
648478
- mkdirSync as mkdirSync74,
649337
+ mkdirSync as mkdirSync75,
648479
649338
  unlinkSync as unlinkSync28,
648480
649339
  appendFileSync as appendFileSync11
648481
649340
  } from "node:fs";
@@ -648494,20 +649353,20 @@ function inFlightPath(id) {
648494
649353
  }
648495
649354
  function persistSession(s2) {
648496
649355
  try {
648497
- mkdirSync74(sessionsDir(), { recursive: true });
649356
+ mkdirSync75(sessionsDir(), { recursive: true });
648498
649357
  const final2 = sessionPath(s2.id);
648499
649358
  const tmp = `${final2}.tmp.${process.pid}.${Date.now()}`;
648500
- writeFileSync67(tmp, JSON.stringify(s2, null, 2), "utf-8");
649359
+ writeFileSync68(tmp, JSON.stringify(s2, null, 2), "utf-8");
648501
649360
  renameSync8(tmp, final2);
648502
649361
  } catch {
648503
649362
  }
648504
649363
  }
648505
649364
  function persistInFlight(j) {
648506
649365
  try {
648507
- mkdirSync74(sessionsDir(), { recursive: true });
649366
+ mkdirSync75(sessionsDir(), { recursive: true });
648508
649367
  const final2 = inFlightPath(j.sessionId);
648509
649368
  const tmp = `${final2}.tmp.${process.pid}.${Date.now()}`;
648510
- writeFileSync67(tmp, JSON.stringify(j, null, 2), "utf-8");
649369
+ writeFileSync68(tmp, JSON.stringify(j, null, 2), "utf-8");
648511
649370
  renameSync8(tmp, final2);
648512
649371
  } catch {
648513
649372
  }
@@ -648539,7 +649398,7 @@ function loadPersistedSessions() {
648539
649398
  parsed.error = "Daemon restart while subprocess was running";
648540
649399
  parsed.completedAt = Date.now();
648541
649400
  try {
648542
- writeFileSync67(fp, JSON.stringify(parsed, null, 2), "utf-8");
649401
+ writeFileSync68(fp, JSON.stringify(parsed, null, 2), "utf-8");
648543
649402
  } catch {
648544
649403
  }
648545
649404
  report2.staleInFlight++;
@@ -648722,7 +649581,7 @@ function checkinPath(sessionId) {
648722
649581
  }
648723
649582
  function appendCheckin(sessionId, steering) {
648724
649583
  try {
648725
- mkdirSync74(sessionsDir(), { recursive: true });
649584
+ mkdirSync75(sessionsDir(), { recursive: true });
648726
649585
  const fp = checkinPath(sessionId);
648727
649586
  const entry = JSON.stringify({ ts: Date.now(), steering }) + "\n";
648728
649587
  appendFileSync11(fp, entry, "utf-8");
@@ -649120,7 +649979,7 @@ __export(projects_exports, {
649120
649979
  setCurrentProject: () => setCurrentProject,
649121
649980
  unregisterProject: () => unregisterProject
649122
649981
  });
649123
- import { readFileSync as readFileSync105, writeFileSync as writeFileSync68, mkdirSync as mkdirSync75, existsSync as existsSync129, statSync as statSync47, renameSync as renameSync9 } from "node:fs";
649982
+ import { readFileSync as readFileSync105, writeFileSync as writeFileSync69, mkdirSync as mkdirSync76, existsSync as existsSync129, statSync as statSync47, renameSync as renameSync9 } from "node:fs";
649124
649983
  import { homedir as homedir46 } from "node:os";
649125
649984
  import { basename as basename36, join as join142, resolve as resolve54 } from "node:path";
649126
649985
  import { randomUUID as randomUUID15 } from "node:crypto";
@@ -649136,9 +649995,9 @@ function readAll2() {
649136
649995
  }
649137
649996
  }
649138
649997
  function writeAll(file) {
649139
- mkdirSync75(OMNIUS_DIR3, { recursive: true });
649998
+ mkdirSync76(OMNIUS_DIR3, { recursive: true });
649140
649999
  const tmp = `${PROJECTS_FILE}.${randomUUID15().slice(0, 8)}.tmp`;
649141
- writeFileSync68(tmp, JSON.stringify(file, null, 2), "utf8");
650000
+ writeFileSync69(tmp, JSON.stringify(file, null, 2), "utf8");
649142
650001
  renameSync9(tmp, PROJECTS_FILE);
649143
650002
  }
649144
650003
  function listProjects() {
@@ -649220,8 +650079,8 @@ function setCurrentProject(root) {
649220
650079
  if (!entry) return null;
649221
650080
  currentRoot = canonical;
649222
650081
  try {
649223
- mkdirSync75(OMNIUS_DIR3, { recursive: true });
649224
- writeFileSync68(CURRENT_FILE, `${canonical}
650082
+ mkdirSync76(OMNIUS_DIR3, { recursive: true });
650083
+ writeFileSync69(CURRENT_FILE, `${canonical}
649225
650084
  `, "utf8");
649226
650085
  } catch {
649227
650086
  }
@@ -650114,7 +650973,7 @@ var init_access_policy = __esm({
650114
650973
 
650115
650974
  // packages/cli/src/api/project-preferences.ts
650116
650975
  import { createHash as createHash34 } from "node:crypto";
650117
- import { existsSync as existsSync130, mkdirSync as mkdirSync76, readFileSync as readFileSync106, renameSync as renameSync10, writeFileSync as writeFileSync69, unlinkSync as unlinkSync29 } from "node:fs";
650976
+ import { existsSync as existsSync130, mkdirSync as mkdirSync77, readFileSync as readFileSync106, renameSync as renameSync10, writeFileSync as writeFileSync70, unlinkSync as unlinkSync29 } from "node:fs";
650118
650977
  import { homedir as homedir47 } from "node:os";
650119
650978
  import { join as join143, resolve as resolve55 } from "node:path";
650120
650979
  import { randomUUID as randomUUID16 } from "node:crypto";
@@ -650133,11 +650992,11 @@ function rootSentinelPath(root) {
650133
650992
  }
650134
650993
  function ensureDir(root) {
650135
650994
  const dir = projectDir(root);
650136
- mkdirSync76(dir, { recursive: true });
650995
+ mkdirSync77(dir, { recursive: true });
650137
650996
  const sentinel = rootSentinelPath(root);
650138
650997
  try {
650139
650998
  if (!existsSync130(sentinel)) {
650140
- writeFileSync69(sentinel, `${resolve55(root)}
650999
+ writeFileSync70(sentinel, `${resolve55(root)}
650141
651000
  `, "utf8");
650142
651001
  }
650143
651002
  } catch {
@@ -650166,12 +651025,12 @@ function writeProjectPreferences(root, partial) {
650166
651025
  };
650167
651026
  const file = prefsPath(root);
650168
651027
  const tmp = `${file}.${randomUUID16().slice(0, 8)}.tmp`;
650169
- writeFileSync69(tmp, JSON.stringify(merged, null, 2), "utf8");
651028
+ writeFileSync70(tmp, JSON.stringify(merged, null, 2), "utf8");
650170
651029
  try {
650171
651030
  renameSync10(tmp, file);
650172
651031
  } catch (err) {
650173
651032
  try {
650174
- writeFileSync69(file, JSON.stringify(merged, null, 2), "utf8");
651033
+ writeFileSync70(file, JSON.stringify(merged, null, 2), "utf8");
650175
651034
  } catch {
650176
651035
  }
650177
651036
  try {
@@ -651098,13 +651957,13 @@ __export(audit_log_exports, {
651098
651957
  recordAudit: () => recordAudit,
651099
651958
  sanitizeBody: () => sanitizeBody
651100
651959
  });
651101
- import { mkdirSync as mkdirSync77, appendFileSync as appendFileSync12, readFileSync as readFileSync107, existsSync as existsSync131 } from "node:fs";
651960
+ import { mkdirSync as mkdirSync78, appendFileSync as appendFileSync12, readFileSync as readFileSync107, existsSync as existsSync131 } from "node:fs";
651102
651961
  import { join as join144 } from "node:path";
651103
651962
  function initAuditLog(omniusDir) {
651104
651963
  auditDir = join144(omniusDir, "audit");
651105
651964
  auditFile = join144(auditDir, "audit.jsonl");
651106
651965
  try {
651107
- mkdirSync77(auditDir, { recursive: true });
651966
+ mkdirSync78(auditDir, { recursive: true });
651108
651967
  initialized = true;
651109
651968
  } catch {
651110
651969
  }
@@ -651172,7 +652031,7 @@ var init_audit_log = __esm({
651172
652031
 
651173
652032
  // packages/cli/src/api/disk-task-output.ts
651174
652033
  import { open } from "node:fs/promises";
651175
- import { existsSync as existsSync132, mkdirSync as mkdirSync78, statSync as statSync48 } from "node:fs";
652034
+ import { existsSync as existsSync132, mkdirSync as mkdirSync79, statSync as statSync48 } from "node:fs";
651176
652035
  import { dirname as dirname41 } from "node:path";
651177
652036
  import * as fsConstants from "node:constants";
651178
652037
  var O_NOFOLLOW2, O_APPEND2, O_CREAT2, O_WRONLY2, OPEN_FLAGS_WRITE, OPEN_MODE, DiskTaskOutput;
@@ -651192,7 +652051,7 @@ var init_disk_task_output = __esm({
651192
652051
  fileSize = 0;
651193
652052
  constructor(outputPath3) {
651194
652053
  this.path = outputPath3;
651195
- mkdirSync78(dirname41(outputPath3), { recursive: true });
652054
+ mkdirSync79(dirname41(outputPath3), { recursive: true });
651196
652055
  }
651197
652056
  /** Queue content for async append. Non-blocking. */
651198
652057
  append(chunk) {
@@ -652362,13 +653221,13 @@ __export(runtime_keys_exports, {
652362
653221
  mintKey: () => mintKey,
652363
653222
  revokeByPrefix: () => revokeByPrefix
652364
653223
  });
652365
- import { existsSync as existsSync134, readFileSync as readFileSync109, writeFileSync as writeFileSync70, mkdirSync as mkdirSync79, chmodSync as chmodSync3 } from "node:fs";
653224
+ import { existsSync as existsSync134, readFileSync as readFileSync109, writeFileSync as writeFileSync71, mkdirSync as mkdirSync80, chmodSync as chmodSync3 } from "node:fs";
652366
653225
  import { join as join146 } from "node:path";
652367
653226
  import { homedir as homedir49 } from "node:os";
652368
653227
  import { randomBytes as randomBytes26 } from "node:crypto";
652369
653228
  function ensureDir2() {
652370
653229
  const dir = join146(homedir49(), ".omnius");
652371
- if (!existsSync134(dir)) mkdirSync79(dir, { recursive: true });
653230
+ if (!existsSync134(dir)) mkdirSync80(dir, { recursive: true });
652372
653231
  }
652373
653232
  function loadAll() {
652374
653233
  if (!existsSync134(KEYS_FILE)) return [];
@@ -652383,7 +653242,7 @@ function loadAll() {
652383
653242
  }
652384
653243
  function persistAll(records) {
652385
653244
  ensureDir2();
652386
- writeFileSync70(KEYS_FILE, JSON.stringify(records, null, 2), "utf-8");
653245
+ writeFileSync71(KEYS_FILE, JSON.stringify(records, null, 2), "utf-8");
652387
653246
  try {
652388
653247
  chmodSync3(KEYS_FILE, 384);
652389
653248
  } catch {
@@ -652617,7 +653476,7 @@ __export(graphical_sudo_exports, {
652617
653476
  runGraphicalSudo: () => runGraphicalSudo
652618
653477
  });
652619
653478
  import { spawn as spawn29 } from "node:child_process";
652620
- import { existsSync as existsSync136, mkdirSync as mkdirSync80, writeFileSync as writeFileSync71, chmodSync as chmodSync4 } from "node:fs";
653479
+ import { existsSync as existsSync136, mkdirSync as mkdirSync81, writeFileSync as writeFileSync72, chmodSync as chmodSync4 } from "node:fs";
652621
653480
  import { join as join148 } from "node:path";
652622
653481
  import { tmpdir as tmpdir21 } from "node:os";
652623
653482
  function detectSudoHelper() {
@@ -652641,7 +653500,7 @@ function which2(cmd) {
652641
653500
  }
652642
653501
  function ensureAskpassShim(helper, description) {
652643
653502
  const shimDir = join148(tmpdir21(), "omnius-askpass");
652644
- mkdirSync80(shimDir, { recursive: true });
653503
+ mkdirSync81(shimDir, { recursive: true });
652645
653504
  const shim = join148(shimDir, `${helper}.sh`);
652646
653505
  let body;
652647
653506
  if (helper === "zenity") {
@@ -652653,7 +653512,7 @@ exec zenity --password --title="Omnius needs sudo" --text="${description.replace
652653
653512
  exec kdialog --password "${description.replace(/"/g, '\\"')}" 2>/dev/null
652654
653513
  `;
652655
653514
  }
652656
- writeFileSync71(shim, body, "utf-8");
653515
+ writeFileSync72(shim, body, "utf-8");
652657
653516
  chmodSync4(shim, 493);
652658
653517
  return shim;
652659
653518
  }
@@ -655349,8 +656208,8 @@ function readAimsFile(name10, fallback) {
655349
656208
  }
655350
656209
  function writeAimsFile(name10, data) {
655351
656210
  const dir = aimsDir();
655352
- const { mkdirSync: mkdirSync88, writeFileSync: wf, renameSync: rn } = __require("node:fs");
655353
- mkdirSync88(dir, { recursive: true });
656211
+ const { mkdirSync: mkdirSync89, writeFileSync: wf, renameSync: rn } = __require("node:fs");
656212
+ mkdirSync89(dir, { recursive: true });
655354
656213
  const finalPath = join149(dir, name10);
655355
656214
  const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
655356
656215
  try {
@@ -665190,11 +666049,11 @@ var init_auth_oidc = __esm({
665190
666049
  });
665191
666050
 
665192
666051
  // packages/cli/src/api/usage-tracker.ts
665193
- import { mkdirSync as mkdirSync81, readFileSync as readFileSync112, writeFileSync as writeFileSync72, existsSync as existsSync138 } from "node:fs";
666052
+ import { mkdirSync as mkdirSync82, readFileSync as readFileSync112, writeFileSync as writeFileSync73, existsSync as existsSync138 } from "node:fs";
665194
666053
  import { join as join150 } from "node:path";
665195
666054
  function initUsageTracker(omniusDir) {
665196
666055
  const dir = join150(omniusDir, "usage");
665197
- mkdirSync81(dir, { recursive: true });
666056
+ mkdirSync82(dir, { recursive: true });
665198
666057
  usageFile = join150(dir, "token-usage.json");
665199
666058
  try {
665200
666059
  if (existsSync138(usageFile)) {
@@ -665234,7 +666093,7 @@ function flush2() {
665234
666093
  if (!initialized2 || !dirty) return;
665235
666094
  try {
665236
666095
  store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
665237
- writeFileSync72(usageFile, JSON.stringify(store, null, 2), "utf-8");
666096
+ writeFileSync73(usageFile, JSON.stringify(store, null, 2), "utf-8");
665238
666097
  dirty = false;
665239
666098
  } catch {
665240
666099
  }
@@ -665263,7 +666122,7 @@ var init_usage_tracker = __esm({
665263
666122
 
665264
666123
  // packages/cli/src/docker.ts
665265
666124
  import { execSync as execSync58, spawn as spawn30 } from "node:child_process";
665266
- import { existsSync as existsSync139, mkdirSync as mkdirSync82, writeFileSync as writeFileSync73 } from "node:fs";
666125
+ import { existsSync as existsSync139, mkdirSync as mkdirSync83, writeFileSync as writeFileSync74 } from "node:fs";
665267
666126
  import { join as join151, resolve as resolve56, dirname as dirname42 } from "node:path";
665268
666127
  import { homedir as homedir52 } from "node:os";
665269
666128
  import { fileURLToPath as fileURLToPath18 } from "node:url";
@@ -665414,7 +666273,7 @@ async function ensureOmniusImage(force = false) {
665414
666273
  buildContext = dockerDir;
665415
666274
  } else {
665416
666275
  buildContext = join151(homedir52(), ".omnius", "docker-build");
665417
- mkdirSync82(buildContext, { recursive: true });
666276
+ mkdirSync83(buildContext, { recursive: true });
665418
666277
  writeDockerfiles(buildContext);
665419
666278
  }
665420
666279
  try {
@@ -665488,8 +666347,8 @@ chown -R node:node /workspace /home/node/.omnius 2>/dev/null || true
665488
666347
  if [ "$1" = "omnius" ]; then shift; exec su - node -c "cd /workspace && omnius $*"; fi
665489
666348
  exec "$@"
665490
666349
  `;
665491
- writeFileSync73(join151(dir, "Dockerfile"), dockerfile);
665492
- writeFileSync73(join151(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
666350
+ writeFileSync74(join151(dir, "Dockerfile"), dockerfile);
666351
+ writeFileSync74(join151(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
665493
666352
  }
665494
666353
  function hasNvidiaGpu() {
665495
666354
  try {
@@ -665747,7 +666606,7 @@ import { fileURLToPath as fileURLToPath19 } from "node:url";
665747
666606
  import { dirname as dirname43, join as join153, resolve as resolve57 } from "node:path";
665748
666607
  import { homedir as homedir53 } from "node:os";
665749
666608
  import { spawn as spawn31, execSync as execSync59 } from "node:child_process";
665750
- import { mkdirSync as mkdirSync83, writeFileSync as writeFileSync74, readFileSync as readFileSync113, readdirSync as readdirSync50, existsSync as existsSync140, watch as fsWatch4, renameSync as renameSync11, unlinkSync as unlinkSync30, statSync as statSync51, openSync as openSync4, readSync as readSync2, closeSync as closeSync4 } from "node:fs";
666609
+ import { mkdirSync as mkdirSync84, writeFileSync as writeFileSync75, readFileSync as readFileSync113, readdirSync as readdirSync50, existsSync as existsSync140, watch as fsWatch4, renameSync as renameSync11, unlinkSync as unlinkSync30, statSync as statSync51, openSync as openSync4, readSync as readSync2, closeSync as closeSync4 } from "node:fs";
665751
666610
  import { randomBytes as randomBytes27, randomUUID as randomUUID17 } from "node:crypto";
665752
666611
  import { createHash as createHash36 } from "node:crypto";
665753
666612
  function memoryDbPaths3(baseDir = process.cwd()) {
@@ -666727,7 +667586,7 @@ function ollamaStream(ollamaUrl, path12, method, body, onData, onEnd, onError, t
666727
667586
  function jobsDir() {
666728
667587
  const root = resolve57(process.cwd());
666729
667588
  const dir = join153(root, ".omnius", "jobs");
666730
- mkdirSync83(dir, { recursive: true });
667589
+ mkdirSync84(dir, { recursive: true });
666731
667590
  return dir;
666732
667591
  }
666733
667592
  function loadJob(id) {
@@ -667072,11 +667931,11 @@ function atomicJobWrite(dir, id, job) {
667072
667931
  const finalPath = join153(dir, `${id}.json`);
667073
667932
  const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
667074
667933
  try {
667075
- writeFileSync74(tmpPath, JSON.stringify(job, null, 2), "utf-8");
667934
+ writeFileSync75(tmpPath, JSON.stringify(job, null, 2), "utf-8");
667076
667935
  renameSync11(tmpPath, finalPath);
667077
667936
  } catch {
667078
667937
  try {
667079
- writeFileSync74(finalPath, JSON.stringify(job, null, 2), "utf-8");
667938
+ writeFileSync75(finalPath, JSON.stringify(job, null, 2), "utf-8");
667080
667939
  } catch {
667081
667940
  }
667082
667941
  try {
@@ -668612,10 +669471,10 @@ function readUpdateState() {
668612
669471
  function writeUpdateState(state) {
668613
669472
  try {
668614
669473
  const dir = join153(homedir53(), ".omnius");
668615
- mkdirSync83(dir, { recursive: true });
669474
+ mkdirSync84(dir, { recursive: true });
668616
669475
  const finalPath = updateStateFile();
668617
669476
  const tmpPath = `${finalPath}.tmp.${process.pid}`;
668618
- writeFileSync74(tmpPath, JSON.stringify(state, null, 2), "utf-8");
669477
+ writeFileSync75(tmpPath, JSON.stringify(state, null, 2), "utf-8");
668619
669478
  renameSync11(tmpPath, finalPath);
668620
669479
  } catch {
668621
669480
  }
@@ -668924,7 +669783,7 @@ async function handleV1Run(req2, res) {
668924
669783
  cwd4 = resolve57(workingDir);
668925
669784
  } else if (isolate) {
668926
669785
  const wsDir = join153(dir, "..", "workspaces", id);
668927
- mkdirSync83(wsDir, { recursive: true });
669786
+ mkdirSync84(wsDir, { recursive: true });
668928
669787
  cwd4 = wsDir;
668929
669788
  } else {
668930
669789
  cwd4 = resolve57(process.cwd());
@@ -670396,10 +671255,10 @@ async function handleRequest(req2, res, ollamaUrl, verbose, runtimeDefaults = {}
670396
671255
  return;
670397
671256
  }
670398
671257
  const { tmpdir: tmpdir23 } = await import("node:os");
670399
- const { writeFileSync: writeFileSync79, unlinkSync: unlinkSync31 } = await import("node:fs");
671258
+ const { writeFileSync: writeFileSync80, unlinkSync: unlinkSync31 } = await import("node:fs");
670400
671259
  const { join: pjoin } = await import("node:path");
670401
671260
  const tmpPath = pjoin(tmpdir23(), `omnius-clone-upload-${Date.now()}-${safeName3}`);
670402
- writeFileSync79(tmpPath, buf);
671261
+ writeFileSync80(tmpPath, buf);
670403
671262
  try {
670404
671263
  const ve = getVoiceEngine();
670405
671264
  const msg = await ve.setCloneVoice(tmpPath);
@@ -670991,7 +671850,7 @@ data: ${JSON.stringify(data)}
670991
671850
  }
670992
671851
  for (const f2 of seenFiles) {
670993
671852
  try {
670994
- writeFileSync74(f2, JSON.stringify({ tasks: [] }, null, 2));
671853
+ writeFileSync75(f2, JSON.stringify({ tasks: [] }, null, 2));
670995
671854
  deleted++;
670996
671855
  } catch {
670997
671856
  }
@@ -672211,11 +673070,11 @@ function setScheduledEnabled(id, enabled2) {
672211
673070
  arr[target.index].enabled = enabled2;
672212
673071
  if (Array.isArray(json?.tasks)) {
672213
673072
  json.tasks = arr;
672214
- writeFileSync74(target.file, JSON.stringify(json, null, 2));
673073
+ writeFileSync75(target.file, JSON.stringify(json, null, 2));
672215
673074
  } else if (Array.isArray(json)) {
672216
- writeFileSync74(target.file, JSON.stringify(arr, null, 2));
673075
+ writeFileSync75(target.file, JSON.stringify(arr, null, 2));
672217
673076
  } else {
672218
- writeFileSync74(target.file, JSON.stringify({ tasks: arr }, null, 2));
673077
+ writeFileSync75(target.file, JSON.stringify({ tasks: arr }, null, 2));
672219
673078
  }
672220
673079
  if (!enabled2) {
672221
673080
  try {
@@ -672245,11 +673104,11 @@ function deleteScheduledById(id) {
672245
673104
  arr.splice(target.index, 1);
672246
673105
  if (Array.isArray(json?.tasks)) {
672247
673106
  json.tasks = arr;
672248
- writeFileSync74(target.file, JSON.stringify(json, null, 2));
673107
+ writeFileSync75(target.file, JSON.stringify(json, null, 2));
672249
673108
  } else if (Array.isArray(json)) {
672250
- writeFileSync74(target.file, JSON.stringify(arr, null, 2));
673109
+ writeFileSync75(target.file, JSON.stringify(arr, null, 2));
672251
673110
  } else {
672252
- writeFileSync74(target.file, JSON.stringify({ tasks: arr }, null, 2));
673111
+ writeFileSync75(target.file, JSON.stringify({ tasks: arr }, null, 2));
672253
673112
  }
672254
673113
  const candidates = [];
672255
673114
  if (id) candidates.push(id);
@@ -672517,9 +673376,9 @@ function reconcileScheduledTasks(apply) {
672517
673376
  const entry = { task: f2.task || `legacy ${f2.id}`, schedule: f2.cron, enabled: true };
672518
673377
  arr.push(entry);
672519
673378
  const toWrite = Array.isArray(json?.tasks) ? { ...json, tasks: arr } : Array.isArray(json) ? arr : { tasks: arr };
672520
- mkdirSync83(join153(wdir, ".omnius", "scheduled"), { recursive: true });
672521
- mkdirSync83(join153(wdir, ".omnius", "scheduled", "logs"), { recursive: true });
672522
- writeFileSync74(file, JSON.stringify(toWrite, null, 2));
673379
+ mkdirSync84(join153(wdir, ".omnius", "scheduled"), { recursive: true });
673380
+ mkdirSync84(join153(wdir, ".omnius", "scheduled", "logs"), { recursive: true });
673381
+ writeFileSync75(file, JSON.stringify(toWrite, null, 2));
672523
673382
  adopted.push({ file, index: arr.length - 1 });
672524
673383
  }
672525
673384
  } else {
@@ -672652,9 +673511,9 @@ Persistent=true
672652
673511
  WantedBy=timers.target
672653
673512
  `;
672654
673513
  if (!dryRun) {
672655
- mkdirSync83(unitDir, { recursive: true });
672656
- writeFileSync74(svc, svcText);
672657
- writeFileSync74(tim, timText);
673514
+ mkdirSync84(unitDir, { recursive: true });
673515
+ writeFileSync75(svc, svcText);
673516
+ writeFileSync75(tim, timText);
672658
673517
  try {
672659
673518
  const { execSync: es } = require4("node:child_process");
672660
673519
  es("systemctl --user daemon-reload", { stdio: "pipe" });
@@ -672798,7 +673657,7 @@ function startApiServer(options2 = {}) {
672798
673657
  if (!apiTestMode) try {
672799
673658
  const dir = todoDir();
672800
673659
  try {
672801
- mkdirSync83(dir, { recursive: true });
673660
+ mkdirSync84(dir, { recursive: true });
672802
673661
  } catch {
672803
673662
  }
672804
673663
  const cache8 = /* @__PURE__ */ new Map();
@@ -672976,8 +673835,8 @@ function startApiServer(options2 = {}) {
672976
673835
  runtimeAccessMode = requested;
672977
673836
  try {
672978
673837
  const dir = join153(homedir53(), ".omnius");
672979
- mkdirSync83(dir, { recursive: true });
672980
- writeFileSync74(join153(dir, "access"), `${runtimeAccessMode}
673838
+ mkdirSync84(dir, { recursive: true });
673839
+ writeFileSync75(join153(dir, "access"), `${runtimeAccessMode}
672981
673840
  `, "utf8");
672982
673841
  } catch {
672983
673842
  }
@@ -673282,7 +674141,7 @@ function startApiServer(options2 = {}) {
673282
674141
  return;
673283
674142
  }
673284
674143
  try {
673285
- const { writeFileSync: writeFileSync79, mkdirSync: mkdirSync88, existsSync: _exists, readFileSync: _rfs } = require4("node:fs");
674144
+ const { writeFileSync: writeFileSync80, mkdirSync: mkdirSync89, existsSync: _exists, readFileSync: _rfs } = require4("node:fs");
673286
674145
  const { join: _join } = require4("node:path");
673287
674146
  const { homedir: _homedir } = require4("node:os");
673288
674147
  const apiHint = JSON.stringify({
@@ -673311,8 +674170,8 @@ function startApiServer(options2 = {}) {
673311
674170
  let written = 0;
673312
674171
  for (const dir of dirSet) {
673313
674172
  try {
673314
- if (!_exists(dir)) mkdirSync88(dir, { recursive: true });
673315
- writeFileSync79(_join(dir, "api-port.json"), apiHint);
674173
+ if (!_exists(dir)) mkdirSync89(dir, { recursive: true });
674174
+ writeFileSync80(_join(dir, "api-port.json"), apiHint);
673316
674175
  written++;
673317
674176
  } catch {
673318
674177
  }
@@ -673597,9 +674456,9 @@ async function handleChatAttachmentUpload(req2, res) {
673597
674456
  }
673598
674457
  const safeName3 = filename.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 180) || `attachment-${Date.now()}.bin`;
673599
674458
  const dir = join153(process.cwd(), ".omnius", "gui-attachments");
673600
- mkdirSync83(dir, { recursive: true });
674459
+ mkdirSync84(dir, { recursive: true });
673601
674460
  const localPath = join153(dir, `${Date.now()}-${randomUUID17().slice(0, 8)}-${safeName3}`);
673602
- writeFileSync74(localPath, Buffer.from(base642, "base64"));
674461
+ writeFileSync75(localPath, Buffer.from(base642, "base64"));
673603
674462
  const mimeType = typeof b.mimeType === "string" ? b.mimeType : typeof b.mime_type === "string" ? b.mime_type : "";
673604
674463
  const isImage = mimeType.toLowerCase().startsWith("image/") || /\.(png|jpe?g|gif|webp|bmp|tiff?)$/i.test(safeName3);
673605
674464
  const sessionId = typeof b.sessionId === "string" ? b.sessionId : typeof b.session_id === "string" ? b.session_id : void 0;
@@ -673970,15 +674829,15 @@ __export(clipboard_media_exports, {
673970
674829
  pasteClipboardImageToFile: () => pasteClipboardImageToFile
673971
674830
  });
673972
674831
  import { execFileSync as execFileSync9, execSync as execSync60 } from "node:child_process";
673973
- import { mkdirSync as mkdirSync84, readFileSync as readFileSync114, rmSync as rmSync8, writeFileSync as writeFileSync75 } from "node:fs";
674832
+ import { mkdirSync as mkdirSync85, readFileSync as readFileSync114, rmSync as rmSync9, writeFileSync as writeFileSync76 } from "node:fs";
673974
674833
  import { join as join154 } from "node:path";
673975
674834
  function pasteClipboardImageToFile(repoRoot) {
673976
674835
  const image = readClipboardImage();
673977
674836
  if (!image) return null;
673978
674837
  const dir = join154(repoRoot, ".omnius", "clipboard");
673979
- mkdirSync84(dir, { recursive: true });
674838
+ mkdirSync85(dir, { recursive: true });
673980
674839
  const path12 = join154(dir, `clipboard-${Date.now()}${image.ext}`);
673981
- writeFileSync75(path12, image.buffer);
674840
+ writeFileSync76(path12, image.buffer);
673982
674841
  return { path: path12, buffer: image.buffer, mime: image.mime };
673983
674842
  }
673984
674843
  function readClipboardImage() {
@@ -673989,7 +674848,7 @@ function readClipboardImage() {
673989
674848
  execFileSync9("pngpaste", [tmp], { timeout: 3e3 });
673990
674849
  const buffer2 = readFileSync114(tmp);
673991
674850
  try {
673992
- rmSync8(tmp);
674851
+ rmSync9(tmp);
673993
674852
  } catch {
673994
674853
  }
673995
674854
  if (buffer2.length > 0) return { buffer: buffer2, mime: "image/png", ext: ".png" };
@@ -674047,11 +674906,11 @@ import { createRequire as createRequire8 } from "node:module";
674047
674906
  import { fileURLToPath as fileURLToPath20 } from "node:url";
674048
674907
  import {
674049
674908
  readFileSync as readFileSync115,
674050
- writeFileSync as writeFileSync76,
674909
+ writeFileSync as writeFileSync77,
674051
674910
  appendFileSync as appendFileSync13,
674052
- rmSync as rmSync9,
674911
+ rmSync as rmSync10,
674053
674912
  readdirSync as readdirSync51,
674054
- mkdirSync as mkdirSync85
674913
+ mkdirSync as mkdirSync86
674055
674914
  } from "node:fs";
674056
674915
  import { existsSync as existsSync141 } from "node:fs";
674057
674916
  import { execSync as execSync61 } from "node:child_process";
@@ -677085,7 +677944,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
677085
677944
  if (existsSync141(ikFile)) {
677086
677945
  ikState = JSON.parse(readFileSync115(ikFile, "utf8"));
677087
677946
  } else {
677088
- mkdirSync85(ikDir, { recursive: true });
677947
+ mkdirSync86(ikDir, { recursive: true });
677089
677948
  const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
677090
677949
  ikState = {
677091
677950
  self_id: `omnius-${machineId}`,
@@ -677195,7 +678054,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
677195
678054
  }
677196
678055
  ikState.session_count = (ikState.session_count || 0) + 1;
677197
678056
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
677198
- writeFileSync76(ikFile, JSON.stringify(ikState, null, 2));
678057
+ writeFileSync77(ikFile, JSON.stringify(ikState, null, 2));
677199
678058
  } catch (ikErr) {
677200
678059
  try {
677201
678060
  console.error("[IK-OBSERVE]", ikErr);
@@ -677251,7 +678110,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
677251
678110
  ikState.version_history = ikState.version_history.slice(-200);
677252
678111
  ikState.session_count = (ikState.session_count || 0) + 1;
677253
678112
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
677254
- writeFileSync76(ikFile, JSON.stringify(ikState, null, 2));
678113
+ writeFileSync77(ikFile, JSON.stringify(ikState, null, 2));
677255
678114
  }
677256
678115
  } catch {
677257
678116
  }
@@ -678825,12 +679684,12 @@ This is an independent background session started from /background.`
678825
679684
  function persistHistoryLine(line) {
678826
679685
  if (!line.trim()) return;
678827
679686
  try {
678828
- mkdirSync85(HISTORY_DIR, { recursive: true });
679687
+ mkdirSync86(HISTORY_DIR, { recursive: true });
678829
679688
  appendFileSync13(HISTORY_FILE, line + "\n", "utf8");
678830
679689
  if (Math.random() < 0.02) {
678831
679690
  const all2 = readFileSync115(HISTORY_FILE, "utf8").trim().split("\n");
678832
679691
  if (all2.length > MAX_HISTORY_LINES) {
678833
- writeFileSync76(
679692
+ writeFileSync77(
678834
679693
  HISTORY_FILE,
678835
679694
  all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n",
678836
679695
  "utf8"
@@ -679733,8 +680592,8 @@ Log: ${nexusLogPath}`)
679733
680592
  setSessionTitle(title) {
679734
680593
  sessionTitle = title.trim() || null;
679735
680594
  try {
679736
- mkdirSync85(join155(repoRoot, ".omnius"), { recursive: true });
679737
- writeFileSync76(join155(repoRoot, ".omnius", "session-title"), `${sessionTitle ?? ""}
680595
+ mkdirSync86(join155(repoRoot, ".omnius"), { recursive: true });
680596
+ writeFileSync77(join155(repoRoot, ".omnius", "session-title"), `${sessionTitle ?? ""}
679738
680597
  `, "utf8");
679739
680598
  } catch {
679740
680599
  }
@@ -681524,7 +682383,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
681524
682383
  let deleted = false;
681525
682384
  for (let attempt = 0; attempt < 3; attempt++) {
681526
682385
  try {
681527
- rmSync9(omniusPath, { recursive: true, force: true });
682386
+ rmSync10(omniusPath, { recursive: true, force: true });
681528
682387
  deleted = true;
681529
682388
  break;
681530
682389
  } catch (err) {
@@ -682935,7 +683794,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
682935
683794
  if (existsSync141(ikFile)) {
682936
683795
  ikState = JSON.parse(readFileSync115(ikFile, "utf8"));
682937
683796
  } else {
682938
- mkdirSync85(ikDir, { recursive: true });
683797
+ mkdirSync86(ikDir, { recursive: true });
682939
683798
  ikState = {
682940
683799
  self_id: `omnius-${Date.now().toString(36)}`,
682941
683800
  version: 1,
@@ -682988,7 +683847,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
682988
683847
  );
682989
683848
  ikState.session_count = (ikState.session_count || 0) + 1;
682990
683849
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
682991
- writeFileSync76(ikFile, JSON.stringify(ikState, null, 2));
683850
+ writeFileSync77(ikFile, JSON.stringify(ikState, null, 2));
682992
683851
  } catch (ikErr) {
682993
683852
  }
682994
683853
  try {
@@ -683020,8 +683879,8 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
683020
683879
  tags: ["general"]
683021
683880
  });
683022
683881
  if (variants.length > 50) variants = variants.slice(-50);
683023
- mkdirSync85(archeDir, { recursive: true });
683024
- writeFileSync76(archeFile, JSON.stringify(variants, null, 2));
683882
+ mkdirSync86(archeDir, { recursive: true });
683883
+ writeFileSync77(archeFile, JSON.stringify(variants, null, 2));
683025
683884
  } catch {
683026
683885
  }
683027
683886
  }
@@ -683052,7 +683911,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
683052
683911
  updated = true;
683053
683912
  }
683054
683913
  if (updated) {
683055
- writeFileSync76(metaFile2, JSON.stringify(store2, null, 2));
683914
+ writeFileSync77(metaFile2, JSON.stringify(store2, null, 2));
683056
683915
  }
683057
683916
  }
683058
683917
  } catch {
@@ -683111,7 +683970,7 @@ Rules:
683111
683970
  const { initDb: initDb2 } = __require("@omnius/memory");
683112
683971
  const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@omnius/memory");
683113
683972
  const dbDir = join155(repoRoot, ".omnius", "memory");
683114
- mkdirSync85(dbDir, { recursive: true });
683973
+ mkdirSync86(dbDir, { recursive: true });
683115
683974
  const db = initDb2(join155(dbDir, "structured.db"));
683116
683975
  const memStore = new ProceduralMemoryStore2(db);
683117
683976
  memStore.createWithEmbedding(
@@ -683160,8 +684019,8 @@ Rules:
683160
684019
  accessCount: 0
683161
684020
  });
683162
684021
  if (store2.length > 100) store2 = store2.slice(-100);
683163
- mkdirSync85(metaDir, { recursive: true });
683164
- writeFileSync76(storeFile, JSON.stringify(store2, null, 2));
684022
+ mkdirSync86(metaDir, { recursive: true });
684023
+ writeFileSync77(storeFile, JSON.stringify(store2, null, 2));
683165
684024
  }
683166
684025
  }
683167
684026
  } catch {
@@ -683225,7 +684084,7 @@ Rules:
683225
684084
  );
683226
684085
  ikState.session_count = (ikState.session_count || 0) + 1;
683227
684086
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
683228
- writeFileSync76(ikFile, JSON.stringify(ikState, null, 2));
684087
+ writeFileSync77(ikFile, JSON.stringify(ikState, null, 2));
683229
684088
  }
683230
684089
  const metaFile2 = join155(
683231
684090
  repoRoot,
@@ -683253,7 +684112,7 @@ Rules:
683253
684112
  (item.scores.confidence || 0.5) - 0.02
683254
684113
  );
683255
684114
  }
683256
- writeFileSync76(metaFile2, JSON.stringify(store2, null, 2));
684115
+ writeFileSync77(metaFile2, JSON.stringify(store2, null, 2));
683257
684116
  }
683258
684117
  try {
683259
684118
  const archeDir = join155(repoRoot, ".omnius", "arche");
@@ -683275,8 +684134,8 @@ Rules:
683275
684134
  tags: ["general"]
683276
684135
  });
683277
684136
  if (variants.length > 50) variants = variants.slice(-50);
683278
- mkdirSync85(archeDir, { recursive: true });
683279
- writeFileSync76(archeFile, JSON.stringify(variants, null, 2));
684137
+ mkdirSync86(archeDir, { recursive: true });
684138
+ writeFileSync77(archeFile, JSON.stringify(variants, null, 2));
683280
684139
  } catch {
683281
684140
  }
683282
684141
  } catch {
@@ -683382,13 +684241,13 @@ __export(run_exports, {
683382
684241
  });
683383
684242
  import { resolve as resolve59 } from "node:path";
683384
684243
  import { spawn as spawn32 } from "node:child_process";
683385
- import { mkdirSync as mkdirSync86, writeFileSync as writeFileSync77, readFileSync as readFileSync116, readdirSync as readdirSync52, existsSync as existsSync142 } from "node:fs";
684244
+ import { mkdirSync as mkdirSync87, writeFileSync as writeFileSync78, readFileSync as readFileSync116, readdirSync as readdirSync52, existsSync as existsSync142 } from "node:fs";
683386
684245
  import { randomBytes as randomBytes28 } from "node:crypto";
683387
684246
  import { join as join156 } from "node:path";
683388
684247
  function jobsDir2(repoPath2) {
683389
684248
  const root = resolve59(repoPath2 ?? process.cwd());
683390
684249
  const dir = join156(root, ".omnius", "jobs");
683391
- mkdirSync86(dir, { recursive: true });
684250
+ mkdirSync87(dir, { recursive: true });
683392
684251
  return dir;
683393
684252
  }
683394
684253
  async function runCommand2(opts, config) {
@@ -683510,7 +684369,7 @@ async function runBackground(task, config, opts) {
683510
684369
  }
683511
684370
  });
683512
684371
  job.pid = child.pid ?? 0;
683513
- writeFileSync77(join156(dir, `${id}.json`), JSON.stringify(job, null, 2));
684372
+ writeFileSync78(join156(dir, `${id}.json`), JSON.stringify(job, null, 2));
683514
684373
  let output = "";
683515
684374
  child.stdout?.on("data", (chunk) => {
683516
684375
  output += chunk.toString();
@@ -683526,7 +684385,7 @@ async function runBackground(task, config, opts) {
683526
684385
  job.summary = result.summary;
683527
684386
  job.durationMs = result.durationMs;
683528
684387
  job.error = result.error;
683529
- writeFileSync77(join156(dir, `${id}.json`), JSON.stringify(job, null, 2));
684388
+ writeFileSync78(join156(dir, `${id}.json`), JSON.stringify(job, null, 2));
683530
684389
  } catch {
683531
684390
  }
683532
684391
  });
@@ -684161,7 +685020,7 @@ __export(eval_exports, {
684161
685020
  evalCommand: () => evalCommand
684162
685021
  });
684163
685022
  import { tmpdir as tmpdir22 } from "node:os";
684164
- import { mkdirSync as mkdirSync87, writeFileSync as writeFileSync78 } from "node:fs";
685023
+ import { mkdirSync as mkdirSync88, writeFileSync as writeFileSync79 } from "node:fs";
684165
685024
  import { join as join158 } from "node:path";
684166
685025
  async function evalCommand(opts, config) {
684167
685026
  const suiteName = opts.suite ?? "basic";
@@ -684292,8 +685151,8 @@ async function evalCommand(opts, config) {
684292
685151
  }
684293
685152
  function createTempEvalRepo() {
684294
685153
  const dir = join158(tmpdir22(), `omnius-eval-${Date.now()}`);
684295
- mkdirSync87(dir, { recursive: true });
684296
- writeFileSync78(
685154
+ mkdirSync88(dir, { recursive: true });
685155
+ writeFileSync79(
684297
685156
  join158(dir, "package.json"),
684298
685157
  JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
684299
685158
  "utf8"
@@ -684820,11 +685679,11 @@ function crashLog(label, err) {
684820
685679
  const logLine = `[${timestamp}] ${label}: ${msg}
684821
685680
  `;
684822
685681
  try {
684823
- const { appendFileSync: appendFileSync14, mkdirSync: mkdirSync88 } = __require("node:fs");
685682
+ const { appendFileSync: appendFileSync14, mkdirSync: mkdirSync89 } = __require("node:fs");
684824
685683
  const { join: join160 } = __require("node:path");
684825
685684
  const { homedir: homedir56 } = __require("node:os");
684826
685685
  const logDir = join160(homedir56(), ".omnius");
684827
- mkdirSync88(logDir, { recursive: true });
685686
+ mkdirSync89(logDir, { recursive: true });
684828
685687
  appendFileSync14(join160(logDir, "crash.log"), logLine);
684829
685688
  } catch {
684830
685689
  }