omnius 1.0.385 → 1.0.386

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
@@ -295326,6 +295326,35 @@ function getTodoSessionId() {
295326
295326
  return envSession;
295327
295327
  return "default";
295328
295328
  }
295329
+ function flattenNestedTodoItems(items, repairNotes, parentId) {
295330
+ const flattened = [];
295331
+ for (const item of items) {
295332
+ if (!item || typeof item !== "object" || Array.isArray(item)) {
295333
+ flattened.push(item);
295334
+ continue;
295335
+ }
295336
+ const record = item;
295337
+ const children2 = Array.isArray(record["children"]) ? record["children"] : Array.isArray(record["subtasks"]) ? record["subtasks"] : [];
295338
+ const parentAware = { ...record };
295339
+ delete parentAware["children"];
295340
+ delete parentAware["subtasks"];
295341
+ if (parentId && typeof parentAware["parentId"] !== "string") {
295342
+ parentAware["parentId"] = parentId;
295343
+ }
295344
+ flattened.push(parentAware);
295345
+ const id = typeof parentAware["id"] === "string" && parentAware["id"].trim() ? parentAware["id"].trim() : void 0;
295346
+ if (children2.length > 0) {
295347
+ if (id) {
295348
+ repairNotes.push("flattened nested children/subtasks into parentId-linked todos");
295349
+ flattened.push(...flattenNestedTodoItems(children2, repairNotes, id));
295350
+ } else {
295351
+ repairNotes.push("left nested children unattached because parent todo had no stable id");
295352
+ flattened.push(...flattenNestedTodoItems(children2, repairNotes, parentId));
295353
+ }
295354
+ }
295355
+ }
295356
+ return flattened;
295357
+ }
295329
295358
  function validateLargeTaskDecomposition(todos) {
295330
295359
  if (todos.length < 20)
295331
295360
  return null;
@@ -295450,6 +295479,16 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
295450
295479
  type: "array",
295451
295480
  items: { type: "string" },
295452
295481
  description: `REG-38: optional list of file paths this todo is expected to produce on disk. When you mark the todo 'completed', the supervisor inspects each declared path; missing/empty/stale files trigger a rejection with a specific gap critique. Use whenever a todo has concrete deliverables (e.g. ["src/lib/foo.ts", "tests/unit/foo.test.ts"]). Generic across stacks.`
295482
+ },
295483
+ children: {
295484
+ type: "array",
295485
+ description: "Optional nested child todos. The tool flattens children into parentId-linked todos before storing.",
295486
+ items: { type: "object" }
295487
+ },
295488
+ subtasks: {
295489
+ type: "array",
295490
+ description: "Alias for children. Use this for decomposed child work under a parent objective.",
295491
+ items: { type: "object" }
295453
295492
  }
295454
295493
  }
295455
295494
  }
@@ -295474,8 +295513,9 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
295474
295513
  }
295475
295514
  const incoming = [];
295476
295515
  const repairNotes = [...normalized.repairNotes];
295477
- for (let index = 0; index < normalized.todos.length; index++) {
295478
- const raw = normalized.todos[index];
295516
+ const flattenedTodos = flattenNestedTodoItems(normalized.todos, repairNotes);
295517
+ for (let index = 0; index < flattenedTodos.length; index++) {
295518
+ const raw = flattenedTodos[index];
295479
295519
  if (!raw || typeof raw !== "object") {
295480
295520
  if (typeof raw === "string" && raw.trim()) {
295481
295521
  incoming.push({
@@ -576377,6 +576417,26 @@ ${contentPreview}
576377
576417
  }
576378
576418
  return true;
576379
576419
  }
576420
+ _shellCommandLikelyMutatesFilesystem(rawCmd) {
576421
+ if (!rawCmd || typeof rawCmd !== "string")
576422
+ return false;
576423
+ const cmd = rawCmd.trim();
576424
+ if (!cmd)
576425
+ return false;
576426
+ if (/(^|[^&\d])(>|>>)\s*\S/.test(cmd))
576427
+ return true;
576428
+ if (/\|\s*(?:tee|dd)\b/i.test(cmd))
576429
+ return true;
576430
+ if (/\b(?:sed|gsed)\s+(?:[^\n;&|]*\s)?(?:-i|--in-place)\b/i.test(cmd))
576431
+ return true;
576432
+ if (/\bperl\s+-[A-Za-z]*i[A-Za-z]*\b/.test(cmd))
576433
+ return true;
576434
+ if (/\b(?:cp|mv|rm|mkdir|rmdir|touch|truncate|ln|install)\b/i.test(cmd))
576435
+ return true;
576436
+ if (/\b(?:python3?|node|ruby|deno|bun)\b[\s\S]{0,240}\b(?:writeFile|writeFileSync|openSync|mkdirSync|renameSync|unlinkSync|rmSync)\b/i.test(cmd))
576437
+ return true;
576438
+ return false;
576439
+ }
576380
576440
  /**
576381
576441
  * REG-5: Render the recent-failures block so the agent SEES its own error
576382
576442
  * output before deciding what to do next. Detects same-fingerprint failure
@@ -582156,6 +582216,7 @@ Respond with EXACTLY this structure before your next tool call:
582156
582216
  }
582157
582217
  }
582158
582218
  }
582219
+ const shellFilesystemMutation = tc.name === "shell" && result.success === true && this._shellCommandLikelyMutatesFilesystem(String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? ""));
582159
582220
  const realFileMutation = this._isRealProjectMutation(tc.name, result);
582160
582221
  const realMutationPaths = realFileMutation ? this._extractToolTargetPaths(tc.name, tc.arguments, result) : [];
582161
582222
  if (realFileMutation && this._reg61PerpetualGateActive) {
@@ -582937,6 +582998,20 @@ Respond with EXACTLY this structure before your next tool call:
582937
582998
  dedupHitCount.clear();
582938
582999
  }
582939
583000
  }
583001
+ if (shellFilesystemMutation && recentToolResults.size > 0) {
583002
+ for (const key of Array.from(recentToolResults.keys())) {
583003
+ if (key.startsWith("shell:") || key.startsWith("file_read:") || key.startsWith("list_directory:") || key.startsWith("grep_search:") || key.startsWith("find_files:")) {
583004
+ recentToolResults.delete(key);
583005
+ dedupHitCount.delete(key);
583006
+ }
583007
+ }
583008
+ this._readCoverage.clear();
583009
+ this.emit({
583010
+ type: "status",
583011
+ content: "Shell filesystem mutation invalidated cached read/shell evidence",
583012
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
583013
+ });
583014
+ }
582940
583015
  if (isFileMutation && recentToolResults.size > 0) {
582941
583016
  for (const key of Array.from(recentToolResults.keys())) {
582942
583017
  if (key.startsWith("shell:"))
@@ -583334,7 +583409,7 @@ Evidence: ${evidencePreview}`.slice(0, 500);
583334
583409
  success: result.success,
583335
583410
  output: result.output ?? result.llmContent ?? "",
583336
583411
  error: result.error ?? "",
583337
- mutated: realFileMutation,
583412
+ mutated: realFileMutation || shellFilesystemMutation,
583338
583413
  isReadLike
583339
583414
  });
583340
583415
  const afterDirective = this._focusSupervisor?.snapshot().directive ?? null;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.385",
3
+ "version": "1.0.386",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.385",
9
+ "version": "1.0.386",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.385",
3
+ "version": "1.0.386",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",