omnius 1.0.525 → 1.0.526

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
@@ -273910,11 +273910,11 @@ var require_out = __commonJS({
273910
273910
  async.read(path16, getSettings(optionsOrSettingsOrCallback), callback);
273911
273911
  }
273912
273912
  exports.stat = stat9;
273913
- function statSync67(path16, optionsOrSettings) {
273913
+ function statSync68(path16, optionsOrSettings) {
273914
273914
  const settings = getSettings(optionsOrSettings);
273915
273915
  return sync.read(path16, settings);
273916
273916
  }
273917
- exports.statSync = statSync67;
273917
+ exports.statSync = statSync68;
273918
273918
  function getSettings(settingsOrOptions = {}) {
273919
273919
  if (settingsOrOptions instanceof settings_1.default) {
273920
273920
  return settingsOrOptions;
@@ -299290,7 +299290,7 @@ var init_project_scaffolding = __esm({
299290
299290
  });
299291
299291
 
299292
299292
  // packages/execution/dist/tools/todo-store.js
299293
- import { existsSync as existsSync59, readFileSync as readFileSync43, writeFileSync as writeFileSync28, mkdirSync as mkdirSync33, renameSync as renameSync7, unlinkSync as unlinkSync11, readdirSync as readdirSync20 } from "node:fs";
299293
+ import { existsSync as existsSync59, readFileSync as readFileSync43, writeFileSync as writeFileSync28, mkdirSync as mkdirSync33, renameSync as renameSync7, unlinkSync as unlinkSync11, readdirSync as readdirSync20, rmSync as rmSync7, statSync as statSync23 } from "node:fs";
299294
299294
  import { join as join71 } from "node:path";
299295
299295
  import { homedir as homedir16 } from "node:os";
299296
299296
  import { randomBytes as randomBytes17 } from "node:crypto";
@@ -299311,24 +299311,164 @@ function emit(type, data) {
299311
299311
  function todoDir() {
299312
299312
  return join71(homedir16(), ".omnius", "todos");
299313
299313
  }
299314
+ function safeSessionId(sessionId) {
299315
+ return sessionId.replace(/[^a-zA-Z0-9_.-]/g, "_");
299316
+ }
299317
+ function safeTodoId(id2) {
299318
+ return id2.replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 160) || "todo";
299319
+ }
299314
299320
  function todoPath(sessionId) {
299315
- const safe = sessionId.replace(/[^a-zA-Z0-9_.-]/g, "_");
299316
- return join71(todoDir(), `${safe}.json`);
299321
+ return join71(todoDir(), `${safeSessionId(sessionId)}.json`);
299322
+ }
299323
+ function todoTaskDir(sessionId) {
299324
+ return join71(todoDir(), `${safeSessionId(sessionId)}.tasks`);
299325
+ }
299326
+ function todoIndexPath(sessionId) {
299327
+ return join71(todoTaskDir(sessionId), "index.json");
299328
+ }
299329
+ function todoTaskPath(sessionId, todoId) {
299330
+ return join71(todoTaskDir(sessionId), `${safeTodoId(todoId)}.json`);
299331
+ }
299332
+ function sleepSync(ms) {
299333
+ const view = new Int32Array(new SharedArrayBuffer(4));
299334
+ Atomics.wait(view, 0, 0, ms);
299335
+ }
299336
+ function withTodoSessionLock(sessionId, fn) {
299337
+ mkdirSync33(todoDir(), { recursive: true });
299338
+ const lockPath = join71(todoDir(), `${safeSessionId(sessionId)}.lock`);
299339
+ const started = Date.now();
299340
+ while (true) {
299341
+ try {
299342
+ mkdirSync33(lockPath);
299343
+ writeFileSync28(join71(lockPath, "owner"), JSON.stringify({ pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
299344
+ break;
299345
+ } catch (err) {
299346
+ const ageMs = (() => {
299347
+ try {
299348
+ return Date.now() - statSync23(lockPath).mtimeMs;
299349
+ } catch {
299350
+ return 0;
299351
+ }
299352
+ })();
299353
+ if (ageMs > 3e4) {
299354
+ try {
299355
+ rmSync7(lockPath, { recursive: true, force: true });
299356
+ } catch {
299357
+ }
299358
+ continue;
299359
+ }
299360
+ if (Date.now() - started > 2e3) {
299361
+ throw new Error(`Timed out acquiring todo store lock for session '${sessionId}'`);
299362
+ }
299363
+ sleepSync(10);
299364
+ }
299365
+ }
299366
+ try {
299367
+ return fn();
299368
+ } finally {
299369
+ try {
299370
+ rmSync7(lockPath, { recursive: true, force: true });
299371
+ } catch {
299372
+ }
299373
+ }
299374
+ }
299375
+ function atomicJsonWrite(path16, value2) {
299376
+ const tmpPath = `${path16}.tmp.${process.pid}.${Date.now()}.${randomBytes17(2).toString("hex")}`;
299377
+ try {
299378
+ writeFileSync28(tmpPath, JSON.stringify(value2, null, 2), "utf-8");
299379
+ renameSync7(tmpPath, path16);
299380
+ } catch (err) {
299381
+ try {
299382
+ unlinkSync11(tmpPath);
299383
+ } catch {
299384
+ }
299385
+ throw err;
299386
+ }
299387
+ }
299388
+ function readTodosFromTaskDir(sessionId) {
299389
+ const indexPath = todoIndexPath(sessionId);
299390
+ if (!existsSync59(indexPath))
299391
+ return null;
299392
+ try {
299393
+ const index = JSON.parse(readFileSync43(indexPath, "utf-8"));
299394
+ if (!Array.isArray(index.order))
299395
+ return null;
299396
+ const out = [];
299397
+ for (const rawId of index.order) {
299398
+ if (typeof rawId !== "string" || !rawId.trim())
299399
+ continue;
299400
+ const taskPath = todoTaskPath(sessionId, rawId);
299401
+ if (!existsSync59(taskPath))
299402
+ continue;
299403
+ const entry = JSON.parse(readFileSync43(taskPath, "utf-8"));
299404
+ if (entry && typeof entry.id === "string" && typeof entry.content === "string") {
299405
+ out.push(entry);
299406
+ }
299407
+ }
299408
+ return out;
299409
+ } catch {
299410
+ return null;
299411
+ }
299412
+ }
299413
+ function readTodosFromLegacyFile(sessionId) {
299414
+ const p2 = todoPath(sessionId);
299415
+ if (!existsSync59(p2))
299416
+ return [];
299417
+ const parsed = JSON.parse(readFileSync43(p2, "utf-8"));
299418
+ return Array.isArray(parsed) ? parsed : [];
299419
+ }
299420
+ function readTodosUnlocked(sessionId) {
299421
+ return readTodosFromTaskDir(sessionId) ?? readTodosFromLegacyFile(sessionId);
299422
+ }
299423
+ function writeTodosToTaskDir(sessionId, todos) {
299424
+ const dir = todoTaskDir(sessionId);
299425
+ mkdirSync33(dir, { recursive: true });
299426
+ const ids = new Set(todos.map((todo) => safeTodoId(todo.id)));
299427
+ for (const todo of todos) {
299428
+ atomicJsonWrite(todoTaskPath(sessionId, todo.id), todo);
299429
+ }
299430
+ atomicJsonWrite(todoIndexPath(sessionId), {
299431
+ version: 1,
299432
+ sessionId,
299433
+ updatedAt: Date.now(),
299434
+ order: todos.map((todo) => todo.id)
299435
+ });
299436
+ for (const file of readdirSync20(dir)) {
299437
+ if (file === "index.json" || file.includes(".tmp."))
299438
+ continue;
299439
+ if (!file.endsWith(".json"))
299440
+ continue;
299441
+ const stem = file.replace(/\.json$/, "");
299442
+ if (!ids.has(stem)) {
299443
+ try {
299444
+ unlinkSync11(join71(dir, file));
299445
+ } catch {
299446
+ }
299447
+ }
299448
+ }
299317
299449
  }
299318
299450
  function readTodos(sessionId) {
299319
299451
  try {
299320
- const p2 = todoPath(sessionId);
299321
- if (!existsSync59(p2))
299322
- return [];
299323
- const parsed = JSON.parse(readFileSync43(p2, "utf-8"));
299324
- return Array.isArray(parsed) ? parsed : [];
299452
+ return readTodosUnlocked(sessionId);
299325
299453
  } catch {
299326
299454
  return [];
299327
299455
  }
299328
299456
  }
299329
299457
  function writeTodos(sessionId, incoming) {
299458
+ return withTodoSessionLock(sessionId, () => writeTodosLocked(sessionId, incoming));
299459
+ }
299460
+ function copyStringArray(value2) {
299461
+ return Array.isArray(value2) ? value2.filter((item) => typeof item === "string" && item.trim()).map((item) => item.trim()) : void 0;
299462
+ }
299463
+ function copyAliasedStringArray(value2, aliases) {
299464
+ const copied = copyStringArray(value2);
299465
+ if (!copied)
299466
+ return void 0;
299467
+ return Array.from(new Set(copied.map((item) => aliases.get(item) ?? item)));
299468
+ }
299469
+ function writeTodosLocked(sessionId, incoming) {
299330
299470
  mkdirSync33(todoDir(), { recursive: true });
299331
- const old = readTodos(sessionId);
299471
+ const old = readTodosUnlocked(sessionId);
299332
299472
  const oldById = new Map(old.map((t2) => [t2.id, t2]));
299333
299473
  const oldByContent = /* @__PURE__ */ new Map();
299334
299474
  for (const todo of old) {
@@ -299366,9 +299506,13 @@ function writeTodos(sessionId, incoming) {
299366
299506
  const next = {
299367
299507
  id: id2,
299368
299508
  content: t2.content,
299509
+ activeForm: t2.activeForm ?? existing?.activeForm,
299369
299510
  status,
299370
299511
  parentId: requestedParentId ?? existing?.parentId,
299371
299512
  blocker: t2.blocker ?? (status === "blocked" ? existing?.blocker : void 0),
299513
+ owner: t2.owner ?? existing?.owner,
299514
+ blocks: copyAliasedStringArray(t2.blocks, idAliases) ?? existing?.blocks,
299515
+ blockedBy: copyAliasedStringArray(t2.blockedBy, idAliases) ?? existing?.blockedBy,
299372
299516
  createdAt: existing?.createdAt ?? now2,
299373
299517
  updatedAt: now2,
299374
299518
  completedAt: status === "completed" ? existing?.completedAt ?? now2 : void 0,
@@ -299379,18 +299523,8 @@ function writeTodos(sessionId, incoming) {
299379
299523
  };
299380
299524
  return next;
299381
299525
  });
299382
- const finalPath = todoPath(sessionId);
299383
- const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
299384
- try {
299385
- writeFileSync28(tmpPath, JSON.stringify(newTodos, null, 2), "utf-8");
299386
- renameSync7(tmpPath, finalPath);
299387
- } catch (err) {
299388
- try {
299389
- unlinkSync11(tmpPath);
299390
- } catch {
299391
- }
299392
- throw err;
299393
- }
299526
+ writeTodosToTaskDir(sessionId, newTodos);
299527
+ atomicJsonWrite(todoPath(sessionId), newTodos);
299394
299528
  for (const next of newTodos) {
299395
299529
  const prev = oldById.get(next.id);
299396
299530
  if (!prev) {
@@ -299408,22 +299542,41 @@ function writeTodos(sessionId, incoming) {
299408
299542
  return { newTodos, oldTodos: old };
299409
299543
  }
299410
299544
  function deleteTodos(sessionId) {
299411
- const p2 = todoPath(sessionId);
299412
- if (!existsSync59(p2))
299413
- return false;
299414
- try {
299415
- unlinkSync11(p2);
299416
- return true;
299417
- } catch {
299418
- return false;
299419
- }
299545
+ return withTodoSessionLock(sessionId, () => {
299546
+ let removed = false;
299547
+ const p2 = todoPath(sessionId);
299548
+ if (existsSync59(p2)) {
299549
+ try {
299550
+ unlinkSync11(p2);
299551
+ removed = true;
299552
+ } catch {
299553
+ }
299554
+ }
299555
+ const dir = todoTaskDir(sessionId);
299556
+ if (existsSync59(dir)) {
299557
+ try {
299558
+ rmSync7(dir, { recursive: true, force: true });
299559
+ removed = true;
299560
+ } catch {
299561
+ }
299562
+ }
299563
+ return removed;
299564
+ });
299420
299565
  }
299421
299566
  function listTodoSessions() {
299422
299567
  try {
299423
299568
  const dir = todoDir();
299424
299569
  if (!existsSync59(dir))
299425
299570
  return [];
299426
- return readdirSync20(dir).filter((f2) => f2.endsWith(".json") && !f2.includes(".tmp.")).map((f2) => f2.replace(/\.json$/, ""));
299571
+ const sessions3 = /* @__PURE__ */ new Set();
299572
+ for (const f2 of readdirSync20(dir)) {
299573
+ if (f2.endsWith(".json") && !f2.includes(".tmp.")) {
299574
+ sessions3.add(f2.replace(/\.json$/, ""));
299575
+ } else if (f2.endsWith(".tasks") && existsSync59(join71(dir, f2, "index.json"))) {
299576
+ sessions3.add(f2.replace(/\.tasks$/, ""));
299577
+ }
299578
+ }
299579
+ return [...sessions3].sort();
299427
299580
  } catch {
299428
299581
  return [];
299429
299582
  }
@@ -299448,6 +299601,101 @@ function getTodoSessionId() {
299448
299601
  return envSession;
299449
299602
  return "default";
299450
299603
  }
299604
+ function coerceStringList(value2) {
299605
+ if (!Array.isArray(value2))
299606
+ return void 0;
299607
+ const out = value2.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
299608
+ return out.length > 0 ? Array.from(new Set(out)) : void 0;
299609
+ }
299610
+ function todoChildrenByParent(todos) {
299611
+ const ids = new Set(todos.map((todo) => todo.id).filter((id2) => typeof id2 === "string" && id2.trim().length > 0));
299612
+ const byParent = /* @__PURE__ */ new Map();
299613
+ todos.forEach((todo, index) => {
299614
+ if (!todo.parentId || !ids.has(todo.parentId))
299615
+ return;
299616
+ const arr = byParent.get(todo.parentId) ?? [];
299617
+ arr.push(index);
299618
+ byParent.set(todo.parentId, arr);
299619
+ });
299620
+ return byParent;
299621
+ }
299622
+ function firstUnresolvedLeafIndex(todos, childrenByParent, startIndex) {
299623
+ const seen = /* @__PURE__ */ new Set();
299624
+ const visit = (index) => {
299625
+ if (seen.has(index))
299626
+ return null;
299627
+ seen.add(index);
299628
+ const todo = todos[index];
299629
+ if (!todo)
299630
+ return null;
299631
+ const children2 = todo.id ? childrenByParent.get(todo.id) ?? [] : [];
299632
+ if (children2.length === 0) {
299633
+ return todo.status === "completed" || todo.status === "blocked" ? null : index;
299634
+ }
299635
+ for (const childIndex of children2) {
299636
+ const found = visit(childIndex);
299637
+ if (found !== null)
299638
+ return found;
299639
+ }
299640
+ return null;
299641
+ };
299642
+ return visit(startIndex);
299643
+ }
299644
+ function enforceActiveLeafTodo(todos, repairNotes) {
299645
+ if (todos.length === 0)
299646
+ return;
299647
+ const childrenByParent = todoChildrenByParent(todos);
299648
+ const hasChildren = childrenByParent.size > 0;
299649
+ const isLeaf = (index) => {
299650
+ const todo = todos[index];
299651
+ return !todo?.id || (childrenByParent.get(todo.id) ?? []).length === 0;
299652
+ };
299653
+ const inProgressIndexes = todos.map((todo, index) => todo.status === "in_progress" ? index : -1).filter((index) => index >= 0);
299654
+ let keep = inProgressIndexes.find((index) => isLeaf(index)) ?? null;
299655
+ if (keep === null && inProgressIndexes.length > 0) {
299656
+ for (const index of inProgressIndexes) {
299657
+ const leaf = firstUnresolvedLeafIndex(todos, childrenByParent, index);
299658
+ if (leaf !== null) {
299659
+ keep = leaf;
299660
+ break;
299661
+ }
299662
+ }
299663
+ }
299664
+ if (keep === null) {
299665
+ keep = todos.findIndex((todo, index) => todo.status === "pending" && isLeaf(index));
299666
+ if (keep < 0) {
299667
+ keep = todos.findIndex((todo) => todo.status === "pending");
299668
+ }
299669
+ if (keep < 0)
299670
+ keep = null;
299671
+ }
299672
+ if (keep === null)
299673
+ return;
299674
+ let changed = false;
299675
+ for (let index = 0; index < todos.length; index++) {
299676
+ const todo = todos[index];
299677
+ if (index === keep) {
299678
+ if (todo.status === "pending") {
299679
+ todos[index] = { ...todo, status: "in_progress" };
299680
+ changed = true;
299681
+ }
299682
+ continue;
299683
+ }
299684
+ if (todo.status === "in_progress") {
299685
+ todos[index] = { ...todo, status: "pending" };
299686
+ changed = true;
299687
+ }
299688
+ }
299689
+ if (!changed)
299690
+ return;
299691
+ const active = todos[keep];
299692
+ const activeKind = active && isLeaf(keep) ? "leaf" : "todo";
299693
+ if (inProgressIndexes.length === 0) {
299694
+ repairNotes.push(hasChildren ? `promoted first pending ${activeKind} todo to in_progress because a non-empty active checklist must name the current leaf task` : "promoted first pending todo to in_progress because a non-empty active checklist must name the current task");
299695
+ } else {
299696
+ repairNotes.push(`kept one concrete active ${activeKind} in_progress and demoted parent/extra in_progress todos to pending because parent status is derived from children`);
299697
+ }
299698
+ }
299451
299699
  function flattenNestedTodoItems(items, repairNotes, parentId) {
299452
299700
  const flattened = [];
299453
299701
  for (const item of items) {
@@ -299644,12 +299892,18 @@ var init_todo_write = __esm({
299644
299892
 
299645
299893
  ## Nested decomposition
299646
299894
  - Use stable ids plus parentId to create subtasks under a parent objective.
299895
+ - Parents summarize objectives; the active in_progress item should be the concrete leaf currently being worked. Parent status is derived from child leaves in the UI/context.
299647
299896
  - Prefer a parent + child leaf todos for any active objective that has multiple concrete actions; the TUI renders the active branch indented for the user and for your next-turn context.
299648
299897
  - Work on leaf subtasks; a parent is completed only after every child is completed with evidence.
299649
299898
  - When evidence changes the plan, rewrite the tree: add new child todos, block invalidated children with root cause, and keep the parent in_progress/blocked until the child set is truthful.
299650
299899
  - If a tool fails for a child, do not mark that child completed. Reconfigure it: re-read/observe current state, choose a different target/tool, or leave it blocked.
299651
299900
 
299652
- Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark completed if tests are failing or implementation is partial. The user watches this list in the chat UI in real time. Canonical nested shape: todo_write({"todos":[{"id":"p1","content":"Implement feature","status":"in_progress","children":[{"id":"c1","content":"Inspect files","status":"in_progress"},{"id":"c2","content":"Make changes","status":"pending"},{"id":"c3","content":"Verify results","status":"pending"}]}]})`;
299901
+ ## Coordination metadata
299902
+ - activeForm is the present-continuous label shown while a leaf is active, e.g. "Running verifier".
299903
+ - owner identifies the responsible agent/sub-agent, e.g. "main", "fixer:compile-a1", or a sub-agent name.
299904
+ - blocks/blockedBy are cross-todo dependencies separate from parentId nesting. Do not start or complete a todo while a blockedBy todo is unresolved.
299905
+
299906
+ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark completed if tests are failing or implementation is partial. The user watches this list in the chat UI in real time. Canonical nested shape: todo_write({"todos":[{"id":"p1","content":"Implement feature","status":"pending","children":[{"id":"c1","content":"Inspect files","activeForm":"Inspecting files","status":"in_progress","owner":"main"},{"id":"c2","content":"Make changes","status":"pending","blockedBy":["c1"]},{"id":"c3","content":"Verify results","status":"pending","blockedBy":["c2"]}]}]})`;
299653
299907
  parameters = {
299654
299908
  type: "object",
299655
299909
  required: ["todos"],
@@ -299663,12 +299917,24 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
299663
299917
  properties: {
299664
299918
  id: { type: "string", description: "Stable id (auto-generated if omitted)" },
299665
299919
  content: { type: "string", description: "What needs to be done" },
299920
+ activeForm: { type: "string", description: "Present-continuous form shown when this leaf is active, e.g. 'Running verifier'." },
299666
299921
  status: {
299667
299922
  type: "string",
299668
299923
  enum: ["pending", "in_progress", "completed", "blocked"]
299669
299924
  },
299670
299925
  parentId: { type: "string", description: "Parent todo id for nested sub-tasks. Parents summarize objectives; children carry concrete implementation/verification work. Never complete a parent until every child is completed with evidence." },
299671
299926
  blocker: { type: "string", description: "Reason this is blocked (status=blocked only)" },
299927
+ owner: { type: "string", description: "Agent/sub-agent responsible for this todo, e.g. 'main' or 'fixer:compile-card'." },
299928
+ blocks: {
299929
+ type: "array",
299930
+ items: { type: "string" },
299931
+ description: "Todo ids that cannot start until this todo completes. Cross-todo dependency graph, separate from parentId nesting."
299932
+ },
299933
+ blockedBy: {
299934
+ type: "array",
299935
+ items: { type: "string" },
299936
+ description: "Todo ids that must complete before this todo can start or complete."
299937
+ },
299672
299938
  verifyCommand: {
299673
299939
  type: "string",
299674
299940
  description: "REG-37: optional shell command that PROVES this todo is complete. When you mark this todo 'completed', the orchestrator checks recent shell history; if verifyCommand has not run successfully recently, you'll be prompted to run it before the completion is accepted. Use for any todo where 'done' has an objective check (e.g. 'tsc --noEmit' for typecheck-pass, 'test -d dist' for build-output-present, 'pytest tests/x.py' for tests-pass). Generic across stacks."
@@ -299756,9 +300022,13 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
299756
300022
  incoming.push({
299757
300023
  id: typeof entry["id"] === "string" ? entry["id"] : void 0,
299758
300024
  content,
300025
+ activeForm: typeof entry["activeForm"] === "string" ? entry["activeForm"] : void 0,
299759
300026
  status: resolvedStatus,
299760
300027
  parentId: typeof entry["parentId"] === "string" ? entry["parentId"] : void 0,
299761
300028
  blocker: typeof entry["blocker"] === "string" ? entry["blocker"] : void 0,
300029
+ owner: typeof entry["owner"] === "string" ? entry["owner"] : void 0,
300030
+ blocks: coerceStringList(entry["blocks"]),
300031
+ blockedBy: coerceStringList(entry["blockedBy"] ?? entry["dependsOn"]),
299762
300032
  // REG-37: verification-aware planning
299763
300033
  verifyCommand: typeof entry["verifyCommand"] === "string" ? entry["verifyCommand"] : void 0,
299764
300034
  // REG-38: declared artifact list for supervisor inspection
@@ -299774,20 +300044,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
299774
300044
  durationMs: performance.now() - start2
299775
300045
  };
299776
300046
  }
299777
- const inProgressIndexes = incoming.map((todo, index) => todo.status === "in_progress" ? index : -1).filter((index) => index >= 0);
299778
- if (inProgressIndexes.length === 0) {
299779
- const firstPending = incoming.findIndex((todo) => todo.status === "pending");
299780
- if (firstPending >= 0) {
299781
- incoming[firstPending] = { ...incoming[firstPending], status: "in_progress" };
299782
- repairNotes.push("promoted first pending todo to in_progress because a non-empty active checklist must name the current task");
299783
- }
299784
- } else if (inProgressIndexes.length > 1) {
299785
- const keep = inProgressIndexes[0];
299786
- for (const index of inProgressIndexes.slice(1)) {
299787
- incoming[index] = { ...incoming[index], status: "pending" };
299788
- }
299789
- repairNotes.push(`kept todo ${keep + 1} in_progress and demoted extra in_progress todos to pending`);
299790
- }
300047
+ enforceActiveLeafTodo(incoming, repairNotes);
299791
300048
  const sessionId = typeof args["session_id"] === "string" && args["session_id"].trim() ? args["session_id"].trim() : typeof args["sessionId"] === "string" && args["sessionId"].trim() ? args["sessionId"].trim() : getTodoSessionId();
299792
300049
  const oldTodos = readTodos(sessionId);
299793
300050
  const canonicalize2 = (todos) => JSON.stringify(todos.map((t2) => ({
@@ -299795,6 +300052,10 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
299795
300052
  status: t2.status,
299796
300053
  parentId: t2.parentId ?? null,
299797
300054
  blocker: t2.blocker ?? null,
300055
+ activeForm: t2.activeForm ?? null,
300056
+ owner: t2.owner ?? null,
300057
+ blocks: Array.isArray(t2.blocks) ? [...t2.blocks].sort() : null,
300058
+ blockedBy: Array.isArray(t2.blockedBy) ? [...t2.blockedBy].sort() : null,
299798
300059
  verifyCommand: t2.verifyCommand ?? null,
299799
300060
  declaredArtifacts: Array.isArray(t2.declaredArtifacts) ? [...t2.declaredArtifacts].sort() : null
299800
300061
  })));
@@ -299826,9 +300087,10 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
299826
300087
  const reminder = "Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Mark the current task in_progress and the next task pending. Proceed with the current task.";
299827
300088
  const payload = {
299828
300089
  reminder,
299829
- decompositionContract: "Use parentId for sub-todos. Split the active objective into concrete child leaf todos whenever it contains multiple remaining actions. Keep parents in_progress/blocked until all children are completed with objective evidence. When tool evidence invalidates a child, rewrite that child as blocked or split it into new children instead of overclaiming completion.",
300090
+ decompositionContract: "Use parentId for sub-todos. Split the active objective into concrete child leaf todos whenever it contains multiple remaining actions. Keep the active in_progress status on one concrete leaf; parent status is derived from children in the UI/context. Use activeForm for the currently-doing wording, owner for assigned agent/sub-agent, and blocks/blockedBy for cross-todo dependencies. When tool evidence invalidates a child, rewrite that child as blocked or split it into new children instead of overclaiming completion.",
299830
300091
  oldTodos: result.oldTodos,
299831
300092
  newTodos: result.newTodos,
300093
+ storageMode: "file-per-task+legacy-mirror",
299832
300094
  verificationNudgeNeeded
299833
300095
  };
299834
300096
  const hasNestedTodos = incoming.some((todo) => typeof todo.parentId === "string" && todo.parentId.trim().length > 0);
@@ -299839,10 +300101,10 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
299839
300101
  payload["inputRepair"] = Array.from(new Set(repairNotes));
299840
300102
  payload["canonicalShape"] = {
299841
300103
  todos: [
299842
- { id: "p1", content: "Implement the requested change", status: "in_progress" },
299843
- { id: "c1", parentId: "p1", content: "Inspect files", status: "in_progress" },
299844
- { id: "c2", parentId: "p1", content: "Make changes", status: "pending" },
299845
- { id: "c3", parentId: "p1", content: "Verify results", status: "pending" }
300104
+ { id: "p1", content: "Implement the requested change", status: "pending" },
300105
+ { id: "c1", parentId: "p1", content: "Inspect files", activeForm: "Inspecting files", status: "in_progress", owner: "main" },
300106
+ { id: "c2", parentId: "p1", content: "Make changes", status: "pending", blockedBy: ["c1"] },
300107
+ { id: "c3", parentId: "p1", content: "Verify results", status: "pending", blockedBy: ["c2"] }
299846
300108
  ]
299847
300109
  };
299848
300110
  }
@@ -299900,7 +300162,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
299900
300162
  });
299901
300163
 
299902
300164
  // packages/execution/dist/tools/repo-map.js
299903
- import { readdirSync as readdirSync21, readFileSync as readFileSync44, statSync as statSync23, existsSync as existsSync60 } from "node:fs";
300165
+ import { readdirSync as readdirSync21, readFileSync as readFileSync44, statSync as statSync24, existsSync as existsSync60 } from "node:fs";
299904
300166
  import { join as join72, relative as relative5, extname as extname9, dirname as dirname19, basename as basename13 } from "node:path";
299905
300167
  function parseJSImports(content, filePath) {
299906
300168
  const imports = [];
@@ -300009,7 +300271,7 @@ function buildGraph(rootDir, maxFiles = 2e3) {
300009
300271
  const full = join72(dir, entry);
300010
300272
  let stat9;
300011
300273
  try {
300012
- stat9 = statSync23(full);
300274
+ stat9 = statSync24(full);
300013
300275
  } catch {
300014
300276
  continue;
300015
300277
  }
@@ -311463,7 +311725,7 @@ ${lanes.join("\n")}
311463
311725
  return process.memoryUsage().heapUsed;
311464
311726
  },
311465
311727
  getFileSize(path16) {
311466
- const stat9 = statSync67(path16);
311728
+ const stat9 = statSync68(path16);
311467
311729
  if (stat9 == null ? void 0 : stat9.isFile()) {
311468
311730
  return stat9.size;
311469
311731
  }
@@ -311507,7 +311769,7 @@ ${lanes.join("\n")}
311507
311769
  }
311508
311770
  };
311509
311771
  return nodeSystem;
311510
- function statSync67(path16) {
311772
+ function statSync68(path16) {
311511
311773
  try {
311512
311774
  return _fs.statSync(path16, statSyncOptions);
311513
311775
  } catch {
@@ -311566,7 +311828,7 @@ ${lanes.join("\n")}
311566
311828
  activeSession.post("Profiler.stop", (err, { profile }) => {
311567
311829
  var _a2;
311568
311830
  if (!err) {
311569
- if ((_a2 = statSync67(profilePath)) == null ? void 0 : _a2.isDirectory()) {
311831
+ if ((_a2 = statSync68(profilePath)) == null ? void 0 : _a2.isDirectory()) {
311570
311832
  profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
311571
311833
  }
311572
311834
  try {
@@ -311686,7 +311948,7 @@ ${lanes.join("\n")}
311686
311948
  let stat9;
311687
311949
  if (typeof dirent === "string" || dirent.isSymbolicLink()) {
311688
311950
  const name10 = combinePaths(path16, entry);
311689
- stat9 = statSync67(name10);
311951
+ stat9 = statSync68(name10);
311690
311952
  if (!stat9) {
311691
311953
  continue;
311692
311954
  }
@@ -311710,7 +311972,7 @@ ${lanes.join("\n")}
311710
311972
  return matchFiles(path16, extensions, excludes, includes, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
311711
311973
  }
311712
311974
  function fileSystemEntryExists(path16, entryKind) {
311713
- const stat9 = statSync67(path16);
311975
+ const stat9 = statSync68(path16);
311714
311976
  if (!stat9) {
311715
311977
  return false;
311716
311978
  }
@@ -311752,7 +312014,7 @@ ${lanes.join("\n")}
311752
312014
  }
311753
312015
  function getModifiedTime3(path16) {
311754
312016
  var _a2;
311755
- return (_a2 = statSync67(path16)) == null ? void 0 : _a2.mtime;
312017
+ return (_a2 = statSync68(path16)) == null ? void 0 : _a2.mtime;
311756
312018
  }
311757
312019
  function setModifiedTime(path16, time) {
311758
312020
  try {
@@ -545315,7 +545577,7 @@ var init_code_graph_events = __esm({
545315
545577
  });
545316
545578
 
545317
545579
  // packages/execution/dist/tools/code-graph-client.js
545318
- import { existsSync as existsSync61, statSync as statSync24, readdirSync as readdirSync22 } from "node:fs";
545580
+ import { existsSync as existsSync61, statSync as statSync25, readdirSync as readdirSync22 } from "node:fs";
545319
545581
  import { join as join75, relative as relative8, sep as sep2 } from "node:path";
545320
545582
  function collectSources(root) {
545321
545583
  const out = [];
@@ -545382,7 +545644,7 @@ function closeAllCodeGraphDBs() {
545382
545644
  function codeGraphDBExists(workingDir) {
545383
545645
  const path16 = join75(workingDir, ".omnius", "index", "code-graph.db");
545384
545646
  try {
545385
- return existsSync61(path16) && statSync24(path16).size > 0;
545647
+ return existsSync61(path16) && statSync25(path16).size > 0;
545386
545648
  } catch {
545387
545649
  return false;
545388
545650
  }
@@ -545927,7 +546189,7 @@ var init_process_health = __esm({
545927
546189
 
545928
546190
  // packages/execution/dist/tools/audio-capture.js
545929
546191
  import { execSync as execSync26 } from "node:child_process";
545930
- import { readFileSync as readFileSync46, unlinkSync as unlinkSync12, existsSync as existsSync62, mkdirSync as mkdirSync35, statSync as statSync25 } from "node:fs";
546192
+ import { readFileSync as readFileSync46, unlinkSync as unlinkSync12, existsSync as existsSync62, mkdirSync as mkdirSync35, statSync as statSync26 } from "node:fs";
545931
546193
  import { join as join76 } from "node:path";
545932
546194
  import { tmpdir as tmpdir12 } from "node:os";
545933
546195
  var AudioCaptureTool;
@@ -546100,7 +546362,7 @@ ${devices.join("\n")}`,
546100
546362
  if (!existsSync62(tempFile)) {
546101
546363
  return { success: false, output: "", error: "Recording produced no output. Device may not support the requested format.", durationMs: performance.now() - start2 };
546102
546364
  }
546103
- const fileSize2 = statSync25(tempFile).size;
546365
+ const fileSize2 = statSync26(tempFile).size;
546104
546366
  const sizeKB = Math.round(fileSize2 / 1024);
546105
546367
  try {
546106
546368
  fetch("http://127.0.0.1:11435/v1/memory/ingest", {
@@ -546178,7 +546440,7 @@ Saved to: ${tempFile}`,
546178
546440
 
546179
546441
  // packages/execution/dist/tools/audio-playback.js
546180
546442
  import { execFileSync as execFileSync2, execSync as execSync27, spawn as spawn18 } from "node:child_process";
546181
- import { copyFileSync as copyFileSync4, existsSync as existsSync63, statSync as statSync26, writeFileSync as writeFileSync29, mkdirSync as mkdirSync36, readdirSync as readdirSync23, writeSync, rmSync as rmSync7 } from "node:fs";
546443
+ import { copyFileSync as copyFileSync4, existsSync as existsSync63, statSync as statSync27, writeFileSync as writeFileSync29, mkdirSync as mkdirSync36, readdirSync as readdirSync23, writeSync, rmSync as rmSync8 } from "node:fs";
546182
546444
  import { basename as basename15, dirname as dirname21, extname as extname12, isAbsolute as isAbsolute5, join as join77, resolve as resolve40 } from "node:path";
546183
546445
  import { homedir as homedir17, tmpdir as tmpdir13 } from "node:os";
546184
546446
  function ttsPythonEnv(extra = {}) {
@@ -546433,7 +546695,7 @@ function mergeDir(src2, dst) {
546433
546695
  if (entry.isDirectory()) {
546434
546696
  mergeDir(s2, d2);
546435
546697
  } else if (entry.isFile()) {
546436
- if (!existsSync63(d2) || statSync26(s2).mtimeMs > statSync26(d2).mtimeMs) {
546698
+ if (!existsSync63(d2) || statSync27(s2).mtimeMs > statSync27(d2).mtimeMs) {
546437
546699
  copyFileSync4(s2, d2);
546438
546700
  }
546439
546701
  }
@@ -546448,7 +546710,7 @@ function consolidateVoiceDirs() {
546448
546710
  mergeDir(join77(oldVoice, "clone-refs"), join77(globalVoice, "clone-refs"));
546449
546711
  mergeDir(join77(oldVoice, "models"), join77(globalVoice, "models"));
546450
546712
  try {
546451
- rmSync7(oldVoice, { recursive: true, force: true });
546713
+ rmSync8(oldVoice, { recursive: true, force: true });
546452
546714
  } catch {
546453
546715
  }
546454
546716
  }
@@ -546481,7 +546743,7 @@ function consolidateVoiceDirs() {
546481
546743
  try {
546482
546744
  mergeDir(join77(candidate, "clone-refs"), join77(globalVoice, "clone-refs"));
546483
546745
  mergeDir(join77(candidate, "models"), join77(globalVoice, "models"));
546484
- rmSync7(candidate, { recursive: true, force: true });
546746
+ rmSync8(candidate, { recursive: true, force: true });
546485
546747
  } catch {
546486
546748
  }
546487
546749
  }
@@ -547654,7 +547916,7 @@ for line in sys.stdin:
547654
547916
  };
547655
547917
  }
547656
547918
  const device = args["device"] || "default";
547657
- const size = statSync26(file).size;
547919
+ const size = statSync27(file).size;
547658
547920
  const ext = file.split(".").pop()?.toLowerCase() || "";
547659
547921
  const played = playSoundFile(file, { device, timeoutMs: 3e5 });
547660
547922
  if (!played.ok) {
@@ -547815,7 +548077,7 @@ ${tried.map((line) => `- ${line}`).join("\n")}`,
547815
548077
  });
547816
548078
  return played.ok ? ` Playback: complete via ${played.player}` : ` Playback: failed - ${played.error}`;
547817
548079
  })() : " Playback: disabled";
547818
- const size = Math.round(statSync26(outputPath3).size / 1024);
548080
+ const size = Math.round(statSync27(outputPath3).size / 1024);
547819
548081
  const preview = text2.length > 140 ? `${text2.slice(0, 137)}...` : text2;
547820
548082
  const fallbackLine = requestedBackend !== "auto" && usedBackend !== requestedBackend ? ` Fallback: requested ${requestedBackend}; ${tried[0] ?? "requested backend unavailable"}` : "";
547821
548083
  return {
@@ -548252,7 +548514,7 @@ ${devices.join("\n")}`,
548252
548514
  durationMs: performance.now() - start2
548253
548515
  };
548254
548516
  }
548255
- const size = statSync26(file).size;
548517
+ const size = statSync27(file).size;
548256
548518
  const ext = extname12(file).replace(/^\./, "").toUpperCase() || "audio";
548257
548519
  const played = playSoundFile(file, { device, timeoutMs });
548258
548520
  if (!played.ok) {
@@ -548771,7 +549033,7 @@ ${info}`, durationMs: performance.now() - start2 };
548771
549033
 
548772
549034
  // packages/execution/dist/tools/sdr-scan.js
548773
549035
  import { execSync as execSync30 } from "node:child_process";
548774
- import { readFileSync as readFileSync47, unlinkSync as unlinkSync13, existsSync as existsSync64, mkdirSync as mkdirSync37, statSync as statSync27 } from "node:fs";
549036
+ import { readFileSync as readFileSync47, unlinkSync as unlinkSync13, existsSync as existsSync64, mkdirSync as mkdirSync37, statSync as statSync28 } from "node:fs";
548775
549037
  import { join as join78 } from "node:path";
548776
549038
  import { tmpdir as tmpdir14 } from "node:os";
548777
549039
  var SdrScanTool;
@@ -548957,7 +549219,7 @@ Tools installed but rtl_test failed — device may be in use by another process.
548957
549219
  } catch (cmdErr) {
548958
549220
  output = cmdErr.stdout?.toString() || cmdErr.stderr?.toString() || "";
548959
549221
  }
548960
- if (!existsSync64(outFile) || statSync27(outFile).size === 0) {
549222
+ if (!existsSync64(outFile) || statSync28(outFile).size === 0) {
548961
549223
  return { success: false, output: output.slice(0, 300), error: "Scan produced no data. SDR device may be busy or frequency range unsupported.", durationMs: performance.now() - start2 };
548962
549224
  }
548963
549225
  const csv = readFileSync47(outFile, "utf8");
@@ -553697,7 +553959,7 @@ var init_mutation_contract = __esm({
553697
553959
 
553698
553960
  // packages/execution/dist/tools/worktree.js
553699
553961
  import { execSync as execSync36 } from "node:child_process";
553700
- import { existsSync as existsSync71, mkdirSync as mkdirSync43, rmSync as rmSync8 } from "node:fs";
553962
+ import { existsSync as existsSync71, mkdirSync as mkdirSync43, rmSync as rmSync9 } from "node:fs";
553701
553963
  import { join as join84, resolve as resolve44 } from "node:path";
553702
553964
  function validateSlug(slug) {
553703
553965
  if (!slug)
@@ -553816,7 +554078,7 @@ function removeWorktree(repoRoot, slug, force = false) {
553816
554078
  });
553817
554079
  } catch (err) {
553818
554080
  try {
553819
- rmSync8(worktreePath, { recursive: true, force: true });
554081
+ rmSync9(worktreePath, { recursive: true, force: true });
553820
554082
  execSync36("git worktree prune", { cwd: repoRoot, stdio: "pipe" });
553821
554083
  } catch {
553822
554084
  return `Failed to remove worktree: ${err}`;
@@ -555067,7 +555329,7 @@ var init_client3 = __esm({
555067
555329
  });
555068
555330
 
555069
555331
  // packages/execution/dist/mcp/secret-store.js
555070
- import { existsSync as existsSync72, readFileSync as readFileSync52, writeFileSync as writeFileSync35, mkdirSync as mkdirSync44, chmodSync, statSync as statSync28 } from "node:fs";
555332
+ import { existsSync as existsSync72, readFileSync as readFileSync52, writeFileSync as writeFileSync35, mkdirSync as mkdirSync44, chmodSync, statSync as statSync29 } from "node:fs";
555071
555333
  import { join as join85, dirname as dirname23 } from "node:path";
555072
555334
  import { homedir as homedir23 } from "node:os";
555073
555335
  import { randomBytes as randomBytes19, createHash as createHash24 } from "node:crypto";
@@ -555099,7 +555361,7 @@ function verifyStorePermissions(scope, repoRoot) {
555099
555361
  if (!existsSync72(path16))
555100
555362
  return true;
555101
555363
  try {
555102
- const mode = statSync28(path16).mode & 511;
555364
+ const mode = statSync29(path16).mode & 511;
555103
555365
  return mode === 384;
555104
555366
  } catch {
555105
555367
  return false;
@@ -556922,7 +557184,7 @@ var init_environment_snapshot = __esm({
556922
557184
  });
556923
557185
 
556924
557186
  // packages/execution/dist/tools/video-understand.js
556925
- import { existsSync as existsSync76, mkdirSync as mkdirSync46, writeFileSync as writeFileSync38, readFileSync as readFileSync56, readdirSync as readdirSync26, unlinkSync as unlinkSync16, rmSync as rmSync9 } from "node:fs";
557187
+ import { existsSync as existsSync76, mkdirSync as mkdirSync46, writeFileSync as writeFileSync38, readFileSync as readFileSync56, readdirSync as readdirSync26, unlinkSync as unlinkSync16, rmSync as rmSync10 } from "node:fs";
556926
557188
  import { join as join88, basename as basename18, isAbsolute as isAbsolute8, resolve as resolve46 } from "node:path";
556927
557189
  import { homedir as homedir26 } from "node:os";
556928
557190
  import { createHash as createHash25 } from "node:crypto";
@@ -557417,7 +557679,7 @@ Topic: ${(segments.slice(0, 5).map((s2) => s2.text).join(" ") || audioComprehens
557417
557679
  }
557418
557680
  }
557419
557681
  try {
557420
- rmSync9(tmpDir, { recursive: true, force: true });
557682
+ rmSync10(tmpDir, { recursive: true, force: true });
557421
557683
  } catch {
557422
557684
  }
557423
557685
  return {
@@ -557439,7 +557701,7 @@ Topic: ${(segments.slice(0, 5).map((s2) => s2.text).join(" ") || audioComprehens
557439
557701
  });
557440
557702
 
557441
557703
  // packages/execution/dist/tools/video-scan.js
557442
- import { existsSync as existsSync77, readFileSync as readFileSync57, statSync as statSync29 } from "node:fs";
557704
+ import { existsSync as existsSync77, readFileSync as readFileSync57, statSync as statSync30 } from "node:fs";
557443
557705
  import { spawn as spawn21 } from "node:child_process";
557444
557706
  import { resolve as resolve47, dirname as dirname25, join as join89, basename as basename19 } from "node:path";
557445
557707
  import { fileURLToPath as fileURLToPath11 } from "node:url";
@@ -557560,7 +557822,7 @@ function resolveVideoPath(workingDir, rawPath) {
557560
557822
  const full = resolve47(workingDir, rawPath);
557561
557823
  if (!existsSync77(full))
557562
557824
  throw new Error(`Video not found: ${rawPath}`);
557563
- const stat9 = statSync29(full);
557825
+ const stat9 = statSync30(full);
557564
557826
  if (!stat9.isFile())
557565
557827
  throw new Error(`Not a file: ${rawPath}`);
557566
557828
  const ext = full.slice(full.lastIndexOf(".")).toLowerCase();
@@ -558106,7 +558368,7 @@ var init_visual_trigger = __esm({
558106
558368
  });
558107
558369
 
558108
558370
  // packages/execution/dist/tools/live-media-loop.js
558109
- import { existsSync as existsSync79, mkdirSync as mkdirSync47, readFileSync as readFileSync58, rmSync as rmSync10, writeFileSync as writeFileSync39 } from "node:fs";
558371
+ import { existsSync as existsSync79, mkdirSync as mkdirSync47, readFileSync as readFileSync58, rmSync as rmSync11, writeFileSync as writeFileSync39 } from "node:fs";
558110
558372
  import { homedir as homedir28, tmpdir as tmpdir20 } from "node:os";
558111
558373
  import { basename as basename20, isAbsolute as isAbsolute10, join as join92, resolve as resolve48 } from "node:path";
558112
558374
  function isAbortSignal(value2) {
@@ -558472,11 +558734,11 @@ print(json.dumps({
558472
558734
  return JSON.parse(jsonLine2);
558473
558735
  } finally {
558474
558736
  try {
558475
- rmSync10(cfgPath, { force: true });
558737
+ rmSync11(cfgPath, { force: true });
558476
558738
  } catch {
558477
558739
  }
558478
558740
  try {
558479
- rmSync10(scriptPath2, { force: true });
558741
+ rmSync11(scriptPath2, { force: true });
558480
558742
  } catch {
558481
558743
  }
558482
558744
  }
@@ -559063,11 +559325,11 @@ var init_live_media_loop = __esm({
559063
559325
  return { success: false, output: "", error: err instanceof Error ? err.message : String(err), durationMs: performance.now() - start2 };
559064
559326
  } finally {
559065
559327
  try {
559066
- rmSync10(cfgPath, { force: true });
559328
+ rmSync11(cfgPath, { force: true });
559067
559329
  } catch {
559068
559330
  }
559069
559331
  try {
559070
- rmSync10(scriptPath2, { force: true });
559332
+ rmSync11(scriptPath2, { force: true });
559071
559333
  } catch {
559072
559334
  }
559073
559335
  }
@@ -566134,6 +566396,247 @@ var init_completionLedger = __esm({
566134
566396
  }
566135
566397
  });
566136
566398
 
566399
+ // packages/orchestrator/dist/todoTruth.js
566400
+ function normalizeText2(value2) {
566401
+ return value2.toLowerCase().replace(/[_-]+/g, " ").replace(/[^a-z0-9./ ]+/g, " ").replace(/\s+/g, " ").trim();
566402
+ }
566403
+ function extractArg(argsKey, key) {
566404
+ if (!argsKey)
566405
+ return "";
566406
+ const re = new RegExp(`(?:^|,)${key}=([^,]+)`);
566407
+ return argsKey.match(re)?.[1]?.trim() ?? "";
566408
+ }
566409
+ function toolAliases(toolName) {
566410
+ const normalized = normalizeText2(toolName);
566411
+ const spaceAlias = normalizeText2(toolName.replace(/_/g, " "));
566412
+ const compactAlias = toolName.toLowerCase().replace(/[^a-z0-9]+/g, "");
566413
+ return [...new Set([normalized, spaceAlias, compactAlias].filter(Boolean))];
566414
+ }
566415
+ function todoMentionsFailedCall(todo, call) {
566416
+ if (NON_WORK_TOOLS.has(call.name))
566417
+ return false;
566418
+ const content = normalizeText2(todo.content);
566419
+ const compactContent2 = todo.content.toLowerCase().replace(/[^a-z0-9]+/g, "");
566420
+ const mentionsTool = toolAliases(call.name).some((alias) => {
566421
+ if (alias.length <= 2)
566422
+ return false;
566423
+ if (/^[a-z0-9]+$/.test(alias) && alias === call.name.toLowerCase().replace(/[^a-z0-9]+/g, "")) {
566424
+ return compactContent2.includes(alias);
566425
+ }
566426
+ return content.includes(alias);
566427
+ });
566428
+ if (!mentionsTool)
566429
+ return false;
566430
+ const action = normalizeText2(extractArg(call.argsKey, "action"));
566431
+ if (!action)
566432
+ return true;
566433
+ return content.includes(action) || action.length <= 2;
566434
+ }
566435
+ function evidenceLine(call) {
566436
+ const preview = String(call.outputPreview ?? "").split("\n").map((line) => line.trim()).find(Boolean);
566437
+ const action = extractArg(call.argsKey, "action");
566438
+ const detail = preview || "tool returned failure";
566439
+ return `${call.name}${action ? ` ${action}` : ""}: ${detail}`.slice(0, 260);
566440
+ }
566441
+ function toolEvidenceFamilies(toolName) {
566442
+ const families = [];
566443
+ if (VISUAL_EVIDENCE_TOOLS.has(toolName))
566444
+ families.push("visual_evidence");
566445
+ if (AUDIO_EVIDENCE_TOOLS.has(toolName))
566446
+ families.push("audio_evidence");
566447
+ return families;
566448
+ }
566449
+ function hasLaterSuccessForCompatibleEvidence(calls, failedIndex) {
566450
+ const failed = calls[failedIndex];
566451
+ if (!failed)
566452
+ return false;
566453
+ const failedAction = normalizeText2(extractArg(failed.argsKey, "action"));
566454
+ const failedFamilies = toolEvidenceFamilies(failed.name);
566455
+ for (let i2 = failedIndex + 1; i2 < calls.length; i2++) {
566456
+ const next = calls[i2];
566457
+ if (!next || next.success !== true)
566458
+ continue;
566459
+ const nextFamilies = toolEvidenceFamilies(next.name);
566460
+ if (failedFamilies.length > 0 && failedFamilies.some((family) => nextFamilies.includes(family))) {
566461
+ return true;
566462
+ }
566463
+ if (next.name !== failed.name)
566464
+ continue;
566465
+ const nextAction = normalizeText2(extractArg(next.argsKey, "action"));
566466
+ if (!failedAction || !nextAction || failedAction === nextAction)
566467
+ return true;
566468
+ }
566469
+ return false;
566470
+ }
566471
+ function stringList(value2) {
566472
+ return Array.isArray(value2) ? Array.from(new Set(value2.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim()))) : [];
566473
+ }
566474
+ function buildTodoTruthIndex(todos) {
566475
+ const byId = /* @__PURE__ */ new Map();
566476
+ for (const todo of todos) {
566477
+ if (todo.id)
566478
+ byId.set(todo.id, todo);
566479
+ }
566480
+ const childrenByParent = /* @__PURE__ */ new Map();
566481
+ const blockedBy = /* @__PURE__ */ new Map();
566482
+ for (const todo of todos) {
566483
+ if (todo.parentId && byId.has(todo.parentId)) {
566484
+ const arr = childrenByParent.get(todo.parentId) ?? [];
566485
+ arr.push(todo);
566486
+ childrenByParent.set(todo.parentId, arr);
566487
+ }
566488
+ if (todo.id) {
566489
+ const deps = stringList(todo.blockedBy);
566490
+ if (deps.length > 0)
566491
+ blockedBy.set(todo.id, deps);
566492
+ }
566493
+ }
566494
+ for (const todo of todos) {
566495
+ if (!todo.id)
566496
+ continue;
566497
+ for (const blockedId of stringList(todo.blocks)) {
566498
+ const arr = blockedBy.get(blockedId) ?? [];
566499
+ arr.push(todo.id);
566500
+ blockedBy.set(blockedId, Array.from(new Set(arr)));
566501
+ }
566502
+ }
566503
+ return { byId, childrenByParent, blockedBy };
566504
+ }
566505
+ function deriveTodoStatus(todo, index, seen = /* @__PURE__ */ new Set()) {
566506
+ if (todo.id) {
566507
+ if (seen.has(todo.id))
566508
+ return todo.status;
566509
+ seen.add(todo.id);
566510
+ }
566511
+ const children2 = todo.id ? index.childrenByParent.get(todo.id) ?? [] : [];
566512
+ if (children2.length === 0)
566513
+ return todo.status;
566514
+ const statuses = children2.map((child) => deriveTodoStatus(child, index, new Set(seen)));
566515
+ if (statuses.some((status) => status === "blocked"))
566516
+ return "blocked";
566517
+ if (statuses.every((status) => status === "completed"))
566518
+ return "completed";
566519
+ if (statuses.every((status) => status === "pending"))
566520
+ return "pending";
566521
+ return "in_progress";
566522
+ }
566523
+ function unmetTodoDependencies(todo, index) {
566524
+ if (!todo.id)
566525
+ return [];
566526
+ const deps = index.blockedBy.get(todo.id) ?? [];
566527
+ return deps.filter((depId) => {
566528
+ const dep = index.byId.get(depId);
566529
+ return !dep || deriveTodoStatus(dep, index) !== "completed";
566530
+ });
566531
+ }
566532
+ function todoLeaves(todos, index = buildTodoTruthIndex(todos)) {
566533
+ const leaves = todos.filter((todo) => !todo.id || (index.childrenByParent.get(todo.id) ?? []).length === 0);
566534
+ return leaves.length > 0 ? leaves : todos;
566535
+ }
566536
+ function openTodoLeaves(todos) {
566537
+ const index = buildTodoTruthIndex(todos);
566538
+ return todoLeaves(todos, index).filter((todo) => {
566539
+ if (deriveTodoStatus(todo, index) !== "completed")
566540
+ return true;
566541
+ return unmetTodoDependencies(todo, index).length > 0;
566542
+ });
566543
+ }
566544
+ function reconcileCompletedTodosWithEvidence(input) {
566545
+ const nextTodos = input.todos.map((todo) => ({ ...todo }));
566546
+ const downgrades = [];
566547
+ const index = buildTodoTruthIndex(nextTodos);
566548
+ for (const todo of nextTodos) {
566549
+ const derived = deriveTodoStatus(todo, index);
566550
+ const children2 = todo.id ? index.childrenByParent.get(todo.id) ?? [] : [];
566551
+ if (derived !== todo.status && children2.length > 0) {
566552
+ const from3 = todo.status;
566553
+ const targetStatus = derived === "blocked" ? "blocked" : derived === "completed" ? "completed" : "in_progress";
566554
+ const unresolvedChild = children2.find((child) => deriveTodoStatus(child, index) === "blocked") ?? children2.find((child) => deriveTodoStatus(child, index) === "in_progress") ?? children2.find((child) => deriveTodoStatus(child, index) === "pending") ?? null;
566555
+ const blocker = targetStatus === "completed" ? "" : unresolvedChild && deriveTodoStatus(unresolvedChild, index) === "blocked" ? `Child todo blocked: ${unresolvedChild.content}${unresolvedChild.blocker ? ` (${unresolvedChild.blocker})` : ""}` : unresolvedChild ? `Child todo not complete: [${deriveTodoStatus(unresolvedChild, index)}] ${unresolvedChild.content}` : `Parent status derived from child todos: ${derived}`;
566556
+ downgrades.push({
566557
+ id: todo.id,
566558
+ content: todo.content,
566559
+ from: from3,
566560
+ to: targetStatus,
566561
+ blocker,
566562
+ evidence: blocker
566563
+ });
566564
+ todo.status = targetStatus;
566565
+ if (blocker)
566566
+ todo.blocker = blocker;
566567
+ }
566568
+ }
566569
+ const refreshedIndex = buildTodoTruthIndex(nextTodos);
566570
+ for (const todo of nextTodos) {
566571
+ if (todo.status !== "completed")
566572
+ continue;
566573
+ const unmet = unmetTodoDependencies(todo, refreshedIndex);
566574
+ if (unmet.length > 0) {
566575
+ const blocker2 = `Todo has unmet dependencies: ${unmet.join(", ")}`;
566576
+ downgrades.push({
566577
+ id: todo.id,
566578
+ content: todo.content,
566579
+ from: "completed",
566580
+ to: "blocked",
566581
+ blocker: blocker2,
566582
+ evidence: blocker2
566583
+ });
566584
+ todo.status = "blocked";
566585
+ todo.blocker = blocker2;
566586
+ continue;
566587
+ }
566588
+ const startTurn = todo.id && input.todoStartTurnById?.has(todo.id) ? input.todoStartTurnById.get(todo.id) : 0;
566589
+ const relevantCalls = input.toolCallLog.filter((call) => (call.turn ?? 0) >= startTurn);
566590
+ const failedIndex = relevantCalls.findIndex((call, index2) => call.success === false && todoMentionsFailedCall(todo, call) && !hasLaterSuccessForCompatibleEvidence(relevantCalls, index2));
566591
+ if (failedIndex < 0)
566592
+ continue;
566593
+ const failed = relevantCalls[failedIndex];
566594
+ const evidence = evidenceLine(failed);
566595
+ const blocker = `Completion claim contradicted by failed ${failed.name} evidence. Reconfigure this subtask: verify whether the goal is already satisfied, choose a different target/tool, or leave the todo blocked with the root cause.`;
566596
+ downgrades.push({
566597
+ id: todo.id,
566598
+ content: todo.content,
566599
+ from: "completed",
566600
+ to: "blocked",
566601
+ blocker,
566602
+ evidence
566603
+ });
566604
+ todo.status = "blocked";
566605
+ todo.blocker = `${blocker} Evidence: ${evidence}`;
566606
+ }
566607
+ return {
566608
+ todos: nextTodos,
566609
+ changed: downgrades.length > 0,
566610
+ downgrades
566611
+ };
566612
+ }
566613
+ var NON_WORK_TOOLS, VISUAL_EVIDENCE_TOOLS, AUDIO_EVIDENCE_TOOLS;
566614
+ var init_todoTruth = __esm({
566615
+ "packages/orchestrator/dist/todoTruth.js"() {
566616
+ "use strict";
566617
+ NON_WORK_TOOLS = /* @__PURE__ */ new Set(["todo_write", "todo_read", "task_complete"]);
566618
+ VISUAL_EVIDENCE_TOOLS = /* @__PURE__ */ new Set([
566619
+ "av_comprehend",
566620
+ "image_read",
566621
+ "ocr",
566622
+ "ocr_image_advanced",
566623
+ "screenshot",
566624
+ "telegram_image_analyze",
566625
+ "video_scan",
566626
+ "video_understand",
566627
+ "vision"
566628
+ ]);
566629
+ AUDIO_EVIDENCE_TOOLS = /* @__PURE__ */ new Set([
566630
+ "asr_listen",
566631
+ "audio_analyze",
566632
+ "av_comprehend",
566633
+ "transcribe_file",
566634
+ "transcribe_url",
566635
+ "video_understand"
566636
+ ]);
566637
+ }
566638
+ });
566639
+
566137
566640
  // packages/orchestrator/dist/completionAutoFinalize.js
566138
566641
  function buildTruthBasedCompletion(input) {
566139
566642
  const maxAge = input.maxValidationAgeTurns ?? 8;
@@ -566177,18 +566680,20 @@ ${fileLines2}` : null,
566177
566680
  summary: summary2
566178
566681
  };
566179
566682
  }
566180
- const open2 = input.todos.filter((todo) => todo.status !== "completed");
566683
+ const open2 = openTodoLeaves(input.todos);
566181
566684
  if (open2.length > 0) {
566182
566685
  return { ready: false, reason: `${open2.length} open todo(s)` };
566183
566686
  }
566184
- const todoLines = input.todos.slice(0, 12).map((todo) => {
566687
+ const index = buildTodoTruthIndex(input.todos);
566688
+ const leaves = todoLeaves(input.todos, index);
566689
+ const todoLines = leaves.slice(0, 12).map((todo) => {
566185
566690
  const id2 = todo.id ? `${todo.id}: ` : "";
566186
566691
  return `- ${id2}${todo.content}`;
566187
566692
  }).join("\n");
566188
566693
  const fileLines = files.map((file) => `- ${file.action ? `${file.action} ` : ""}${file.path}`).join("\n");
566189
566694
  const summary = [
566190
566695
  "Completed with structured task evidence.",
566191
- `Todos completed: ${input.todos.length}/${input.todos.length}`,
566696
+ `Todos completed: ${leaves.length}/${leaves.length}`,
566192
566697
  todoLines ? `Completed todo tree:
566193
566698
  ${todoLines}` : null,
566194
566699
  fileLines ? `Files changed:
@@ -566204,6 +566709,7 @@ ${fileLines}` : null,
566204
566709
  var init_completionAutoFinalize = __esm({
566205
566710
  "packages/orchestrator/dist/completionAutoFinalize.js"() {
566206
566711
  "use strict";
566712
+ init_todoTruth();
566207
566713
  }
566208
566714
  });
566209
566715
 
@@ -566931,7 +567437,7 @@ var init_ollama_pool_cleanup = __esm({
566931
567437
 
566932
567438
  // packages/orchestrator/dist/ollama-pool.js
566933
567439
  import { spawn as spawn25, exec as exec2 } from "node:child_process";
566934
- import { existsSync as existsSync88, readFileSync as readFileSync68, readdirSync as readdirSync28, statfsSync as statfsSync5, statSync as statSync30 } from "node:fs";
567440
+ import { existsSync as existsSync88, readFileSync as readFileSync68, readdirSync as readdirSync28, statfsSync as statfsSync5, statSync as statSync31 } from "node:fs";
566935
567441
  import { homedir as homedir33 } from "node:os";
566936
567442
  import { join as join100 } from "node:path";
566937
567443
  import { createServer as createServer3 } from "node:net";
@@ -566956,7 +567462,7 @@ function discoverSystemOllamaModelStore() {
566956
567462
  }
566957
567463
  function isDirectory(path16) {
566958
567464
  try {
566959
- return existsSync88(path16) && statSync30(path16).isDirectory();
567465
+ return existsSync88(path16) && statSync31(path16).isDirectory();
566960
567466
  } catch {
566961
567467
  return false;
566962
567468
  }
@@ -568803,7 +569309,7 @@ var init_mast_tagger = __esm({
568803
569309
  });
568804
569310
 
568805
569311
  // packages/orchestrator/dist/artifact-inspector.js
568806
- import { existsSync as existsSync89, statSync as statSync31 } from "node:fs";
569312
+ import { existsSync as existsSync89, statSync as statSync32 } from "node:fs";
568807
569313
  import { isAbsolute as isAbsolute11, resolve as resolve52 } from "node:path";
568808
569314
  function extractCandidatePaths(content) {
568809
569315
  const out = /* @__PURE__ */ new Set();
@@ -568835,7 +569341,7 @@ function inspectClaimedArtifacts(input) {
568835
569341
  }
568836
569342
  let st;
568837
569343
  try {
568838
- st = statSync31(resolved);
569344
+ st = statSync32(resolved);
568839
569345
  } catch {
568840
569346
  missing.push(p2);
568841
569347
  continue;
@@ -569116,7 +569622,7 @@ var init_intervention_replay = __esm({
569116
569622
  });
569117
569623
 
569118
569624
  // packages/orchestrator/dist/world-state-disk-scan.js
569119
- import { existsSync as existsSync92, readFileSync as readFileSync71, readdirSync as readdirSync30, statSync as statSync32 } from "node:fs";
569625
+ import { existsSync as existsSync92, readFileSync as readFileSync71, readdirSync as readdirSync30, statSync as statSync33 } from "node:fs";
569120
569626
  import { join as join103, relative as relative10, basename as basename23 } from "node:path";
569121
569627
  function loadIgnoreFile(path16) {
569122
569628
  if (!existsSync92(path16))
@@ -569205,7 +569711,7 @@ function scanWorkspace(opts) {
569205
569711
  }
569206
569712
  if (dirs.length < maxDirs) {
569207
569713
  try {
569208
- const st = statSync32(dir);
569714
+ const st = statSync33(dir);
569209
569715
  dirs.push({
569210
569716
  abs: dir,
569211
569717
  rel: relative10(root, dir) || ".",
@@ -569230,7 +569736,7 @@ function scanWorkspace(opts) {
569230
569736
  continue;
569231
569737
  let st;
569232
569738
  try {
569233
- st = statSync32(abs);
569739
+ st = statSync33(abs);
569234
569740
  } catch {
569235
569741
  continue;
569236
569742
  }
@@ -569433,7 +569939,7 @@ var init_world_state_disk_scan = __esm({
569433
569939
  });
569434
569940
 
569435
569941
  // packages/orchestrator/dist/world-state-plan-reconciler.js
569436
- import { existsSync as existsSync93, statSync as statSync33 } from "node:fs";
569942
+ import { existsSync as existsSync93, statSync as statSync34 } from "node:fs";
569437
569943
  import { isAbsolute as isAbsolute12, join as join104 } from "node:path";
569438
569944
  function tokenize5(content) {
569439
569945
  const STOP2 = /* @__PURE__ */ new Set([
@@ -569519,7 +570025,7 @@ function reconcileTodo(todo, files, opts) {
569519
570025
  const abs = isAbsolute12(p2) ? p2 : join104(opts.workingDir, p2);
569520
570026
  let st = null;
569521
570027
  try {
569522
- st = statSync33(abs);
570028
+ st = statSync34(abs);
569523
570029
  } catch {
569524
570030
  st = null;
569525
570031
  }
@@ -569622,7 +570128,7 @@ var init_world_state_plan_reconciler = __esm({
569622
570128
  });
569623
570129
 
569624
570130
  // packages/orchestrator/dist/world-state-drift-detector.js
569625
- import { existsSync as existsSync94, readFileSync as readFileSync72, statSync as statSync34 } from "node:fs";
570131
+ import { existsSync as existsSync94, readFileSync as readFileSync72, statSync as statSync35 } from "node:fs";
569626
570132
  import { dirname as dirname32, isAbsolute as isAbsolute13, join as join105, resolve as pathResolve } from "node:path";
569627
570133
  function parseImports(source) {
569628
570134
  const out = [];
@@ -569831,7 +570337,7 @@ function resolveImportPath2(importingFile, source, workingDir, aliases) {
569831
570337
  candidates.push(base3);
569832
570338
  for (const c9 of candidates) {
569833
570339
  try {
569834
- if (existsSync94(c9) && statSync34(c9).isFile())
570340
+ if (existsSync94(c9) && statSync35(c9).isFile())
569835
570341
  return c9;
569836
570342
  } catch {
569837
570343
  }
@@ -570620,7 +571126,7 @@ var init_process_async2 = __esm({
570620
571126
  });
570621
571127
 
570622
571128
  // packages/orchestrator/dist/backward-pass-runner.js
570623
- import { existsSync as existsSync95, readFileSync as readFileSync73, statSync as statSync35 } from "node:fs";
571129
+ import { existsSync as existsSync95, readFileSync as readFileSync73, statSync as statSync36 } from "node:fs";
570624
571130
  import { isAbsolute as isAbsolute14, join as join106, relative as relative11 } from "node:path";
570625
571131
  function collectDiff(opts) {
570626
571132
  const cap = Math.max(1, opts.maxFiles);
@@ -570632,7 +571138,7 @@ function collectDiff(opts) {
570632
571138
  continue;
570633
571139
  let bytes = 0;
570634
571140
  try {
570635
- bytes = statSync35(abs).size;
571141
+ bytes = statSync36(abs).size;
570636
571142
  } catch {
570637
571143
  }
570638
571144
  files.push({ path: relative11(opts.workingDir, abs), bytes, status: "modified" });
@@ -570669,7 +571175,7 @@ async function collectDiffAsync(opts) {
570669
571175
  let bytes = 0;
570670
571176
  if (existsSync95(abs)) {
570671
571177
  try {
570672
- bytes = statSync35(abs).size;
571178
+ bytes = statSync36(abs).size;
570673
571179
  } catch {
570674
571180
  }
570675
571181
  }
@@ -575134,8 +575640,8 @@ function buildDecompositionDirective(modules, strategy) {
575134
575640
  more,
575135
575641
  ``,
575136
575642
  `Recommended workflow:`,
575137
- ` 1. Call todo_write with one todo per module (the orchestrator pre-populated this for you).`,
575138
- ` 2. For EACH module, mark its todo in_progress, then call:`,
575643
+ ` 1. Use todo_write with the pre-populated parent todo plus module leaf todos. Keep exactly one module leaf in_progress.`,
575644
+ ` 2. For EACH module leaf, then call:`,
575139
575645
  ` sub_agent({ subagent_type: "general", prompt: "Implement <module-path> per spec",`,
575140
575646
  ` relevantFiles: [{path:"<module-path>", content:"<existing or empty>"}], ... })`,
575141
575647
  ` 3. When sub_agent returns, mark the todo completed.`,
@@ -575148,11 +575654,26 @@ function buildDecompositionDirective(modules, strategy) {
575148
575654
  ].filter(Boolean).join("\n");
575149
575655
  }
575150
575656
  function buildDecompositionTodos(modules) {
575151
- return modules.map((m2, i2) => ({
575152
- id: `decomp-mod-${i2 + 1}`,
575153
- content: `Implement ${m2.path} (use sub_agent for focused context)`,
575154
- status: "pending"
575155
- }));
575657
+ if (modules.length === 0)
575658
+ return [];
575659
+ const parentId = "decomp-root";
575660
+ return [
575661
+ {
575662
+ id: parentId,
575663
+ content: "Implement decomposed specification modules",
575664
+ status: "pending",
575665
+ owner: "main"
575666
+ },
575667
+ ...modules.map((m2, i2) => ({
575668
+ id: `decomp-mod-${i2 + 1}`,
575669
+ parentId,
575670
+ content: `Implement ${m2.path} (use sub_agent for focused context)`,
575671
+ activeForm: `Implementing ${m2.path}`,
575672
+ status: i2 === 0 ? "in_progress" : "pending",
575673
+ owner: `module:${m2.path}`,
575674
+ blockedBy: i2 === 0 ? void 0 : [`decomp-mod-${i2}`]
575675
+ }))
575676
+ ];
575156
575677
  }
575157
575678
  var SOURCE_EXTENSIONS, EXCLUDE_PATTERNS;
575158
575679
  var init_specDecomposer = __esm({
@@ -576289,7 +576810,7 @@ context_fabric: included=${included.length} dropped=${dropped.length} truncated=
576289
576810
  });
576290
576811
 
576291
576812
  // packages/orchestrator/dist/evidenceLedger.js
576292
- import { statSync as statSync36 } from "node:fs";
576813
+ import { statSync as statSync37 } from "node:fs";
576293
576814
  function buildExtract(content) {
576294
576815
  const lines = content.split("\n");
576295
576816
  if (lines.length <= SMALL_LINES && content.length <= SMALL_CHARS) {
@@ -576406,7 +576927,7 @@ var init_evidenceLedger = __esm({
576406
576927
  if (e2.mtimeMs <= 0)
576407
576928
  return true;
576408
576929
  try {
576409
- const st = statSync36(statPath, { throwIfNoEntry: false });
576930
+ const st = statSync37(statPath, { throwIfNoEntry: false });
576410
576931
  if (!st)
576411
576932
  return true;
576412
576933
  if (st.mtimeMs > e2.mtimeMs) {
@@ -576471,7 +576992,7 @@ var init_evidenceLedger = __esm({
576471
576992
  });
576472
576993
 
576473
576994
  // packages/orchestrator/dist/contextWindowDump.js
576474
- import { existsSync as existsSync100, mkdirSync as mkdirSync58, readdirSync as readdirSync32, readFileSync as readFileSync78, statSync as statSync37, unlinkSync as unlinkSync17, writeFileSync as writeFileSync48, appendFileSync as appendFileSync9 } from "node:fs";
576995
+ import { existsSync as existsSync100, mkdirSync as mkdirSync58, readdirSync as readdirSync32, readFileSync as readFileSync78, statSync as statSync38, unlinkSync as unlinkSync17, writeFileSync as writeFileSync48, appendFileSync as appendFileSync9 } from "node:fs";
576475
576996
  import { homedir as homedir35 } from "node:os";
576476
576997
  import { join as join111, resolve as resolve53 } from "node:path";
576477
576998
  import { createHash as createHash29 } from "node:crypto";
@@ -576740,7 +577261,7 @@ function pruneOldDumpFiles(dir) {
576740
577261
  try {
576741
577262
  const files = readdirSync32(dir).filter((file) => file.endsWith(".json") && !file.startsWith("latest")).map((file) => {
576742
577263
  const path16 = join111(dir, file);
576743
- return { path: path16, mtimeMs: statSync37(path16).mtimeMs };
577264
+ return { path: path16, mtimeMs: statSync38(path16).mtimeMs };
576744
577265
  }).sort((a2, b) => b.mtimeMs - a2.mtimeMs);
576745
577266
  for (const file of files.slice(maxFiles))
576746
577267
  unlinkSync17(file.path);
@@ -577144,7 +577665,7 @@ var init_adversaryStream = __esm({
577144
577665
  });
577145
577666
 
577146
577667
  // packages/orchestrator/dist/debugArtifactLibrary.js
577147
- import { appendFileSync as appendFileSync10, existsSync as existsSync101, mkdirSync as mkdirSync59, readFileSync as readFileSync79, statSync as statSync38, writeFileSync as writeFileSync49 } from "node:fs";
577668
+ import { appendFileSync as appendFileSync10, existsSync as existsSync101, mkdirSync as mkdirSync59, readFileSync as readFileSync79, statSync as statSync39, writeFileSync as writeFileSync49 } from "node:fs";
577148
577669
  import { createHash as createHash30 } from "node:crypto";
577149
577670
  import { basename as basename24, join as join112, relative as relative12, resolve as resolve54 } from "node:path";
577150
577671
  function debugArtifactRoot(cwd4 = process.cwd(), stateDir) {
@@ -577882,7 +578403,7 @@ function readJson2(path16) {
577882
578403
  }
577883
578404
  function pathExists(path16) {
577884
578405
  try {
577885
- statSync38(path16);
578406
+ statSync39(path16);
577886
578407
  return true;
577887
578408
  } catch {
577888
578409
  return false;
@@ -581167,168 +581688,6 @@ var init_completion_resolution_verifier = __esm({
581167
581688
  }
581168
581689
  });
581169
581690
 
581170
- // packages/orchestrator/dist/todoTruth.js
581171
- function normalizeText2(value2) {
581172
- return value2.toLowerCase().replace(/[_-]+/g, " ").replace(/[^a-z0-9./ ]+/g, " ").replace(/\s+/g, " ").trim();
581173
- }
581174
- function extractArg(argsKey, key) {
581175
- if (!argsKey)
581176
- return "";
581177
- const re = new RegExp(`(?:^|,)${key}=([^,]+)`);
581178
- return argsKey.match(re)?.[1]?.trim() ?? "";
581179
- }
581180
- function toolAliases(toolName) {
581181
- const normalized = normalizeText2(toolName);
581182
- const spaceAlias = normalizeText2(toolName.replace(/_/g, " "));
581183
- const compactAlias = toolName.toLowerCase().replace(/[^a-z0-9]+/g, "");
581184
- return [...new Set([normalized, spaceAlias, compactAlias].filter(Boolean))];
581185
- }
581186
- function todoMentionsFailedCall(todo, call) {
581187
- if (NON_WORK_TOOLS.has(call.name))
581188
- return false;
581189
- const content = normalizeText2(todo.content);
581190
- const compactContent2 = todo.content.toLowerCase().replace(/[^a-z0-9]+/g, "");
581191
- const mentionsTool = toolAliases(call.name).some((alias) => {
581192
- if (alias.length <= 2)
581193
- return false;
581194
- if (/^[a-z0-9]+$/.test(alias) && alias === call.name.toLowerCase().replace(/[^a-z0-9]+/g, "")) {
581195
- return compactContent2.includes(alias);
581196
- }
581197
- return content.includes(alias);
581198
- });
581199
- if (!mentionsTool)
581200
- return false;
581201
- const action = normalizeText2(extractArg(call.argsKey, "action"));
581202
- if (!action)
581203
- return true;
581204
- return content.includes(action) || action.length <= 2;
581205
- }
581206
- function evidenceLine(call) {
581207
- const preview = String(call.outputPreview ?? "").split("\n").map((line) => line.trim()).find(Boolean);
581208
- const action = extractArg(call.argsKey, "action");
581209
- const detail = preview || "tool returned failure";
581210
- return `${call.name}${action ? ` ${action}` : ""}: ${detail}`.slice(0, 260);
581211
- }
581212
- function toolEvidenceFamilies(toolName) {
581213
- const families = [];
581214
- if (VISUAL_EVIDENCE_TOOLS.has(toolName))
581215
- families.push("visual_evidence");
581216
- if (AUDIO_EVIDENCE_TOOLS.has(toolName))
581217
- families.push("audio_evidence");
581218
- return families;
581219
- }
581220
- function hasLaterSuccessForCompatibleEvidence(calls, failedIndex) {
581221
- const failed = calls[failedIndex];
581222
- if (!failed)
581223
- return false;
581224
- const failedAction = normalizeText2(extractArg(failed.argsKey, "action"));
581225
- const failedFamilies = toolEvidenceFamilies(failed.name);
581226
- for (let i2 = failedIndex + 1; i2 < calls.length; i2++) {
581227
- const next = calls[i2];
581228
- if (!next || next.success !== true)
581229
- continue;
581230
- const nextFamilies = toolEvidenceFamilies(next.name);
581231
- if (failedFamilies.length > 0 && failedFamilies.some((family) => nextFamilies.includes(family))) {
581232
- return true;
581233
- }
581234
- if (next.name !== failed.name)
581235
- continue;
581236
- const nextAction = normalizeText2(extractArg(next.argsKey, "action"));
581237
- if (!failedAction || !nextAction || failedAction === nextAction)
581238
- return true;
581239
- }
581240
- return false;
581241
- }
581242
- function firstUnresolvedChild(todo, childrenByParent) {
581243
- const id2 = todo.id;
581244
- if (!id2)
581245
- return null;
581246
- const children2 = childrenByParent.get(id2) ?? [];
581247
- return children2.find((child) => child.status === "blocked") ?? children2.find((child) => child.status === "in_progress") ?? children2.find((child) => child.status === "pending") ?? null;
581248
- }
581249
- function reconcileCompletedTodosWithEvidence(input) {
581250
- const nextTodos = input.todos.map((todo) => ({ ...todo }));
581251
- const downgrades = [];
581252
- const childrenByParent = /* @__PURE__ */ new Map();
581253
- for (const todo of nextTodos) {
581254
- if (!todo.parentId)
581255
- continue;
581256
- const arr = childrenByParent.get(todo.parentId) ?? [];
581257
- arr.push(todo);
581258
- childrenByParent.set(todo.parentId, arr);
581259
- }
581260
- for (const todo of nextTodos) {
581261
- if (todo.status !== "completed")
581262
- continue;
581263
- const unresolvedChild = firstUnresolvedChild(todo, childrenByParent);
581264
- if (unresolvedChild) {
581265
- const childStatus = unresolvedChild.status;
581266
- const targetStatus = childStatus === "blocked" ? "blocked" : "in_progress";
581267
- const blocker2 = childStatus === "blocked" ? `Child todo blocked: ${unresolvedChild.content}${unresolvedChild.blocker ? ` (${unresolvedChild.blocker})` : ""}` : `Child todo not complete: [${childStatus}] ${unresolvedChild.content}`;
581268
- downgrades.push({
581269
- id: todo.id,
581270
- content: todo.content,
581271
- from: "completed",
581272
- to: targetStatus,
581273
- blocker: blocker2,
581274
- evidence: blocker2
581275
- });
581276
- todo.status = targetStatus;
581277
- todo.blocker = blocker2;
581278
- continue;
581279
- }
581280
- const startTurn = todo.id && input.todoStartTurnById?.has(todo.id) ? input.todoStartTurnById.get(todo.id) : 0;
581281
- const relevantCalls = input.toolCallLog.filter((call) => (call.turn ?? 0) >= startTurn);
581282
- const failedIndex = relevantCalls.findIndex((call, index) => call.success === false && todoMentionsFailedCall(todo, call) && !hasLaterSuccessForCompatibleEvidence(relevantCalls, index));
581283
- if (failedIndex < 0)
581284
- continue;
581285
- const failed = relevantCalls[failedIndex];
581286
- const evidence = evidenceLine(failed);
581287
- const blocker = `Completion claim contradicted by failed ${failed.name} evidence. Reconfigure this subtask: verify whether the goal is already satisfied, choose a different target/tool, or leave the todo blocked with the root cause.`;
581288
- downgrades.push({
581289
- id: todo.id,
581290
- content: todo.content,
581291
- from: "completed",
581292
- to: "blocked",
581293
- blocker,
581294
- evidence
581295
- });
581296
- todo.status = "blocked";
581297
- todo.blocker = `${blocker} Evidence: ${evidence}`;
581298
- }
581299
- return {
581300
- todos: nextTodos,
581301
- changed: downgrades.length > 0,
581302
- downgrades
581303
- };
581304
- }
581305
- var NON_WORK_TOOLS, VISUAL_EVIDENCE_TOOLS, AUDIO_EVIDENCE_TOOLS;
581306
- var init_todoTruth = __esm({
581307
- "packages/orchestrator/dist/todoTruth.js"() {
581308
- "use strict";
581309
- NON_WORK_TOOLS = /* @__PURE__ */ new Set(["todo_write", "todo_read", "task_complete"]);
581310
- VISUAL_EVIDENCE_TOOLS = /* @__PURE__ */ new Set([
581311
- "av_comprehend",
581312
- "image_read",
581313
- "ocr",
581314
- "ocr_image_advanced",
581315
- "screenshot",
581316
- "telegram_image_analyze",
581317
- "video_scan",
581318
- "video_understand",
581319
- "vision"
581320
- ]);
581321
- AUDIO_EVIDENCE_TOOLS = /* @__PURE__ */ new Set([
581322
- "asr_listen",
581323
- "audio_analyze",
581324
- "av_comprehend",
581325
- "transcribe_file",
581326
- "transcribe_url",
581327
- "video_understand"
581328
- ]);
581329
- }
581330
- });
581331
-
581332
581691
  // packages/orchestrator/dist/evidenceBranch.js
581333
581692
  function buildStructuralPreview2(lines, path16, query) {
581334
581693
  const n2 = lines.length;
@@ -582470,7 +582829,7 @@ __export(preflightSnapshot_exports, {
582470
582829
  formatPreflightStatus: () => formatPreflightStatus,
582471
582830
  freeDiskBytes: () => freeDiskBytes
582472
582831
  });
582473
- import { existsSync as existsSync102, readFileSync as readFileSync80, statSync as statSync39, statfsSync as statfsSync6 } from "node:fs";
582832
+ import { existsSync as existsSync102, readFileSync as readFileSync80, statSync as statSync40, statfsSync as statfsSync6 } from "node:fs";
582474
582833
  import { homedir as homedir36, platform as platform4, arch as arch2, totalmem as totalmem4, freemem as freemem3, hostname as hostname3 } from "node:os";
582475
582834
  import { join as join113 } from "node:path";
582476
582835
  import { createHash as createHash32 } from "node:crypto";
@@ -582646,7 +583005,7 @@ function sha2564(s2) {
582646
583005
  }
582647
583006
  function freeDiskBytes(path16 = "/tmp") {
582648
583007
  try {
582649
- const st = statSync39(path16);
583008
+ const st = statSync40(path16);
582650
583009
  if (!st.isDirectory())
582651
583010
  return -1;
582652
583011
  const fs14 = statfsSync6(path16);
@@ -582690,7 +583049,7 @@ __export(postActionVerifier_exports, {
582690
583049
  classifyShellIntent: () => classifyShellIntent,
582691
583050
  verifyShellOutcome: () => verifyShellOutcome
582692
583051
  });
582693
- import { existsSync as existsSync103, readFileSync as readFileSync81, readdirSync as readdirSync33, statSync as statSync40 } from "node:fs";
583052
+ import { existsSync as existsSync103, readFileSync as readFileSync81, readdirSync as readdirSync33, statSync as statSync41 } from "node:fs";
582694
583053
  import { join as join114 } from "node:path";
582695
583054
  function classifyShellIntent(cmd) {
582696
583055
  const stripped = cmd.replace(/^cd\s+\S+\s*&&\s*/, "").trim();
@@ -582906,7 +583265,7 @@ function listNpmInstalled(installRootAbs) {
582906
583265
  continue;
582907
583266
  const sub2 = join114(installRootAbs, name10);
582908
583267
  try {
582909
- if (!statSync40(sub2).isDirectory())
583268
+ if (!statSync41(sub2).isDirectory())
582910
583269
  continue;
582911
583270
  } catch {
582912
583271
  continue;
@@ -582978,7 +583337,7 @@ function mostRecentFileMtimeMs(root, maxDepth) {
582978
583337
  const full = join114(dir, name10);
582979
583338
  let st;
582980
583339
  try {
582981
- st = statSync40(full);
583340
+ st = statSync41(full);
582982
583341
  } catch {
582983
583342
  continue;
582984
583343
  }
@@ -585257,6 +585616,14 @@ var init_agenticRunner = __esm({
585257
585616
  }
585258
585617
  if (todo.blocker)
585259
585618
  requirements.push(`blocker: ${todo.blocker}`);
585619
+ if (todo.activeForm)
585620
+ requirements.push(`activeForm: ${todo.activeForm}`);
585621
+ if (todo.blockedBy?.length) {
585622
+ requirements.push(`blockedBy: ${todo.blockedBy.slice(0, 5).join(", ")}`);
585623
+ }
585624
+ if (todo.blocks?.length) {
585625
+ requirements.push(`blocks: ${todo.blocks.slice(0, 5).join(", ")}`);
585626
+ }
585260
585627
  if (requirements.length === 0)
585261
585628
  requirements.push("todo status evidence");
585262
585629
  const lane = todo.status === "blocked" ? "blocked" : todo.status === "pending" ? "ready" : "worker";
@@ -585267,7 +585634,7 @@ var init_agenticRunner = __esm({
585267
585634
  description: path16.map((item) => item.content).join(" > ").slice(0, 800),
585268
585635
  lane,
585269
585636
  status,
585270
- assignee: "any",
585637
+ assignee: todo.owner || "any",
585271
585638
  role: "worker",
585272
585639
  evidenceRequired: true,
585273
585640
  evidenceRequirements: requirements
@@ -587359,12 +587726,7 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
587359
587726
  readSessionTodos() {
587360
587727
  try {
587361
587728
  const sid = this._sessionId || process.env["OMNIUS_SESSION_ID"] || "default";
587362
- const safe = sid.replace(/[^a-zA-Z0-9_.-]/g, "_");
587363
- const fp = _pathJoin(_osHomedir(), ".omnius", "todos", `${safe}.json`);
587364
- if (!_fsExistsSync(fp))
587365
- return null;
587366
- const parsed = JSON.parse(_fsReadFileSync(fp, "utf-8"));
587367
- return Array.isArray(parsed) ? parsed : null;
587729
+ return readTodos(sid);
587368
587730
  } catch {
587369
587731
  return null;
587370
587732
  }
@@ -588299,7 +588661,40 @@ ${result.output ?? ""}`;
588299
588661
  const todos = this.readSessionTodos();
588300
588662
  if (!todos || todos.length === 0)
588301
588663
  return [];
588302
- return todos.filter((t2) => t2.status !== "completed");
588664
+ return openTodoLeaves(todos);
588665
+ }
588666
+ _todoExpansionRequiredBlocker(toolName) {
588667
+ if (!this._todoWriteAvailable())
588668
+ return null;
588669
+ if (toolName === "todo_write" || toolName === "todo_read")
588670
+ return null;
588671
+ const mustHaveActiveLeaf = toolName === "task_complete" || this._isProjectEditTool(toolName);
588672
+ if (!mustHaveActiveLeaf)
588673
+ return null;
588674
+ const todos = this._normalizeTodosForPrompt(this.readSessionTodos() ?? []);
588675
+ if (todos.length === 0)
588676
+ return null;
588677
+ const truthIndex = buildTodoTruthIndex(todos);
588678
+ const open2 = openTodoLeaves(todos);
588679
+ if (open2.length === 0)
588680
+ return null;
588681
+ const activeLeaf = open2.find((todo) => todo.status === "in_progress" && unmetTodoDependencies(todo, truthIndex).length === 0);
588682
+ if (activeLeaf)
588683
+ return null;
588684
+ const treeIndex = this._todoTreeIndex(todos);
588685
+ const rawActive = todos.find((todo) => todo.status === "in_progress") ?? null;
588686
+ const rawActiveChildren = rawActive?.id ? treeIndex.byParent.get(rawActive.id) ?? [] : [];
588687
+ const top = rawActive ?? open2[0];
588688
+ const path16 = this._todoPath(top, treeIndex).map((todo) => todo.content).join(" > ").slice(0, 220);
588689
+ const blockedDeps = open2.flatMap((todo) => unmetTodoDependencies(todo, truthIndex)).slice(0, 6);
588690
+ return [
588691
+ `[TODO EXPANSION REQUIRED]`,
588692
+ `The ${toolName} call was not executed because the active todo state has unresolved leaf work but no unblocked in_progress leaf.`,
588693
+ rawActiveChildren.length > 0 ? `Current active item is a parent with ${rawActiveChildren.length} child todo(s): ${path16}` : `Current todo focus: ${path16}`,
588694
+ blockedDeps.length > 0 ? `Unmet dependencies: ${Array.from(new Set(blockedDeps)).join(", ")}` : null,
588695
+ `Call todo_write first. Keep parent objectives pending/in_progress only as summaries, set exactly one concrete unblocked leaf to in_progress, and use blockedBy for prerequisites.`,
588696
+ `After todo_write records the active leaf, retry the smallest next action.`
588697
+ ].filter((line) => Boolean(line)).join("\n");
588303
588698
  }
588304
588699
  _taskCompleteArgsReportDegraded(args) {
588305
588700
  const status = completionStatusFromTaskCompleteArgs(args);
@@ -589341,7 +589736,7 @@ ${_checks}`
589341
589736
  const todos = this.readSessionTodos();
589342
589737
  if (todos && todos.length > 0) {
589343
589738
  const index = this._todoTreeIndex(todos);
589344
- const leaves = this._todoLeaves(todos, index);
589739
+ const leaves = todoLeaves(todos, buildTodoTruthIndex(todos));
589345
589740
  const current = this._activeTodoForPrompt(todos, index);
589346
589741
  const completedN = leaves.filter((t2) => t2.status === "completed").length;
589347
589742
  const totalN = leaves.length;
@@ -589392,13 +589787,22 @@ ${body}`;
589392
589787
  * Only includes items with status != completed. Capped to 12 lines.
589393
589788
  */
589394
589789
  buildIncompleteTodosSection() {
589395
- const todos = this.readSessionTodos();
589790
+ const todos = this._normalizeTodosForPrompt(this.readSessionTodos() ?? []);
589396
589791
  if (!todos || todos.length === 0)
589397
589792
  return "";
589398
- const incomplete = todos.filter((t2) => t2.status !== "completed");
589793
+ const index = this._todoTreeIndex(todos);
589794
+ const truthIndex = buildTodoTruthIndex(todos);
589795
+ const incomplete = openTodoLeaves(todos);
589399
589796
  if (incomplete.length === 0)
589400
589797
  return "";
589401
- const lines = incomplete.slice(0, 12).map((t2, i2) => `${i2 + 1}. [${t2.status}] ${t2.content}`);
589798
+ const lines = incomplete.slice(0, 12).map((t2, i2) => {
589799
+ const path16 = this._todoPath(t2, index).map((item) => item.content).join(" > ");
589800
+ const owner = t2.owner ? ` owner=${t2.owner}` : "";
589801
+ const doing = t2.activeForm && t2.status === "in_progress" ? ` doing=${t2.activeForm}` : "";
589802
+ const deps = unmetTodoDependencies(t2, truthIndex);
589803
+ const depText = deps.length > 0 ? ` blockedBy=${deps.join(",")}` : "";
589804
+ return `${i2 + 1}. [${t2.status}] ${path16 || t2.content}${owner}${doing}${depText}`;
589805
+ });
589402
589806
  const tier = this.options.modelTier ?? "large";
589403
589807
  const useXml = tier === "small" || tier === "medium";
589404
589808
  const body = lines.join("\n");
@@ -590411,6 +590815,12 @@ ${latest.output || ""}`.trim();
590411
590815
  ];
590412
590816
  if (activePath)
590413
590817
  lines.push(`active_branch=${activePath.slice(0, 220)}`);
590818
+ if (active?.activeForm) {
590819
+ lines.push(`active_form=${active.activeForm.slice(0, 140)}`);
590820
+ }
590821
+ if (active?.owner) {
590822
+ lines.push(`active_owner=${active.owner.slice(0, 80)}`);
590823
+ }
590414
590824
  const ordered = this._orderedTodosForPrompt(todos);
590415
590825
  const activeIndex = active ? ordered.findIndex((entry) => entry.todo.id === active.id) : -1;
590416
590826
  let visible = ordered;
@@ -590454,11 +590864,16 @@ ${latest.output || ""}`.trim();
590454
590864
  blocked: "!!"
590455
590865
  };
590456
590866
  lines.push("tree:");
590867
+ const truthIndex = buildTodoTruthIndex(todos);
590457
590868
  for (const entry of visible) {
590458
590869
  const indent2 = " ".repeat(entry.depth);
590459
590870
  const childSuffix = entry.childStats && entry.childStats.total > 0 ? ` [${entry.childStats.completed}/${entry.childStats.total}]` : "";
590460
590871
  const blocker = entry.todo.blocker ? ` blocker=${entry.todo.blocker.slice(0, 120)}` : "";
590461
- lines.push(`${indent2}${statusMark[entry.displayStatus]} ${entry.todo.content.slice(0, 140)}${childSuffix}${blocker}`);
590872
+ const owner = entry.todo.owner ? ` owner=${entry.todo.owner.slice(0, 60)}` : "";
590873
+ const activeForm = active?.id === entry.todo.id && entry.todo.activeForm ? ` doing=${entry.todo.activeForm.slice(0, 100)}` : "";
590874
+ const deps = unmetTodoDependencies(entry.todo, truthIndex);
590875
+ const depSuffix = deps.length > 0 ? ` blockedBy=${deps.slice(0, 4).join(",")}` : entry.todo.blockedBy?.length ? ` deps=${entry.todo.blockedBy.slice(0, 4).join(",")}` : "";
590876
+ lines.push(`${indent2}${statusMark[entry.displayStatus]} ${entry.todo.content.slice(0, 140)}${childSuffix}${owner}${activeForm}${depSuffix}${blocker}`);
590462
590877
  }
590463
590878
  if (ordered.length > visible.length) {
590464
590879
  lines.push(`... +${ordered.length - visible.length} more todo node(s)`);
@@ -594906,7 +595321,7 @@ MANDATORY FIRST ACTION: Call todo_write NOW with the complete plan.
594906
595321
  Each todo item is { id, content, status, parentId? } or a parent with children/subtasks. Use stable ids.
594907
595322
  Represent broad objectives as parent todos and concrete work as child leaf todos. Mark the active leaf in_progress, the rest pending.
594908
595323
  Only count substantive work phases. Do NOT count observing a tool result, reporting findings, or calling task_complete as todo phases.
594909
- Example: todo_write({todos: [{id: "impl", content: "Implement requested change", status: "in_progress", children: [{id: "inspect", content: "Read relevant files", status: "in_progress"}, {id: "edit", content: "Make scoped edits", status: "pending"}, {id: "verify", content: "Run verification", status: "pending"}]}]})
595324
+ Example: todo_write({todos: [{id: "impl", content: "Implement requested change", status: "pending", children: [{id: "inspect", content: "Read relevant files", activeForm: "Reading relevant files", status: "in_progress", owner: "main"}, {id: "edit", content: "Make scoped edits", status: "pending", blockedBy: ["inspect"]}, {id: "verify", content: "Run verification", status: "pending", blockedBy: ["edit"]}]}]})
594910
595325
 
594911
595326
  After EACH leaf finishes, call todo_write AGAIN with that leaf completed and the next leaf in_progress.
594912
595327
  If new work is discovered, decompose the current leaf into children or add siblings under the same parent instead of flattening a long list.
@@ -595907,6 +596322,34 @@ Corrective action: try a different approach first: read relevant files, adjust a
595907
596322
  });
595908
596323
  return { tc, output: blockMsg, success: false };
595909
596324
  }
596325
+ {
596326
+ const todoExpansionBlock = this._todoExpansionRequiredBlocker(tc.name);
596327
+ if (todoExpansionBlock) {
596328
+ this.emit({
596329
+ type: "tool_call",
596330
+ toolName: tc.name,
596331
+ toolArgs: tc.arguments,
596332
+ turn,
596333
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
596334
+ });
596335
+ const lastLog = toolCallLog[_toolLogTailIdx];
596336
+ if (lastLog) {
596337
+ lastLog.success = false;
596338
+ lastLog.mutated = false;
596339
+ lastLog.mutatedFiles = [];
596340
+ lastLog.outputPreview = todoExpansionBlock.slice(0, 100);
596341
+ }
596342
+ this.emit({
596343
+ type: "tool_result",
596344
+ toolName: tc.name,
596345
+ success: false,
596346
+ content: todoExpansionBlock.slice(0, 180),
596347
+ turn,
596348
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
596349
+ });
596350
+ return { tc, output: todoExpansionBlock, success: false };
596351
+ }
596352
+ }
595910
596353
  this._toolLastUsedTurn.set(tc.name, turn);
595911
596354
  const _treeTransition = this._advanceContextTreeOnToolCall(tc.name, argsKey, turn, messages2);
595912
596355
  if (_treeTransition) {
@@ -601218,6 +601661,19 @@ ${marker}` : marker);
601218
601661
  if (typeof args["parentId"] === "string" && args["parentId"].trim()) {
601219
601662
  todo["parentId"] = args["parentId"].trim();
601220
601663
  }
601664
+ if (typeof args["activeForm"] === "string" && args["activeForm"].trim()) {
601665
+ todo["activeForm"] = args["activeForm"].trim();
601666
+ }
601667
+ if (typeof args["owner"] === "string" && args["owner"].trim()) {
601668
+ todo["owner"] = args["owner"].trim();
601669
+ }
601670
+ if (Array.isArray(args["blocks"])) {
601671
+ todo["blocks"] = args["blocks"].filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
601672
+ }
601673
+ const blockedBy = args["blockedBy"] ?? args["dependsOn"];
601674
+ if (Array.isArray(blockedBy)) {
601675
+ todo["blockedBy"] = blockedBy.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
601676
+ }
601221
601677
  const artifact = args["file"] ?? args["path"];
601222
601678
  if (typeof artifact === "string" && artifact.trim()) {
601223
601679
  todo["declaredArtifacts"] = [artifact.trim()];
@@ -606644,7 +607100,7 @@ var init_constraint_learner = __esm({
606644
607100
  });
606645
607101
 
606646
607102
  // packages/orchestrator/dist/nexusBackend.js
606647
- import { existsSync as existsSync104, statSync as statSync41, openSync, readSync, closeSync, unlinkSync as unlinkSync18, writeFileSync as writeFileSync50 } from "node:fs";
607103
+ import { existsSync as existsSync104, statSync as statSync42, openSync, readSync, closeSync, unlinkSync as unlinkSync18, writeFileSync as writeFileSync50 } from "node:fs";
606648
607104
  import { watch as fsWatch } from "node:fs";
606649
607105
  import { join as join115 } from "node:path";
606650
607106
  import { tmpdir as tmpdir21 } from "node:os";
@@ -607005,7 +607461,7 @@ ${suffix}` } : m2);
607005
607461
  finish();
607006
607462
  }, 50);
607007
607463
  });
607008
- const stat9 = statSync41(streamFile, { throwIfNoEntry: false });
607464
+ const stat9 = statSync42(streamFile, { throwIfNoEntry: false });
607009
607465
  if (!stat9 || stat9.size <= position)
607010
607466
  continue;
607011
607467
  const fd = openSync(streamFile, "r");
@@ -611937,7 +612393,7 @@ var init_missionSystem = __esm({
611937
612393
  });
611938
612394
 
611939
612395
  // packages/orchestrator/dist/context-references.js
611940
- import { readFileSync as readFileSync88, readdirSync as readdirSync35, statSync as statSync42 } from "node:fs";
612396
+ import { readFileSync as readFileSync88, readdirSync as readdirSync35, statSync as statSync43 } from "node:fs";
611941
612397
  import { homedir as homedir38 } from "node:os";
611942
612398
  import { join as join123, resolve as resolve55, relative as relative13, sep as sep4, extname as extname13 } from "node:path";
611943
612399
  function estimateTokens6(text2) {
@@ -612084,7 +612540,7 @@ function buildFolderListing(dirPath, cwd4, limit = 200) {
612084
612540
  continue;
612085
612541
  const full = join123(current, entry);
612086
612542
  try {
612087
- if (statSync42(full).isDirectory()) {
612543
+ if (statSync43(full).isDirectory()) {
612088
612544
  dirs.push(entry);
612089
612545
  } else {
612090
612546
  files.push(entry);
@@ -612108,7 +612564,7 @@ function buildFolderListing(dirPath, cwd4, limit = 200) {
612108
612564
  const full = join123(current, f2);
612109
612565
  let meta = "?";
612110
612566
  try {
612111
- const st = statSync42(full);
612567
+ const st = statSync43(full);
612112
612568
  if (st.isFile()) {
612113
612569
  const size = st.size;
612114
612570
  if (isBinaryFile(full)) {
@@ -612147,7 +612603,7 @@ function expandFileReference(ref, cwd4, allowedRoot) {
612147
612603
  } catch (err) {
612148
612604
  return [`${ref.raw}: ${err.message}`, null];
612149
612605
  }
612150
- if (!statSync42(filePath, { throwIfNoEntry: false })?.isFile()) {
612606
+ if (!statSync43(filePath, { throwIfNoEntry: false })?.isFile()) {
612151
612607
  return [`${ref.raw}: file not found`, null];
612152
612608
  }
612153
612609
  if (isBinaryFile(filePath)) {
@@ -612180,7 +612636,7 @@ function expandFolderReference(ref, cwd4, allowedRoot) {
612180
612636
  } catch (err) {
612181
612637
  return [`${ref.raw}: ${err.message}`, null];
612182
612638
  }
612183
- if (!statSync42(dirPath, { throwIfNoEntry: false })?.isDirectory()) {
612639
+ if (!statSync43(dirPath, { throwIfNoEntry: false })?.isDirectory()) {
612184
612640
  return [`${ref.raw}: folder not found`, null];
612185
612641
  }
612186
612642
  const listing = buildFolderListing(dirPath, cwd4);
@@ -613640,7 +614096,7 @@ __export(memory_maintenance_exports, {
613640
614096
  startIdleMemoryMaintenance: () => startIdleMemoryMaintenance
613641
614097
  });
613642
614098
  import { spawn as spawn27 } from "node:child_process";
613643
- import { createWriteStream, existsSync as existsSync109, mkdirSync as mkdirSync66, readFileSync as readFileSync89, statSync as statSync43, writeFileSync as writeFileSync56 } from "node:fs";
614099
+ import { createWriteStream, existsSync as existsSync109, mkdirSync as mkdirSync66, readFileSync as readFileSync89, statSync as statSync44, writeFileSync as writeFileSync56 } from "node:fs";
613644
614100
  import { fileURLToPath as fileURLToPath15 } from "node:url";
613645
614101
  import { join as join124 } from "node:path";
613646
614102
  function startIdleMemoryMaintenance(options2) {
@@ -613873,7 +614329,7 @@ function writeLastRunAt(repoRoot, value2) {
613873
614329
  function readLatestSummary(repoRoot) {
613874
614330
  const ledgerPath = join124(repoRoot, ".omnius", "memory-maintenance", "runs.jsonl");
613875
614331
  try {
613876
- if (!existsSync109(ledgerPath) || statSync43(ledgerPath).size === 0) return null;
614332
+ if (!existsSync109(ledgerPath) || statSync44(ledgerPath).size === 0) return null;
613877
614333
  const lines = readFileSync89(ledgerPath, "utf8").split(/\r?\n/).filter(Boolean);
613878
614334
  const last2 = lines.at(-1);
613879
614335
  if (!last2) return null;
@@ -614147,7 +614603,7 @@ __export(image_ascii_preview_exports, {
614147
614603
  isLowInformationAsciiPreview: () => isLowInformationAsciiPreview
614148
614604
  });
614149
614605
  import { createRequire as createRequire5 } from "node:module";
614150
- import { existsSync as existsSync110, readFileSync as readFileSync90, statSync as statSync44 } from "node:fs";
614606
+ import { existsSync as existsSync110, readFileSync as readFileSync90, statSync as statSync45 } from "node:fs";
614151
614607
  import { resolve as resolve56 } from "node:path";
614152
614608
  function clamp7(n2, min, max) {
614153
614609
  if (!Number.isFinite(n2)) return min;
@@ -614427,7 +614883,7 @@ async function buildImageAsciiPreview(inputPath, options2 = {}) {
614427
614883
  const imagePath = resolve56(inputPath);
614428
614884
  if (!existsSync110(imagePath)) return null;
614429
614885
  try {
614430
- if (!statSync44(imagePath).isFile()) return null;
614886
+ if (!statSync45(imagePath).isFile()) return null;
614431
614887
  } catch {
614432
614888
  return null;
614433
614889
  }
@@ -616519,7 +616975,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
616519
616975
 
616520
616976
  // packages/cli/src/tui/camera-streamer.ts
616521
616977
  import { spawn as spawn30 } from "node:child_process";
616522
- import { existsSync as existsSync113, mkdirSync as mkdirSync70, statSync as statSync45, unlinkSync as unlinkSync20 } from "node:fs";
616978
+ import { existsSync as existsSync113, mkdirSync as mkdirSync70, statSync as statSync46, unlinkSync as unlinkSync20 } from "node:fs";
616523
616979
  import { join as join128 } from "node:path";
616524
616980
  function streamFps(configured) {
616525
616981
  const raw = configured ?? Number(process.env["OMNIUS_LIVE_STREAM_FPS"] ?? "");
@@ -616582,7 +617038,7 @@ var init_camera_streamer = __esm({
616582
617038
  const stream = this.streams.get(source);
616583
617039
  if (!stream || !existsSync113(stream.framePath)) return null;
616584
617040
  try {
616585
- const stats = statSync45(stream.framePath);
617041
+ const stats = statSync46(stream.framePath);
616586
617042
  if (!stats.isFile() || stats.size <= 0) return null;
616587
617043
  return { path: stream.framePath, mtimeMs: stats.mtimeMs };
616588
617044
  } catch {
@@ -616730,7 +617186,7 @@ var init_camera_streamer = __esm({
616730
617186
  });
616731
617187
 
616732
617188
  // packages/cli/src/tui/live-vlm.ts
616733
- import { existsSync as existsSync114, readFileSync as readFileSync93, statSync as statSync46 } from "node:fs";
617189
+ import { existsSync as existsSync114, readFileSync as readFileSync93, statSync as statSync47 } from "node:fs";
616734
617190
  var DEFAULT_LIVE_VLM_MODEL, MAX_IMAGE_BYTES, VLM_SYSTEM_PROMPT, LiveVlmEngine;
616735
617191
  var init_live_vlm = __esm({
616736
617192
  "packages/cli/src/tui/live-vlm.ts"() {
@@ -616853,7 +617309,7 @@ var init_live_vlm = __esm({
616853
617309
  if (Date.now() - this.lastFailureAt < 2e4) return null;
616854
617310
  if (!existsSync114(framePath)) return null;
616855
617311
  try {
616856
- if (statSync46(framePath).size > MAX_IMAGE_BYTES) return null;
617312
+ if (statSync47(framePath).size > MAX_IMAGE_BYTES) return null;
616857
617313
  } catch {
616858
617314
  return null;
616859
617315
  }
@@ -625265,6 +625721,9 @@ function setTasksHeight(height) {
625265
625721
  _tasksHeight = next;
625266
625722
  return true;
625267
625723
  }
625724
+ function tasksHeight() {
625725
+ return _tasksHeight;
625726
+ }
625268
625727
  function headerHeight() {
625269
625728
  return _headerHeight;
625270
625729
  }
@@ -632520,7 +632979,7 @@ import { EventEmitter as EventEmitter8 } from "node:events";
632520
632979
  import { randomBytes as randomBytes22, timingSafeEqual } from "node:crypto";
632521
632980
  import { URL as URL2 } from "node:url";
632522
632981
  import { loadavg as loadavg2, cpus as cpus4, totalmem as totalmem7, freemem as freemem6 } from "node:os";
632523
- import { existsSync as existsSync119, readFileSync as readFileSync98, writeFileSync as writeFileSync61, unlinkSync as unlinkSync21, mkdirSync as mkdirSync73, readdirSync as readdirSync39, statSync as statSync47, statfsSync as statfsSync8 } from "node:fs";
632982
+ import { existsSync as existsSync119, readFileSync as readFileSync98, writeFileSync as writeFileSync61, unlinkSync as unlinkSync21, mkdirSync as mkdirSync73, readdirSync as readdirSync39, statSync as statSync48, statfsSync as statfsSync8 } from "node:fs";
632524
632983
  import { join as join133 } from "node:path";
632525
632984
  function cleanForwardHeaders(raw, targetHost) {
632526
632985
  const out = {};
@@ -634391,7 +634850,7 @@ ${this.formatConnectionInfo()}`);
634391
634850
  let recentActive = 0;
634392
634851
  for (const f2 of files.slice(-10)) {
634393
634852
  try {
634394
- const st = statSync47(join133(invocDir, f2));
634853
+ const st = statSync48(join133(invocDir, f2));
634395
634854
  if (now2 - st.mtimeMs < 1e4) recentActive++;
634396
634855
  } catch {
634397
634856
  }
@@ -636383,7 +636842,7 @@ __export(omnius_directory_exports, {
636383
636842
  writeIndexMeta: () => writeIndexMeta,
636384
636843
  writeTaskHandoff: () => writeTaskHandoff2
636385
636844
  });
636386
- import { appendFileSync as appendFileSync14, cpSync as cpSync2, existsSync as existsSync122, mkdirSync as mkdirSync76, readFileSync as readFileSync101, writeFileSync as writeFileSync64, readdirSync as readdirSync41, statSync as statSync48, unlinkSync as unlinkSync23, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync11, watch as fsWatch2 } from "node:fs";
636845
+ import { appendFileSync as appendFileSync14, cpSync as cpSync2, existsSync as existsSync122, mkdirSync as mkdirSync76, readFileSync as readFileSync101, writeFileSync as writeFileSync64, readdirSync as readdirSync41, statSync as statSync49, unlinkSync as unlinkSync23, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync11, watch as fsWatch2 } from "node:fs";
636387
636846
  import { join as join136, relative as relative16, basename as basename27, dirname as dirname40, resolve as resolve60 } from "node:path";
636388
636847
  import { homedir as homedir42 } from "node:os";
636389
636848
  import { createHash as createHash41 } from "node:crypto";
@@ -636391,7 +636850,7 @@ function isGitRoot(dir) {
636391
636850
  const gitPath = join136(dir, ".git");
636392
636851
  if (!existsSync122(gitPath)) return false;
636393
636852
  try {
636394
- const stat9 = statSync48(gitPath);
636853
+ const stat9 = statSync49(gitPath);
636395
636854
  if (stat9.isFile()) {
636396
636855
  return readFileSync101(gitPath, "utf-8").trim().startsWith("gitdir:");
636397
636856
  }
@@ -636743,7 +637202,7 @@ function loadRecentSessions(repoRoot, limit = 5) {
636743
637202
  if (!existsSync122(historyDir)) return [];
636744
637203
  try {
636745
637204
  const files = readdirSync41(historyDir).filter((f2) => f2.endsWith(".json") && f2 !== "pending-task.json").map((f2) => {
636746
- const stat9 = statSync48(join136(historyDir, f2));
637205
+ const stat9 = statSync49(join136(historyDir, f2));
636747
637206
  return { file: f2, mtime: stat9.mtimeMs };
636748
637207
  }).sort((a2, b) => b.mtime - a2.mtime).slice(0, limit);
636749
637208
  return files.map((f2) => {
@@ -637004,7 +637463,7 @@ function mergeSessionContextEntry(previous, incoming) {
637004
637463
  function pruneContextLedger(ledgerPath) {
637005
637464
  try {
637006
637465
  if (!existsSync122(ledgerPath)) return;
637007
- const st = statSync48(ledgerPath);
637466
+ const st = statSync49(ledgerPath);
637008
637467
  if (st.size <= MAX_CONTEXT_LEDGER_BYTES) return;
637009
637468
  const lines = readFileSync101(ledgerPath, "utf-8").split(/\r?\n/).filter((line) => line.trim().length > 0);
637010
637469
  if (lines.length <= MAX_CONTEXT_LEDGER_LINES) return;
@@ -637278,7 +637737,7 @@ function selectActiveTaskAnchor(repoRoot) {
637278
637737
  const runId = ledger.runId || name10.replace(/\.json$/, "");
637279
637738
  const workboard = readRestoreWorkboard(repoRoot, runId);
637280
637739
  const score = scoreRestoreLedger(ledger, workboard);
637281
- const mtimeMs = statSync48(filePath).mtimeMs;
637740
+ const mtimeMs = statSync49(filePath).mtimeMs;
637282
637741
  return { ledger: { ...ledger, runId }, workboard, score, mtimeMs };
637283
637742
  }).filter((item) => Boolean(item));
637284
637743
  candidates.sort((a2, b) => b.score - a2.score || b.mtimeMs - a2.mtimeMs);
@@ -638174,14 +638633,14 @@ var init_session_summary = __esm({
638174
638633
 
638175
638634
  // packages/cli/src/tui/cad-model-viewer.ts
638176
638635
  import { createServer as createServer7 } from "node:http";
638177
- import { existsSync as existsSync123, readFileSync as readFileSync102, statSync as statSync49 } from "node:fs";
638636
+ import { existsSync as existsSync123, readFileSync as readFileSync102, statSync as statSync50 } from "node:fs";
638178
638637
  import { basename as basename28, extname as extname16, resolve as resolve61 } from "node:path";
638179
638638
  function getCurrentCadModelViewer() {
638180
638639
  return currentViewer;
638181
638640
  }
638182
638641
  async function startCadModelViewer(filePath) {
638183
638642
  const resolved = filePath ? resolve61(filePath) : void 0;
638184
- if (resolved && (!existsSync123(resolved) || !statSync49(resolved).isFile())) {
638643
+ if (resolved && (!existsSync123(resolved) || !statSync50(resolved).isFile())) {
638185
638644
  throw new Error(`3D model file not found: ${resolved}`);
638186
638645
  }
638187
638646
  if (currentViewer) {
@@ -638964,6 +639423,7 @@ var init_stageIndicator = __esm({
638964
639423
  // packages/cli/src/tui/tui-tasks-renderer.ts
638965
639424
  var tui_tasks_renderer_exports = {};
638966
639425
  __export(tui_tasks_renderer_exports, {
639426
+ __testFormatTodoContent: () => __testFormatTodoContent,
638967
639427
  __testOrderTodosForDisplay: () => __testOrderTodosForDisplay,
638968
639428
  __testSelectPanelTodoRows: () => __testSelectPanelTodoRows,
638969
639429
  getTuiTasksScope: () => getTuiTasksScope,
@@ -638971,6 +639431,7 @@ __export(tui_tasks_renderer_exports, {
638971
639431
  isTuiTasksExpanded: () => isTuiTasksExpanded,
638972
639432
  onTuiTasksHeightChange: () => onTuiTasksHeightChange,
638973
639433
  refreshTuiTasks: () => refreshTuiTasks,
639434
+ refreshTuiTasksAnimationFrame: () => refreshTuiTasksAnimationFrame,
638974
639435
  refreshTuiTasksSync: () => refreshTuiTasksSync,
638975
639436
  refreshTuiTasksThemeVars: () => refreshTuiTasksThemeVars,
638976
639437
  setTasksRendererWriter: () => setTasksRendererWriter,
@@ -639085,6 +639546,13 @@ function refreshTuiTasksSync() {
639085
639546
  _redrawScheduled = false;
639086
639547
  render();
639087
639548
  }
639549
+ function refreshTuiTasksAnimationFrame() {
639550
+ if (_redrawScheduled) return;
639551
+ if (!panelEffectivelyVisible()) return;
639552
+ if (_lastTodos.length === 0) return;
639553
+ if (!_lastTodos.some((t2) => t2.status === "in_progress")) return;
639554
+ render({ animationFrame: true });
639555
+ }
639088
639556
  function teardownTuiTasks() {
639089
639557
  if (_watcher) {
639090
639558
  try {
@@ -639307,6 +639775,16 @@ function activeDisplayIndex(displayTodos) {
639307
639775
  if (blocked >= 0) return blocked;
639308
639776
  return displayTodos.findIndex((todo) => todo.displayStatus === "pending");
639309
639777
  }
639778
+ function formatTodoContent(t2, activeId) {
639779
+ const indent2 = t2.depth > 0 ? `${" ".repeat(t2.depth)}- ` : "";
639780
+ const label = activeId && t2.id === activeId && t2.activeForm ? t2.activeForm : t2.content;
639781
+ const childSummary = t2.childSummary && t2.childSummary.total > 0 ? ` [${t2.childSummary.completed}/${t2.childSummary.total}]` : "";
639782
+ const owner = t2.owner ? ` @${t2.owner}` : "";
639783
+ const blockedBy = Array.isArray(t2.blockedBy) && t2.blockedBy.length > 0 ? ` dep:${t2.blockedBy.length}` : "";
639784
+ const blocks = Array.isArray(t2.blocks) && t2.blocks.length > 0 ? ` blocks:${t2.blocks.length}` : "";
639785
+ const blocker = t2.blocker ? ` (blocked: ${t2.blocker})` : "";
639786
+ return `${indent2}${label}${childSummary}${owner}${blockedBy}${blocks}${blocker}`;
639787
+ }
639310
639788
  function selectFocusedTodoItems(todos, maxItems) {
639311
639789
  const displayTodos = orderTodosForDisplay(todos);
639312
639790
  if (maxItems <= 0) return [];
@@ -639390,16 +639868,29 @@ function __testOrderTodosForDisplay(todos) {
639390
639868
  function __testSelectPanelTodoRows(todos, maxRows) {
639391
639869
  return selectPanelTodoRows(todos, maxRows);
639392
639870
  }
639393
- function render() {
639871
+ function __testFormatTodoContent(t2, activeId) {
639872
+ return formatTodoContent(t2, activeId);
639873
+ }
639874
+ function render(options2 = {}) {
639394
639875
  if (!_enabled) return;
639395
639876
  if (!panelEffectivelyVisible()) {
639877
+ if (options2.animationFrame) return;
639396
639878
  clearLastPaintedRows();
639397
639879
  applyHeightChange(0);
639398
639880
  return;
639399
639881
  }
639400
639882
  const target = computeTargetHeight();
639401
- applyHeightChange(target);
639883
+ if (options2.animationFrame) {
639884
+ if (target === 0 || tasksHeight() <= 0) return;
639885
+ if (target !== tasksHeight()) {
639886
+ scheduleRedraw();
639887
+ return;
639888
+ }
639889
+ } else {
639890
+ applyHeightChange(target);
639891
+ }
639402
639892
  if (target === 0) {
639893
+ if (options2.animationFrame) return;
639403
639894
  clearLastPaintedRows();
639404
639895
  return;
639405
639896
  }
@@ -639426,9 +639917,7 @@ function render() {
639426
639917
  for (const t2 of visible) {
639427
639918
  const { mark, color } = statusToAnsi(t2.displayStatus);
639428
639919
  const contentWidth = Math.max(4, cols - 8);
639429
- const indent2 = t2.depth > 0 ? `${" ".repeat(t2.depth)}- ` : "";
639430
- const childSummary = t2.childSummary && t2.childSummary.total > 0 ? ` [${t2.childSummary.completed}/${t2.childSummary.total}]` : "";
639431
- const contentText = indent2 + t2.content + childSummary + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
639920
+ const contentText = formatTodoContent(t2, activeId);
639432
639921
  const truncated = truncate2(contentText, contentWidth);
639433
639922
  if (activeId && t2.id === activeId) {
639434
639923
  const grad = paintActiveRowGradient(truncated);
@@ -639845,7 +640334,7 @@ var init_braille_spinner = __esm({
639845
640334
  });
639846
640335
 
639847
640336
  // packages/cli/src/tui/project-context.ts
639848
- import { existsSync as existsSync127, readFileSync as readFileSync106, readdirSync as readdirSync42, mkdirSync as mkdirSync78, statSync as statSync50, writeFileSync as writeFileSync66 } from "node:fs";
640337
+ import { existsSync as existsSync127, readFileSync as readFileSync106, readdirSync as readdirSync42, mkdirSync as mkdirSync78, statSync as statSync51, writeFileSync as writeFileSync66 } from "node:fs";
639849
640338
  import { dirname as dirname43, join as join141, basename as basename29, resolve as resolve62 } from "node:path";
639850
640339
  import { homedir as homedir45 } from "node:os";
639851
640340
  function projectContextUrlSpanAt(text2, index) {
@@ -640507,7 +640996,7 @@ function safeReadDir(dir) {
640507
640996
  }
640508
640997
  function isDirectory2(path16) {
640509
640998
  try {
640510
- return statSync50(path16).isDirectory();
640999
+ return statSync51(path16).isDirectory();
640511
641000
  } catch {
640512
641001
  return false;
640513
641002
  }
@@ -643036,6 +643525,7 @@ var init_status_bar = __esm({
643036
643525
  }
643037
643526
  this.advanceStagePhase();
643038
643527
  this.renderFooterPreserveCursor();
643528
+ refreshTuiTasksAnimationFrame();
643039
643529
  }, _StatusBar.FOOTER_ANIMATION_INTERVAL_MS);
643040
643530
  this._footerAnimationTimer.unref?.();
643041
643531
  }
@@ -646296,10 +646786,26 @@ ${CONTENT_BG_SEQ}`);
646296
646786
  }
646297
646787
  const w = getTermWidth();
646298
646788
  const pos = this.rowPositions(termRows());
646789
+ const inputWrap = this.wrapInput(w);
646299
646790
  let buf = "\x1B7\x1B[?7l";
646300
646791
  if (pos.tabBarRow > 0) {
646301
646792
  buf += `\x1B[${pos.tabBarRow};1H${PANEL_BG_SEQ}\x1B[2K${RESET4}`;
646302
646793
  }
646794
+ buf += `\x1B[${pos.inputStartRow};1H${PANEL_BG_SEQ}\x1B[2K${this.buildInputBoxTop(w)}${PANEL_BG_SEQ}`;
646795
+ for (let i2 = 0; i2 < inputWrap.lines.length; i2++) {
646796
+ const row = pos.inputStartRow + 1 + i2;
646797
+ const prefix = i2 === 0 ? this.promptText : " ".repeat(this.promptWidth);
646798
+ const lineContent = `${prefix}${inputWrap.lines[i2]}`;
646799
+ buf += `\x1B[${row};1H${PANEL_BG_SEQ}\x1B[2K`;
646800
+ buf += `${this.borderVSeq(1)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}${lineContent}`;
646801
+ buf += `${PANEL_BG_SEQ}\x1B[K`;
646802
+ buf += `\x1B[${row};${w}H${this.borderVSeq(w)}${BOX_V3}${RESET4}${PANEL_BG_SEQ}`;
646803
+ }
646804
+ buf += this.buildEnhanceSegment(
646805
+ w,
646806
+ pos.inputStartRow + 1,
646807
+ inputWrap.lines.length
646808
+ );
646303
646809
  if (this._suggestions.length > 0 && pos.suggestStartRow > 0) {
646304
646810
  for (let si = 0; si < this._suggestions.length; si++) {
646305
646811
  const row = pos.suggestStartRow + si;
@@ -647608,7 +648114,7 @@ __export(personaplex_exports, {
647608
648114
  startPersonaPlexDaemon: () => startPersonaPlexDaemon,
647609
648115
  stopPersonaPlex: () => stopPersonaPlex
647610
648116
  });
647611
- import { existsSync as existsSync128, writeFileSync as writeFileSync67, readFileSync as readFileSync107, mkdirSync as mkdirSync79, copyFileSync as copyFileSync5, readdirSync as readdirSync43, statSync as statSync51 } from "node:fs";
648117
+ import { existsSync as existsSync128, writeFileSync as writeFileSync67, readFileSync as readFileSync107, mkdirSync as mkdirSync79, copyFileSync as copyFileSync5, readdirSync as readdirSync43, statSync as statSync52 } from "node:fs";
647612
648118
  import { join as join142, dirname as dirname45 } from "node:path";
647613
648119
  import { homedir as homedir46 } from "node:os";
647614
648120
  import { spawn as spawn33 } from "node:child_process";
@@ -648143,7 +648649,7 @@ print('Converted')
648143
648649
  }
648144
648650
  if (existsSync128(cachedBf16)) {
648145
648651
  extraArgs.push("--moshi-weight", cachedBf16);
648146
- log22(`Using distilled weights: ${(statSync51(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
648652
+ log22(`Using distilled weights: ${(statSync52(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
648147
648653
  } else {
648148
648654
  extraArgs.push("--moshi-weight", weightPath);
648149
648655
  }
@@ -648174,7 +648680,7 @@ print('Converted')
648174
648680
  );
648175
648681
  if (existsSync128(cachedBf16)) {
648176
648682
  extraArgs.push("--moshi-weight", cachedBf16);
648177
- log22(`Using dequantized cache: ${(statSync51(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
648683
+ log22(`Using dequantized cache: ${(statSync52(cachedBf16).size / 1024 ** 3).toFixed(1)}GB`);
648178
648684
  }
648179
648685
  } catch (e2) {
648180
648686
  log22(`Dequantization failed — server will try to load original weights`);
@@ -652226,7 +652732,7 @@ var init_platforms = __esm({
652226
652732
  });
652227
652733
 
652228
652734
  // packages/cli/src/tui/workspace-explorer.ts
652229
- import { existsSync as existsSync131, readdirSync as readdirSync44, readFileSync as readFileSync109, statSync as statSync52 } from "node:fs";
652735
+ import { existsSync as existsSync131, readdirSync as readdirSync44, readFileSync as readFileSync109, statSync as statSync53 } from "node:fs";
652230
652736
  import { basename as basename31, extname as extname17, join as join144, relative as relative17, resolve as resolve63 } from "node:path";
652231
652737
  function exploreWorkspace(root, options2 = {}) {
652232
652738
  const query = (options2.query ?? "").trim().toLowerCase();
@@ -652263,7 +652769,7 @@ function exploreWorkspace(root, options2 = {}) {
652263
652769
  const rel = relative17(root, full).replace(/\\/g, "/");
652264
652770
  if (query && !rel.toLowerCase().includes(query)) continue;
652265
652771
  try {
652266
- const st = statSync52(full);
652772
+ const st = statSync53(full);
652267
652773
  entries.push({
652268
652774
  path: rel,
652269
652775
  sizeBytes: st.size,
@@ -652315,7 +652821,7 @@ function previewWorkspaceFile(root, relPath, options2 = {}) {
652315
652821
  throw new Error("File path escapes workspace root");
652316
652822
  }
652317
652823
  if (!existsSync131(full)) throw new Error(`File not found: ${relPath}`);
652318
- const st = statSync52(full);
652824
+ const st = statSync53(full);
652319
652825
  if (!st.isFile()) throw new Error(`Not a file: ${relPath}`);
652320
652826
  if (st.size > maxBytes) {
652321
652827
  return [
@@ -656488,7 +656994,7 @@ __export(kg_prune_exports, {
656488
656994
  pruneKnowledgeGraph: () => pruneKnowledgeGraph,
656489
656995
  pruneKnowledgeGraphWithInference: () => pruneKnowledgeGraphWithInference
656490
656996
  });
656491
- import { existsSync as existsSync138, statSync as statSync54 } from "node:fs";
656997
+ import { existsSync as existsSync138, statSync as statSync55 } from "node:fs";
656492
656998
  import { join as join150 } from "node:path";
656493
656999
  function stateDirFor(workingDir) {
656494
657000
  return join150(workingDir, ".omnius");
@@ -656508,13 +657014,13 @@ function knowledgeGraphStats(workingDir) {
656508
657014
  };
656509
657015
  if (stats.exists) {
656510
657016
  try {
656511
- stats.sizeBytes = statSync54(dbPath).size;
657017
+ stats.sizeBytes = statSync55(dbPath).size;
656512
657018
  } catch {
656513
657019
  }
656514
657020
  }
656515
657021
  if (existsSync138(archivePath)) {
656516
657022
  try {
656517
- stats.archiveSizeBytes = statSync54(archivePath).size;
657023
+ stats.archiveSizeBytes = statSync55(archivePath).size;
656518
657024
  } catch {
656519
657025
  }
656520
657026
  }
@@ -659057,9 +659563,9 @@ import {
659057
659563
  readFileSync as readFileSync116,
659058
659564
  unlinkSync as unlinkSync29,
659059
659565
  readdirSync as readdirSync47,
659060
- statSync as statSync55,
659566
+ statSync as statSync56,
659061
659567
  copyFileSync as copyFileSync6,
659062
- rmSync as rmSync11
659568
+ rmSync as rmSync12
659063
659569
  } from "node:fs";
659064
659570
  import { join as join154, dirname as dirname47, resolve as resolve65 } from "node:path";
659065
659571
  import { homedir as homedir52, tmpdir as tmpdir23, platform as platform7 } from "node:os";
@@ -659191,7 +659697,7 @@ function mergeDir2(src2, dst) {
659191
659697
  if (entry.isDirectory()) {
659192
659698
  mergeDir2(s2, d2);
659193
659699
  } else if (entry.isFile()) {
659194
- if (!existsSync142(d2) || statSync55(s2).mtimeMs > statSync55(d2).mtimeMs) {
659700
+ if (!existsSync142(d2) || statSync56(s2).mtimeMs > statSync56(d2).mtimeMs) {
659195
659701
  copyFileSync6(s2, d2);
659196
659702
  }
659197
659703
  }
@@ -659208,7 +659714,7 @@ function consolidateVoiceDirs2() {
659208
659714
  mergeDir2(join154(oldVoice, "clone-refs"), join154(globalVoice, "clone-refs"));
659209
659715
  mergeDir2(join154(oldVoice, "models"), join154(globalVoice, "models"));
659210
659716
  try {
659211
- rmSync11(oldVoice, { recursive: true, force: true });
659717
+ rmSync12(oldVoice, { recursive: true, force: true });
659212
659718
  cleaned++;
659213
659719
  } catch {
659214
659720
  }
@@ -659239,7 +659745,7 @@ function consolidateVoiceDirs2() {
659239
659745
  try {
659240
659746
  mergeDir2(join154(candidate, "clone-refs"), join154(globalVoice, "clone-refs"));
659241
659747
  mergeDir2(join154(candidate, "models"), join154(globalVoice, "models"));
659242
- rmSync11(candidate, { recursive: true, force: true });
659748
+ rmSync12(candidate, { recursive: true, force: true });
659243
659749
  cleaned++;
659244
659750
  migrated++;
659245
659751
  } catch {
@@ -660673,7 +661179,7 @@ except Exception as exc:
660673
661179
  const p2 = join154(dir, f2);
660674
661180
  let size = 0;
660675
661181
  try {
660676
- size = statSync55(p2).size;
661182
+ size = statSync56(p2).size;
660677
661183
  } catch {
660678
661184
  }
660679
661185
  const entry = meta[f2];
@@ -663651,8 +664157,8 @@ import {
663651
664157
  mkdirSync as mkdirSync86,
663652
664158
  readdirSync as readdirSync48,
663653
664159
  lstatSync as lstatSync2,
663654
- statSync as statSync56,
663655
- rmSync as rmSync12,
664160
+ statSync as statSync57,
664161
+ rmSync as rmSync13,
663656
664162
  appendFileSync as appendFileSync16,
663657
664163
  writeSync as writeSync2
663658
664164
  } from "node:fs";
@@ -666460,7 +666966,7 @@ async function handleSlashCommand(input, ctx3) {
666460
666966
  ipfsFiles = files.length;
666461
666967
  for (const f2 of files) {
666462
666968
  try {
666463
- ipfsBytes += statSync56(join155(ipfsLocalDir, f2)).size;
666969
+ ipfsBytes += statSync57(join155(ipfsLocalDir, f2)).size;
666464
666970
  } catch {
666465
666971
  }
666466
666972
  }
@@ -666473,7 +666979,7 @@ async function handleSlashCommand(input, ctx3) {
666473
666979
  else {
666474
666980
  heliaBlocks++;
666475
666981
  try {
666476
- heliaBytes += statSync56(join155(dir, entry.name)).size;
666982
+ heliaBytes += statSync57(join155(dir, entry.name)).size;
666477
666983
  } catch {
666478
666984
  }
666479
666985
  }
@@ -666616,7 +667122,7 @@ async function handleSlashCommand(input, ctx3) {
666616
667122
  lines.push(`
666617
667123
  ${c3.bold("Structured Memory (SQLite)")}`);
666618
667124
  lines.push(
666619
- ` Memories: ${c3.bold(String(count))} DB: ${c3.dim(formatFileSize(statSync56(dbPath).size))}`
667125
+ ` Memories: ${c3.bold(String(count))} DB: ${c3.dim(formatFileSize(statSync57(dbPath).size))}`
666620
667126
  );
666621
667127
  cDb(db);
666622
667128
  }
@@ -666648,7 +667154,7 @@ async function handleSlashCommand(input, ctx3) {
666648
667154
  walkStorage(full, subCat);
666649
667155
  } else {
666650
667156
  try {
666651
- const sz = statSync56(full).size;
667157
+ const sz = statSync57(full).size;
666652
667158
  totalBytes += sz;
666653
667159
  if (!categories[category])
666654
667160
  categories[category] = { files: 0, bytes: 0 };
@@ -666953,7 +667459,7 @@ async function handleSlashCommand(input, ctx3) {
666953
667459
  } catch {
666954
667460
  }
666955
667461
  try {
666956
- rmSync12(bridgeFile);
667462
+ rmSync13(bridgeFile);
666957
667463
  } catch {
666958
667464
  }
666959
667465
  renderInfo("Fortemi bridge stopped.");
@@ -672227,7 +672733,7 @@ function removeCachedModelPaths(root, model) {
672227
672733
  const removed = [];
672228
672734
  for (const path16 of cacheCandidatePaths(root, model)) {
672229
672735
  if (!existsSync143(path16)) continue;
672230
- rmSync12(path16, { recursive: true, force: true });
672736
+ rmSync13(path16, { recursive: true, force: true });
672231
672737
  removed.push(path16);
672232
672738
  }
672233
672739
  return removed;
@@ -673809,7 +674315,7 @@ async function showCohereDashboard(ctx3) {
673809
674315
  const snapItems = snaps.slice(0, 20).map((f2) => ({
673810
674316
  key: f2,
673811
674317
  label: f2.replace(".json", ""),
673812
- detail: `${formatFileSize(statSync56(join155(snapDir, f2)).size)}`
674318
+ detail: `${formatFileSize(statSync57(join155(snapDir, f2)).size)}`
673813
674319
  }));
673814
674320
  if (snapItems.length > 0) {
673815
674321
  await tuiSelect({
@@ -684374,7 +684880,7 @@ var init_edit_history = __esm({
684374
684880
  });
684375
684881
 
684376
684882
  // packages/cli/src/tui/snr-engine.ts
684377
- import { existsSync as existsSync149, readdirSync as readdirSync52, readFileSync as readFileSync122, writeFileSync as writeFileSync78, mkdirSync as mkdirSync91, rmSync as rmSync13 } from "node:fs";
684883
+ import { existsSync as existsSync149, readdirSync as readdirSync52, readFileSync as readFileSync122, writeFileSync as writeFileSync78, mkdirSync as mkdirSync91, rmSync as rmSync14 } from "node:fs";
684378
684884
  import { join as join161, basename as basename37 } from "node:path";
684379
684885
  function computeDPrime2(signalScores, noiseScores) {
684380
684886
  if (signalScores.length === 0 || noiseScores.length === 0) return 0;
@@ -684805,7 +685311,7 @@ Call task_complete with the JSON array when done.`,
684805
685311
  writeFileSync78(archiveFile, JSON.stringify(archiveData, null, 2));
684806
685312
  if (Object.keys(data).length === 0) {
684807
685313
  try {
684808
- rmSync13(file);
685314
+ rmSync14(file);
684809
685315
  } catch {
684810
685316
  }
684811
685317
  } else {
@@ -689979,7 +690485,7 @@ import {
689979
690485
  existsSync as existsSync153,
689980
690486
  mkdirSync as mkdirSync95,
689981
690487
  readFileSync as readFileSync126,
689982
- statSync as statSync57,
690488
+ statSync as statSync58,
689983
690489
  unlinkSync as unlinkSync32,
689984
690490
  writeFileSync as writeFileSync82
689985
690491
  } from "node:fs";
@@ -690492,7 +690998,7 @@ function materializeTelegramCreativeArtifactForSend(root, rawPath) {
690492
690998
  }
690493
690999
  function safeStatFile(path16) {
690494
691000
  try {
690495
- return statSync57(path16).isFile();
691001
+ return statSync58(path16).isFile();
690496
691002
  } catch {
690497
691003
  return false;
690498
691004
  }
@@ -690763,7 +691269,7 @@ ${(result.error || result.output || "").slice(0, 1200)}`,
690763
691269
  for (const fn of cleanup) fn();
690764
691270
  }
690765
691271
  rememberCreated(this.root, guarded.path.abs);
690766
- const sizeKB = Math.round(statSync57(guarded.path.abs).size / 1024);
691272
+ const sizeKB = Math.round(statSync58(guarded.path.abs).size / 1024);
690767
691273
  this.emitProgress(start2, {
690768
691274
  stage: "save",
690769
691275
  message: `Saved scoped audio file (${sizeKB}KB)`
@@ -691247,7 +691753,7 @@ import { basename as basename41 } from "node:path";
691247
691753
  function stringValue3(value2) {
691248
691754
  return typeof value2 === "string" ? value2.trim() : "";
691249
691755
  }
691250
- function stringList(value2) {
691756
+ function stringList2(value2) {
691251
691757
  if (Array.isArray(value2)) {
691252
691758
  return value2.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim());
691253
691759
  }
@@ -691287,7 +691793,7 @@ function identityNames(payload) {
691287
691793
  for (const key of ["person", "person_name", "personName", "face_name", "faceName"]) {
691288
691794
  add3(payload[key]);
691289
691795
  }
691290
- for (const person of stringList(payload["people"])) add3(person);
691796
+ for (const person of stringList2(payload["people"])) add3(person);
691291
691797
  const assertions = Array.isArray(payload["identityAssertions"]) ? payload["identityAssertions"] : Array.isArray(payload["identity_assertions"]) ? payload["identity_assertions"] : [];
691292
691798
  for (const item of assertions) {
691293
691799
  if (item && typeof item === "object") add3(item["name"]);
@@ -691304,34 +691810,34 @@ function isRejectedObjectLabel(label, payload) {
691304
691810
  function extractExplicitVisualObjectLabels(payload) {
691305
691811
  const media = payload["media"] && typeof payload["media"] === "object" ? payload["media"] : {};
691306
691812
  const candidates = uniqueLabels([
691307
- ...stringList(payload["object_label"]),
691308
- ...stringList(payload["objectLabel"]),
691309
- ...stringList(payload["object_labels"]),
691310
- ...stringList(payload["objectLabels"]),
691311
- ...stringList(payload["visualObjectLabel"]),
691312
- ...stringList(payload["visual_object_label"]),
691313
- ...stringList(payload["visualObjectLabels"]),
691314
- ...stringList(payload["visual_object_labels"]),
691315
- ...stringList(payload["label"]),
691316
- ...stringList(payload["labels"]),
691317
- ...stringList(media["objectLabel"]),
691318
- ...stringList(media["object_label"]),
691319
- ...stringList(media["objectLabels"]),
691320
- ...stringList(media["object_labels"]),
691321
- ...stringList(media["label"]),
691322
- ...stringList(media["labels"]),
691813
+ ...stringList2(payload["object_label"]),
691814
+ ...stringList2(payload["objectLabel"]),
691815
+ ...stringList2(payload["object_labels"]),
691816
+ ...stringList2(payload["objectLabels"]),
691817
+ ...stringList2(payload["visualObjectLabel"]),
691818
+ ...stringList2(payload["visual_object_label"]),
691819
+ ...stringList2(payload["visualObjectLabels"]),
691820
+ ...stringList2(payload["visual_object_labels"]),
691821
+ ...stringList2(payload["label"]),
691822
+ ...stringList2(payload["labels"]),
691823
+ ...stringList2(media["objectLabel"]),
691824
+ ...stringList2(media["object_label"]),
691825
+ ...stringList2(media["objectLabels"]),
691826
+ ...stringList2(media["object_labels"]),
691827
+ ...stringList2(media["label"]),
691828
+ ...stringList2(media["labels"]),
691323
691829
  ...explicitCaptionLabels(payload["caption"]),
691324
691830
  ...explicitCaptionLabels(media["caption"])
691325
691831
  ]).filter((label) => !isRejectedObjectLabel(label, payload));
691326
691832
  const aliases = uniqueLabels([
691327
- ...stringList(payload["aliases"]),
691328
- ...stringList(payload["object_aliases"]),
691329
- ...stringList(payload["objectAliases"]),
691330
- ...stringList(payload["visualObjectAliases"]),
691331
- ...stringList(payload["visual_object_aliases"]),
691332
- ...stringList(media["aliases"]),
691333
- ...stringList(media["objectAliases"]),
691334
- ...stringList(media["object_aliases"]),
691833
+ ...stringList2(payload["aliases"]),
691834
+ ...stringList2(payload["object_aliases"]),
691835
+ ...stringList2(payload["objectAliases"]),
691836
+ ...stringList2(payload["visualObjectAliases"]),
691837
+ ...stringList2(payload["visual_object_aliases"]),
691838
+ ...stringList2(media["aliases"]),
691839
+ ...stringList2(media["objectAliases"]),
691840
+ ...stringList2(media["object_aliases"]),
691335
691841
  ...candidates.slice(1)
691336
691842
  ]).filter((label) => !isRejectedObjectLabel(label, payload));
691337
691843
  return {
@@ -694146,7 +694652,7 @@ import {
694146
694652
  existsSync as existsSync156,
694147
694653
  unlinkSync as unlinkSync35,
694148
694654
  readdirSync as readdirSync56,
694149
- statSync as statSync58,
694655
+ statSync as statSync59,
694150
694656
  readFileSync as readFileSync129,
694151
694657
  writeFileSync as writeFileSync84,
694152
694658
  appendFileSync as appendFileSync20
@@ -699104,7 +699610,7 @@ Model: <code>${escapeTelegramHTML(model.id)}</code>`
699104
699610
  }
699105
699611
  let sent = 0;
699106
699612
  for (const path16 of paths) {
699107
- if (!existsSync156(path16) || !statSync58(path16).isFile()) continue;
699613
+ if (!existsSync156(path16) || !statSync59(path16).isFile()) continue;
699108
699614
  const kind = classifyMedia(path16) ?? "document";
699109
699615
  const messageId = await this.sendMediaReference(
699110
699616
  msg.chatId,
@@ -711250,7 +711756,7 @@ ${knownList}` : "Private-user telegram_send_file target must be this DM or a kno
711250
711756
  const abs = isAbsolute16(trimmed) ? resolve71(trimmed) : resolve71(base3, trimmed);
711251
711757
  if (!existsSync156(abs))
711252
711758
  return { ok: false, error: `File does not exist: ${trimmed}` };
711253
- if (!statSync58(abs).isFile())
711759
+ if (!statSync59(abs).isFile())
711254
711760
  return { ok: false, error: `Path is not a file: ${trimmed}` };
711255
711761
  return { ok: true, path: abs };
711256
711762
  }
@@ -711764,7 +712270,7 @@ ${text2}`.trim()
711764
712270
  }
711765
712271
  async sendTelegramFileToChat(chatId, path16, options2) {
711766
712272
  const abs = resolve71(path16);
711767
- if (!existsSync156(abs) || !statSync58(abs).isFile()) {
712273
+ if (!existsSync156(abs) || !statSync59(abs).isFile()) {
711768
712274
  throw new Error(`File does not exist or is not a regular file: ${path16}`);
711769
712275
  }
711770
712276
  return this.sendMediaReferenceStrict(
@@ -712034,7 +712540,7 @@ Content-Type: ${contentType}\r
712034
712540
  for (const path16 of paths) {
712035
712541
  const abs = resolve71(path16);
712036
712542
  if (subAgent.deliveredArtifacts.includes(abs)) continue;
712037
- if (!existsSync156(abs) || !statSync58(abs).isFile()) continue;
712543
+ if (!existsSync156(abs) || !statSync59(abs).isFile()) continue;
712038
712544
  subAgent.deliveredArtifacts.push(abs);
712039
712545
  await this.sendMediaReference(
712040
712546
  msg.chatId,
@@ -712076,7 +712582,7 @@ Content-Type: ${contentType}\r
712076
712582
  abs
712077
712583
  );
712078
712584
  if (!materialized.ok) continue;
712079
- if (!existsSync156(materialized.path) || !statSync58(materialized.path).isFile()) {
712585
+ if (!existsSync156(materialized.path) || !statSync59(materialized.path).isFile()) {
712080
712586
  materialized.cleanup?.();
712081
712587
  continue;
712082
712588
  }
@@ -714259,7 +714765,7 @@ __export(projects_exports, {
714259
714765
  setCurrentProject: () => setCurrentProject,
714260
714766
  unregisterProject: () => unregisterProject
714261
714767
  });
714262
- import { readFileSync as readFileSync130, writeFileSync as writeFileSync85, mkdirSync as mkdirSync98, existsSync as existsSync157, statSync as statSync59, renameSync as renameSync14 } from "node:fs";
714768
+ import { readFileSync as readFileSync130, writeFileSync as writeFileSync85, mkdirSync as mkdirSync98, existsSync as existsSync157, statSync as statSync60, renameSync as renameSync14 } from "node:fs";
714263
714769
  import { homedir as homedir56 } from "node:os";
714264
714770
  import { basename as basename43, join as join170, resolve as resolve72 } from "node:path";
714265
714771
  import { randomUUID as randomUUID19 } from "node:crypto";
@@ -714285,7 +714791,7 @@ function listProjects() {
714285
714791
  const alive = [];
714286
714792
  for (const p2 of projects) {
714287
714793
  try {
714288
- if (statSync59(p2.root).isDirectory()) alive.push(p2);
714794
+ if (statSync60(p2.root).isDirectory()) alive.push(p2);
714289
714795
  } catch {
714290
714796
  }
714291
714797
  }
@@ -715425,7 +715931,7 @@ var init_audit_log = __esm({
715425
715931
 
715426
715932
  // packages/cli/src/api/disk-task-output.ts
715427
715933
  import { open } from "node:fs/promises";
715428
- import { existsSync as existsSync160, mkdirSync as mkdirSync101, statSync as statSync60 } from "node:fs";
715934
+ import { existsSync as existsSync160, mkdirSync as mkdirSync101, statSync as statSync61 } from "node:fs";
715429
715935
  import { dirname as dirname52 } from "node:path";
715430
715936
  import * as fsConstants from "node:constants";
715431
715937
  var O_NOFOLLOW2, O_APPEND2, O_CREAT2, O_WRONLY2, OPEN_FLAGS_WRITE, OPEN_MODE, DiskTaskOutput;
@@ -715523,7 +716029,7 @@ var init_disk_task_output = __esm({
715523
716029
  if (!existsSync160(this.path)) {
715524
716030
  return { content: "", nextOffset: offset, eof: true, size: 0 };
715525
716031
  }
715526
- const st = statSync60(this.path);
716032
+ const st = statSync61(this.path);
715527
716033
  if (offset >= st.size) {
715528
716034
  return { content: "", nextOffset: offset, eof: true, size: st.size };
715529
716035
  }
@@ -715710,7 +716216,7 @@ data: ${JSON.stringify(ev)}
715710
716216
  });
715711
716217
 
715712
716218
  // packages/cli/src/api/routes-media.ts
715713
- import { existsSync as existsSync161, mkdirSync as mkdirSync102, statSync as statSync61, copyFileSync as copyFileSync7, createReadStream } from "node:fs";
716219
+ import { existsSync as existsSync161, mkdirSync as mkdirSync102, statSync as statSync62, copyFileSync as copyFileSync7, createReadStream } from "node:fs";
715714
716220
  import { basename as basename44, join as join173, resolve as pathResolve2 } from "node:path";
715715
716221
  function mediaWorkDir() {
715716
716222
  return join173(omniusHomeDir(), "media", "_work");
@@ -716011,7 +716517,7 @@ async function runGeneration(ctx3, kind, buildTool, buildArgs) {
716011
716517
  const published = publishToGallery(srcPath, kind);
716012
716518
  const size = (() => {
716013
716519
  try {
716014
- return statSync61(published.path).size;
716520
+ return statSync62(published.path).size;
716015
716521
  } catch {
716016
716522
  return 0;
716017
716523
  }
@@ -716118,7 +716624,7 @@ function handleFile(ctx3) {
716118
716624
  const ext = full.slice(full.lastIndexOf(".")).toLowerCase();
716119
716625
  ctx3.res.writeHead(200, {
716120
716626
  "Content-Type": MIME_BY_EXT[ext] || "application/octet-stream",
716121
- "Content-Length": statSync61(full).size,
716627
+ "Content-Length": statSync62(full).size,
716122
716628
  "Cache-Control": "private, max-age=3600"
716123
716629
  });
716124
716630
  createReadStream(full).pipe(ctx3.res);
@@ -716702,7 +717208,7 @@ __export(aiwg_exports, {
716702
717208
  resolveAiwgRoot: () => resolveAiwgRoot,
716703
717209
  tryRouteAiwg: () => tryRouteAiwg
716704
717210
  });
716705
- import { existsSync as existsSync163, readFileSync as readFileSync134, readdirSync as readdirSync57, statSync as statSync62 } from "node:fs";
717211
+ import { existsSync as existsSync163, readFileSync as readFileSync134, readdirSync as readdirSync57, statSync as statSync63 } from "node:fs";
716706
717212
  import { join as join175 } from "node:path";
716707
717213
  import { homedir as homedir58 } from "node:os";
716708
717214
  import { execSync as execSync38 } from "node:child_process";
@@ -716804,7 +717310,7 @@ function listAiwgFrameworks() {
716804
717310
  for (const name10 of readdirSync57(frameworksDir)) {
716805
717311
  const p2 = join175(frameworksDir, name10);
716806
717312
  try {
716807
- const st = statSync62(p2);
717313
+ const st = statSync63(p2);
716808
717314
  if (!st.isDirectory()) continue;
716809
717315
  const agg = aggregateDir(p2);
716810
717316
  out.push({
@@ -716841,7 +717347,7 @@ function aggregateDir(dir, depth = 0) {
716841
717347
  out.commands += sub2.commands;
716842
717348
  } else if (e2.isFile()) {
716843
717349
  try {
716844
- const st = statSync62(p2);
717350
+ const st = statSync63(p2);
716845
717351
  out.files++;
716846
717352
  out.bytes += st.size;
716847
717353
  if (e2.name.endsWith(".md")) {
@@ -716975,7 +717481,7 @@ function listAiwgAddons() {
716975
717481
  for (const name10 of readdirSync57(addonsDir)) {
716976
717482
  const p2 = join175(addonsDir, name10);
716977
717483
  try {
716978
- const st = statSync62(p2);
717484
+ const st = statSync63(p2);
716979
717485
  if (!st.isDirectory()) continue;
716980
717486
  const agg = aggregateDir(p2);
716981
717487
  out.push({
@@ -717861,7 +718367,7 @@ import {
717861
718367
  mkdirSync as mkdirSync106,
717862
718368
  readFileSync as readFileSync137,
717863
718369
  readdirSync as readdirSync58,
717864
- statSync as statSync63
718370
+ statSync as statSync64
717865
718371
  } from "node:fs";
717866
718372
  import { join as join179, resolve as pathResolve3 } from "node:path";
717867
718373
  import { homedir as homedir61 } from "node:os";
@@ -719314,7 +719820,7 @@ async function handleFilesRead(ctx3) {
719314
719820
  );
719315
719821
  return true;
719316
719822
  }
719317
- const st = statSync63(resolved);
719823
+ const st = statSync64(resolved);
719318
719824
  if (st.isDirectory()) {
719319
719825
  sendProblem(
719320
719826
  res,
@@ -730934,7 +731440,17 @@ function renderTasksRow(todos) {
730934
731440
  for (const t of todos) {
730935
731441
  const item = document.createElement('span');
730936
731442
  item.className = 'task-item ' + t.status;
730937
- item.title = t.content + (t.blocker ? ' (blocked: ' + t.blocker + ')' : '');
731443
+ const metaTitle = [
731444
+ t.activeForm ? 'doing: ' + t.activeForm : '',
731445
+ t.owner ? 'owner: ' + t.owner : '',
731446
+ Array.isArray(t.blockedBy) && t.blockedBy.length ? 'blockedBy: ' + t.blockedBy.join(', ') : '',
731447
+ Array.isArray(t.blocks) && t.blocks.length ? 'blocks: ' + t.blocks.join(', ') : '',
731448
+ t.blocker ? 'blocked: ' + t.blocker : '',
731449
+ ].filter(Boolean).join(' | ');
731450
+ item.title = t.content + (metaTitle ? ' (' + metaTitle + ')' : '');
731451
+ if (t.parentId) {
731452
+ item.style.marginLeft = '10px';
731453
+ }
730938
731454
  const mark = document.createElement('span');
730939
731455
  mark.className = 'mark';
730940
731456
  mark.textContent = statusMark(t.status);
@@ -730942,8 +731458,20 @@ function renderTasksRow(todos) {
730942
731458
  const label = document.createElement('span');
730943
731459
  label.className = 'label';
730944
731460
  // Show short ID + first ~32 chars of content so dense plans stay readable
730945
- label.textContent = t.content.length > 36 ? t.content.slice(0, 33) + '...' : t.content;
731461
+ const displayText = t.status === 'in_progress' && t.activeForm ? t.activeForm : t.content;
731462
+ label.textContent = displayText.length > 36 ? displayText.slice(0, 33) + '...' : displayText;
730946
731463
  item.appendChild(label);
731464
+ const meta = [];
731465
+ if (t.owner) meta.push('@' + t.owner);
731466
+ if (Array.isArray(t.blockedBy) && t.blockedBy.length) meta.push('dep:' + t.blockedBy.length);
731467
+ if (Array.isArray(t.blocks) && t.blocks.length) meta.push('blocks:' + t.blocks.length);
731468
+ if (meta.length) {
731469
+ const metaEl = document.createElement('span');
731470
+ metaEl.className = 'label';
731471
+ metaEl.style.opacity = '0.65';
731472
+ metaEl.textContent = ' ' + meta.join(' ');
731473
+ item.appendChild(metaEl);
731474
+ }
730947
731475
  tasksRowEl.appendChild(item);
730948
731476
  }
730949
731477
  }
@@ -730970,8 +731498,7 @@ async function refreshTodos(sessionId) {
730970
731498
  todoChecklistEl.style.display = 'none';
730971
731499
  todoListEl.innerHTML = '';
730972
731500
  }
730973
- // 2) Chat mode should not surface transient planning todos in the UI.
730974
- renderTasksRow([]);
731501
+ renderTasksRow(todos);
730975
731502
  } catch { /* network or parse failure — leave panel as-is */ }
730976
731503
  }
730977
731504
 
@@ -735084,7 +735611,7 @@ import {
735084
735611
  watch as fsWatch4,
735085
735612
  renameSync as renameSync17,
735086
735613
  unlinkSync as unlinkSync37,
735087
- statSync as statSync64,
735614
+ statSync as statSync65,
735088
735615
  openSync as openSync6,
735089
735616
  readSync as readSync2,
735090
735617
  closeSync as closeSync6
@@ -735444,7 +735971,7 @@ function fileEntryMetadata(dir, entry) {
735444
735971
  kind: fileKindForPath(entry.name)
735445
735972
  };
735446
735973
  try {
735447
- const st = statSync64(target);
735974
+ const st = statSync65(target);
735448
735975
  meta["size"] = st.size;
735449
735976
  meta["mtime"] = new Date(st.mtimeMs).toISOString();
735450
735977
  } catch {
@@ -735456,7 +735983,7 @@ function contentDispositionName(filePath) {
735456
735983
  return name10.replace(/["\r\n]/g, "");
735457
735984
  }
735458
735985
  function streamWorkspaceFile(req3, res, target) {
735459
- const st = statSync64(target);
735986
+ const st = statSync65(target);
735460
735987
  if (!st.isFile()) {
735461
735988
  jsonResponse(res, 400, { error: "Path is not a file", path: target });
735462
735989
  return;
@@ -739263,9 +739790,13 @@ async function handleWriteTodos(req3, res) {
739263
739790
  validated.push({
739264
739791
  id: typeof t2["id"] === "string" ? t2["id"] : void 0,
739265
739792
  content: t2["content"],
739793
+ activeForm: typeof t2["activeForm"] === "string" ? t2["activeForm"] : void 0,
739266
739794
  status: t2["status"],
739267
739795
  parentId: typeof t2["parentId"] === "string" ? t2["parentId"] : void 0,
739268
- blocker: typeof t2["blocker"] === "string" ? t2["blocker"] : void 0
739796
+ blocker: typeof t2["blocker"] === "string" ? t2["blocker"] : void 0,
739797
+ owner: typeof t2["owner"] === "string" ? t2["owner"] : void 0,
739798
+ blocks: Array.isArray(t2["blocks"]) ? t2["blocks"].filter((x) => typeof x === "string") : void 0,
739799
+ blockedBy: Array.isArray(t2["blockedBy"]) ? t2["blockedBy"].filter((x) => typeof x === "string") : void 0
739269
739800
  });
739270
739801
  }
739271
739802
  const result = writeTodos(sessionId, validated);
@@ -739358,7 +739889,7 @@ function handleV1RunsById(res, id2) {
739358
739889
  const enriched = { ...job };
739359
739890
  if (outputFile && existsSync170(outputFile)) {
739360
739891
  try {
739361
- const size = statSync64(outputFile).size;
739892
+ const size = statSync65(outputFile).size;
739362
739893
  const tailSize = Math.min(size, 4096);
739363
739894
  const buffer2 = Buffer.alloc(tailSize);
739364
739895
  const fd = openSync6(outputFile, "r");
@@ -740006,7 +740537,7 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
740006
740537
  const dir = path16.dirname(cssEntry);
740007
740538
  const fullPath = path16.join(dir, entry.path);
740008
740539
  if (fs14.existsSync(fullPath)) {
740009
- const stat9 = statSync64(fullPath);
740540
+ const stat9 = statSync65(fullPath);
740010
740541
  res.writeHead(200, {
740011
740542
  "Content-Type": entry.ct,
740012
740543
  "Content-Length": String(stat9.size),
@@ -740558,17 +741089,17 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
740558
741089
  const child = join183(dir, e2.name);
740559
741090
  const omniusDir = join183(child, ".omnius");
740560
741091
  try {
740561
- if (statSync64(omniusDir).isDirectory()) {
741092
+ if (statSync65(omniusDir).isDirectory()) {
740562
741093
  const name10 = e2.name;
740563
741094
  const prefsFile = join183(omniusDir, "config.json");
740564
741095
  let lastSeen = 0;
740565
741096
  try {
740566
- lastSeen = statSync64(prefsFile).mtimeMs;
741097
+ lastSeen = statSync65(prefsFile).mtimeMs;
740567
741098
  } catch {
740568
741099
  }
740569
741100
  if (!lastSeen) {
740570
741101
  try {
740571
- lastSeen = statSync64(omniusDir).mtimeMs;
741102
+ lastSeen = statSync65(omniusDir).mtimeMs;
740572
741103
  } catch {
740573
741104
  }
740574
741105
  }
@@ -740616,17 +741147,17 @@ async function handleRequest(req3, res, ollamaUrl, verbose, runtimeDefaults = {}
740616
741147
  const child = join183(dir, e2.name);
740617
741148
  const omniusDir = join183(child, ".omnius");
740618
741149
  try {
740619
- if (statSync64(omniusDir).isDirectory()) {
741150
+ if (statSync65(omniusDir).isDirectory()) {
740620
741151
  const name10 = e2.name;
740621
741152
  const prefsFile = join183(omniusDir, "config.json");
740622
741153
  let lastSeen = 0;
740623
741154
  try {
740624
- lastSeen = statSync64(prefsFile).mtimeMs;
741155
+ lastSeen = statSync65(prefsFile).mtimeMs;
740625
741156
  } catch {
740626
741157
  }
740627
741158
  if (!lastSeen) {
740628
741159
  try {
740629
- lastSeen = statSync64(omniusDir).mtimeMs;
741160
+ lastSeen = statSync65(omniusDir).mtimeMs;
740630
741161
  } catch {
740631
741162
  }
740632
741163
  }
@@ -742480,9 +743011,13 @@ ${historyLines}
742480
743011
  const updated = finalTodos.map((t2) => ({
742481
743012
  id: t2.id,
742482
743013
  content: t2.content,
743014
+ activeForm: t2.activeForm,
742483
743015
  status: t2.status === "blocked" ? "blocked" : "completed",
742484
743016
  parentId: t2.parentId,
742485
- blocker: t2.blocker
743017
+ blocker: t2.blocker,
743018
+ owner: t2.owner,
743019
+ blocks: t2.blocks,
743020
+ blockedBy: t2.blockedBy
742486
743021
  }));
742487
743022
  writeTodos(session.id, updated);
742488
743023
  }
@@ -745536,7 +746071,7 @@ var clipboard_media_exports = {};
745536
746071
  __export(clipboard_media_exports, {
745537
746072
  pasteClipboardImageToFile: () => pasteClipboardImageToFile
745538
746073
  });
745539
- import { mkdirSync as mkdirSync110, readFileSync as readFileSync140, rmSync as rmSync15, writeFileSync as writeFileSync93 } from "node:fs";
746074
+ import { mkdirSync as mkdirSync110, readFileSync as readFileSync140, rmSync as rmSync16, writeFileSync as writeFileSync93 } from "node:fs";
745540
746075
  import { join as join184 } from "node:path";
745541
746076
  async function pasteClipboardImageToFile(repoRoot) {
745542
746077
  const image = await readClipboardImage();
@@ -745555,7 +746090,7 @@ async function readClipboardImage() {
745555
746090
  await execFileBuffer("pngpaste", [tmp], { timeout: 3e3 });
745556
746091
  const buffer2 = readFileSync140(tmp);
745557
746092
  try {
745558
- rmSync15(tmp);
746093
+ rmSync16(tmp);
745559
746094
  } catch {
745560
746095
  }
745561
746096
  if (buffer2.length > 0) return { buffer: buffer2, mime: "image/png", ext: ".png" };
@@ -745615,9 +746150,9 @@ import {
745615
746150
  readFileSync as readFileSync141,
745616
746151
  writeFileSync as writeFileSync94,
745617
746152
  appendFileSync as appendFileSync22,
745618
- rmSync as rmSync16,
746153
+ rmSync as rmSync17,
745619
746154
  readdirSync as readdirSync60,
745620
- statSync as statSync65,
746155
+ statSync as statSync66,
745621
746156
  mkdirSync as mkdirSync111
745622
746157
  } from "node:fs";
745623
746158
  import { existsSync as existsSync171 } from "node:fs";
@@ -751281,7 +751816,7 @@ This is an independent background session started from /background.`
751281
751816
  if (!entry.startsWith(partialName)) continue;
751282
751817
  const full = join185(searchDir, entry);
751283
751818
  try {
751284
- const st = statSync65(full);
751819
+ const st = statSync66(full);
751285
751820
  const suffix = st.isDirectory() ? "/" : "";
751286
751821
  const display = isAbsolute17 ? full : full.startsWith(repoRoot + sep6) ? full.slice(repoRoot.length + 1) : full;
751287
751822
  completions.push(display + suffix);
@@ -754045,11 +754580,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
754045
754580
  }
754046
754581
  if (name10 === "voice_list_files") {
754047
754582
  const baseDir = String(args?.dir ?? ".");
754048
- const { readdirSync: readdirSync62, statSync: statSync67 } = __require("node:fs");
754583
+ const { readdirSync: readdirSync62, statSync: statSync68 } = __require("node:fs");
754049
754584
  const { join: join190, resolve: resolve80 } = __require("node:path");
754050
754585
  const base3 = baseDir.startsWith("/") ? baseDir : resolve80(join190(repoRoot, baseDir));
754051
754586
  const items = readdirSync62(base3).slice(0, 200).map((f2) => {
754052
- const s2 = statSync67(join190(base3, f2));
754587
+ const s2 = statSync68(join190(base3, f2));
754053
754588
  return { name: f2, dir: s2.isDirectory(), size: s2.size };
754054
754589
  });
754055
754590
  return JSON.stringify({ dir: base3, items }, null, 2);
@@ -754603,7 +755138,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
754603
755138
  let deleted = false;
754604
755139
  for (let attempt = 0; attempt < 3; attempt++) {
754605
755140
  try {
754606
- rmSync16(omniusPath, { recursive: true, force: true });
755141
+ rmSync17(omniusPath, { recursive: true, force: true });
754607
755142
  deleted = true;
754608
755143
  break;
754609
755144
  } catch (err) {
@@ -756878,7 +757413,7 @@ __export(index_repo_exports, {
756878
757413
  indexRepoCommand: () => indexRepoCommand
756879
757414
  });
756880
757415
  import { resolve as resolve78 } from "node:path";
756881
- import { existsSync as existsSync173, statSync as statSync66 } from "node:fs";
757416
+ import { existsSync as existsSync173, statSync as statSync67 } from "node:fs";
756882
757417
  import { cwd as cwd2 } from "node:process";
756883
757418
  async function indexRepoCommand(opts, _config3) {
756884
757419
  const repoRoot = resolve78(opts.repoPath ?? cwd2());
@@ -756888,7 +757423,7 @@ async function indexRepoCommand(opts, _config3) {
756888
757423
  printError(`Path does not exist: ${repoRoot}`);
756889
757424
  process.exit(1);
756890
757425
  }
756891
- const stat9 = statSync66(repoRoot);
757426
+ const stat9 = statSync67(repoRoot);
756892
757427
  if (!stat9.isDirectory()) {
756893
757428
  printError(`Path is not a directory: ${repoRoot}`);
756894
757429
  process.exit(1);