@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.
- package/node_modules/@aws-sdk/core/dist-cjs/index.js +47 -2297
- package/node_modules/@aws-sdk/core/dist-es/index.js +3 -3
- package/node_modules/@aws-sdk/core/dist-types/index.d.ts +5 -5
- package/node_modules/@aws-sdk/core/dist-types/ts3.4/index.d.ts +5 -5
- package/node_modules/@aws-sdk/core/package.json +8 -8
- package/node_modules/@aws-sdk/credential-provider-env/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/package.json +7 -7
- package/node_modules/@aws-sdk/credential-provider-http/package.json +6 -5
- package/node_modules/@aws-sdk/credential-provider-ini/package.json +11 -11
- package/node_modules/@aws-sdk/credential-provider-login/package.json +5 -5
- package/node_modules/@aws-sdk/credential-provider-node/package.json +9 -9
- package/node_modules/@aws-sdk/credential-provider-process/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/index.js +4 -1
- package/node_modules/@aws-sdk/credential-provider-sso/dist-es/resolveSSOCredentials.js +4 -1
- package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/package.json +5 -5
- package/node_modules/@aws-sdk/credential-provider-sso/package.json +9 -7
- package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +5 -5
- package/node_modules/@aws-sdk/eventstream-handler-node/package.json +3 -3
- package/node_modules/@aws-sdk/middleware-eventstream/package.json +3 -3
- package/node_modules/@aws-sdk/middleware-websocket/package.json +5 -5
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/package.json +7 -7
- package/node_modules/@aws-sdk/nested-clients/package.json +6 -6
- package/node_modules/@aws-sdk/signature-v4-multi-region/package.json +7 -6
- package/node_modules/@aws-sdk/types/package.json +2 -2
- package/node_modules/@aws-sdk/util-locate-window/package.json +2 -2
- package/node_modules/@aws-sdk/xml-builder/package.json +2 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +6 -6
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +906 -873
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +25 -8
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +19 -12
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +8 -4
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -2
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +3 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.js +48 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.js +133 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +14 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js +4 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +9 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js +4 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js +34 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +5 -57
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +41 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +31 -17
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js +58 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js +24 -26
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js +0 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +121 -54
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +11 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +26 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js +89 -17
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +65 -76
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js +1 -118
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.js +103 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +7 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +20 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +87 -12
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.js +23 -18
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +104 -30
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js +19 -41
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +72 -18
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +78 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.js +4 -27
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/LICENSE +15 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/bin/semver.js +195 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/comparator.js +143 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/index.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/range.js +557 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/classes/semver.js +333 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/clean.js +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/cmp.js +54 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/coerce.js +62 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-build.js +9 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare-loose.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/compare.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/diff.js +60 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/eq.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gt.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/gte.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/inc.js +21 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lt.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/lte.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/major.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/minor.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/neq.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/parse.js +18 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/patch.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/prerelease.js +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rcompare.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/rsort.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/satisfies.js +12 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/sort.js +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/truncate.js +48 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/functions/valid.js +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/index.js +93 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/constants.js +37 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/debug.js +11 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/identifiers.js +29 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/lrucache.js +42 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/parse-options.js +17 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/internal/re.js +223 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/package.json +78 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/preload.js +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/range.bnf +17 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/gtr.js +6 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/intersects.js +9 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/ltr.js +6 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/max-satisfying.js +27 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-satisfying.js +26 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/min-version.js +63 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/outside.js +82 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/simplify.js +49 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/subset.js +249 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/to-comparators.js +10 -0
- package/node_modules/@earendil-works/pi-coding-agent/node_modules/semver/ranges/valid.js +13 -0
- package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +25 -12
- package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -8
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +102 -43
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +11 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.js +51 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +38 -77
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +145 -21
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +44 -16
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/node_modules/@nodable/entities/package.json +4 -1
- package/node_modules/@nodable/entities/src/EntityDecoder.js +104 -3
- package/node_modules/@nodable/entities/src/index.d.ts +77 -0
- package/node_modules/@nodable/entities/src/index.js +1 -1
- package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.browser.js +3 -3
- package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.js +3 -3
- package/node_modules/@smithy/core/dist-es/submodules/retry/middleware-retry/retry-pre-sra-deprecated/StandardRetryStrategy.js +2 -2
- package/node_modules/@smithy/core/dist-es/submodules/retry/util-retry/DefaultRateLimiter.js +1 -1
- package/node_modules/@smithy/core/package.json +17 -17
- package/node_modules/@smithy/credential-provider-imds/package.json +6 -6
- package/node_modules/@smithy/fetch-http-handler/package.json +9 -9
- package/node_modules/@smithy/signature-v4/package.json +6 -6
- package/node_modules/@smithy/types/package.json +9 -9
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/http2.d.ts +1 -0
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/anynum/LICENSE +21 -0
- package/node_modules/anynum/README.md +142 -0
- package/node_modules/anynum/anynum.js +135 -0
- package/node_modules/anynum/digitTable.js +116 -0
- package/node_modules/anynum/package.json +42 -0
- package/node_modules/protobufjs/dist/light/protobuf.js +161 -203
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +34 -77
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +181 -223
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/index.d.ts +0 -8
- package/node_modules/protobufjs/package.json +2 -3
- package/node_modules/protobufjs/src/converter.js +5 -4
- package/node_modules/protobufjs/src/decoder.js +1 -1
- package/node_modules/protobufjs/src/service.js +5 -7
- package/node_modules/protobufjs/src/type.js +3 -1
- package/node_modules/protobufjs/src/util/minimal.js +1 -4
- package/node_modules/protobufjs/src/verifier.js +1 -1
- package/node_modules/semver/classes/range.js +11 -2
- package/node_modules/semver/package.json +2 -2
- package/node_modules/strnum/CHANGELOG.md +8 -0
- package/node_modules/strnum/README.md +9 -0
- package/node_modules/strnum/package.json +4 -1
- package/node_modules/strnum/strnum.js +9 -1
- package/package.json +6 -6
- package/slingshot/index.js +260 -258
- package/node_modules/@protobufjs/inquire/CHANGELOG.md +0 -8
- package/node_modules/@protobufjs/inquire/LICENSE +0 -26
- package/node_modules/@protobufjs/inquire/README.md +0 -13
- package/node_modules/@protobufjs/inquire/index.d.ts +0 -10
- package/node_modules/@protobufjs/inquire/index.js +0 -38
- package/node_modules/@protobufjs/inquire/package.json +0 -21
- package/node_modules/@protobufjs/inquire/tests/data/array.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/emptyArray.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/emptyObject.js +0 -1
- package/node_modules/@protobufjs/inquire/tests/data/object.js +0 -1
- 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,
|
|
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
|
-
|
|
664
|
-
this.
|
|
665
|
-
this.
|
|
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
|
-
|
|
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 "${
|
|
367
|
-
: `Model "${
|
|
368
|
-
return { model
|
|
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
|
|
877
|
-
return
|
|
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
|
-
|
|
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
|
|
1143
|
+
async installedNpmMatchesConfiguredVersion(source, installedPath) {
|
|
1136
1144
|
const installedVersion = this.getInstalledNpmVersion(installedPath);
|
|
1137
1145
|
if (!installedVersion) {
|
|
1138
1146
|
return false;
|
|
1139
1147
|
}
|
|
1140
|
-
|
|
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
|
|
1156
|
-
return
|
|
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(
|
|
1179
|
+
async getLatestNpmVersion(packageSpec, range) {
|
|
1176
1180
|
const npmCommand = this.getNpmCommand();
|
|
1177
|
-
const stdout = await this.runCommandCapture(npmCommand.command, [...npmCommand.args, "view",
|
|
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
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return args.slice(start
|
|
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
|
-
|
|
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)
|