indusagi 0.12.33 → 0.13.0

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/agent.js +1247 -184
  3. package/dist/ai.js +72 -4
  4. package/dist/capabilities.js +69 -2
  5. package/dist/cli.js +1353 -29
  6. package/dist/connectors-saas.js +66 -0
  7. package/dist/index.js +1353 -29
  8. package/dist/interop.js +66 -0
  9. package/dist/mcp.js +270 -363
  10. package/dist/react-ink.js +1391 -41
  11. package/dist/shell-app.js +1353 -29
  12. package/dist/smithy.js +69 -2
  13. package/dist/swarm.js +69 -2
  14. package/dist/types/capabilities/backends/node-backends.d.ts +3 -1
  15. package/dist/types/capabilities/files/read-state-gate.d.ts +69 -0
  16. package/dist/types/capabilities/files/read-state-gate.test.d.ts +14 -0
  17. package/dist/types/capabilities/kernel/context.d.ts +4 -0
  18. package/dist/types/capabilities/kernel/index.d.ts +2 -2
  19. package/dist/types/capabilities/kernel/spec.d.ts +55 -0
  20. package/dist/types/facade/bot/actions/bash.d.ts +15 -0
  21. package/dist/types/facade/bot/actions/bash.test.d.ts +1 -0
  22. package/dist/types/facade/bot/actions/checkpoint.d.ts +49 -0
  23. package/dist/types/facade/bot/actions/checkpoint.test.d.ts +1 -0
  24. package/dist/types/facade/bot/actions/edit-utils.d.ts +86 -0
  25. package/dist/types/facade/bot/actions/edit.d.ts +18 -0
  26. package/dist/types/facade/bot/actions/edit.test.d.ts +1 -0
  27. package/dist/types/facade/bot/actions/find.d.ts +2 -0
  28. package/dist/types/facade/bot/actions/find.test.d.ts +1 -0
  29. package/dist/types/facade/bot/actions/grep.d.ts +10 -0
  30. package/dist/types/facade/bot/actions/grep.test.d.ts +1 -0
  31. package/dist/types/facade/bot/actions/index.d.ts +16 -0
  32. package/dist/types/facade/bot/actions/read-state.d.ts +83 -0
  33. package/dist/types/facade/bot/actions/read-state.test.d.ts +1 -0
  34. package/dist/types/facade/bot/actions/read.d.ts +7 -0
  35. package/dist/types/facade/bot/actions/read.test.d.ts +1 -0
  36. package/dist/types/facade/bot/actions/sandbox-backend.d.ts +99 -0
  37. package/dist/types/facade/bot/actions/sandbox-backend.test.d.ts +1 -0
  38. package/dist/types/facade/bot/actions/websearch.d.ts +5 -2
  39. package/dist/types/facade/bot/actions/websearch.test.d.ts +1 -0
  40. package/dist/types/facade/bot/actions/write.d.ts +15 -0
  41. package/dist/types/facade/bot/agent-loop.d.ts +10 -0
  42. package/dist/types/facade/bot/agent-loop.test.d.ts +1 -0
  43. package/dist/types/facade/bot/agent.d.ts +9 -1
  44. package/dist/types/facade/bot/permission-gate.test.d.ts +1 -0
  45. package/dist/types/facade/bot/types.d.ts +60 -0
  46. package/dist/types/facade/mcp-core/client.d.ts +71 -15
  47. package/dist/types/facade/mcp-core/client.test.d.ts +18 -0
  48. package/dist/types/facade/mcp-core/types.d.ts +10 -0
  49. package/dist/types/facade/ml/adapters/anthropic-retry.test.d.ts +1 -0
  50. package/dist/types/facade/ml/adapters/anthropic.d.ts +17 -0
  51. package/dist/types/facade/ml/adapters/simple-options.d.ts +13 -0
  52. package/dist/types/facade/ml/adapters/simple-options.test.d.ts +1 -0
  53. package/dist/types/react-ink/components/StatusLine.d.ts +10 -1
  54. package/dist/types/react-ink/components/ToolEventBlock.d.ts +9 -1
  55. package/dist/types/react-ink/components/ToolEventBlock.test.d.ts +1 -0
  56. package/dist/types/react-ink/components/dialogs/SelectableDialog.d.ts +7 -1
  57. package/dist/types/react-ink/components/dialogs/ThemeDialog.d.ts +21 -2
  58. package/dist/types/react-ink/diff/Diff.d.ts +22 -0
  59. package/dist/types/react-ink/diff/diff.test.d.ts +1 -0
  60. package/dist/types/react-ink/diff/structured.d.ts +41 -0
  61. package/dist/types/react-ink/diff/word-diff.d.ts +27 -0
  62. package/dist/types/react-ink/index.d.ts +8 -0
  63. package/dist/types/react-ink/markdown/Markdown.d.ts +23 -0
  64. package/dist/types/react-ink/markdown/MarkdownTable.d.ts +19 -0
  65. package/dist/types/react-ink/markdown/StreamingMarkdown.d.ts +34 -0
  66. package/dist/types/react-ink/markdown/format-token.d.ts +39 -0
  67. package/dist/types/react-ink/markdown/highlight.d.ts +31 -0
  68. package/dist/types/react-ink/theme-adapter.d.ts +58 -1
  69. package/dist/types/react-ink/utils/tool-display.d.ts +17 -1
  70. package/package.json +5 -1
package/dist/interop.js CHANGED
@@ -427,6 +427,7 @@ async function startServerFleet(config) {
427
427
  }
428
428
 
429
429
  // src/capabilities/kernel/spec.ts
