@psnext/slingcli 2.5.20260607-2 → 2.5.20260615-2

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 (205) hide show
  1. package/node_modules/@aws-sdk/core/dist-cjs/index.js +47 -2297
  2. package/node_modules/@aws-sdk/core/dist-es/index.js +3 -3
  3. package/node_modules/@aws-sdk/core/dist-types/index.d.ts +5 -5
  4. package/node_modules/@aws-sdk/core/dist-types/ts3.4/index.d.ts +5 -5
  5. package/node_modules/@aws-sdk/core/package.json +8 -8
  6. package/node_modules/@aws-sdk/credential-provider-env/package.json +4 -4
  7. package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/package.json +7 -7
  8. package/node_modules/@aws-sdk/credential-provider-http/package.json +6 -5
  9. package/node_modules/@aws-sdk/credential-provider-ini/package.json +11 -11
  10. package/node_modules/@aws-sdk/credential-provider-login/package.json +5 -5
  11. package/node_modules/@aws-sdk/credential-provider-node/package.json +9 -9
  12. package/node_modules/@aws-sdk/credential-provider-process/package.json +4 -4
  13. package/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/index.js +4 -1
  14. package/node_modules/@aws-sdk/credential-provider-sso/dist-es/resolveSSOCredentials.js +4 -1
  15. package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/package.json +5 -5
  16. package/node_modules/@aws-sdk/credential-provider-sso/package.json +9 -7
  17. package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +5 -5
  18. package/node_modules/@aws-sdk/eventstream-handler-node/package.json +3 -3
  19. package/node_modules/@aws-sdk/middleware-eventstream/package.json +3 -3
  20. package/node_modules/@aws-sdk/middleware-websocket/package.json +5 -5
  21. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +1 -1
  22. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +1 -1
  23. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +1 -1
  24. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +1 -1
  25. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +1 -1
  26. package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/package.json +7 -7
  27. package/node_modules/@aws-sdk/nested-clients/package.json +6 -6
  28. package/node_modules/@aws-sdk/signature-v4-multi-region/package.json +7 -6
  29. package/node_modules/@aws-sdk/types/package.json +2 -2
  30. package/node_modules/@aws-sdk/util-locate-window/package.json +2 -2
  31. package/node_modules/@aws-sdk/xml-builder/package.json +2 -2
  32. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
  33. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -1
  34. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  35. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +6 -6
  36. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +906 -873
  37. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +25 -8
  38. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +19 -12
  39. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +1 -0
  40. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +8 -4
  41. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +2 -1
  42. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +2 -1
  43. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +1 -0
  44. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +1 -1
  45. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -2
  46. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  47. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +3 -5
  48. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.js +48 -0
  49. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.js +133 -0
  50. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +14 -3
  51. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js +4 -1
  52. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +2 -2
  53. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +9 -2
  54. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.js +1 -1
  55. package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js +4 -0
  56. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js +4 -4
  57. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js +34 -0
  58. package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.js +1 -0
  59. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +5 -57
  60. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +41 -5
  61. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +31 -17
  62. package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js +58 -0
  63. package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js +24 -26
  64. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js +0 -4
  65. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +121 -54
  66. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +11 -2
  67. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +26 -0
  68. package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js +89 -17
  69. package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -2
  70. package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +65 -76
  71. package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js +1 -118
  72. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.js +103 -0
  73. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js +1 -0
  74. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +7 -1
  75. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +20 -0
  76. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +87 -12
  77. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.js +23 -18
  78. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +104 -30
  79. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js +19 -41
  80. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +72 -18
  81. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +78 -0
  82. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.js +4 -27
  83. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/LICENSE +15 -0
  84. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/bin/semver.js +195 -0
  85. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/comparator.js +143 -0
  86. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/index.js +7 -0
  87. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/range.js +557 -0
  88. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/semver.js +333 -0
  89. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/clean.js +8 -0
  90. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/cmp.js +54 -0
  91. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/coerce.js +62 -0
  92. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-build.js +9 -0
  93. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-loose.js +5 -0
  94. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare.js +7 -0
  95. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/diff.js +60 -0
  96. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/eq.js +5 -0
  97. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gt.js +5 -0
  98. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gte.js +5 -0
  99. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/inc.js +21 -0
  100. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lt.js +5 -0
  101. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lte.js +5 -0
  102. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/major.js +5 -0
  103. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/minor.js +5 -0
  104. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/neq.js +5 -0
  105. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/parse.js +18 -0
  106. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/patch.js +5 -0
  107. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/prerelease.js +8 -0
  108. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rcompare.js +5 -0
  109. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rsort.js +5 -0
  110. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/satisfies.js +12 -0
  111. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/sort.js +5 -0
  112. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/truncate.js +48 -0
  113. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/valid.js +8 -0
  114. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/index.js +93 -0
  115. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/constants.js +37 -0
  116. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/debug.js +11 -0
  117. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/identifiers.js +29 -0
  118. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/lrucache.js +42 -0
  119. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/parse-options.js +17 -0
  120. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/re.js +223 -0
  121. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/package.json +78 -0
  122. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/preload.js +4 -0
  123. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/range.bnf +17 -0
  124. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/gtr.js +6 -0
  125. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/intersects.js +9 -0
  126. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/ltr.js +6 -0
  127. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/max-satisfying.js +27 -0
  128. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-satisfying.js +26 -0
  129. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-version.js +63 -0
  130. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/outside.js +82 -0
  131. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/simplify.js +49 -0
  132. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/subset.js +249 -0
  133. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/to-comparators.js +10 -0
  134. package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/valid.js +13 -0
  135. package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +25 -12
  136. package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -8
  137. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +102 -43
  138. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +11 -1
  139. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
  140. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -0
  141. package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.js +51 -0
  142. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +38 -77
  143. package/node_modules/@earendil-works/pi-tui/dist/tui.js +145 -21
  144. package/node_modules/@earendil-works/pi-tui/dist/utils.js +44 -16
  145. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  146. package/node_modules/@nodable/entities/package.json +4 -1
  147. package/node_modules/@nodable/entities/src/EntityDecoder.js +104 -3
  148. package/node_modules/@nodable/entities/src/index.d.ts +77 -0
  149. package/node_modules/@nodable/entities/src/index.js +1 -1
  150. package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.browser.js +3 -3
  151. package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.js +3 -3
  152. package/node_modules/@smithy/core/dist-es/submodules/retry/middleware-retry/retry-pre-sra-deprecated/StandardRetryStrategy.js +2 -2
  153. package/node_modules/@smithy/core/dist-es/submodules/retry/util-retry/DefaultRateLimiter.js +1 -1
  154. package/node_modules/@smithy/core/package.json +17 -17
  155. package/node_modules/@smithy/credential-provider-imds/package.json +6 -6
  156. package/node_modules/@smithy/fetch-http-handler/package.json +9 -9
  157. package/node_modules/@smithy/signature-v4/package.json +6 -6
  158. package/node_modules/@smithy/types/package.json +9 -9
  159. package/node_modules/@types/node/README.md +1 -1
  160. package/node_modules/@types/node/http2.d.ts +1 -0
  161. package/node_modules/@types/node/package.json +2 -2
  162. package/node_modules/anynum/LICENSE +21 -0
  163. package/node_modules/anynum/README.md +142 -0
  164. package/node_modules/anynum/anynum.js +135 -0
  165. package/node_modules/anynum/digitTable.js +116 -0
  166. package/node_modules/anynum/package.json +42 -0
  167. package/node_modules/protobufjs/dist/light/protobuf.js +161 -203
  168. package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
  169. package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
  170. package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
  171. package/node_modules/protobufjs/dist/minimal/protobuf.js +34 -77
  172. package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
  173. package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
  174. package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
  175. package/node_modules/protobufjs/dist/protobuf.js +181 -223
  176. package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
  177. package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
  178. package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
  179. package/node_modules/protobufjs/index.d.ts +0 -8
  180. package/node_modules/protobufjs/package.json +2 -3
  181. package/node_modules/protobufjs/src/converter.js +5 -4
  182. package/node_modules/protobufjs/src/decoder.js +1 -1
  183. package/node_modules/protobufjs/src/service.js +5 -7
  184. package/node_modules/protobufjs/src/type.js +3 -1
  185. package/node_modules/protobufjs/src/util/minimal.js +1 -4
  186. package/node_modules/protobufjs/src/verifier.js +1 -1
  187. package/node_modules/semver/classes/range.js +11 -2
  188. package/node_modules/semver/package.json +2 -2
  189. package/node_modules/strnum/CHANGELOG.md +8 -0
  190. package/node_modules/strnum/README.md +9 -0
  191. package/node_modules/strnum/package.json +4 -1
  192. package/node_modules/strnum/strnum.js +9 -1
  193. package/package.json +6 -6
  194. package/slingshot/index.js +260 -258
  195. package/node_modules/@protobufjs/inquire/CHANGELOG.md +0 -8
  196. package/node_modules/@protobufjs/inquire/LICENSE +0 -26
  197. package/node_modules/@protobufjs/inquire/README.md +0 -13
  198. package/node_modules/@protobufjs/inquire/index.d.ts +0 -10
  199. package/node_modules/@protobufjs/inquire/index.js +0 -38
  200. package/node_modules/@protobufjs/inquire/package.json +0 -21
  201. package/node_modules/@protobufjs/inquire/tests/data/array.js +0 -1
  202. package/node_modules/@protobufjs/inquire/tests/data/emptyArray.js +0 -1
  203. package/node_modules/@protobufjs/inquire/tests/data/emptyObject.js +0 -1
  204. package/node_modules/@protobufjs/inquire/tests/data/object.js +0 -1
  205. package/node_modules/@protobufjs/inquire/tests/index.js +0 -20
