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
@@ -1,4 +1,5 @@
1
1
  // src/capabilities/kernel/spec.ts
2
+ var READ_STATE_HANDLE_KEY = "readState";
2
3
  function coerceInput(raw) {
3
4
  if (typeof raw === "string") {
4
5
  const trimmed = raw.trim();
@@ -450,6 +451,55 @@ var standardBudget = {
450
451
  `
451
452
  };
452
453
 
454
+ // src/capabilities/files/read-state-gate.ts
455
+ var READ_BEFORE_EDIT_MESSAGE = "File has not been read yet. Read it first before writing to it.";
456
+ 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.";
457
+ function getReadStateHandle(ctx) {
458
+ const bag = ctx.framework;
459
+ if (!bag || typeof bag !== "object") return void 0;
460
+ const candidate = bag[READ_STATE_HANDLE_KEY];
461
+ if (!candidate || typeof candidate !== "object") return void 0;
462
+ const handle = candidate;
463
+ if (typeof handle.get !== "function" || typeof handle.set !== "function" || typeof handle.has !== "function") {
464
+ return void 0;
465
+ }
466
+ return handle;
467
+ }
468
+ async function recordReadState(ctx, absPath, handle) {
469
+ if (!handle) return;
470
+ try {
471
+ const info = await ctx.fs.stat(absPath);
472
+ const record = {
473
+ mtimeMs: Math.floor(info.modifiedMs),
474
+ size: info.size,
475
+ readAt: Date.now()
476
+ };
477
+ handle.set(absPath, record);
478
+ } catch {
479
+ }
480
+ }
481
+ async function enforceReadGate(ctx, absPath, handle) {
482
+ if (!handle) return { ok: true };
483
+ if (!handle.has(absPath)) {
484
+ return { ok: false, message: READ_BEFORE_EDIT_MESSAGE };
485
+ }
486
+ const recorded = handle.get(absPath);
487
+ if (!recorded) {
488
+ return { ok: false, message: READ_BEFORE_EDIT_MESSAGE };
489
+ }
490
+ let info;
491
+ try {
492
+ info = await ctx.fs.stat(absPath);
493
+ } catch {
494
+ return { ok: true };
495
+ }
496
+ const currentMtime = Math.floor(info.modifiedMs);
497
+ if (currentMtime > recorded.mtimeMs || info.size !== recorded.size) {
498
+ return { ok: false, message: MODIFIED_SINCE_READ_MESSAGE };
499
+ }
500
+ return { ok: true };
501
+ }
502
+
453
503
  // src/capabilities/files/read.ts
454
504
  var GUTTER_WIDTH = 6;
455
505
  var DESCRIPTION = [
@@ -552,6 +602,7 @@ var readTool = defineTool({
552
602
  const detail = err instanceof Error ? err.message : String(err);
553
603
  return failure(`Could not read ${path}: ${detail}`);
554
604
  }
605
+ await recordReadState(ctx, path, getReadStateHandle(ctx));
555
606
  const allLines = toLines(text);
556
607
  const totalLines = allLines.length;
557
608
  if (totalLines === 0) {
@@ -659,11 +710,19 @@ var writeTool = defineTool({
659
710
  async run(input, ctx) {
660
711
  const path = readPath(input?.path);
661
712
  const content = readContent(input?.content);
713
+ const handle = getReadStateHandle(ctx);
714
+ if (handle && await ctx.fs.exists(path)) {
715
+ const gate = await enforceReadGate(ctx, path, handle);
716
+ if (!gate.ok) {
717
+ return asText(gate.message, true);
718
+ }
719
+ }
662
720
  const folder = parentDir(path);
663
721
  if (folder.length > 0) {
664
722
  await ctx.fs.mkdir(folder, { recursive: true });
665
723
  }
666
724
  await ctx.fs.writeFile(path, content, "utf8");
725
+ await recordReadState(ctx, path, handle);
667
726
  const bytes = Buffer.byteLength(content, "utf8");
668
727
  const unit = bytes === 1 ? "byte" : "bytes";
669
728
  return asText(`Saved ${bytes} ${unit} to ${path}.`);
@@ -953,6 +1012,11 @@ async function runEdit(input, ctx) {
953
1012
  if (!info.isFile) {
954
1013
  return failure2(`${path} is not a regular file, so it cannot be edited.`);
955
1014
  }
1015
+ const handle = getReadStateHandle(ctx);
1016
+ const gate = await enforceReadGate(ctx, path, handle);
1017
+ if (!gate.ok) {
1018
+ return failure2(gate.message);
1019
+ }
956
1020
  const before = await ctx.fs.readFile(path, "utf8");
957
1021
  const literalHits = countLiteral(before, oldText);
958
1022
  if (literalHits > 0) {
@@ -966,6 +1030,7 @@ async function runEdit(input, ctx) {
966
1030
  return failure2(`The replacement left ${path} unchanged.`);
967
1031
  }
968
1032
  await ctx.fs.writeFile(path, after2, "utf8");
1033
+ await recordReadState(ctx, path, handle);
969
1034
  return success(path, before, after2, replaceAll ? literalHits : 1);
970
1035
  }
971
1036
  const spans = findFuzzySpans(before, oldText);
@@ -989,6 +1054,7 @@ async function runEdit(input, ctx) {
989
1054
  return failure2(`The fuzzy replacement left ${path} unchanged.`);
990
1055
  }
991
1056
  await ctx.fs.writeFile(path, after, "utf8");
1057
+ await recordReadState(ctx, path, handle);
992
1058
  return success(path, before, after, targets.length);
993
1059
  }
994
1060
  var editTool = defineTool({