430
+ var READ_STATE_HANDLE_KEY = "readState";
430
431
  function coerceInput(raw) {
431
432
  if (typeof raw === "string") {
432
433
  const trimmed = raw.trim();
@@ -878,6 +879,55 @@ var standardBudget = {
878
879
  `
879
880
  };
880
881
 
882
+ // src/capabilities/files/read-state-gate.ts
883
+ var READ_BEFORE_EDIT_MESSAGE = "File has not been read yet. Read it first before writing to it.";
884
+ var MODIFIED_SINCE_READ_MESSAGE = "File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.";
885
+ function getReadStateHandle(ctx) {
886
+ const bag = ctx.framework;
887
+ if (!bag || typeof bag !== "object") return void 0;
888
+ const candidate = bag[READ_STATE_HANDLE_KEY];
889
+ if (!candidate || typeof candidate !== "object") return void 0;
890
+ const handle = candidate;
891
+ if (typeof handle.get !== "function" || typeof handle.set !== "function" || typeof handle.has !== "function") {
892
+ return void 0;
893
+ }
894
+ return handle;
895
+ }
896
+ async function recordReadState(ctx, absPath, handle) {
897
+ if (!handle) return;
898
+ try {
899
+ const info = await ctx.fs.stat(absPath);
900
+ const record = {
901
+ mtimeMs: Math.floor(info.modifiedMs),
902
+ size: info.size,
903
+ readAt: Date.now()
904
+ };
905
+ handle.set(absPath, record);
906
+ } catch {
907
+ }
908
+ }
909
+ async function enforceReadGate(ctx, absPath, handle) {
910
+ if (!handle) return { ok: true };
911
+ if (!handle.has(absPath)) {
912
+ return { ok: false, message: READ_BEFORE_EDIT_MESSAGE };
913
+ }
914
+ const recorded = handle.get(absPath);
915
+ if (!recorded) {
916
+ return { ok: false, message: READ_BEFORE_EDIT_MESSAGE };
917
+ }
918
+ let info;
919
+ try {
920
+ info = await ctx.fs.stat(absPath);
921
+ } catch {
922
+ return { ok: true };
923
+ }
924
+ const currentMtime = Math.floor(info.modifiedMs);
925
+ if (currentMtime > recorded.mtimeMs || info.size !== recorded.size) {
926
+ return { ok: false, message: MODIFIED_SINCE_READ_MESSAGE };
927
+ }
928
+ return { ok: true };
929
+ }
930
+
881
931
  // src/capabilities/files/read.ts
882
932
  var GUTTER_WIDTH = 6;
883
933
  var DESCRIPTION = [
@@ -980,6 +1030,7 @@ var readTool = defineTool({
980
1030
  const detail = err instanceof Error ? err.message : String(err);
981
1031
  return failure(`Could not read ${path}: ${detail}`);
982
1032
  }
1033
+ await recordReadState(ctx, path, getReadStateHandle(ctx));
983
1034
  const allLines = toLines(text);
984
1035
  const totalLines = allLines.length;
985
1036
  if (totalLines === 0) {
@@ -1087,11 +1138,19 @@ var writeTool = defineTool({
1087
1138
  async run(input, ctx) {
1088
1139
  const path = readPath(input?.path);
1089
1140
  const content = readContent(input?.content);
1141
+ const handle = getReadStateHandle(ctx);
1142
+ if (handle && await ctx.fs.exists(path)) {
1143
+ const gate = await enforceReadGate(ctx, path, handle);
1144
+ if (!gate.ok) {
1145
+ return asText(gate.message, true);
1146
+ }
1147
+ }
1090
1148
  const folder = parentDir(path);
1091
1149
  if (folder.length > 0) {
1092
1150
  await ctx.fs.mkdir(folder, { recursive: true });
1093
1151
  }
1094
1152
  await ctx.fs.writeFile(path, content, "utf8");
1153
+ await recordReadState(ctx, path, handle);
1095
1154
  const bytes = Buffer.byteLength(content, "utf8");
1096
1155
  const unit = bytes === 1 ? "byte" : "bytes";
1097
1156
  return asText(`Saved ${bytes} ${unit} to ${path}.`);
@@ -1381,6 +1440,11 @@ async function runEdit(input, ctx) {
1381
1440
  if (!info.isFile) {
1382
1441
  return failure2(`${path} is not a regular file, so it cannot be edited.`);
1383
1442
  }
1443
+ const handle = getReadStateHandle(ctx);
1444
+ const gate = await enforceReadGate(ctx, path, handle);
1445
+ if (!gate.ok) {
1446
+ return failure2(gate.message);
1447
+ }
1384
1448
  const before = await ctx.fs.readFile(path, "utf8");
1385
1449
  const literalHits = countLiteral(before, oldText);
1386
1450
  if (literalHits > 0) {
@@ -1394,6 +1458,7 @@ async function runEdit(input, ctx) {
1394
1458
  return failure2(`The replacement left ${path} unchanged.`);
1395
1459
  }
1396
1460
  await ctx.fs.writeFile(path, after2, "utf8");
1461
+ await recordReadState(ctx, path, handle);
1397
1462
  return success(path, before, after2, replaceAll ? literalHits : 1);
1398
1463
  }
1399
1464
  const spans = findFuzzySpans(before, oldText);
@@ -1417,6 +1482,7 @@ async function runEdit(input, ctx) {
1417
1482
  return failure2(`The fuzzy replacement left ${path} unchanged.`);
1418
1483
  }
1419
1484
  await ctx.fs.writeFile(path, after, "utf8");
1485
+ await recordReadState(ctx, path, handle);
1420
1486
  return success(path, before, after, targets.length);
1421
1487
  }
1422
1488
  var editTool = defineTool({