iosm-cli 0.2.14 → 0.2.16

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 (161) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +18 -1
  3. package/dist/cli/args.d.ts +2 -1
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +16 -3
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/core/agent-profiles.d.ts.map +1 -1
  8. package/dist/core/agent-profiles.js +3 -0
  9. package/dist/core/agent-profiles.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +2 -0
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +26 -10
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/agent-teams.d.ts.map +1 -1
  15. package/dist/core/agent-teams.js +12 -9
  16. package/dist/core/agent-teams.js.map +1 -1
  17. package/dist/core/checkpoint/fs-checkpoint.d.ts +14 -0
  18. package/dist/core/checkpoint/fs-checkpoint.d.ts.map +1 -0
  19. package/dist/core/checkpoint/fs-checkpoint.js +211 -0
  20. package/dist/core/checkpoint/fs-checkpoint.js.map +1 -0
  21. package/dist/core/command-dispatcher.d.ts +2 -0
  22. package/dist/core/command-dispatcher.d.ts.map +1 -1
  23. package/dist/core/command-dispatcher.js +78 -13
  24. package/dist/core/command-dispatcher.js.map +1 -1
  25. package/dist/core/mcp/cli.d.ts.map +1 -1
  26. package/dist/core/mcp/cli.js +26 -0
  27. package/dist/core/mcp/cli.js.map +1 -1
  28. package/dist/core/mcp/config.d.ts.map +1 -1
  29. package/dist/core/mcp/config.js +55 -0
  30. package/dist/core/mcp/config.js.map +1 -1
  31. package/dist/core/mcp/index.d.ts +1 -1
  32. package/dist/core/mcp/index.d.ts.map +1 -1
  33. package/dist/core/mcp/index.js.map +1 -1
  34. package/dist/core/mcp/runtime.d.ts +3 -1
  35. package/dist/core/mcp/runtime.d.ts.map +1 -1
  36. package/dist/core/mcp/runtime.js +21 -2
  37. package/dist/core/mcp/runtime.js.map +1 -1
  38. package/dist/core/mcp/types.d.ts +30 -2
  39. package/dist/core/mcp/types.d.ts.map +1 -1
  40. package/dist/core/mcp/types.js.map +1 -1
  41. package/dist/core/package-manager.d.ts +10 -0
  42. package/dist/core/package-manager.d.ts.map +1 -1
  43. package/dist/core/package-manager.js +100 -2
  44. package/dist/core/package-manager.js.map +1 -1
  45. package/dist/core/policy/engine.d.ts +77 -0
  46. package/dist/core/policy/engine.d.ts.map +1 -0
  47. package/dist/core/policy/engine.js +614 -0
  48. package/dist/core/policy/engine.js.map +1 -0
  49. package/dist/core/policy/index.d.ts +2 -0
  50. package/dist/core/policy/index.d.ts.map +1 -0
  51. package/dist/core/policy/index.js +2 -0
  52. package/dist/core/policy/index.js.map +1 -0
  53. package/dist/core/sandbox/executor.d.ts +13 -0
  54. package/dist/core/sandbox/executor.d.ts.map +1 -0
  55. package/dist/core/sandbox/executor.js +64 -0
  56. package/dist/core/sandbox/executor.js.map +1 -0
  57. package/dist/core/sdk.d.ts +2 -2
  58. package/dist/core/sdk.d.ts.map +1 -1
  59. package/dist/core/sdk.js +3 -3
  60. package/dist/core/sdk.js.map +1 -1
  61. package/dist/core/security/index.d.ts +3 -0
  62. package/dist/core/security/index.d.ts.map +1 -0
  63. package/dist/core/security/index.js +3 -0
  64. package/dist/core/security/index.js.map +1 -0
  65. package/dist/core/security/source-security.d.ts +43 -0
  66. package/dist/core/security/source-security.d.ts.map +1 -0
  67. package/dist/core/security/source-security.js +94 -0
  68. package/dist/core/security/source-security.js.map +1 -0
  69. package/dist/core/security/trust-ledger.d.ts +24 -0
  70. package/dist/core/security/trust-ledger.d.ts.map +1 -0
  71. package/dist/core/security/trust-ledger.js +66 -0
  72. package/dist/core/security/trust-ledger.js.map +1 -0
  73. package/dist/core/session-manager.d.ts.map +1 -1
  74. package/dist/core/session-manager.js +128 -15
  75. package/dist/core/session-manager.js.map +1 -1
  76. package/dist/core/settings-manager.d.ts +6 -0
  77. package/dist/core/settings-manager.d.ts.map +1 -1
  78. package/dist/core/settings-manager.js +22 -1
  79. package/dist/core/settings-manager.js.map +1 -1
  80. package/dist/core/system-prompt.d.ts.map +1 -1
  81. package/dist/core/system-prompt.js +9 -2
  82. package/dist/core/system-prompt.js.map +1 -1
  83. package/dist/core/task-plan.d.ts +1 -0
  84. package/dist/core/task-plan.d.ts.map +1 -1
  85. package/dist/core/task-plan.js +103 -0
  86. package/dist/core/task-plan.js.map +1 -1
  87. package/dist/core/tools/apply-patch.d.ts +29 -0
  88. package/dist/core/tools/apply-patch.d.ts.map +1 -0
  89. package/dist/core/tools/apply-patch.js +167 -0
  90. package/dist/core/tools/apply-patch.js.map +1 -0
  91. package/dist/core/tools/bash.d.ts.map +1 -1
  92. package/dist/core/tools/bash.js +15 -1
  93. package/dist/core/tools/bash.js.map +1 -1
  94. package/dist/core/tools/git-common.d.ts.map +1 -1
  95. package/dist/core/tools/git-common.js +15 -1
  96. package/dist/core/tools/git-common.js.map +1 -1
  97. package/dist/core/tools/index.d.ts +20 -2
  98. package/dist/core/tools/index.d.ts.map +1 -1
  99. package/dist/core/tools/index.js +85 -25
  100. package/dist/core/tools/index.js.map +1 -1
  101. package/dist/core/tools/permissions.d.ts +16 -0
  102. package/dist/core/tools/permissions.d.ts.map +1 -1
  103. package/dist/core/tools/permissions.js +34 -1
  104. package/dist/core/tools/permissions.js.map +1 -1
  105. package/dist/core/tools/task.d.ts.map +1 -1
  106. package/dist/core/tools/task.js +68 -24
  107. package/dist/core/tools/task.js.map +1 -1
  108. package/dist/core/tools/tool-search.d.ts +24 -0
  109. package/dist/core/tools/tool-search.d.ts.map +1 -0
  110. package/dist/core/tools/tool-search.js +85 -0
  111. package/dist/core/tools/tool-search.js.map +1 -0
  112. package/dist/core/tools/tool-suggest.d.ts +18 -0
  113. package/dist/core/tools/tool-suggest.d.ts.map +1 -0
  114. package/dist/core/tools/tool-suggest.js +94 -0
  115. package/dist/core/tools/tool-suggest.js.map +1 -0
  116. package/dist/core/tools/verification-runner.d.ts.map +1 -1
  117. package/dist/core/tools/verification-runner.js +15 -1
  118. package/dist/core/tools/verification-runner.js.map +1 -1
  119. package/dist/core/unified-exec.d.ts +39 -0
  120. package/dist/core/unified-exec.d.ts.map +1 -0
  121. package/dist/core/unified-exec.js +286 -0
  122. package/dist/core/unified-exec.js.map +1 -0
  123. package/dist/main.d.ts.map +1 -1
  124. package/dist/main.js +93 -11
  125. package/dist/main.js.map +1 -1
  126. package/dist/modes/acp/acp-mode.d.ts +17 -0
  127. package/dist/modes/acp/acp-mode.d.ts.map +1 -0
  128. package/dist/modes/acp/acp-mode.js +352 -0
  129. package/dist/modes/acp/acp-mode.js.map +1 -0
  130. package/dist/modes/index.d.ts +2 -1
  131. package/dist/modes/index.d.ts.map +1 -1
  132. package/dist/modes/index.js +1 -0
  133. package/dist/modes/index.js.map +1 -1
  134. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  135. package/dist/modes/interactive/components/tool-execution.js +217 -0
  136. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  137. package/dist/modes/interactive/interactive-mode.d.ts +8 -0
  138. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  139. package/dist/modes/interactive/interactive-mode.js +159 -72
  140. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  141. package/dist/modes/rpc/rpc-client.d.ts +25 -1
  142. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  143. package/dist/modes/rpc/rpc-client.js +33 -0
  144. package/dist/modes/rpc/rpc-client.js.map +1 -1
  145. package/dist/modes/rpc/rpc-mode.d.ts +13 -1
  146. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  147. package/dist/modes/rpc/rpc-mode.js +189 -28
  148. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  149. package/dist/modes/rpc/rpc-types.d.ts +54 -1
  150. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  151. package/dist/modes/rpc/rpc-types.js.map +1 -1
  152. package/dist/modes/telegram/telegram-bridge-mode.js +51 -22
  153. package/dist/modes/telegram/telegram-bridge-mode.js.map +1 -1
  154. package/dist/utils/tools-manager.d.ts.map +1 -1
  155. package/dist/utils/tools-manager.js +96 -9
  156. package/dist/utils/tools-manager.js.map +1 -1
  157. package/docs/README.md +2 -0
  158. package/docs/acp-rpc-mapping.md +38 -0
  159. package/docs/configuration.generated.md +81 -0
  160. package/docs/configuration.md +7 -0
  161. package/package.json +4 -1