@@ -56,6 +56,34 @@ export async function emitSessionShutdownEvent(extensionRunner, event) {
56
56
  }
57
57
  return false;
58
58
  }
59
+ export async function emitProjectTrustEvent(extensionsResult, event, ctx) {
60
+ const errors = [];
61
+ for (const ext of extensionsResult.extensions) {
62
+ // A single extension may register multiple handlers for the same event.
63
+ // The first project_trust handler that returns yes/no wins; undecided falls through.
64
+ const handlers = ext.handlers.get("project_trust");
65
+ if (!handlers || handlers.length === 0)
66
+ continue;
67
+ for (const handler of handlers) {
68
+ try {
69
+ const handlerResult = (await handler(event, ctx));
70
+ if (handlerResult.trusted === "undecided") {
71
+ continue;
72
+ }
73
+ return { result: handlerResult, errors };
74
+ }
75
+ catch (error) {
76
+ errors.push({
77
+ extensionPath: ext.path,
78
+ event: event.type,
79
+ error: error instanceof Error ? error.message : String(error),
80
+ stack: error instanceof Error ? error.stack : undefined,
81
+ });
82
+ }
83
+ }
84
+ }
85
+ return { errors };
86
+ }
59
87
  const noOpUIContext = {
60
88
  select: async () => undefined,
61
89
  confirm: async () => false,
@@ -99,6 +127,7 @@ export class ExtensionRunner {
99
127
  errorListeners = new Set();
100
128
  getModel = () => undefined;
101
129
  isIdleFn = () => true;
130
+ isProjectTrustedFn = () => true;
102
131
  getSignalFn = () => undefined;
103
132
  waitForIdleFn = async () => { };
104
133
  abortFn = () => { };
@@ -143,6 +172,7 @@ export class ExtensionRunner {
143
172
  // Context actions (required)
144
173
  this.getModel = contextActions.getModel;
145
174
  this.isIdleFn = contextActions.isIdle;
175
+ this.isProjectTrustedFn = contextActions.isProjectTrusted;
146
176
  this.getSignalFn = contextActions.getSignal;
147
177
  this.abortFn = contextActions.abort;
148
178
  this.hasPendingMessagesFn = contextActions.hasPendingMessages;
@@ -414,6 +444,10 @@ export class ExtensionRunner {
414
444
  runner.assertActive();
415
445
  return runner.isIdleFn();
416
446
  },
447
+ isProjectTrusted: () => {
448
+ runner.assertActive();
449
+ return runner.isProjectTrustedFn();
450
+ },
417
451
  get signal() {
418
452
  runner.assertActive();
419
453
  return runner.getSignalFn();
@@ -6,6 +6,7 @@ export { AgentSessionRuntime, createAgentSessionRuntime, } from "./agent-session
6
6
  export { createAgentSessionFromServices, createAgentSessionServices, } from "./agent-session-services.js";
7
7
  export { executeBashWithOperations } from "./bash-executor.js";
8
8
  export { createEventBus } from "./event-bus.js";
9
+ export { areExperimentalFeaturesEnabled } from "./experimental.js";
9
10
  // Extensions system
10
11
  export { defineTool, discoverAndLoadExtensions, ExtensionRunner, } from "./extensions/index.js";
11
12
  export { createSyntheticSourceInfo } from "./source-info.js";
@@ -8,11 +8,10 @@ import { join } from "path";
8
8
  import { Type } from "typebox";
9
9
  import { Compile } from "typebox/compile";
10
10
  import { getAgentDir } from "../config.js";
11
- import { warnDeprecation } from "../utils/deprecation.js";
12
11
  import { stripJsonComments } from "../utils/json.js";
13
12
  import { normalizePath } from "../utils/paths.js";
14
13
  import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "./provider-display-names.js";
15
- import { clearConfigValueCache, getConfigValueEnvVarNames, isCommandConfigValue, isConfigValueConfigured, isLegacyEnvVarNameConfigValue, resolveConfigValueOrThrow, resolveConfigValueUncached, resolveHeadersOrThrow, } from "./resolve-config-value.js";
14
+ import { clearConfigValueCache, getConfigValueEnvVarNames, isCommandConfigValue, isConfigValueConfigured, resolveConfigValueOrThrow, resolveConfigValueUncached, resolveHeadersOrThrow, } from "./resolve-config-value.js";
16
15
  // Schema for OpenRouter routing preferences
17
16
  const PercentileCutoffsSchema = Type.Object({
18
17
  p50: Type.Optional(Type.Number()),
@@ -88,6 +87,7 @@ const OpenAICompletionsCompatSchema = Type.Object({
88
87
  supportsLongCacheRetention: Type.Optional(Type.Boolean()),
89
88
  });
90
89
  const OpenAIResponsesCompatSchema = Type.Object({
90
+ supportsDeveloperRole: Type.Optional(Type.Boolean()),
91
91
  sendSessionIdHeader: Type.Optional(Type.Boolean()),
92
92
  supportsLongCacheRetention: Type.Optional(Type.Boolean()),
93
93
  });
@@ -168,57 +168,6 @@ function formatValidationPath(error) {
168
168
  const path = error.instancePath.replace(/^\//, "").replace(/\//g, ".");
169
169
  return path || "root";
170
170
  }
171
- function migrateLegacyRegisterProviderConfigValue(providerName, field, value) {
172
- if (!isLegacyEnvVarNameConfigValue(value))
173
- return value;
174
- warnDeprecation(`registerProvider("${providerName}") ${field} value "${value}" is treated as a legacy environment variable reference. This will no longer be detected as an environment variable reference in a future release. Pass "$${value}" instead.`);
175
- return `$${value}`;
176
- }
177
- function migrateLegacyRegisterProviderHeaders(providerName, field, headers) {
178
- if (!headers)
179
- return undefined;
180
- let migratedHeaders;
181
- for (const [key, value] of Object.entries(headers)) {
182
- const migratedValue = migrateLegacyRegisterProviderConfigValue(providerName, `${field} header "${key}"`, value);
183
- if (migratedValue === value)
184
- continue;
185
- migratedHeaders ??= { ...headers };
186
- migratedHeaders[key] = migratedValue;
187
- }
188
- return migratedHeaders ?? headers;
189
- }
190
- function migrateLegacyRegisterProviderConfigValues(providerName, config) {
191
- let migratedConfig;
192
- const setMigratedConfigValue = (key, value) => {
193
- migratedConfig ??= { ...config };
194
- migratedConfig[key] = value;
195
- };
196
- if (config.apiKey) {
197
- const apiKey = migrateLegacyRegisterProviderConfigValue(providerName, "apiKey", config.apiKey);
198
- if (apiKey !== config.apiKey) {
199
- setMigratedConfigValue("apiKey", apiKey);
200
- }
201
- }
202
- const headers = migrateLegacyRegisterProviderHeaders(providerName, "headers", config.headers);
203
- if (headers !== config.headers) {
204
- setMigratedConfigValue("headers", headers);
205
- }
206
- if (config.models) {
207
- let models;
208
- for (let index = 0; index < config.models.length; index++) {
209
- const model = config.models[index];
210
- const modelHeaders = migrateLegacyRegisterProviderHeaders(providerName, `model "${model.id}" headers`, model.headers);
211
- if (modelHeaders === model.headers)
212
- continue;
213
- models ??= [...config.models];
214
- models[index] = { ...model, headers: modelHeaders };
215
- }
216
- if (models) {
217
- setMigratedConfigValue("models", models);
218
- }
219
- }
220
- return migratedConfig ?? config;
221
- }
222
171
  function emptyCustomModelsResult(error) {
223
172
  return { models: [], overrides: new Map(), modelOverrides: new Map(), error };
224
173
  }
@@ -660,10 +609,9 @@ export class ModelRegistry {
660
609
  * If provider has oauth: registers OAuth provider for /login support.
661
610
  */
662
611
  registerProvider(providerName, config) {
663
- const migratedConfig = migrateLegacyRegisterProviderConfigValues(providerName, config);
664
- this.validateProviderConfig(providerName, migratedConfig);
665
- this.applyProviderConfig(providerName, migratedConfig);
666
- this.upsertRegisteredProvider(providerName, migratedConfig);
612
+ this.validateProviderConfig(providerName, config);
613
+ this.applyProviderConfig(providerName, config);
614
+ this.upsertRegisteredProvider(providerName, config);
667
615
  }
668
616
  /**
669
617
  * Unregister a previously registered provider.
@@ -267,7 +267,7 @@ export async function resolveModelScope(patterns, modelRegistry) {
267
267
  * return a thinking level from "<pattern>:<thinking>" so the caller can apply it.
268
268
  */
269
269
  export function resolveCliModel(options) {
270
- const { cliProvider, cliModel, modelRegistry } = options;
270
+ const { cliProvider, cliModel, cliThinking, modelRegistry } = options;
271
271
  if (!cliModel) {
272
272
  return { model: undefined, warning: undefined, error: undefined };
273
273
  }
@@ -334,6 +334,25 @@ export function resolveCliModel(options) {
334
334
  allowInvalidThinkingLevelFallback: false,
335
335
  });
336
336
  if (model) {
337
+ // If provider inference matched an unauthenticated provider/model pair, prefer
338
+ // one exact raw model-id match that is authenticated. This keeps
339
+ // "provider/model" syntax preferred when usable, but handles models whose
340
+ // literal id starts with a known provider name (for example
341
+ // commandcode model id "xiaomi/mimo-v2.5-pro").
342
+ if (inferredProvider) {
343
+ const rawExactMatches = availableModels.filter((m) => m.id.toLowerCase() === cliModel.toLowerCase() && !modelsAreEqual(m, model));
344
+ if (rawExactMatches.length > 0 && !modelRegistry.hasConfiguredAuth(model)) {
345
+ const authenticatedRawMatches = rawExactMatches.filter((m) => modelRegistry.hasConfiguredAuth(m));
346
+ if (authenticatedRawMatches.length === 1) {
347
+ return {
348
+ model: authenticatedRawMatches[0],
349
+ thinkingLevel: undefined,
350
+ warning: undefined,
351
+ error: undefined,
352
+ };
353
+ }
354
+ }
355
+ }
337
356
  return { model, thinkingLevel, warning, error: undefined };
338
357
  }
339
358
  // If we inferred a provider from the slash but found no match within that provider,
@@ -360,12 +379,29 @@ export function resolveCliModel(options) {
360
379
  }
361
380
  }
362
381
  if (provider) {
363
- const fallbackModel = buildFallbackModel(provider, pattern, availableModels);
382
+ // Parse thinking level suffix from the pattern before building the fallback model,
383
+ // but only when --thinking is not explicitly provided.
384
+ // e.g. "zai-org/GLM-5.1-FP8:high" → modelId="zai-org/GLM-5.1-FP8", fallbackThinking="high"
385
+ let fallbackPattern = pattern;
386
+ let fallbackThinking;
387
+ if (!cliThinking) {
388
+ const lastColon = pattern.lastIndexOf(":");
389
+ if (lastColon !== -1) {
390
+ const suffix = pattern.substring(lastColon + 1);
391
+ if (isValidThinkingLevel(suffix)) {
392
+ fallbackPattern = pattern.substring(0, lastColon);
393
+ fallbackThinking = suffix;
394
+ }
395
+ }
396
+ }
397
+ const fallbackModel = buildFallbackModel(provider, fallbackPattern, availableModels);
364
398
  if (fallbackModel) {
399
+ const requestedThinking = cliThinking ?? fallbackThinking;
400
+ const model = requestedThinking && requestedThinking !== "off" ? { ...fallbackModel, reasoning: true } : fallbackModel;
365
401
  const fallbackWarning = warning
366
- ? `${warning} Model "${pattern}" not found for provider "${provider}". Using custom model id.`
367
- : `Model "${pattern}" not found for provider "${provider}". Using custom model id.`;
368
- return { model: fallbackModel, thinkingLevel: undefined, warning: fallbackWarning, error: undefined };
402
+ ? `${warning} Model "${fallbackPattern}" not found for provider "${provider}". Using custom model id.`
403
+ : `Model "${fallbackPattern}" not found for provider "${provider}". Using custom model id.`;
404
+ return { model, thinkingLevel: fallbackThinking, warning: fallbackWarning, error: undefined };
369
405
  }
370
406
  }
371
407
  const display = provider ? `${provider}/${pattern}` : cliModel;
@@ -24,6 +24,7 @@ import { basename, dirname, join, relative, resolve, sep } from "node:path";
24
24
  import { globSync } from "glob";
25
25
  import ignore from "ignore";
26
26
  import { minimatch } from "minimatch";
27
+ import { maxSatisfying, rcompare, satisfies, valid, validRange } from "semver";
27
28
  import { CONFIG_DIR_NAME } from "../config.js";
28
29
  import { spawnProcess, spawnProcessSync } from "../utils/child-process.js";
29
30
  import { parseGitUrl } from "../utils/git.js";
@@ -38,6 +39,12 @@ function isOfflineModeEnabled() {
38
39
  return false;
39
40
  return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
40
41
  }
42
+ function isExactNpmVersion(version) {
43
+ return valid(version ?? "") !== null;
44
+ }
45
+ function getNpmVersionRange(version) {
46
+ return version ? (validRange(version) ?? undefined) : undefined;
47
+ }
41
48
  /**
42
49
  * Compute a numeric precedence rank for a resource based on its metadata.
43
50
  * Lower rank = higher precedence. Used to sort resolved resources so that
@@ -873,8 +880,8 @@ export class DefaultPackageManager {
873
880
  return true;
874
881
  }
875
882
  try {
876
- const latestVersion = await this.getLatestNpmVersion(source.name);
877
- return latestVersion !== installedVersion;
883
+ const targetVersion = await this.getLatestNpmVersion(source.version ? source.spec : source.name, source.range);
884
+ return targetVersion !== installedVersion;
878
885
  }
879
886
  catch {
880
887
  // Preserve existing update behavior when version lookup fails.
@@ -887,7 +894,7 @@ export class DefaultPackageManager {
887
894
  }
888
895
  const sourceLabel = sources.length === 1 ? sources[0].source : `${scope} npm packages`;
889
896
  const message = sources.length === 1 ? `Updating ${sources[0].source}...` : `Updating ${scope} npm packages...`;
890
- const specs = sources.map((entry) => `${entry.parsed.name}@latest`);
897
+ const specs = sources.map((entry) => (entry.parsed.version ? entry.parsed.spec : `${entry.parsed.name}@latest`));
891
898
  await this.withProgress("update", sourceLabel, message, async () => {
892
899
  await this.installNpmBatch(specs, scope);
893
900
  });
@@ -982,8 +989,7 @@ export class DefaultPackageManager {
982
989
  };
983
990
  if (parsed.type === "npm") {
984
991
  let installedPath = this.getNpmInstallPath(parsed, scope);
985
- const needsInstall = !existsSync(installedPath) ||
986
- (parsed.pinned && !(await this.installedNpmMatchesPinnedVersion(parsed, installedPath)));
992
+ const needsInstall = !existsSync(installedPath) || !(await this.installedNpmMatchesConfiguredVersion(parsed, installedPath));
987
993
  if (needsInstall) {
988
994
  const installed = await installMissing();
989
995
  if (!installed)
@@ -1119,7 +1125,9 @@ export class DefaultPackageManager {
1119
1125
  type: "npm",
1120
1126
  spec,
1121
1127
  name,
1122
- pinned: Boolean(version),
1128
+ version,
1129
+ range: getNpmVersionRange(version),
1130
+ pinned: isExactNpmVersion(version),
1123
1131
  };
1124
1132
  }
1125
1133
  if (isLocalPath(source)) {
@@ -1132,16 +1140,12 @@ export class DefaultPackageManager {
1132
1140
  }
1133
1141
  return { type: "local", path: source };
1134
1142
  }
1135
- async installedNpmMatchesPinnedVersion(source, installedPath) {
1143
+ async installedNpmMatchesConfiguredVersion(source, installedPath) {
1136
1144
  const installedVersion = this.getInstalledNpmVersion(installedPath);
1137
1145
  if (!installedVersion) {
1138
1146
  return false;
1139
1147
  }
1140
- const { version: pinnedVersion } = this.parseNpmSpec(source.spec);
1141
- if (!pinnedVersion) {
1142
- return true;
1143
- }
1144
- return installedVersion === pinnedVersion;
1148
+ return source.range ? satisfies(installedVersion, source.range) : true;
1145
1149
  }
1146
1150
  async npmHasAvailableUpdate(source, installedPath) {
1147
1151
  if (isOfflineModeEnabled()) {
@@ -1152,8 +1156,8 @@ export class DefaultPackageManager {
1152
1156
  return false;
1153
1157
  }
1154
1158
  try {
1155
- const latestVersion = await this.getLatestNpmVersion(source.name);
1156
- return latestVersion !== installedVersion;
1159
+ const targetVersion = await this.getLatestNpmVersion(source.version ? source.spec : source.name, source.range);
1160
+ return targetVersion !== installedVersion;
1157
1161
  }
1158
1162
  catch {
1159
1163
  return false;
@@ -1172,13 +1176,23 @@ export class DefaultPackageManager {
1172
1176
  return undefined;
1173
1177
  }
1174
1178
  }
1175
- async getLatestNpmVersion(packageName) {
1179
+ async getLatestNpmVersion(packageSpec, range) {
1176
1180
  const npmCommand = this.getNpmCommand();
1177
- const stdout = await this.runCommandCapture(npmCommand.command, [...npmCommand.args, "view", packageName, "version", "--json"], { cwd: this.cwd, timeoutMs: NETWORK_TIMEOUT_MS });
1181
+ const stdout = await this.runCommandCapture(npmCommand.command, [...npmCommand.args, "view", packageSpec, "version", "--json"], { cwd: this.cwd, timeoutMs: NETWORK_TIMEOUT_MS });
1178
1182
  const raw = stdout.trim();
1179
1183
  if (!raw)
1180
1184
  throw new Error("Empty response from npm view");
1181
- return JSON.parse(raw);
1185
+ const parsed = JSON.parse(raw);
1186
+ if (typeof parsed === "string") {
1187
+ return parsed;
1188
+ }
1189
+ if (Array.isArray(parsed)) {
1190
+ const versions = parsed.filter((value) => typeof value === "string" && value.length > 0);
1191
+ const latest = range ? maxSatisfying(versions, range) : [...versions].sort(rcompare)[0];
1192
+ if (latest)
1193
+ return latest;
1194
+ }
1195
+ throw new Error("Unexpected response from npm view");
1182
1196
  }
1183
1197
  async gitHasAvailableUpdate(installedPath) {
1184
1198
  if (isOfflineModeEnabled()) {
@@ -0,0 +1,58 @@
1
+ import { emitProjectTrustEvent } from "./extensions/runner.js";
2
+ import { getProjectTrustOptions, hasTrustRequiringProjectResources, } from "./trust-manager.js";
3
+ function formatProjectTrustPrompt(cwd) {
4
+ return `Trust project folder?\n${cwd}\n\nThis allows sling to load .sling settings and resources, install missing project packages, and execute project extensions.`;
5
+ }
6
+ async function selectProjectTrustOption(cwd, ctx) {
7
+ const options = getProjectTrustOptions(cwd, { includeSessionOnly: true });
8
+ const selected = await ctx.ui.select(formatProjectTrustPrompt(cwd), options.map((option) => option.label));
9
+ return options.find((option) => option.label === selected);
10
+ }
11
+ function saveProjectTrustPromptResult(trustStore, result) {
12
+ if (result.updates.length > 0) {
13
+ trustStore.setMany(result.updates);
14
+ }
15
+ }
16
+ export async function resolveProjectTrusted(options) {
17
+ if (options.trustOverride !== undefined) {
18
+ return options.trustOverride;
19
+ }
20
+ if (!hasTrustRequiringProjectResources(options.cwd)) {
21
+ return true;
22
+ }
23
+ if (options.extensionsResult) {
24
+ const { result, errors } = await emitProjectTrustEvent(options.extensionsResult, { type: "project_trust", cwd: options.cwd }, options.projectTrustContext);
25
+ for (const error of errors) {
26
+ options.onExtensionError?.(`Extension "${error.extensionPath}" project_trust error: ${error.error}`);
27
+ }
28
+ if (result) {
29
+ const trusted = result.trusted === "yes";
30
+ if (result.remember === true) {
31
+ options.trustStore.set(options.cwd, trusted);
32
+ }
33
+ return trusted;
34
+ }
35
+ }
36
+ const decision = options.trustStore.get(options.cwd);
37
+ if (decision !== null) {
38
+ return decision;
39
+ }
40
+ switch (options.defaultProjectTrust ?? "ask") {
41
+ case "always":
42
+ return true;
43
+ case "never":
44
+ return false;
45
+ case "ask":
46
+ break;
47
+ }
48
+ if (!options.projectTrustContext.hasUI) {
49
+ return false;
50
+ }
51
+ const selected = await selectProjectTrustOption(options.cwd, options.projectTrustContext);
52
+ if (selected !== undefined) {
53
+ saveProjectTrustPromptResult(options.trustStore, selected);
54
+ return selected.trusted;
55
+ }
56
+ return false;
57
+ }
58
+ //# sourceMappingURL=project-trust.js.map
@@ -45,40 +45,38 @@ export function parseCommandArgs(argsString) {
45
45
  * Supports:
46
46
  * - $1, $2, ... for positional args
47
47
  * - $@ and $ARGUMENTS for all args
48
+ * - ${N:-default} for positional arg N with default when missing/empty
48
49
  * - ${@:N} for args from Nth onwards (bash-style slicing)
49
50
  * - ${@:N:L} for L args starting from Nth
50
51
  *
51
- * Note: Replacement happens on the template string only. Argument values
52
+ * Note: Replacement happens on the template string only. Argument and default values
52
53
  * containing patterns like $1, $@, or $ARGUMENTS are NOT recursively substituted.
53
54
  */
54
55
  export function substituteArgs(content, args) {
55
- let result = content;
56
- // Replace $1, $2, etc. with positional args FIRST (before wildcards)
57
- // This prevents wildcard replacement values containing $<digit> patterns from being re-substituted
58
- result = result.replace(/\$(\d+)/g, (_, num) => {
59
- const index = parseInt(num, 10) - 1;
60
- return args[index] ?? "";
61
- });
62
- // Replace ${@:start} or ${@:start:length} with sliced args (bash-style)
63
- // Process BEFORE simple $@ to avoid conflicts
64
- result = result.replace(/\$\{@:(\d+)(?::(\d+))?\}/g, (_, startStr, lengthStr) => {
65
- let start = parseInt(startStr, 10) - 1; // Convert to 0-indexed (user provides 1-indexed)
66
- // Treat 0 as 1 (bash convention: args start at 1)
67
- if (start < 0)
68
- start = 0;
69
- if (lengthStr) {
70
- const length = parseInt(lengthStr, 10);
71
- return args.slice(start, start + length).join(" ");
56
+ const allArgs = args.join(" ");
57
+ return content.replace(/\$\{(\d+):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g, (_match, defaultNum, defaultValue, sliceStart, sliceLength, simple) => {
58
+ if (defaultNum) {
59
+ const index = parseInt(defaultNum, 10) - 1;
60
+ const value = args[index];
61
+ return value ? value : defaultValue;
62
+ }
63
+ if (sliceStart) {
64
+ let start = parseInt(sliceStart, 10) - 1; // Convert to 0-indexed (user provides 1-indexed)
65
+ // Treat 0 as 1 (bash convention: args start at 1)
66
+ if (start < 0)
67
+ start = 0;
68
+ if (sliceLength) {
69
+ const length = parseInt(sliceLength, 10);
70
+ return args.slice(start, start + length).join(" ");
71
+ }
72
+ return args.slice(start).join(" ");
73
+ }
74
+ if (simple === "ARGUMENTS" || simple === "@") {
75
+ return allArgs;
72
76
  }
73
- return args.slice(start).join(" ");
77
+ const index = parseInt(simple, 10) - 1;
78
+ return args[index] ?? "";
74
79
  });
75
- // Pre-compute all args joined (optimization)
76
- const allArgs = args.join(" ");
77
- // Replace $ARGUMENTS with all args joined (new syntax, aligns with Claude, Codex, OpenCode)
78
- result = result.replace(/\$ARGUMENTS/g, allArgs);
79
- // Replace $@ with all args joined (existing syntax)
80
- result = result.replace(/\$@/g, allArgs);
81
- return result;
82
80
  }
83
81
  function loadTemplateFromFile(filePath, sourceInfo) {
84
82
  try {
@@ -8,7 +8,6 @@ import { getShellConfig } from "../utils/shell.js";
8
8
  const commandResultCache = new Map();
9
9
  const ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
10
10
  const ENV_VAR_NAME_PREFIX_RE = /^[A-Za-z_][A-Za-z0-9_]*/;
11
- const LEGACY_ENV_VAR_NAME_RE = /^[A-Z_][A-Z0-9_]*$/;
12
11
  function appendLiteral(parts, value) {
13
12
  if (!value)
14
13
  return;
@@ -114,9 +113,6 @@ export function isCommandConfigValue(config) {
114
113
  export function isConfigValueConfigured(config) {
115
114
  return getMissingConfigValueEnvVarNames(config).length === 0;
116
115
  }
117
- export function isLegacyEnvVarNameConfigValue(config) {
118
- return LEGACY_ENV_VAR_NAME_RE.test(config);
119
- }
120
116
  /**
121
117
  * Resolve a config value (API key, header value, etc.) to an actual value.
122
118
  * - If starts with "!", executes the rest as a shell command and uses stdout (cached)