@@ -7,6 +7,7 @@ import ignore from "ignore";
7
7
  import { minimatch } from "minimatch";
8
8
  import { CONFIG_DIR_NAME, ENV_OFFLINE } from "../config.js";
9
9
  import { parseGitUrl } from "../utils/git.js";
10
+ import { SourceSecurityManager } from "./security/index.js";
10
11
  const NETWORK_TIMEOUT_MS = 10000;
11
12
  function isOfflineModeEnabled() {
12
13
  const value = process.env[ENV_OFFLINE] || process.env.PI_OFFLINE;
@@ -500,6 +501,14 @@ export class DefaultPackageManager {
500
501
  this.cwd = options.cwd;
501
502
  this.agentDir = options.agentDir;
502
503
  this.settingsManager = options.settingsManager;
504
+ this.sourceSecurityManager =
505
+ options.sourceSecurityManager ??
506
+ new SourceSecurityManager({
507
+ agentDir: this.agentDir,
508
+ allowedHosts: options.allowedSourceHosts,
509
+ consentProvider: options.trustConsentProvider,
510
+ });
511
+ this.allowNonInteractiveTrustOverride = options.allowNonInteractiveTrustOverride ?? false;
503
512
  }
504
513
  setProgressCallback(callback) {
505
514
  this.progressCallback = callback;
@@ -679,7 +688,7 @@ export class DefaultPackageManager {
679
688
  if (parsed.pinned)
680
689
  return;
681
690
  await this.withProgress("update", source, `Updating ${source}...`, async () => {
682
- await this.installNpm(parsed, scope, false);
691
+ await this.installNpm(parsed, scope, false, "update");
683
692
  });
684
693
  return;
685
694
  }
@@ -948,7 +957,92 @@ export class DefaultPackageManager {
948
957
  const version = match[2];
949
958
  return { name, version };
950
959
  }
951
- async installNpm(source, scope, temporary) {
960
+ async ensureSourceTrust(sourceRaw, parsed, action, options) {
961
+ if (parsed.type === "local") {
962
+ return;
963
+ }
964
+ if (parsed.type === "npm") {
965
+ const fingerprint = await this.resolveNpmFingerprint(parsed);
966
+ await this.sourceSecurityManager.verify({
967
+ action,
968
+ sourceType: "npm",
969
+ source: sourceRaw,
970
+ identity: fingerprint.identity,
971
+ host: fingerprint.host,
972
+ fingerprint: fingerprint.fingerprint,
973
+ allowOverride: this.allowNonInteractiveTrustOverride,
974
+ });
975
+ return;
976
+ }
977
+ const gitFingerprint = this.resolveGitFingerprint(parsed, options?.repositoryDir);
978
+ await this.sourceSecurityManager.verify({
979
+ action,
980
+ sourceType: "git",
981
+ source: sourceRaw,
982
+ identity: gitFingerprint.identity,
983
+ host: gitFingerprint.host,
984
+ fingerprint: gitFingerprint.fingerprint,
985
+ allowOverride: this.allowNonInteractiveTrustOverride,
986
+ });
987
+ }
988
+ async resolveNpmFingerprint(source) {
989
+ const { name, version } = this.parseNpmSpec(source.spec);
990
+ const encodedName = encodeURIComponent(name).replace("%40", "@");
991
+ const endpoint = version
992
+ ? `https://registry.npmjs.org/${encodedName}/${encodeURIComponent(version)}`
993
+ : `https://registry.npmjs.org/${encodedName}/latest`;
994
+ const response = await fetch(endpoint, {
995
+ signal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),
996
+ });
997
+ if (!response.ok) {
998
+ throw new Error(`Failed to resolve npm package metadata for ${name}: ${response.status}`);
999
+ }
1000
+ const payload = (await response.json());
1001
+ const resolvedName = payload.name ?? name;
1002
+ const resolvedVersion = payload.version ?? version ?? "unknown";
1003
+ const integrity = payload.dist?.integrity?.trim();
1004
+ const tarball = payload.dist?.tarball?.trim();
1005
+ if (!integrity && !tarball) {
1006
+ throw new Error(`npm integrity metadata is missing for ${resolvedName}@${resolvedVersion}`);
1007
+ }
1008
+ return {
1009
+ identity: `${resolvedName}@${resolvedVersion}`,
1010
+ fingerprint: integrity ?? `tarball:${tarball}`,
1011
+ host: "registry.npmjs.org",
1012
+ };
1013
+ }
1014
+ resolveGitFingerprint(source, repositoryDir) {
1015
+ let lsRemote;
1016
+ if (repositoryDir && existsSync(join(repositoryDir, ".git"))) {
1017
+ lsRemote = spawnSync("git", ["ls-remote", "origin", "HEAD"], {
1018
+ encoding: "utf8",
1019
+ timeout: NETWORK_TIMEOUT_MS,
1020
+ cwd: repositoryDir,
1021
+ });
1022
+ }
1023
+ if (!lsRemote || lsRemote.status !== 0) {
1024
+ lsRemote = spawnSync("git", ["ls-remote", source.repo, "HEAD"], {
1025
+ encoding: "utf8",
1026
+ timeout: NETWORK_TIMEOUT_MS,
1027
+ });
1028
+ }
1029
+ if (lsRemote.status !== 0) {
1030
+ const stderr = typeof lsRemote.stderr === "string" ? lsRemote.stderr.trim() : "";
1031
+ throw new Error(`Failed to resolve git fingerprint for ${source.repo}: ${stderr || "git ls-remote failed"}`);
1032
+ }
1033
+ const output = typeof lsRemote.stdout === "string" ? lsRemote.stdout.trim() : "";
1034
+ const commit = output.split(/\s+/)[0];
1035
+ if (!commit) {
1036
+ throw new Error(`Failed to parse git fingerprint for ${source.repo}`);
1037
+ }
1038
+ return {
1039
+ identity: `${source.host}/${source.path}`,
1040
+ fingerprint: commit,
1041
+ host: source.host.toLowerCase(),
1042
+ };
1043
+ }
1044
+ async installNpm(source, scope, temporary, action = "install") {
1045
+ await this.ensureSourceTrust(`npm:${source.spec}`, source, action);
952
1046
  if (scope === "user" && !temporary) {
953
1047
  await this.runCommand("npm", ["install", "-g", source.spec]);
954
1048
  return;
@@ -969,6 +1063,7 @@ export class DefaultPackageManager {
969
1063
  await this.runCommand("npm", ["uninstall", source.name, "--prefix", installRoot]);
970
1064
  }
971
1065
  async installGit(source, scope) {
1066
+ await this.ensureSourceTrust(source.repo, source, "install");
972
1067
  const targetDir = this.getGitInstallPath(source, scope);
973
1068
  if (existsSync(targetDir)) {
974
1069
  return;
@@ -993,6 +1088,9 @@ export class DefaultPackageManager {
993
1088
  await this.installGit(source, scope);
994
1089
  return;
995
1090
  }
1091
+ if (scope !== "temporary") {
1092
+ await this.ensureSourceTrust(source.repo, source, "update", { repositoryDir: targetDir });
1093
+ }
996
1094
  // Fetch latest from remote (handles force-push by getting new history)
997
1095
  await this.runCommand("git", ["fetch", "--prune", "origin"], { cwd: targetDir });
998
1096
  // Reset to tracking branch. Fall back to origin/HEAD when no upstream is configured.