@cnwenf/occ 2.1.344 → 2.1.345
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/README.md +5 -5
- package/README.zh-CN.md +3 -3
- package/dist/cli.js +1065 -1076
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
globalThis.MACRO={"VERSION":"2.1.
|
|
2
|
+
globalThis.MACRO={"VERSION":"2.1.345","BINARY_NAME":"occ","BUILD_TIME":"2026-09-20T21:35:23.753Z","FEEDBACK_CHANNEL":"","ISSUES_EXPLAINER":"","NATIVE_PACKAGE_URL":"","PACKAGE_URL":"@cnwenf/occ","VERSION_CHANGELOG":""};
|
|
3
3
|
// @bun
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -57751,496 +57751,246 @@ var init_managedPath = __esm(() => {
|
|
|
57751
57751
|
});
|
|
57752
57752
|
});
|
|
57753
57753
|
|
|
57754
|
-
// src/utils/
|
|
57755
|
-
function
|
|
57756
|
-
let
|
|
57757
|
-
|
|
57758
|
-
|
|
57759
|
-
|
|
57760
|
-
// src/entrypoints/sandboxTypes.ts
|
|
57761
|
-
var SandboxNetworkConfigSchema, SandboxFilesystemConfigSchema, SandboxSettingsSchema;
|
|
57762
|
-
var init_sandboxTypes = __esm(() => {
|
|
57763
|
-
init_v4();
|
|
57764
|
-
SandboxNetworkConfigSchema = lazySchema(() => exports_external.object({
|
|
57765
|
-
allowedDomains: exports_external.array(exports_external.string()).optional(),
|
|
57766
|
-
deniedDomains: exports_external.array(exports_external.string()).optional().describe("Domains to block even when a broader allowedDomains wildcard would otherwise permit them."),
|
|
57767
|
-
allowManagedDomainsOnly: exports_external.boolean().optional().describe("When true (and set in managed settings), only allowedDomains and WebFetch(domain:...) allow rules from managed settings are respected. " + "User, project, local, and flag settings domains are ignored. Denied domains are still respected from all sources."),
|
|
57768
|
-
strictAllowlist: exports_external.boolean().optional().describe("When true, the sandbox runtime deterministically denies hosts not in allowedDomains instead of prompting. " + "Enforced for sandboxed commands only \u2014 in-process tools such as WebFetch are not gated by this setting. " + "Only honored from user, managed/policy, or CLI (--settings) settings \u2014 " + "project settings (.claude/settings.json and .claude/settings.local.json) are ignored."),
|
|
57769
|
-
allowUnixSockets: exports_external.array(exports_external.string()).optional().describe("macOS only: Unix socket paths to allow. Ignored on Linux (seccomp cannot filter by path)."),
|
|
57770
|
-
allowAllUnixSockets: exports_external.boolean().optional().describe("If true, allow all Unix sockets (disables blocking on both platforms)."),
|
|
57771
|
-
allowLocalBinding: exports_external.boolean().optional(),
|
|
57772
|
-
httpProxyPort: exports_external.number().optional(),
|
|
57773
|
-
socksProxyPort: exports_external.number().optional()
|
|
57774
|
-
}).optional());
|
|
57775
|
-
SandboxFilesystemConfigSchema = lazySchema(() => exports_external.object({
|
|
57776
|
-
disabled: exports_external.boolean().optional().describe("macOS and Linux/WSL only: skip filesystem isolation entirely while " + "keeping network and seccomp isolation. Ignored on native Windows, " + "where the sandboxed process runs as a separate user with no " + "inherent rights, so skipping the filesystem rules would withhold " + "every access grant rather than loosen them \u2014 filesystem isolation " + "stays on there."),
|
|
57777
|
-
allowWrite: exports_external.array(exports_external.string()).optional().describe("Additional paths to allow writing within the sandbox. " + "Merged with paths from Edit(...) allow permission rules."),
|
|
57778
|
-
denyWrite: exports_external.array(exports_external.string()).optional().describe("Additional paths to deny writing within the sandbox. " + "Merged with paths from Edit(...) deny permission rules."),
|
|
57779
|
-
denyRead: exports_external.array(exports_external.string()).optional().describe("Additional paths to deny reading within the sandbox. " + "Merged with paths from Read(...) deny permission rules."),
|
|
57780
|
-
allowRead: exports_external.array(exports_external.string()).optional().describe("Paths to re-allow reading within denyRead regions. " + "Takes precedence over denyRead for matching paths."),
|
|
57781
|
-
allowManagedReadPathsOnly: exports_external.boolean().optional().describe("When true (set in managed settings), only allowRead paths from policySettings are used.")
|
|
57782
|
-
}).optional());
|
|
57783
|
-
SandboxSettingsSchema = lazySchema(() => exports_external.object({
|
|
57784
|
-
enabled: exports_external.boolean().optional(),
|
|
57785
|
-
failIfUnavailable: exports_external.boolean().optional().describe("Exit with an error at startup if sandbox.enabled is true but the sandbox cannot start " + "(missing dependencies, unsupported platform, or platform not in enabledPlatforms). " + "When false (default), a warning is shown and commands run unsandboxed. " + "Intended for managed-settings deployments that require sandboxing as a hard gate."),
|
|
57786
|
-
autoAllowBashIfSandboxed: exports_external.boolean().optional(),
|
|
57787
|
-
allowUnsandboxedCommands: exports_external.boolean().optional().describe("Allow commands to run outside the sandbox via the dangerouslyDisableSandbox parameter. " + "When false, the dangerouslyDisableSandbox parameter is completely ignored and all commands must run sandboxed. " + "Default: true."),
|
|
57788
|
-
network: SandboxNetworkConfigSchema(),
|
|
57789
|
-
filesystem: SandboxFilesystemConfigSchema(),
|
|
57790
|
-
ignoreViolations: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
|
|
57791
|
-
enableWeakerNestedSandbox: exports_external.boolean().optional(),
|
|
57792
|
-
enableWeakerNetworkIsolation: exports_external.boolean().optional().describe("macOS only: Allow access to com.apple.trustd.agent in the sandbox. " + "Needed for Go-based CLI tools (gh, gcloud, terraform, etc.) to verify TLS certificates " + "when using httpProxyPort with a MITM proxy and custom CA. " + "**Reduces security** \u2014 opens a potential data exfiltration vector through the trustd service. Default: false"),
|
|
57793
|
-
allowAppleEvents: exports_external.boolean().optional().describe("macOS only: Allow sandboxed commands to send Apple Events to other " + "applications via the Apple Event service. Default: false"),
|
|
57794
|
-
excludedCommands: exports_external.array(exports_external.string()).optional(),
|
|
57795
|
-
credentials: exports_external.object({
|
|
57796
|
-
enabled: exports_external.boolean().optional().describe("When true, block sandboxed commands from reading credential files and secret env vars.")
|
|
57797
|
-
}).optional(),
|
|
57798
|
-
ripgrep: exports_external.object({
|
|
57799
|
-
command: exports_external.string(),
|
|
57800
|
-
args: exports_external.array(exports_external.string()).optional()
|
|
57801
|
-
}).optional().describe("Custom ripgrep configuration for bundled ripgrep support")
|
|
57802
|
-
}).passthrough());
|
|
57803
|
-
});
|
|
57804
|
-
|
|
57805
|
-
// src/utils/bundledMode.ts
|
|
57806
|
-
function isRunningWithBun() {
|
|
57807
|
-
return process.versions.bun !== undefined;
|
|
57808
|
-
}
|
|
57809
|
-
function isInBundledMode() {
|
|
57810
|
-
return typeof Bun !== "undefined" && Array.isArray(Bun.embeddedFiles) && Bun.embeddedFiles.length > 0;
|
|
57811
|
-
}
|
|
57812
|
-
|
|
57813
|
-
// src/utils/findExecutable.ts
|
|
57814
|
-
function findExecutable2(exe, args) {
|
|
57815
|
-
const resolved = whichSync(exe);
|
|
57816
|
-
return { cmd: resolved ?? exe, args };
|
|
57754
|
+
// src/utils/plugins/marketplacePolicyValidation.ts
|
|
57755
|
+
function stripTrailingDots(host) {
|
|
57756
|
+
let end = host.length;
|
|
57757
|
+
while (end > 0 && host[end - 1] === ".")
|
|
57758
|
+
end--;
|
|
57759
|
+
return host.slice(0, end);
|
|
57817
57760
|
}
|
|
57818
|
-
|
|
57819
|
-
|
|
57820
|
-
|
|
57821
|
-
|
|
57822
|
-
// src/utils/env.ts
|
|
57823
|
-
import { homedir as homedir8 } from "os";
|
|
57824
|
-
import { join as join17 } from "path";
|
|
57825
|
-
async function isCommandAvailable(command) {
|
|
57761
|
+
function normalizeHostname(raw) {
|
|
57762
|
+
const host = stripTrailingDots(raw.replace(/[\t\n\r]/g, "").toLowerCase());
|
|
57763
|
+
if (host === "" || INVALID_HOST_CHARS.test(host))
|
|
57764
|
+
return host;
|
|
57826
57765
|
try {
|
|
57827
|
-
|
|
57766
|
+
const parsed = new URL(`https://${host}`);
|
|
57767
|
+
if (parsed.username !== "" || parsed.password !== "" || parsed.port !== "" || parsed.pathname !== "/" || parsed.search !== "" || parsed.hash !== "")
|
|
57768
|
+
return host;
|
|
57769
|
+
return stripTrailingDots(parsed.hostname);
|
|
57828
57770
|
} catch {
|
|
57829
|
-
return
|
|
57771
|
+
return host;
|
|
57830
57772
|
}
|
|
57831
57773
|
}
|
|
57832
|
-
function
|
|
57833
|
-
|
|
57834
|
-
|
|
57835
|
-
|
|
57836
|
-
|
|
57837
|
-
|
|
57838
|
-
|
|
57839
|
-
|
|
57840
|
-
|
|
57841
|
-
if (process.env.VSCODE_GIT_ASKPASS_MAIN?.includes("windsurf")) {
|
|
57842
|
-
return "windsurf";
|
|
57774
|
+
function normalizeHostForComparison(raw) {
|
|
57775
|
+
const cached2 = hostNormalizeCache.get(raw);
|
|
57776
|
+
if (cached2 !== undefined)
|
|
57777
|
+
return cached2;
|
|
57778
|
+
let host = normalizeHostname(raw);
|
|
57779
|
+
while (host.startsWith("www."))
|
|
57780
|
+
host = host.slice(4);
|
|
57781
|
+
if (hostNormalizeCache.size >= HOST_NORMALIZE_CACHE_LIMIT) {
|
|
57782
|
+
hostNormalizeCache.clear();
|
|
57843
57783
|
}
|
|
57844
|
-
|
|
57845
|
-
|
|
57784
|
+
hostNormalizeCache.set(raw, host);
|
|
57785
|
+
return host;
|
|
57786
|
+
}
|
|
57787
|
+
function hostMatches(raw, expected) {
|
|
57788
|
+
return normalizeHostForComparison(raw) === expected;
|
|
57789
|
+
}
|
|
57790
|
+
function isGitHubHost(raw) {
|
|
57791
|
+
return hostMatches(raw, GITHUB_HOST);
|
|
57792
|
+
}
|
|
57793
|
+
function isGitHubOrSshGitHubHost(raw) {
|
|
57794
|
+
return isGitHubHost(raw) || normalizeHostname(raw) === GITHUB_SSH_HOST;
|
|
57795
|
+
}
|
|
57796
|
+
function hasSuspiciousHostChars(value) {
|
|
57797
|
+
return /[%\x00-\x1f\x7f-\u{10FFFF}]/u.test(value);
|
|
57798
|
+
}
|
|
57799
|
+
function hasBackslashSmuggling(raw) {
|
|
57800
|
+
const url3 = raw.replace(/^[\x00-\x20]+/, "");
|
|
57801
|
+
const schemeEnd = url3.indexOf("://");
|
|
57802
|
+
if (schemeEnd === -1)
|
|
57803
|
+
return false;
|
|
57804
|
+
let rest = url3.slice(schemeEnd + 3);
|
|
57805
|
+
const scheme = url3.slice(0, schemeEnd).toLowerCase();
|
|
57806
|
+
if (URL_LIKE_PROTOCOLS.has(scheme)) {
|
|
57807
|
+
const slashes = rest.match(/^[/\\]+/)?.[0] ?? "";
|
|
57808
|
+
if (slashes.includes("\\"))
|
|
57809
|
+
return true;
|
|
57810
|
+
rest = rest.slice(slashes.length);
|
|
57846
57811
|
}
|
|
57847
|
-
const
|
|
57848
|
-
|
|
57849
|
-
|
|
57850
|
-
|
|
57851
|
-
|
|
57852
|
-
|
|
57853
|
-
|
|
57854
|
-
|
|
57855
|
-
|
|
57856
|
-
if (
|
|
57857
|
-
return
|
|
57812
|
+
const pathStart = rest.search(/[/?#]/);
|
|
57813
|
+
return (pathStart === -1 ? rest : rest.slice(0, pathStart)).includes("\\");
|
|
57814
|
+
}
|
|
57815
|
+
function isSuspiciousGitUrl(url3) {
|
|
57816
|
+
if (url3.includes("://")) {
|
|
57817
|
+
if (hasBackslashSmuggling(url3))
|
|
57818
|
+
return true;
|
|
57819
|
+
try {
|
|
57820
|
+
const parsed = new URL(url3);
|
|
57821
|
+
if (parsed.protocol === "http:" || parsed.protocol === "https:")
|
|
57822
|
+
return false;
|
|
57823
|
+
return hasSuspiciousHostChars(parsed.hostname);
|
|
57824
|
+
} catch {
|
|
57825
|
+
return true;
|
|
57858
57826
|
}
|
|
57859
57827
|
}
|
|
57860
|
-
|
|
57861
|
-
|
|
57862
|
-
|
|
57863
|
-
|
|
57864
|
-
|
|
57865
|
-
|
|
57866
|
-
return "pycharm";
|
|
57867
|
-
}
|
|
57868
|
-
if (process.env.TERM === "xterm-ghostty") {
|
|
57869
|
-
return "ghostty";
|
|
57870
|
-
}
|
|
57871
|
-
if (process.env.TERM?.includes("kitty")) {
|
|
57872
|
-
return "kitty";
|
|
57873
|
-
}
|
|
57874
|
-
if (process.env.TERM_PROGRAM) {
|
|
57875
|
-
return process.env.TERM_PROGRAM;
|
|
57876
|
-
}
|
|
57877
|
-
if (process.env.TMUX)
|
|
57878
|
-
return "tmux";
|
|
57879
|
-
if (process.env.STY)
|
|
57880
|
-
return "screen";
|
|
57881
|
-
if (process.env.KONSOLE_VERSION)
|
|
57882
|
-
return "konsole";
|
|
57883
|
-
if (process.env.GNOME_TERMINAL_SERVICE)
|
|
57884
|
-
return "gnome-terminal";
|
|
57885
|
-
if (process.env.XTERM_VERSION)
|
|
57886
|
-
return "xterm";
|
|
57887
|
-
if (process.env.VTE_VERSION)
|
|
57888
|
-
return "vte-based";
|
|
57889
|
-
if (process.env.TERMINATOR_UUID)
|
|
57890
|
-
return "terminator";
|
|
57891
|
-
if (process.env.KITTY_WINDOW_ID) {
|
|
57892
|
-
return "kitty";
|
|
57893
|
-
}
|
|
57894
|
-
if (process.env.ALACRITTY_LOG)
|
|
57895
|
-
return "alacritty";
|
|
57896
|
-
if (process.env.TILIX_ID)
|
|
57897
|
-
return "tilix";
|
|
57898
|
-
if (process.env.WT_SESSION)
|
|
57899
|
-
return "windows-terminal";
|
|
57900
|
-
if (process.env.SESSIONNAME && process.env.TERM === "cygwin")
|
|
57901
|
-
return "cygwin";
|
|
57902
|
-
if (process.env.MSYSTEM)
|
|
57903
|
-
return process.env.MSYSTEM.toLowerCase();
|
|
57904
|
-
if (process.env.ConEmuANSI || process.env.ConEmuPID || process.env.ConEmuTask) {
|
|
57905
|
-
return "conemu";
|
|
57906
|
-
}
|
|
57907
|
-
if (process.env.WSL_DISTRO_NAME)
|
|
57908
|
-
return `wsl-${process.env.WSL_DISTRO_NAME}`;
|
|
57909
|
-
if (isSSHSession()) {
|
|
57910
|
-
return "ssh-session";
|
|
57911
|
-
}
|
|
57912
|
-
if (process.env.TERM) {
|
|
57913
|
-
const term = process.env.TERM;
|
|
57914
|
-
if (term.includes("alacritty"))
|
|
57915
|
-
return "alacritty";
|
|
57916
|
-
if (term.includes("rxvt"))
|
|
57917
|
-
return "rxvt";
|
|
57918
|
-
if (term.includes("termite"))
|
|
57919
|
-
return "termite";
|
|
57920
|
-
return process.env.TERM;
|
|
57921
|
-
}
|
|
57922
|
-
if (!process.stdout.isTTY)
|
|
57923
|
-
return "non-interactive";
|
|
57924
|
-
return null;
|
|
57828
|
+
const colonIndex = url3.indexOf(":");
|
|
57829
|
+
const atIndex = url3.indexOf("@");
|
|
57830
|
+
if (colonIndex >= 0 && atIndex > colonIndex)
|
|
57831
|
+
return true;
|
|
57832
|
+
const host = url3.match(/^(?:[^@]+@)?([^:]+):/)?.[1];
|
|
57833
|
+
return host ? hasSuspiciousHostChars(host) : false;
|
|
57925
57834
|
}
|
|
57926
|
-
function
|
|
57927
|
-
|
|
57835
|
+
function normalizeGithubAwareHost(raw) {
|
|
57836
|
+
const host = normalizeHostname(raw);
|
|
57837
|
+
return isGitHubHost(host) ? GITHUB_HOST : host;
|
|
57928
57838
|
}
|
|
57929
|
-
function
|
|
57930
|
-
const
|
|
57931
|
-
|
|
57932
|
-
return override;
|
|
57933
|
-
}
|
|
57934
|
-
return env4.platform;
|
|
57839
|
+
function normalizeGithubHostForUrl(raw) {
|
|
57840
|
+
const host = normalizeGithubAwareHost(raw);
|
|
57841
|
+
return host === GITHUB_SSH_HOST ? GITHUB_HOST : host;
|
|
57935
57842
|
}
|
|
57936
|
-
|
|
57937
|
-
|
|
57938
|
-
|
|
57939
|
-
|
|
57940
|
-
|
|
57941
|
-
|
|
57942
|
-
|
|
57943
|
-
|
|
57944
|
-
getGlobalClaudeFile = memoize_default(() => {
|
|
57945
|
-
if (getFsImplementation().existsSync(join17(getClaudeConfigHomeDir(), ".config.json"))) {
|
|
57946
|
-
return join17(getClaudeConfigHomeDir(), ".config.json");
|
|
57843
|
+
function normalizePathSegments(path9) {
|
|
57844
|
+
const segments = [];
|
|
57845
|
+
for (const segment of path9.split("/")) {
|
|
57846
|
+
if (segment === ".")
|
|
57847
|
+
continue;
|
|
57848
|
+
if (segment === "..") {
|
|
57849
|
+
segments.pop();
|
|
57850
|
+
continue;
|
|
57947
57851
|
}
|
|
57948
|
-
|
|
57949
|
-
|
|
57950
|
-
|
|
57951
|
-
|
|
57952
|
-
|
|
57852
|
+
segments.push(segment);
|
|
57853
|
+
}
|
|
57854
|
+
return segments.filter((segment) => segment !== "").join("/");
|
|
57855
|
+
}
|
|
57856
|
+
function stripDotGitSuffix(path9) {
|
|
57857
|
+
let length = path9.length;
|
|
57858
|
+
for (;; ) {
|
|
57859
|
+
let end = length;
|
|
57860
|
+
while (end > 0 && path9.charCodeAt(end - 1) === 47)
|
|
57861
|
+
end--;
|
|
57862
|
+
if (end >= 4 && path9.startsWith(".git", end - 4))
|
|
57863
|
+
end -= 4;
|
|
57864
|
+
if (end === length)
|
|
57865
|
+
return length === path9.length ? path9 : path9.slice(0, length);
|
|
57866
|
+
length = end;
|
|
57867
|
+
}
|
|
57868
|
+
}
|
|
57869
|
+
function normalizeUrlForComparison(raw, options) {
|
|
57870
|
+
if (raw.includes("://")) {
|
|
57953
57871
|
try {
|
|
57954
|
-
const
|
|
57955
|
-
|
|
57956
|
-
|
|
57957
|
-
|
|
57958
|
-
|
|
57872
|
+
const parsed = new URL(raw);
|
|
57873
|
+
parsed.hostname = normalizeGithubHostForUrl(parsed.hostname);
|
|
57874
|
+
parsed.username = "";
|
|
57875
|
+
parsed.password = "";
|
|
57876
|
+
parsed.search = "";
|
|
57877
|
+
parsed.hash = "";
|
|
57878
|
+
try {
|
|
57879
|
+
parsed.pathname = decodeURIComponent(parsed.pathname);
|
|
57880
|
+
} catch {}
|
|
57881
|
+
const normalized = normalizePathSegments(parsed.pathname);
|
|
57882
|
+
parsed.pathname = options?.stripDotGit ? stripDotGitSuffix(normalized) : normalized;
|
|
57883
|
+
return parsed.toString();
|
|
57959
57884
|
} catch {
|
|
57960
|
-
return
|
|
57885
|
+
return raw;
|
|
57961
57886
|
}
|
|
57962
|
-
}
|
|
57963
|
-
|
|
57964
|
-
|
|
57965
|
-
|
|
57966
|
-
|
|
57967
|
-
|
|
57968
|
-
|
|
57969
|
-
|
|
57970
|
-
|
|
57971
|
-
|
|
57972
|
-
|
|
57973
|
-
|
|
57974
|
-
const runtimes = [];
|
|
57975
|
-
if (await isCommandAvailable("bun"))
|
|
57976
|
-
runtimes.push("bun");
|
|
57977
|
-
if (await isCommandAvailable("deno"))
|
|
57978
|
-
runtimes.push("deno");
|
|
57979
|
-
if (await isCommandAvailable("node"))
|
|
57980
|
-
runtimes.push("node");
|
|
57981
|
-
return runtimes;
|
|
57982
|
-
});
|
|
57983
|
-
isWslEnvironment = memoize_default(() => {
|
|
57887
|
+
}
|
|
57888
|
+
const scpLike = raw.match(/^[^@]+@([^:]+)(:.*)$/s);
|
|
57889
|
+
return scpLike ? `${normalizeGithubHostForUrl(scpLike[1] ?? "")}${scpLike[2]}` : raw;
|
|
57890
|
+
}
|
|
57891
|
+
function parseScpLikeGitUrl(raw) {
|
|
57892
|
+
const match = SCP_LIKE_GIT_URL_PATTERN.exec(raw);
|
|
57893
|
+
return match ? { user: match[1], host: match[2], path: match[3] } : null;
|
|
57894
|
+
}
|
|
57895
|
+
function normalizeGitUrl(raw) {
|
|
57896
|
+
if (isSuspiciousGitUrl(raw))
|
|
57897
|
+
return raw;
|
|
57898
|
+
if (raw.includes("://")) {
|
|
57984
57899
|
try {
|
|
57985
|
-
|
|
57986
|
-
|
|
57987
|
-
|
|
57900
|
+
const parsed = new URL(raw);
|
|
57901
|
+
parsed.hostname = normalizeGithubAwareHost(parsed.hostname);
|
|
57902
|
+
if (CREDENTIAL_STRIP_PROTOCOLS.has(parsed.protocol) || isGitHubHost(parsed.hostname)) {
|
|
57903
|
+
parsed.username = "";
|
|
57904
|
+
parsed.password = "";
|
|
57905
|
+
}
|
|
57906
|
+
return parsed.toString();
|
|
57907
|
+
} catch {
|
|
57908
|
+
return raw;
|
|
57988
57909
|
}
|
|
57989
|
-
}
|
|
57990
|
-
|
|
57910
|
+
}
|
|
57911
|
+
const scpLike = parseScpLikeGitUrl(raw);
|
|
57912
|
+
if (!scpLike)
|
|
57913
|
+
return raw;
|
|
57914
|
+
const host = scpLike.host.toLowerCase().replace(/\.+$/, "");
|
|
57915
|
+
return isGitHubHost(host) ? `${GITHUB_HOST}:${scpLike.path}` : `${scpLike.user}@${host}:${scpLike.path}`;
|
|
57916
|
+
}
|
|
57917
|
+
function gitUrlHasWildcard(url3) {
|
|
57918
|
+
if (url3.includes("://")) {
|
|
57919
|
+
if (hasBackslashSmuggling(url3))
|
|
57920
|
+
return false;
|
|
57921
|
+
let hostname3;
|
|
57991
57922
|
try {
|
|
57992
|
-
|
|
57993
|
-
|
|
57994
|
-
}
|
|
57995
|
-
const { cmd } = findExecutable2("npm", []);
|
|
57996
|
-
return cmd.startsWith("/mnt/c/");
|
|
57997
|
-
} catch (_error) {
|
|
57923
|
+
hostname3 = new URL(url3).hostname;
|
|
57924
|
+
} catch {
|
|
57998
57925
|
return false;
|
|
57999
57926
|
}
|
|
58000
|
-
|
|
58001
|
-
|
|
58002
|
-
"
|
|
58003
|
-
|
|
58004
|
-
|
|
58005
|
-
"phpstorm",
|
|
58006
|
-
"rubymine",
|
|
58007
|
-
"clion",
|
|
58008
|
-
"goland",
|
|
58009
|
-
"rider",
|
|
58010
|
-
"datagrip",
|
|
58011
|
-
"appcode",
|
|
58012
|
-
"dataspell",
|
|
58013
|
-
"aqua",
|
|
58014
|
-
"gateway",
|
|
58015
|
-
"fleet",
|
|
58016
|
-
"jetbrains",
|
|
58017
|
-
"androidstudio"
|
|
58018
|
-
];
|
|
58019
|
-
detectDeploymentEnvironment = memoize_default(() => {
|
|
58020
|
-
if (isEnvTruthy(process.env.CODESPACES))
|
|
58021
|
-
return "codespaces";
|
|
58022
|
-
if (process.env.GITPOD_WORKSPACE_ID)
|
|
58023
|
-
return "gitpod";
|
|
58024
|
-
if (process.env.REPL_ID || process.env.REPL_SLUG)
|
|
58025
|
-
return "replit";
|
|
58026
|
-
if (process.env.PROJECT_DOMAIN)
|
|
58027
|
-
return "glitch";
|
|
58028
|
-
if (isEnvTruthy(process.env.VERCEL))
|
|
58029
|
-
return "vercel";
|
|
58030
|
-
if (process.env.RAILWAY_ENVIRONMENT_NAME || process.env.RAILWAY_SERVICE_NAME) {
|
|
58031
|
-
return "railway";
|
|
58032
|
-
}
|
|
58033
|
-
if (isEnvTruthy(process.env.RENDER))
|
|
58034
|
-
return "render";
|
|
58035
|
-
if (isEnvTruthy(process.env.NETLIFY))
|
|
58036
|
-
return "netlify";
|
|
58037
|
-
if (process.env.DYNO)
|
|
58038
|
-
return "heroku";
|
|
58039
|
-
if (process.env.FLY_APP_NAME || process.env.FLY_MACHINE_ID)
|
|
58040
|
-
return "fly.io";
|
|
58041
|
-
if (isEnvTruthy(process.env.CF_PAGES))
|
|
58042
|
-
return "cloudflare-pages";
|
|
58043
|
-
if (process.env.DENO_DEPLOYMENT_ID)
|
|
58044
|
-
return "deno-deploy";
|
|
58045
|
-
if (process.env.AWS_LAMBDA_FUNCTION_NAME)
|
|
58046
|
-
return "aws-lambda";
|
|
58047
|
-
if (process.env.AWS_EXECUTION_ENV === "AWS_ECS_FARGATE")
|
|
58048
|
-
return "aws-fargate";
|
|
58049
|
-
if (process.env.AWS_EXECUTION_ENV === "AWS_ECS_EC2")
|
|
58050
|
-
return "aws-ecs";
|
|
57927
|
+
if (!isGitHubOrSshGitHubHost(hostname3))
|
|
57928
|
+
return false;
|
|
57929
|
+
if (normalizeUrlForComparison(url3, { stripDotGit: true }).includes("*"))
|
|
57930
|
+
return true;
|
|
57931
|
+
const normalized = normalizeGitUrl(url3);
|
|
58051
57932
|
try {
|
|
58052
|
-
const
|
|
58053
|
-
|
|
58054
|
-
|
|
58055
|
-
|
|
58056
|
-
if (process.env.K_SERVICE)
|
|
58057
|
-
return "gcp-cloud-run";
|
|
58058
|
-
if (process.env.GOOGLE_CLOUD_PROJECT)
|
|
58059
|
-
return "gcp";
|
|
58060
|
-
if (process.env.WEBSITE_SITE_NAME || process.env.WEBSITE_SKU)
|
|
58061
|
-
return "azure-app-service";
|
|
58062
|
-
if (process.env.AZURE_FUNCTIONS_ENVIRONMENT)
|
|
58063
|
-
return "azure-functions";
|
|
58064
|
-
if (process.env.APP_URL?.includes("ondigitalocean.app")) {
|
|
58065
|
-
return "digitalocean-app-platform";
|
|
57933
|
+
const parsed = new URL(normalized);
|
|
57934
|
+
return parsed.hostname.includes("*") || parsed.pathname.includes("*");
|
|
57935
|
+
} catch {
|
|
57936
|
+
return normalized.includes("*");
|
|
58066
57937
|
}
|
|
58067
|
-
if (process.env.SPACE_CREATOR_USER_ID)
|
|
58068
|
-
return "huggingface-spaces";
|
|
58069
|
-
if (isEnvTruthy(process.env.GITHUB_ACTIONS))
|
|
58070
|
-
return "github-actions";
|
|
58071
|
-
if (isEnvTruthy(process.env.GITLAB_CI))
|
|
58072
|
-
return "gitlab-ci";
|
|
58073
|
-
if (process.env.CIRCLECI)
|
|
58074
|
-
return "circleci";
|
|
58075
|
-
if (process.env.BUILDKITE)
|
|
58076
|
-
return "buildkite";
|
|
58077
|
-
if (isEnvTruthy(process.env.CI))
|
|
58078
|
-
return "ci";
|
|
58079
|
-
if (process.env.KUBERNETES_SERVICE_HOST)
|
|
58080
|
-
return "kubernetes";
|
|
58081
|
-
try {
|
|
58082
|
-
if (getFsImplementation().existsSync("/.dockerenv"))
|
|
58083
|
-
return "docker";
|
|
58084
|
-
} catch {}
|
|
58085
|
-
if (env4.platform === "darwin")
|
|
58086
|
-
return "unknown-darwin";
|
|
58087
|
-
if (env4.platform === "linux")
|
|
58088
|
-
return "unknown-linux";
|
|
58089
|
-
if (env4.platform === "win32")
|
|
58090
|
-
return "unknown-win32";
|
|
58091
|
-
return "unknown";
|
|
58092
|
-
});
|
|
58093
|
-
env4 = {
|
|
58094
|
-
hasInternetAccess,
|
|
58095
|
-
isCI: isEnvTruthy(process.env.CI),
|
|
58096
|
-
platform: ["win32", "darwin"].includes(process.platform) ? process.platform : "linux",
|
|
58097
|
-
arch: process.arch,
|
|
58098
|
-
nodeVersion: process.version,
|
|
58099
|
-
terminal: detectTerminal(),
|
|
58100
|
-
isSSH: isSSHSession,
|
|
58101
|
-
getPackageManagers: detectPackageManagers,
|
|
58102
|
-
getRuntimes: detectRuntimes,
|
|
58103
|
-
isRunningWithBun: memoize_default(isRunningWithBun),
|
|
58104
|
-
isWslEnvironment,
|
|
58105
|
-
isNpmFromWindowsPath,
|
|
58106
|
-
isConductor,
|
|
58107
|
-
detectDeploymentEnvironment
|
|
58108
|
-
};
|
|
58109
|
-
});
|
|
58110
|
-
|
|
58111
|
-
// src/constants/figures.ts
|
|
58112
|
-
var BLACK_CIRCLE, BULLET_OPERATOR = "\u2219", TEARDROP_ASTERISK = "\u273B", UP_ARROW = "\u2191", DOWN_ARROW = "\u2193", LIGHTNING_BOLT = "\u21AF", EFFORT_LOW = "\u25CB", EFFORT_MEDIUM = "\u25D0", EFFORT_HIGH = "\u25CF", EFFORT_XHIGH = "\u25C9", EFFORT_MAX = "\u25C8", PAUSE_ICON = "\u23F8", REFRESH_ARROW = "\u21BB", CHANNEL_ARROW = "\u2190", DIAMOND_OPEN = "\u25C7", DIAMOND_FILLED = "\u25C6", REFERENCE_MARK = "\u203B", BLOCKQUOTE_BAR = "\u258E", BRIDGE_SPINNER_FRAMES, BRIDGE_READY_INDICATOR = "\xB7\u2714\uFE0E\xB7", BRIDGE_FAILED_INDICATOR = "\xD7";
|
|
58113
|
-
var init_figures2 = __esm(() => {
|
|
58114
|
-
init_env();
|
|
58115
|
-
BLACK_CIRCLE = env4.platform === "darwin" ? "\u23FA" : "\u25CF";
|
|
58116
|
-
BRIDGE_SPINNER_FRAMES = [
|
|
58117
|
-
"\xB7|\xB7",
|
|
58118
|
-
"\xB7/\xB7",
|
|
58119
|
-
"\xB7\u2014\xB7",
|
|
58120
|
-
"\xB7\\\xB7"
|
|
58121
|
-
];
|
|
58122
|
-
});
|
|
58123
|
-
|
|
58124
|
-
// src/types/permissions.ts
|
|
58125
|
-
var exports_permissions = {};
|
|
58126
|
-
__export(exports_permissions, {
|
|
58127
|
-
PERMISSION_MODES_CLI_CHOICES: () => PERMISSION_MODES_CLI_CHOICES,
|
|
58128
|
-
PERMISSION_MODES: () => PERMISSION_MODES,
|
|
58129
|
-
INTERNAL_PERMISSION_MODES: () => INTERNAL_PERMISSION_MODES,
|
|
58130
|
-
EXTERNAL_PERMISSION_MODES: () => EXTERNAL_PERMISSION_MODES
|
|
58131
|
-
});
|
|
58132
|
-
var EXTERNAL_PERMISSION_MODES, INTERNAL_PERMISSION_MODES, PERMISSION_MODES, PERMISSION_MODES_CLI_CHOICES;
|
|
58133
|
-
var init_permissions = __esm(() => {
|
|
58134
|
-
EXTERNAL_PERMISSION_MODES = [
|
|
58135
|
-
"acceptEdits",
|
|
58136
|
-
"auto",
|
|
58137
|
-
"bypassPermissions",
|
|
58138
|
-
"default",
|
|
58139
|
-
"dontAsk",
|
|
58140
|
-
"plan"
|
|
58141
|
-
];
|
|
58142
|
-
INTERNAL_PERMISSION_MODES = [
|
|
58143
|
-
...EXTERNAL_PERMISSION_MODES
|
|
58144
|
-
];
|
|
58145
|
-
PERMISSION_MODES = INTERNAL_PERMISSION_MODES;
|
|
58146
|
-
PERMISSION_MODES_CLI_CHOICES = PERMISSION_MODES.map((mode) => mode === "default" ? "manual" : mode);
|
|
58147
|
-
});
|
|
58148
|
-
|
|
58149
|
-
// src/utils/permissions/PermissionMode.ts
|
|
58150
|
-
function isExternalPermissionMode(mode) {
|
|
58151
|
-
if (process.env.USER_TYPE !== "ant") {
|
|
58152
|
-
return true;
|
|
58153
57938
|
}
|
|
58154
|
-
|
|
58155
|
-
|
|
58156
|
-
|
|
58157
|
-
|
|
58158
|
-
|
|
58159
|
-
|
|
58160
|
-
|
|
58161
|
-
|
|
58162
|
-
|
|
58163
|
-
return
|
|
58164
|
-
}
|
|
58165
|
-
function permissionModeFromString(str) {
|
|
58166
|
-
const normalized = normalizePermissionModeInput(str);
|
|
58167
|
-
return PERMISSION_MODES.includes(normalized) ? normalized : "default";
|
|
58168
|
-
}
|
|
58169
|
-
function permissionModeTitle(mode) {
|
|
58170
|
-
return getModeConfig(mode).title;
|
|
57939
|
+
const match = url3.match(SCP_LIKE_HOST_PATTERN);
|
|
57940
|
+
const host = match?.[1];
|
|
57941
|
+
const path9 = match?.[2];
|
|
57942
|
+
if (!host || path9 === undefined || !isGitHubOrSshGitHubHost(host))
|
|
57943
|
+
return false;
|
|
57944
|
+
let decoded = path9;
|
|
57945
|
+
try {
|
|
57946
|
+
decoded = decodeURIComponent(path9);
|
|
57947
|
+
} catch {}
|
|
57948
|
+
return decoded.includes("*");
|
|
58171
57949
|
}
|
|
58172
|
-
function
|
|
58173
|
-
|
|
57950
|
+
function regexCompiles(pattern) {
|
|
57951
|
+
try {
|
|
57952
|
+
new RegExp(pattern);
|
|
57953
|
+
return true;
|
|
57954
|
+
} catch {
|
|
57955
|
+
return false;
|
|
57956
|
+
}
|
|
58174
57957
|
}
|
|
58175
|
-
function
|
|
58176
|
-
return
|
|
57958
|
+
function isValidWildcardOwner(owner) {
|
|
57959
|
+
return OWNER_CHARS_PATTERN.test(owner) && !owner.startsWith("-") && owner !== "." && owner !== "..";
|
|
58177
57960
|
}
|
|
58178
|
-
function
|
|
58179
|
-
|
|
57961
|
+
function parseGitHubOwnerWildcard(repo) {
|
|
57962
|
+
if (!repo.endsWith("/*"))
|
|
57963
|
+
return null;
|
|
57964
|
+
const owner = repo.slice(0, -2);
|
|
57965
|
+
return isValidWildcardOwner(owner) ? owner : null;
|
|
58180
57966
|
}
|
|
58181
|
-
function
|
|
58182
|
-
|
|
57967
|
+
function checkMarketplaceEntryEnforceability(entry) {
|
|
57968
|
+
const pattern = entry.source === "hostPattern" ? entry.hostPattern : entry.source === "pathPattern" ? entry.pathPattern : null;
|
|
57969
|
+
if (pattern !== null && !regexCompiles(pattern))
|
|
57970
|
+
return `${entry.source}: regex does not compile; the entry cannot be enforced`;
|
|
57971
|
+
if (entry.source === "github" && entry.repo.includes("*") && parseGitHubOwnerWildcard(entry.repo) === null)
|
|
57972
|
+
return 'github: an owner wildcard must be exactly "<owner>/*"; the entry cannot be enforced';
|
|
57973
|
+
if (entry.source === "git" && gitUrlHasWildcard(entry.url))
|
|
57974
|
+
return 'git: wildcards are only supported in github-form entries, as "<owner>/*"; the entry cannot be enforced';
|
|
57975
|
+
if ((entry.source === "github" || entry.source === "git") && entry.ref !== undefined && entry.ref.includes("*"))
|
|
57976
|
+
return `${entry.source}: ref contains "*", which git does not allow in ref names; the entry cannot be enforced`;
|
|
57977
|
+
return null;
|
|
58183
57978
|
}
|
|
58184
|
-
var
|
|
58185
|
-
var
|
|
58186
|
-
|
|
58187
|
-
|
|
58188
|
-
|
|
58189
|
-
|
|
58190
|
-
|
|
58191
|
-
|
|
58192
|
-
|
|
58193
|
-
|
|
58194
|
-
|
|
58195
|
-
|
|
58196
|
-
|
|
58197
|
-
|
|
58198
|
-
|
|
58199
|
-
indicator: "manual mode"
|
|
58200
|
-
},
|
|
58201
|
-
plan: {
|
|
58202
|
-
title: "Plan Mode",
|
|
58203
|
-
shortTitle: "Plan",
|
|
58204
|
-
symbol: PAUSE_ICON,
|
|
58205
|
-
color: "planMode",
|
|
58206
|
-
external: "plan",
|
|
58207
|
-
indicator: "plan mode"
|
|
58208
|
-
},
|
|
58209
|
-
acceptEdits: {
|
|
58210
|
-
title: "Accept edits",
|
|
58211
|
-
shortTitle: "Accept",
|
|
58212
|
-
symbol: "\u23F5\u23F5",
|
|
58213
|
-
color: "autoAccept",
|
|
58214
|
-
external: "acceptEdits",
|
|
58215
|
-
indicator: "accept edits"
|
|
58216
|
-
},
|
|
58217
|
-
bypassPermissions: {
|
|
58218
|
-
title: "Bypass Permissions",
|
|
58219
|
-
shortTitle: "Bypass",
|
|
58220
|
-
symbol: "\u23F5\u23F5",
|
|
58221
|
-
color: "error",
|
|
58222
|
-
external: "bypassPermissions",
|
|
58223
|
-
indicator: "bypass permissions"
|
|
58224
|
-
},
|
|
58225
|
-
dontAsk: {
|
|
58226
|
-
title: "Don't Ask",
|
|
58227
|
-
shortTitle: "DontAsk",
|
|
58228
|
-
symbol: "\u23F5\u23F5",
|
|
58229
|
-
color: "error",
|
|
58230
|
-
external: "dontAsk",
|
|
58231
|
-
indicator: "don't ask"
|
|
58232
|
-
},
|
|
58233
|
-
...feature("TRANSCRIPT_CLASSIFIER") ? {
|
|
58234
|
-
auto: {
|
|
58235
|
-
title: "Auto mode",
|
|
58236
|
-
shortTitle: "Auto",
|
|
58237
|
-
symbol: "\u23F5\u23F5",
|
|
58238
|
-
color: "warning",
|
|
58239
|
-
external: "default",
|
|
58240
|
-
indicator: "auto mode"
|
|
58241
|
-
}
|
|
58242
|
-
} : {}
|
|
58243
|
-
};
|
|
57979
|
+
var GITHUB_HOST = "github.com", GITHUB_SSH_HOST = "ssh.github.com", INVALID_HOST_CHARS, URL_LIKE_PROTOCOLS, CREDENTIAL_STRIP_PROTOCOLS, OWNER_CHARS_PATTERN, SCP_LIKE_GIT_URL_PATTERN, SCP_LIKE_HOST_PATTERN, HOST_NORMALIZE_CACHE_LIMIT = 50, hostNormalizeCache;
|
|
57980
|
+
var init_marketplacePolicyValidation = __esm(() => {
|
|
57981
|
+
INVALID_HOST_CHARS = /[:/\\?#@\s]/;
|
|
57982
|
+
URL_LIKE_PROTOCOLS = new Set(["http", "https", "ws", "wss", "ftp"]);
|
|
57983
|
+
CREDENTIAL_STRIP_PROTOCOLS = new Set([
|
|
57984
|
+
"http:",
|
|
57985
|
+
"https:",
|
|
57986
|
+
"git:",
|
|
57987
|
+
"git+http:",
|
|
57988
|
+
"git+https:"
|
|
57989
|
+
]);
|
|
57990
|
+
OWNER_CHARS_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
57991
|
+
SCP_LIKE_GIT_URL_PATTERN = /^([^@:/[\]]+)@([^@:/[\]]+):(.*)$/s;
|
|
57992
|
+
SCP_LIKE_HOST_PATTERN = /^(?:[^@]+@)?([^@:/]+):(.*)$/s;
|
|
57993
|
+
hostNormalizeCache = new Map;
|
|
58244
57994
|
});
|
|
58245
57995
|
|
|
58246
57996
|
// src/entrypoints/agentSdkTypes.js
|
|
@@ -58282,6 +58032,12 @@ var init_agentSdkTypes = __esm(() => {
|
|
|
58282
58032
|
];
|
|
58283
58033
|
});
|
|
58284
58034
|
|
|
58035
|
+
// src/utils/lazySchema.ts
|
|
58036
|
+
function lazySchema(factory2) {
|
|
58037
|
+
let cached2;
|
|
58038
|
+
return () => cached2 ??= factory2();
|
|
58039
|
+
}
|
|
58040
|
+
|
|
58285
58041
|
// src/utils/shell/shellProvider.ts
|
|
58286
58042
|
var SHELL_TYPES, DEFAULT_HOOK_SHELL = "bash";
|
|
58287
58043
|
var init_shellProvider = __esm(() => {
|
|
@@ -58906,6 +58662,306 @@ var init_schemas3 = __esm(() => {
|
|
|
58906
58662
|
KnownMarketplacesFileSchema = lazySchema(() => exports_external.record(exports_external.string(), KnownMarketplaceSchema()));
|
|
58907
58663
|
});
|
|
58908
58664
|
|
|
58665
|
+
// src/utils/settings/marketplacePolicySanitizer.ts
|
|
58666
|
+
function firstIssueDetail(issues) {
|
|
58667
|
+
for (const issue2 of issues) {
|
|
58668
|
+
const prefix = issue2.path.length > 0 ? `${issue2.path.map(String).join(".")}: ` : "";
|
|
58669
|
+
if (issue2.code === "invalid_union") {
|
|
58670
|
+
for (const branch of issue2.errors) {
|
|
58671
|
+
const detail = firstIssueDetail(branch);
|
|
58672
|
+
if (detail !== null)
|
|
58673
|
+
return `${prefix}${detail}`;
|
|
58674
|
+
}
|
|
58675
|
+
const noted = issue2;
|
|
58676
|
+
if (typeof noted.note === "string" && noted.note !== "")
|
|
58677
|
+
return `${prefix}${noted.note}`;
|
|
58678
|
+
}
|
|
58679
|
+
if (issue2.message !== "")
|
|
58680
|
+
return `${prefix}${issue2.message}`;
|
|
58681
|
+
}
|
|
58682
|
+
return null;
|
|
58683
|
+
}
|
|
58684
|
+
function sanitizeMarketplacePolicy(data, filePath) {
|
|
58685
|
+
if (!data || typeof data !== "object")
|
|
58686
|
+
return [];
|
|
58687
|
+
const obj = data;
|
|
58688
|
+
const warnings = [];
|
|
58689
|
+
for (const key of POLICY_KEYS) {
|
|
58690
|
+
if (!(key in obj))
|
|
58691
|
+
continue;
|
|
58692
|
+
const raw = obj[key];
|
|
58693
|
+
if (raw === null) {
|
|
58694
|
+
delete obj[key];
|
|
58695
|
+
continue;
|
|
58696
|
+
}
|
|
58697
|
+
if (!Array.isArray(raw)) {
|
|
58698
|
+
if (key === "strictKnownMarketplaces") {
|
|
58699
|
+
obj[key] = [];
|
|
58700
|
+
} else {
|
|
58701
|
+
delete obj[key];
|
|
58702
|
+
}
|
|
58703
|
+
warnings.push({
|
|
58704
|
+
file: filePath,
|
|
58705
|
+
path: key,
|
|
58706
|
+
message: key === "strictKnownMarketplaces" ? STRICT_PRESENT_INVALID_MESSAGE : BLOCKED_PRESENT_INVALID_MESSAGE,
|
|
58707
|
+
invalidValue: raw
|
|
58708
|
+
});
|
|
58709
|
+
continue;
|
|
58710
|
+
}
|
|
58711
|
+
const kept = [];
|
|
58712
|
+
for (const [index2, entry] of raw.entries()) {
|
|
58713
|
+
const parsed = MarketplaceSourceSchema().safeParse(entry);
|
|
58714
|
+
if (!parsed.success) {
|
|
58715
|
+
warnings.push({
|
|
58716
|
+
file: filePath,
|
|
58717
|
+
path: `${key}[${index2}]`,
|
|
58718
|
+
message: `Invalid entry was ignored: ${firstIssueDetail(parsed.error.issues) ?? "failed validation"}`,
|
|
58719
|
+
invalidValue: entry
|
|
58720
|
+
});
|
|
58721
|
+
continue;
|
|
58722
|
+
}
|
|
58723
|
+
const problem = checkMarketplaceEntryEnforceability(parsed.data);
|
|
58724
|
+
if (problem === null) {
|
|
58725
|
+
kept.push(parsed.data);
|
|
58726
|
+
continue;
|
|
58727
|
+
}
|
|
58728
|
+
if (key === "blockedMarketplaces") {
|
|
58729
|
+
kept.push(parsed.data);
|
|
58730
|
+
warnings.push({
|
|
58731
|
+
file: filePath,
|
|
58732
|
+
path: `${key}[${index2}]`,
|
|
58733
|
+
message: `Unenforceable entry was kept: ${problem}; it can never match a marketplace source, but marketplace restrictions stay active`,
|
|
58734
|
+
invalidValue: entry
|
|
58735
|
+
});
|
|
58736
|
+
} else {
|
|
58737
|
+
warnings.push({
|
|
58738
|
+
file: filePath,
|
|
58739
|
+
path: `${key}[${index2}]`,
|
|
58740
|
+
message: `Invalid entry was ignored: ${problem}`,
|
|
58741
|
+
invalidValue: entry
|
|
58742
|
+
});
|
|
58743
|
+
}
|
|
58744
|
+
}
|
|
58745
|
+
obj[key] = kept;
|
|
58746
|
+
}
|
|
58747
|
+
return warnings;
|
|
58748
|
+
}
|
|
58749
|
+
var POLICY_KEYS, STRICT_PRESENT_INVALID_MESSAGE = '"strictKnownMarketplaces" was present but invalid; enforcing an empty allowlist (no marketplaces admitted) until it is fixed.', BLOCKED_PRESENT_INVALID_MESSAGE = '"blockedMarketplaces" was present but invalid and was dropped; its entries cannot be enforced until it is fixed.';
|
|
58750
|
+
var init_marketplacePolicySanitizer = __esm(() => {
|
|
58751
|
+
init_marketplacePolicyValidation();
|
|
58752
|
+
init_schemas3();
|
|
58753
|
+
POLICY_KEYS = ["strictKnownMarketplaces", "blockedMarketplaces"];
|
|
58754
|
+
});
|
|
58755
|
+
|
|
58756
|
+
// src/utils/settings/sanitizeAllowlists.ts
|
|
58757
|
+
function issueDetail(error49) {
|
|
58758
|
+
const issue2 = error49.issues[0];
|
|
58759
|
+
if (issue2 === undefined)
|
|
58760
|
+
return "failed validation";
|
|
58761
|
+
return issue2.path.length > 0 ? `${issue2.path.join(".")}: ${issue2.message}` : issue2.message;
|
|
58762
|
+
}
|
|
58763
|
+
function validateAllowlistEntry(key, entry) {
|
|
58764
|
+
if (key === "allowedChannelPlugins") {
|
|
58765
|
+
if (typeof entry === "string") {
|
|
58766
|
+
const at = entry.indexOf("@");
|
|
58767
|
+
const plugin = entry.slice(0, at);
|
|
58768
|
+
const marketplace = entry.slice(at + 1);
|
|
58769
|
+
if (at > 0 && marketplace.length > 0) {
|
|
58770
|
+
return {
|
|
58771
|
+
ok: true,
|
|
58772
|
+
value: { marketplace, plugin },
|
|
58773
|
+
notice: `"allowedChannelPlugins" entry "${entry}" was accepted; prefer the documented object form {"plugin": "${plugin}", "marketplace": "${marketplace}"}.`
|
|
58774
|
+
};
|
|
58775
|
+
}
|
|
58776
|
+
}
|
|
58777
|
+
const parsed2 = CHANNEL_PLUGIN_ENTRY.safeParse(entry);
|
|
58778
|
+
return parsed2.success ? { ok: true, value: parsed2.data } : { ok: false, detail: issueDetail(parsed2.error) };
|
|
58779
|
+
}
|
|
58780
|
+
const parsed = STRING_ENTRY.safeParse(entry);
|
|
58781
|
+
return parsed.success ? { ok: true, value: parsed.data } : { ok: false, detail: issueDetail(parsed.error) };
|
|
58782
|
+
}
|
|
58783
|
+
function sanitizeSecurityAllowlists(data, filePath) {
|
|
58784
|
+
if (!data || typeof data !== "object")
|
|
58785
|
+
return [];
|
|
58786
|
+
const obj = data;
|
|
58787
|
+
const warnings = [];
|
|
58788
|
+
for (const { key, emptyReason } of ALLOWLIST_SPECS) {
|
|
58789
|
+
if (!(key in obj))
|
|
58790
|
+
continue;
|
|
58791
|
+
const raw = obj[key];
|
|
58792
|
+
if (!Array.isArray(raw)) {
|
|
58793
|
+
obj[key] = [];
|
|
58794
|
+
warnings.push({
|
|
58795
|
+
file: filePath,
|
|
58796
|
+
path: key,
|
|
58797
|
+
message: `"${key}" was present but invalid; enforcing an empty allowlist (${emptyReason}) until it is fixed.`,
|
|
58798
|
+
invalidValue: raw
|
|
58799
|
+
});
|
|
58800
|
+
continue;
|
|
58801
|
+
}
|
|
58802
|
+
const valid = [];
|
|
58803
|
+
for (const [index2, entry] of raw.entries()) {
|
|
58804
|
+
const result = validateAllowlistEntry(key, entry);
|
|
58805
|
+
if (result.ok) {
|
|
58806
|
+
valid.push(result.value);
|
|
58807
|
+
if (result.notice !== undefined) {
|
|
58808
|
+
warnings.push({
|
|
58809
|
+
file: filePath,
|
|
58810
|
+
path: `${key}[${index2}]`,
|
|
58811
|
+
message: result.notice
|
|
58812
|
+
});
|
|
58813
|
+
}
|
|
58814
|
+
} else {
|
|
58815
|
+
warnings.push({
|
|
58816
|
+
file: filePath,
|
|
58817
|
+
path: `${key}[${index2}]`,
|
|
58818
|
+
message: `Invalid entry was ignored: ${result.detail}`,
|
|
58819
|
+
invalidValue: entry
|
|
58820
|
+
});
|
|
58821
|
+
}
|
|
58822
|
+
}
|
|
58823
|
+
if (raw.length > 0 && valid.length === 0) {
|
|
58824
|
+
warnings.push({
|
|
58825
|
+
file: filePath,
|
|
58826
|
+
path: key,
|
|
58827
|
+
message: `Every entry of "${key}" was invalid; enforcing an empty allowlist (${emptyReason}) until it is fixed.`
|
|
58828
|
+
});
|
|
58829
|
+
}
|
|
58830
|
+
obj[key] = valid;
|
|
58831
|
+
}
|
|
58832
|
+
return warnings;
|
|
58833
|
+
}
|
|
58834
|
+
var STRING_ENTRY, CHANNEL_PLUGIN_ENTRY, ALLOWLIST_SPECS;
|
|
58835
|
+
var init_sanitizeAllowlists = __esm(() => {
|
|
58836
|
+
init_v4();
|
|
58837
|
+
STRING_ENTRY = exports_external.string();
|
|
58838
|
+
CHANNEL_PLUGIN_ENTRY = exports_external.object({
|
|
58839
|
+
marketplace: exports_external.string(),
|
|
58840
|
+
plugin: exports_external.string()
|
|
58841
|
+
});
|
|
58842
|
+
ALLOWLIST_SPECS = [
|
|
58843
|
+
{ key: "allowedHttpHookUrls", emptyReason: "no HTTP hooks may run" },
|
|
58844
|
+
{
|
|
58845
|
+
key: "httpHookAllowedEnvVars",
|
|
58846
|
+
emptyReason: "no environment variables may be interpolated into HTTP hook headers"
|
|
58847
|
+
},
|
|
58848
|
+
{ key: "allowedChannelPlugins", emptyReason: "no channel plugins admitted" }
|
|
58849
|
+
];
|
|
58850
|
+
});
|
|
58851
|
+
|
|
58852
|
+
// src/utils/stringUtils.ts
|
|
58853
|
+
function escapeRegExp(str) {
|
|
58854
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
58855
|
+
}
|
|
58856
|
+
function capitalize(str) {
|
|
58857
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
58858
|
+
}
|
|
58859
|
+
function plural(n2, word, pluralWord = word + "s") {
|
|
58860
|
+
return n2 === 1 ? word : pluralWord;
|
|
58861
|
+
}
|
|
58862
|
+
function firstLineOf(s) {
|
|
58863
|
+
const nl = s.indexOf(`
|
|
58864
|
+
`);
|
|
58865
|
+
return nl === -1 ? s : s.slice(0, nl);
|
|
58866
|
+
}
|
|
58867
|
+
function countCharInString(str, char, start = 0) {
|
|
58868
|
+
let count3 = 0;
|
|
58869
|
+
let i2 = str.indexOf(char, start);
|
|
58870
|
+
while (i2 !== -1) {
|
|
58871
|
+
count3++;
|
|
58872
|
+
i2 = str.indexOf(char, i2 + 1);
|
|
58873
|
+
}
|
|
58874
|
+
return count3;
|
|
58875
|
+
}
|
|
58876
|
+
function normalizeFullWidthDigits(input) {
|
|
58877
|
+
return input.replace(/[\uFF10-\uFF19]/g, (ch) => String.fromCharCode(ch.charCodeAt(0) - 65248));
|
|
58878
|
+
}
|
|
58879
|
+
function normalizeFullWidthSpace(input) {
|
|
58880
|
+
return input.replace(/\u3000/g, " ");
|
|
58881
|
+
}
|
|
58882
|
+
function safeJoinLines(lines, delimiter = ",", maxSize = MAX_STRING_LENGTH) {
|
|
58883
|
+
const truncationMarker = "...[truncated]";
|
|
58884
|
+
let result = "";
|
|
58885
|
+
for (const line of lines) {
|
|
58886
|
+
const delimiterToAdd = result ? delimiter : "";
|
|
58887
|
+
const fullAddition = delimiterToAdd + line;
|
|
58888
|
+
if (result.length + fullAddition.length <= maxSize) {
|
|
58889
|
+
result += fullAddition;
|
|
58890
|
+
} else {
|
|
58891
|
+
const remainingSpace = maxSize - result.length - delimiterToAdd.length - truncationMarker.length;
|
|
58892
|
+
if (remainingSpace > 0) {
|
|
58893
|
+
result += delimiterToAdd + line.slice(0, remainingSpace) + truncationMarker;
|
|
58894
|
+
} else {
|
|
58895
|
+
result += truncationMarker;
|
|
58896
|
+
}
|
|
58897
|
+
return result;
|
|
58898
|
+
}
|
|
58899
|
+
}
|
|
58900
|
+
return result;
|
|
58901
|
+
}
|
|
58902
|
+
|
|
58903
|
+
class EndTruncatingAccumulator {
|
|
58904
|
+
maxSize;
|
|
58905
|
+
content = "";
|
|
58906
|
+
isTruncated = false;
|
|
58907
|
+
totalBytesReceived = 0;
|
|
58908
|
+
constructor(maxSize = MAX_STRING_LENGTH) {
|
|
58909
|
+
this.maxSize = maxSize;
|
|
58910
|
+
}
|
|
58911
|
+
append(data) {
|
|
58912
|
+
const str = typeof data === "string" ? data : data.toString();
|
|
58913
|
+
this.totalBytesReceived += str.length;
|
|
58914
|
+
if (this.isTruncated && this.content.length >= this.maxSize) {
|
|
58915
|
+
return;
|
|
58916
|
+
}
|
|
58917
|
+
if (this.content.length + str.length > this.maxSize) {
|
|
58918
|
+
const remainingSpace = this.maxSize - this.content.length;
|
|
58919
|
+
if (remainingSpace > 0) {
|
|
58920
|
+
this.content += str.slice(0, remainingSpace);
|
|
58921
|
+
}
|
|
58922
|
+
this.isTruncated = true;
|
|
58923
|
+
} else {
|
|
58924
|
+
this.content += str;
|
|
58925
|
+
}
|
|
58926
|
+
}
|
|
58927
|
+
toString() {
|
|
58928
|
+
if (!this.isTruncated) {
|
|
58929
|
+
return this.content;
|
|
58930
|
+
}
|
|
58931
|
+
const truncatedBytes = this.totalBytesReceived - this.maxSize;
|
|
58932
|
+
const truncatedKB = Math.round(truncatedBytes / 1024);
|
|
58933
|
+
return this.content + `
|
|
58934
|
+
... [output truncated - ${truncatedKB}KB removed]`;
|
|
58935
|
+
}
|
|
58936
|
+
clear() {
|
|
58937
|
+
this.content = "";
|
|
58938
|
+
this.isTruncated = false;
|
|
58939
|
+
this.totalBytesReceived = 0;
|
|
58940
|
+
}
|
|
58941
|
+
get length() {
|
|
58942
|
+
return this.content.length;
|
|
58943
|
+
}
|
|
58944
|
+
get truncated() {
|
|
58945
|
+
return this.isTruncated;
|
|
58946
|
+
}
|
|
58947
|
+
get totalBytes() {
|
|
58948
|
+
return this.totalBytesReceived;
|
|
58949
|
+
}
|
|
58950
|
+
}
|
|
58951
|
+
function truncateToLines(text, maxLines) {
|
|
58952
|
+
const lines = text.split(`
|
|
58953
|
+
`);
|
|
58954
|
+
if (lines.length <= maxLines) {
|
|
58955
|
+
return text;
|
|
58956
|
+
}
|
|
58957
|
+
return lines.slice(0, maxLines).join(`
|
|
58958
|
+
`) + "\u2026";
|
|
58959
|
+
}
|
|
58960
|
+
var MAX_STRING_LENGTH;
|
|
58961
|
+
var init_stringUtils = __esm(() => {
|
|
58962
|
+
MAX_STRING_LENGTH = 2 ** 25;
|
|
58963
|
+
});
|
|
58964
|
+
|
|
58909
58965
|
// src/services/mcp/normalization.ts
|
|
58910
58966
|
function normalizeNameForMCP(name) {
|
|
58911
58967
|
let normalized = name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
@@ -59129,119 +59185,6 @@ var init_permissionRuleParser = __esm(() => {
|
|
|
59129
59185
|
};
|
|
59130
59186
|
});
|
|
59131
59187
|
|
|
59132
|
-
// src/utils/stringUtils.ts
|
|
59133
|
-
function escapeRegExp(str) {
|
|
59134
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
59135
|
-
}
|
|
59136
|
-
function capitalize(str) {
|
|
59137
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
59138
|
-
}
|
|
59139
|
-
function plural(n2, word, pluralWord = word + "s") {
|
|
59140
|
-
return n2 === 1 ? word : pluralWord;
|
|
59141
|
-
}
|
|
59142
|
-
function firstLineOf(s) {
|
|
59143
|
-
const nl = s.indexOf(`
|
|
59144
|
-
`);
|
|
59145
|
-
return nl === -1 ? s : s.slice(0, nl);
|
|
59146
|
-
}
|
|
59147
|
-
function countCharInString(str, char, start = 0) {
|
|
59148
|
-
let count3 = 0;
|
|
59149
|
-
let i2 = str.indexOf(char, start);
|
|
59150
|
-
while (i2 !== -1) {
|
|
59151
|
-
count3++;
|
|
59152
|
-
i2 = str.indexOf(char, i2 + 1);
|
|
59153
|
-
}
|
|
59154
|
-
return count3;
|
|
59155
|
-
}
|
|
59156
|
-
function normalizeFullWidthDigits(input) {
|
|
59157
|
-
return input.replace(/[\uFF10-\uFF19]/g, (ch) => String.fromCharCode(ch.charCodeAt(0) - 65248));
|
|
59158
|
-
}
|
|
59159
|
-
function normalizeFullWidthSpace(input) {
|
|
59160
|
-
return input.replace(/\u3000/g, " ");
|
|
59161
|
-
}
|
|
59162
|
-
function safeJoinLines(lines, delimiter = ",", maxSize = MAX_STRING_LENGTH) {
|
|
59163
|
-
const truncationMarker = "...[truncated]";
|
|
59164
|
-
let result = "";
|
|
59165
|
-
for (const line of lines) {
|
|
59166
|
-
const delimiterToAdd = result ? delimiter : "";
|
|
59167
|
-
const fullAddition = delimiterToAdd + line;
|
|
59168
|
-
if (result.length + fullAddition.length <= maxSize) {
|
|
59169
|
-
result += fullAddition;
|
|
59170
|
-
} else {
|
|
59171
|
-
const remainingSpace = maxSize - result.length - delimiterToAdd.length - truncationMarker.length;
|
|
59172
|
-
if (remainingSpace > 0) {
|
|
59173
|
-
result += delimiterToAdd + line.slice(0, remainingSpace) + truncationMarker;
|
|
59174
|
-
} else {
|
|
59175
|
-
result += truncationMarker;
|
|
59176
|
-
}
|
|
59177
|
-
return result;
|
|
59178
|
-
}
|
|
59179
|
-
}
|
|
59180
|
-
return result;
|
|
59181
|
-
}
|
|
59182
|
-
|
|
59183
|
-
class EndTruncatingAccumulator {
|
|
59184
|
-
maxSize;
|
|
59185
|
-
content = "";
|
|
59186
|
-
isTruncated = false;
|
|
59187
|
-
totalBytesReceived = 0;
|
|
59188
|
-
constructor(maxSize = MAX_STRING_LENGTH) {
|
|
59189
|
-
this.maxSize = maxSize;
|
|
59190
|
-
}
|
|
59191
|
-
append(data) {
|
|
59192
|
-
const str = typeof data === "string" ? data : data.toString();
|
|
59193
|
-
this.totalBytesReceived += str.length;
|
|
59194
|
-
if (this.isTruncated && this.content.length >= this.maxSize) {
|
|
59195
|
-
return;
|
|
59196
|
-
}
|
|
59197
|
-
if (this.content.length + str.length > this.maxSize) {
|
|
59198
|
-
const remainingSpace = this.maxSize - this.content.length;
|
|
59199
|
-
if (remainingSpace > 0) {
|
|
59200
|
-
this.content += str.slice(0, remainingSpace);
|
|
59201
|
-
}
|
|
59202
|
-
this.isTruncated = true;
|
|
59203
|
-
} else {
|
|
59204
|
-
this.content += str;
|
|
59205
|
-
}
|
|
59206
|
-
}
|
|
59207
|
-
toString() {
|
|
59208
|
-
if (!this.isTruncated) {
|
|
59209
|
-
return this.content;
|
|
59210
|
-
}
|
|
59211
|
-
const truncatedBytes = this.totalBytesReceived - this.maxSize;
|
|
59212
|
-
const truncatedKB = Math.round(truncatedBytes / 1024);
|
|
59213
|
-
return this.content + `
|
|
59214
|
-
... [output truncated - ${truncatedKB}KB removed]`;
|
|
59215
|
-
}
|
|
59216
|
-
clear() {
|
|
59217
|
-
this.content = "";
|
|
59218
|
-
this.isTruncated = false;
|
|
59219
|
-
this.totalBytesReceived = 0;
|
|
59220
|
-
}
|
|
59221
|
-
get length() {
|
|
59222
|
-
return this.content.length;
|
|
59223
|
-
}
|
|
59224
|
-
get truncated() {
|
|
59225
|
-
return this.isTruncated;
|
|
59226
|
-
}
|
|
59227
|
-
get totalBytes() {
|
|
59228
|
-
return this.totalBytesReceived;
|
|
59229
|
-
}
|
|
59230
|
-
}
|
|
59231
|
-
function truncateToLines(text, maxLines) {
|
|
59232
|
-
const lines = text.split(`
|
|
59233
|
-
`);
|
|
59234
|
-
if (lines.length <= maxLines) {
|
|
59235
|
-
return text;
|
|
59236
|
-
}
|
|
59237
|
-
return lines.slice(0, maxLines).join(`
|
|
59238
|
-
`) + "\u2026";
|
|
59239
|
-
}
|
|
59240
|
-
var MAX_STRING_LENGTH;
|
|
59241
|
-
var init_stringUtils = __esm(() => {
|
|
59242
|
-
MAX_STRING_LENGTH = 2 ** 25;
|
|
59243
|
-
});
|
|
59244
|
-
|
|
59245
59188
|
// src/utils/settings/toolValidationConfig.ts
|
|
59246
59189
|
function isFilePatternTool(toolName) {
|
|
59247
59190
|
return TOOL_VALIDATION_CONFIG.filePatternTools.includes(toolName);
|
|
@@ -59528,6 +59471,492 @@ var init_permissionValidation = __esm(() => {
|
|
|
59528
59471
|
}));
|
|
59529
59472
|
});
|
|
59530
59473
|
|
|
59474
|
+
// src/entrypoints/sandboxTypes.ts
|
|
59475
|
+
var SandboxNetworkConfigSchema, SandboxFilesystemConfigSchema, SandboxSettingsSchema;
|
|
59476
|
+
var init_sandboxTypes = __esm(() => {
|
|
59477
|
+
init_v4();
|
|
59478
|
+
SandboxNetworkConfigSchema = lazySchema(() => exports_external.object({
|
|
59479
|
+
allowedDomains: exports_external.array(exports_external.string()).optional(),
|
|
59480
|
+
deniedDomains: exports_external.array(exports_external.string()).optional().describe("Domains to block even when a broader allowedDomains wildcard would otherwise permit them."),
|
|
59481
|
+
allowManagedDomainsOnly: exports_external.boolean().optional().describe("When true (and set in managed settings), only allowedDomains and WebFetch(domain:...) allow rules from managed settings are respected. " + "User, project, local, and flag settings domains are ignored. Denied domains are still respected from all sources."),
|
|
59482
|
+
strictAllowlist: exports_external.boolean().optional().describe("When true, the sandbox runtime deterministically denies hosts not in allowedDomains instead of prompting. " + "Enforced for sandboxed commands only \u2014 in-process tools such as WebFetch are not gated by this setting. " + "Only honored from user, managed/policy, or CLI (--settings) settings \u2014 " + "project settings (.claude/settings.json and .claude/settings.local.json) are ignored."),
|
|
59483
|
+
allowUnixSockets: exports_external.array(exports_external.string()).optional().describe("macOS only: Unix socket paths to allow. Ignored on Linux (seccomp cannot filter by path)."),
|
|
59484
|
+
allowAllUnixSockets: exports_external.boolean().optional().describe("If true, allow all Unix sockets (disables blocking on both platforms)."),
|
|
59485
|
+
allowLocalBinding: exports_external.boolean().optional(),
|
|
59486
|
+
httpProxyPort: exports_external.number().optional(),
|
|
59487
|
+
socksProxyPort: exports_external.number().optional()
|
|
59488
|
+
}).optional());
|
|
59489
|
+
SandboxFilesystemConfigSchema = lazySchema(() => exports_external.object({
|
|
59490
|
+
disabled: exports_external.boolean().optional().describe("macOS and Linux/WSL only: skip filesystem isolation entirely while " + "keeping network and seccomp isolation. Ignored on native Windows, " + "where the sandboxed process runs as a separate user with no " + "inherent rights, so skipping the filesystem rules would withhold " + "every access grant rather than loosen them \u2014 filesystem isolation " + "stays on there."),
|
|
59491
|
+
allowWrite: exports_external.array(exports_external.string()).optional().describe("Additional paths to allow writing within the sandbox. " + "Merged with paths from Edit(...) allow permission rules."),
|
|
59492
|
+
denyWrite: exports_external.array(exports_external.string()).optional().describe("Additional paths to deny writing within the sandbox. " + "Merged with paths from Edit(...) deny permission rules."),
|
|
59493
|
+
denyRead: exports_external.array(exports_external.string()).optional().describe("Additional paths to deny reading within the sandbox. " + "Merged with paths from Read(...) deny permission rules."),
|
|
59494
|
+
allowRead: exports_external.array(exports_external.string()).optional().describe("Paths to re-allow reading within denyRead regions. " + "Takes precedence over denyRead for matching paths."),
|
|
59495
|
+
allowManagedReadPathsOnly: exports_external.boolean().optional().describe("When true (set in managed settings), only allowRead paths from policySettings are used.")
|
|
59496
|
+
}).optional());
|
|
59497
|
+
SandboxSettingsSchema = lazySchema(() => exports_external.object({
|
|
59498
|
+
enabled: exports_external.boolean().optional(),
|
|
59499
|
+
failIfUnavailable: exports_external.boolean().optional().describe("Exit with an error at startup if sandbox.enabled is true but the sandbox cannot start " + "(missing dependencies, unsupported platform, or platform not in enabledPlatforms). " + "When false (default), a warning is shown and commands run unsandboxed. " + "Intended for managed-settings deployments that require sandboxing as a hard gate."),
|
|
59500
|
+
autoAllowBashIfSandboxed: exports_external.boolean().optional(),
|
|
59501
|
+
allowUnsandboxedCommands: exports_external.boolean().optional().describe("Allow commands to run outside the sandbox via the dangerouslyDisableSandbox parameter. " + "When false, the dangerouslyDisableSandbox parameter is completely ignored and all commands must run sandboxed. " + "Default: true."),
|
|
59502
|
+
network: SandboxNetworkConfigSchema(),
|
|
59503
|
+
filesystem: SandboxFilesystemConfigSchema(),
|
|
59504
|
+
ignoreViolations: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
|
|
59505
|
+
enableWeakerNestedSandbox: exports_external.boolean().optional(),
|
|
59506
|
+
enableWeakerNetworkIsolation: exports_external.boolean().optional().describe("macOS only: Allow access to com.apple.trustd.agent in the sandbox. " + "Needed for Go-based CLI tools (gh, gcloud, terraform, etc.) to verify TLS certificates " + "when using httpProxyPort with a MITM proxy and custom CA. " + "**Reduces security** \u2014 opens a potential data exfiltration vector through the trustd service. Default: false"),
|
|
59507
|
+
allowAppleEvents: exports_external.boolean().optional().describe("macOS only: Allow sandboxed commands to send Apple Events to other " + "applications via the Apple Event service. Default: false"),
|
|
59508
|
+
excludedCommands: exports_external.array(exports_external.string()).optional(),
|
|
59509
|
+
credentials: exports_external.object({
|
|
59510
|
+
enabled: exports_external.boolean().optional().describe("When true, block sandboxed commands from reading credential files and secret env vars.")
|
|
59511
|
+
}).optional(),
|
|
59512
|
+
ripgrep: exports_external.object({
|
|
59513
|
+
command: exports_external.string(),
|
|
59514
|
+
args: exports_external.array(exports_external.string()).optional()
|
|
59515
|
+
}).optional().describe("Custom ripgrep configuration for bundled ripgrep support")
|
|
59516
|
+
}).passthrough());
|
|
59517
|
+
});
|
|
59518
|
+
|
|
59519
|
+
// src/utils/bundledMode.ts
|
|
59520
|
+
function isRunningWithBun() {
|
|
59521
|
+
return process.versions.bun !== undefined;
|
|
59522
|
+
}
|
|
59523
|
+
function isInBundledMode() {
|
|
59524
|
+
return typeof Bun !== "undefined" && Array.isArray(Bun.embeddedFiles) && Bun.embeddedFiles.length > 0;
|
|
59525
|
+
}
|
|
59526
|
+
|
|
59527
|
+
// src/utils/findExecutable.ts
|
|
59528
|
+
function findExecutable2(exe, args) {
|
|
59529
|
+
const resolved = whichSync(exe);
|
|
59530
|
+
return { cmd: resolved ?? exe, args };
|
|
59531
|
+
}
|
|
59532
|
+
var init_findExecutable = __esm(() => {
|
|
59533
|
+
init_which();
|
|
59534
|
+
});
|
|
59535
|
+
|
|
59536
|
+
// src/utils/env.ts
|
|
59537
|
+
import { homedir as homedir8 } from "os";
|
|
59538
|
+
import { join as join17 } from "path";
|
|
59539
|
+
async function isCommandAvailable(command) {
|
|
59540
|
+
try {
|
|
59541
|
+
return !!await which(command);
|
|
59542
|
+
} catch {
|
|
59543
|
+
return false;
|
|
59544
|
+
}
|
|
59545
|
+
}
|
|
59546
|
+
function isConductor() {
|
|
59547
|
+
return process.env.__CFBundleIdentifier === "com.conductor.app";
|
|
59548
|
+
}
|
|
59549
|
+
function detectTerminal() {
|
|
59550
|
+
if (process.env.CURSOR_TRACE_ID)
|
|
59551
|
+
return "cursor";
|
|
59552
|
+
if (process.env.VSCODE_GIT_ASKPASS_MAIN?.includes("cursor")) {
|
|
59553
|
+
return "cursor";
|
|
59554
|
+
}
|
|
59555
|
+
if (process.env.VSCODE_GIT_ASKPASS_MAIN?.includes("windsurf")) {
|
|
59556
|
+
return "windsurf";
|
|
59557
|
+
}
|
|
59558
|
+
if (process.env.VSCODE_GIT_ASKPASS_MAIN?.includes("antigravity")) {
|
|
59559
|
+
return "antigravity";
|
|
59560
|
+
}
|
|
59561
|
+
const bundleId = process.env.__CFBundleIdentifier?.toLowerCase();
|
|
59562
|
+
if (bundleId?.includes("vscodium"))
|
|
59563
|
+
return "codium";
|
|
59564
|
+
if (bundleId?.includes("windsurf"))
|
|
59565
|
+
return "windsurf";
|
|
59566
|
+
if (bundleId?.includes("com.google.android.studio"))
|
|
59567
|
+
return "androidstudio";
|
|
59568
|
+
if (bundleId) {
|
|
59569
|
+
for (const ide of JETBRAINS_IDES) {
|
|
59570
|
+
if (bundleId.includes(ide))
|
|
59571
|
+
return ide;
|
|
59572
|
+
}
|
|
59573
|
+
}
|
|
59574
|
+
if (process.env.VisualStudioVersion) {
|
|
59575
|
+
return "visualstudio";
|
|
59576
|
+
}
|
|
59577
|
+
if (process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm") {
|
|
59578
|
+
if (process.platform === "darwin")
|
|
59579
|
+
return "pycharm";
|
|
59580
|
+
return "pycharm";
|
|
59581
|
+
}
|
|
59582
|
+
if (process.env.TERM === "xterm-ghostty") {
|
|
59583
|
+
return "ghostty";
|
|
59584
|
+
}
|
|
59585
|
+
if (process.env.TERM?.includes("kitty")) {
|
|
59586
|
+
return "kitty";
|
|
59587
|
+
}
|
|
59588
|
+
if (process.env.TERM_PROGRAM) {
|
|
59589
|
+
return process.env.TERM_PROGRAM;
|
|
59590
|
+
}
|
|
59591
|
+
if (process.env.TMUX)
|
|
59592
|
+
return "tmux";
|
|
59593
|
+
if (process.env.STY)
|
|
59594
|
+
return "screen";
|
|
59595
|
+
if (process.env.KONSOLE_VERSION)
|
|
59596
|
+
return "konsole";
|
|
59597
|
+
if (process.env.GNOME_TERMINAL_SERVICE)
|
|
59598
|
+
return "gnome-terminal";
|
|
59599
|
+
if (process.env.XTERM_VERSION)
|
|
59600
|
+
return "xterm";
|
|
59601
|
+
if (process.env.VTE_VERSION)
|
|
59602
|
+
return "vte-based";
|
|
59603
|
+
if (process.env.TERMINATOR_UUID)
|
|
59604
|
+
return "terminator";
|
|
59605
|
+
if (process.env.KITTY_WINDOW_ID) {
|
|
59606
|
+
return "kitty";
|
|
59607
|
+
}
|
|
59608
|
+
if (process.env.ALACRITTY_LOG)
|
|
59609
|
+
return "alacritty";
|
|
59610
|
+
if (process.env.TILIX_ID)
|
|
59611
|
+
return "tilix";
|
|
59612
|
+
if (process.env.WT_SESSION)
|
|
59613
|
+
return "windows-terminal";
|
|
59614
|
+
if (process.env.SESSIONNAME && process.env.TERM === "cygwin")
|
|
59615
|
+
return "cygwin";
|
|
59616
|
+
if (process.env.MSYSTEM)
|
|
59617
|
+
return process.env.MSYSTEM.toLowerCase();
|
|
59618
|
+
if (process.env.ConEmuANSI || process.env.ConEmuPID || process.env.ConEmuTask) {
|
|
59619
|
+
return "conemu";
|
|
59620
|
+
}
|
|
59621
|
+
if (process.env.WSL_DISTRO_NAME)
|
|
59622
|
+
return `wsl-${process.env.WSL_DISTRO_NAME}`;
|
|
59623
|
+
if (isSSHSession()) {
|
|
59624
|
+
return "ssh-session";
|
|
59625
|
+
}
|
|
59626
|
+
if (process.env.TERM) {
|
|
59627
|
+
const term = process.env.TERM;
|
|
59628
|
+
if (term.includes("alacritty"))
|
|
59629
|
+
return "alacritty";
|
|
59630
|
+
if (term.includes("rxvt"))
|
|
59631
|
+
return "rxvt";
|
|
59632
|
+
if (term.includes("termite"))
|
|
59633
|
+
return "termite";
|
|
59634
|
+
return process.env.TERM;
|
|
59635
|
+
}
|
|
59636
|
+
if (!process.stdout.isTTY)
|
|
59637
|
+
return "non-interactive";
|
|
59638
|
+
return null;
|
|
59639
|
+
}
|
|
59640
|
+
function isSSHSession() {
|
|
59641
|
+
return !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY);
|
|
59642
|
+
}
|
|
59643
|
+
function getHostPlatformForAnalytics() {
|
|
59644
|
+
const override = process.env.CLAUDE_CODE_HOST_PLATFORM;
|
|
59645
|
+
if (override === "win32" || override === "darwin" || override === "linux") {
|
|
59646
|
+
return override;
|
|
59647
|
+
}
|
|
59648
|
+
return env4.platform;
|
|
59649
|
+
}
|
|
59650
|
+
var getGlobalClaudeFile, hasInternetAccess, detectPackageManagers, detectRuntimes, isWslEnvironment, isNpmFromWindowsPath, JETBRAINS_IDES, detectDeploymentEnvironment, env4;
|
|
59651
|
+
var init_env = __esm(() => {
|
|
59652
|
+
init_memoize();
|
|
59653
|
+
init_oauth();
|
|
59654
|
+
init_envUtils();
|
|
59655
|
+
init_findExecutable();
|
|
59656
|
+
init_fsOperations();
|
|
59657
|
+
init_which();
|
|
59658
|
+
getGlobalClaudeFile = memoize_default(() => {
|
|
59659
|
+
if (getFsImplementation().existsSync(join17(getClaudeConfigHomeDir(), ".config.json"))) {
|
|
59660
|
+
return join17(getClaudeConfigHomeDir(), ".config.json");
|
|
59661
|
+
}
|
|
59662
|
+
const filename = `.claude${fileSuffixForOauthConfig()}.json`;
|
|
59663
|
+
const p = join17(process.env.CLAUDE_CONFIG_DIR || homedir8(), filename);
|
|
59664
|
+
return p;
|
|
59665
|
+
});
|
|
59666
|
+
hasInternetAccess = memoize_default(async () => {
|
|
59667
|
+
try {
|
|
59668
|
+
const { default: axiosClient } = await Promise.resolve().then(() => (init_axios2(), exports_axios));
|
|
59669
|
+
await axiosClient.head("http://1.1.1.1", {
|
|
59670
|
+
signal: AbortSignal.timeout(1000)
|
|
59671
|
+
});
|
|
59672
|
+
return true;
|
|
59673
|
+
} catch {
|
|
59674
|
+
return false;
|
|
59675
|
+
}
|
|
59676
|
+
});
|
|
59677
|
+
detectPackageManagers = memoize_default(async () => {
|
|
59678
|
+
const packageManagers = [];
|
|
59679
|
+
if (await isCommandAvailable("npm"))
|
|
59680
|
+
packageManagers.push("npm");
|
|
59681
|
+
if (await isCommandAvailable("yarn"))
|
|
59682
|
+
packageManagers.push("yarn");
|
|
59683
|
+
if (await isCommandAvailable("pnpm"))
|
|
59684
|
+
packageManagers.push("pnpm");
|
|
59685
|
+
return packageManagers;
|
|
59686
|
+
});
|
|
59687
|
+
detectRuntimes = memoize_default(async () => {
|
|
59688
|
+
const runtimes = [];
|
|
59689
|
+
if (await isCommandAvailable("bun"))
|
|
59690
|
+
runtimes.push("bun");
|
|
59691
|
+
if (await isCommandAvailable("deno"))
|
|
59692
|
+
runtimes.push("deno");
|
|
59693
|
+
if (await isCommandAvailable("node"))
|
|
59694
|
+
runtimes.push("node");
|
|
59695
|
+
return runtimes;
|
|
59696
|
+
});
|
|
59697
|
+
isWslEnvironment = memoize_default(() => {
|
|
59698
|
+
try {
|
|
59699
|
+
return getFsImplementation().existsSync("/proc/sys/fs/binfmt_misc/WSLInterop");
|
|
59700
|
+
} catch (_error) {
|
|
59701
|
+
return false;
|
|
59702
|
+
}
|
|
59703
|
+
});
|
|
59704
|
+
isNpmFromWindowsPath = memoize_default(() => {
|
|
59705
|
+
try {
|
|
59706
|
+
if (!isWslEnvironment()) {
|
|
59707
|
+
return false;
|
|
59708
|
+
}
|
|
59709
|
+
const { cmd } = findExecutable2("npm", []);
|
|
59710
|
+
return cmd.startsWith("/mnt/c/");
|
|
59711
|
+
} catch (_error) {
|
|
59712
|
+
return false;
|
|
59713
|
+
}
|
|
59714
|
+
});
|
|
59715
|
+
JETBRAINS_IDES = [
|
|
59716
|
+
"pycharm",
|
|
59717
|
+
"intellij",
|
|
59718
|
+
"webstorm",
|
|
59719
|
+
"phpstorm",
|
|
59720
|
+
"rubymine",
|
|
59721
|
+
"clion",
|
|
59722
|
+
"goland",
|
|
59723
|
+
"rider",
|
|
59724
|
+
"datagrip",
|
|
59725
|
+
"appcode",
|
|
59726
|
+
"dataspell",
|
|
59727
|
+
"aqua",
|
|
59728
|
+
"gateway",
|
|
59729
|
+
"fleet",
|
|
59730
|
+
"jetbrains",
|
|
59731
|
+
"androidstudio"
|
|
59732
|
+
];
|
|
59733
|
+
detectDeploymentEnvironment = memoize_default(() => {
|
|
59734
|
+
if (isEnvTruthy(process.env.CODESPACES))
|
|
59735
|
+
return "codespaces";
|
|
59736
|
+
if (process.env.GITPOD_WORKSPACE_ID)
|
|
59737
|
+
return "gitpod";
|
|
59738
|
+
if (process.env.REPL_ID || process.env.REPL_SLUG)
|
|
59739
|
+
return "replit";
|
|
59740
|
+
if (process.env.PROJECT_DOMAIN)
|
|
59741
|
+
return "glitch";
|
|
59742
|
+
if (isEnvTruthy(process.env.VERCEL))
|
|
59743
|
+
return "vercel";
|
|
59744
|
+
if (process.env.RAILWAY_ENVIRONMENT_NAME || process.env.RAILWAY_SERVICE_NAME) {
|
|
59745
|
+
return "railway";
|
|
59746
|
+
}
|
|
59747
|
+
if (isEnvTruthy(process.env.RENDER))
|
|
59748
|
+
return "render";
|
|
59749
|
+
if (isEnvTruthy(process.env.NETLIFY))
|
|
59750
|
+
return "netlify";
|
|
59751
|
+
if (process.env.DYNO)
|
|
59752
|
+
return "heroku";
|
|
59753
|
+
if (process.env.FLY_APP_NAME || process.env.FLY_MACHINE_ID)
|
|
59754
|
+
return "fly.io";
|
|
59755
|
+
if (isEnvTruthy(process.env.CF_PAGES))
|
|
59756
|
+
return "cloudflare-pages";
|
|
59757
|
+
if (process.env.DENO_DEPLOYMENT_ID)
|
|
59758
|
+
return "deno-deploy";
|
|
59759
|
+
if (process.env.AWS_LAMBDA_FUNCTION_NAME)
|
|
59760
|
+
return "aws-lambda";
|
|
59761
|
+
if (process.env.AWS_EXECUTION_ENV === "AWS_ECS_FARGATE")
|
|
59762
|
+
return "aws-fargate";
|
|
59763
|
+
if (process.env.AWS_EXECUTION_ENV === "AWS_ECS_EC2")
|
|
59764
|
+
return "aws-ecs";
|
|
59765
|
+
try {
|
|
59766
|
+
const uuid3 = getFsImplementation().readFileSync("/sys/hypervisor/uuid", { encoding: "utf8" }).trim().toLowerCase();
|
|
59767
|
+
if (uuid3.startsWith("ec2"))
|
|
59768
|
+
return "aws-ec2";
|
|
59769
|
+
} catch {}
|
|
59770
|
+
if (process.env.K_SERVICE)
|
|
59771
|
+
return "gcp-cloud-run";
|
|
59772
|
+
if (process.env.GOOGLE_CLOUD_PROJECT)
|
|
59773
|
+
return "gcp";
|
|
59774
|
+
if (process.env.WEBSITE_SITE_NAME || process.env.WEBSITE_SKU)
|
|
59775
|
+
return "azure-app-service";
|
|
59776
|
+
if (process.env.AZURE_FUNCTIONS_ENVIRONMENT)
|
|
59777
|
+
return "azure-functions";
|
|
59778
|
+
if (process.env.APP_URL?.includes("ondigitalocean.app")) {
|
|
59779
|
+
return "digitalocean-app-platform";
|
|
59780
|
+
}
|
|
59781
|
+
if (process.env.SPACE_CREATOR_USER_ID)
|
|
59782
|
+
return "huggingface-spaces";
|
|
59783
|
+
if (isEnvTruthy(process.env.GITHUB_ACTIONS))
|
|
59784
|
+
return "github-actions";
|
|
59785
|
+
if (isEnvTruthy(process.env.GITLAB_CI))
|
|
59786
|
+
return "gitlab-ci";
|
|
59787
|
+
if (process.env.CIRCLECI)
|
|
59788
|
+
return "circleci";
|
|
59789
|
+
if (process.env.BUILDKITE)
|
|
59790
|
+
return "buildkite";
|
|
59791
|
+
if (isEnvTruthy(process.env.CI))
|
|
59792
|
+
return "ci";
|
|
59793
|
+
if (process.env.KUBERNETES_SERVICE_HOST)
|
|
59794
|
+
return "kubernetes";
|
|
59795
|
+
try {
|
|
59796
|
+
if (getFsImplementation().existsSync("/.dockerenv"))
|
|
59797
|
+
return "docker";
|
|
59798
|
+
} catch {}
|
|
59799
|
+
if (env4.platform === "darwin")
|
|
59800
|
+
return "unknown-darwin";
|
|
59801
|
+
if (env4.platform === "linux")
|
|
59802
|
+
return "unknown-linux";
|
|
59803
|
+
if (env4.platform === "win32")
|
|
59804
|
+
return "unknown-win32";
|
|
59805
|
+
return "unknown";
|
|
59806
|
+
});
|
|
59807
|
+
env4 = {
|
|
59808
|
+
hasInternetAccess,
|
|
59809
|
+
isCI: isEnvTruthy(process.env.CI),
|
|
59810
|
+
platform: ["win32", "darwin"].includes(process.platform) ? process.platform : "linux",
|
|
59811
|
+
arch: process.arch,
|
|
59812
|
+
nodeVersion: process.version,
|
|
59813
|
+
terminal: detectTerminal(),
|
|
59814
|
+
isSSH: isSSHSession,
|
|
59815
|
+
getPackageManagers: detectPackageManagers,
|
|
59816
|
+
getRuntimes: detectRuntimes,
|
|
59817
|
+
isRunningWithBun: memoize_default(isRunningWithBun),
|
|
59818
|
+
isWslEnvironment,
|
|
59819
|
+
isNpmFromWindowsPath,
|
|
59820
|
+
isConductor,
|
|
59821
|
+
detectDeploymentEnvironment
|
|
59822
|
+
};
|
|
59823
|
+
});
|
|
59824
|
+
|
|
59825
|
+
// src/constants/figures.ts
|
|
59826
|
+
var BLACK_CIRCLE, BULLET_OPERATOR = "\u2219", TEARDROP_ASTERISK = "\u273B", UP_ARROW = "\u2191", DOWN_ARROW = "\u2193", LIGHTNING_BOLT = "\u21AF", EFFORT_LOW = "\u25CB", EFFORT_MEDIUM = "\u25D0", EFFORT_HIGH = "\u25CF", EFFORT_XHIGH = "\u25C9", EFFORT_MAX = "\u25C8", PAUSE_ICON = "\u23F8", REFRESH_ARROW = "\u21BB", CHANNEL_ARROW = "\u2190", DIAMOND_OPEN = "\u25C7", DIAMOND_FILLED = "\u25C6", REFERENCE_MARK = "\u203B", BLOCKQUOTE_BAR = "\u258E", BRIDGE_SPINNER_FRAMES, BRIDGE_READY_INDICATOR = "\xB7\u2714\uFE0E\xB7", BRIDGE_FAILED_INDICATOR = "\xD7";
|
|
59827
|
+
var init_figures2 = __esm(() => {
|
|
59828
|
+
init_env();
|
|
59829
|
+
BLACK_CIRCLE = env4.platform === "darwin" ? "\u23FA" : "\u25CF";
|
|
59830
|
+
BRIDGE_SPINNER_FRAMES = [
|
|
59831
|
+
"\xB7|\xB7",
|
|
59832
|
+
"\xB7/\xB7",
|
|
59833
|
+
"\xB7\u2014\xB7",
|
|
59834
|
+
"\xB7\\\xB7"
|
|
59835
|
+
];
|
|
59836
|
+
});
|
|
59837
|
+
|
|
59838
|
+
// src/types/permissions.ts
|
|
59839
|
+
var exports_permissions = {};
|
|
59840
|
+
__export(exports_permissions, {
|
|
59841
|
+
PERMISSION_MODES_CLI_CHOICES: () => PERMISSION_MODES_CLI_CHOICES,
|
|
59842
|
+
PERMISSION_MODES: () => PERMISSION_MODES,
|
|
59843
|
+
INTERNAL_PERMISSION_MODES: () => INTERNAL_PERMISSION_MODES,
|
|
59844
|
+
EXTERNAL_PERMISSION_MODES: () => EXTERNAL_PERMISSION_MODES
|
|
59845
|
+
});
|
|
59846
|
+
var EXTERNAL_PERMISSION_MODES, INTERNAL_PERMISSION_MODES, PERMISSION_MODES, PERMISSION_MODES_CLI_CHOICES;
|
|
59847
|
+
var init_permissions = __esm(() => {
|
|
59848
|
+
EXTERNAL_PERMISSION_MODES = [
|
|
59849
|
+
"acceptEdits",
|
|
59850
|
+
"auto",
|
|
59851
|
+
"bypassPermissions",
|
|
59852
|
+
"default",
|
|
59853
|
+
"dontAsk",
|
|
59854
|
+
"plan"
|
|
59855
|
+
];
|
|
59856
|
+
INTERNAL_PERMISSION_MODES = [
|
|
59857
|
+
...EXTERNAL_PERMISSION_MODES
|
|
59858
|
+
];
|
|
59859
|
+
PERMISSION_MODES = INTERNAL_PERMISSION_MODES;
|
|
59860
|
+
PERMISSION_MODES_CLI_CHOICES = PERMISSION_MODES.map((mode) => mode === "default" ? "manual" : mode);
|
|
59861
|
+
});
|
|
59862
|
+
|
|
59863
|
+
// src/utils/permissions/PermissionMode.ts
|
|
59864
|
+
function isExternalPermissionMode(mode) {
|
|
59865
|
+
if (process.env.USER_TYPE !== "ant") {
|
|
59866
|
+
return true;
|
|
59867
|
+
}
|
|
59868
|
+
return mode !== "auto" && mode !== "bubble";
|
|
59869
|
+
}
|
|
59870
|
+
function getModeConfig(mode) {
|
|
59871
|
+
return PERMISSION_MODE_CONFIG[mode] ?? PERMISSION_MODE_CONFIG.default;
|
|
59872
|
+
}
|
|
59873
|
+
function toExternalPermissionMode(mode) {
|
|
59874
|
+
return getModeConfig(mode).external;
|
|
59875
|
+
}
|
|
59876
|
+
function normalizePermissionModeInput(str) {
|
|
59877
|
+
return str === PERMISSION_MODE_MANUAL_ALIAS ? "default" : str;
|
|
59878
|
+
}
|
|
59879
|
+
function permissionModeFromString(str) {
|
|
59880
|
+
const normalized = normalizePermissionModeInput(str);
|
|
59881
|
+
return PERMISSION_MODES.includes(normalized) ? normalized : "default";
|
|
59882
|
+
}
|
|
59883
|
+
function permissionModeTitle(mode) {
|
|
59884
|
+
return getModeConfig(mode).title;
|
|
59885
|
+
}
|
|
59886
|
+
function isDefaultMode(mode) {
|
|
59887
|
+
return mode === "default" || mode === undefined;
|
|
59888
|
+
}
|
|
59889
|
+
function permissionModeSymbol(mode) {
|
|
59890
|
+
return getModeConfig(mode).symbol;
|
|
59891
|
+
}
|
|
59892
|
+
function permissionModeIndicator(mode) {
|
|
59893
|
+
return getModeConfig(mode).indicator;
|
|
59894
|
+
}
|
|
59895
|
+
function getModeColor(mode) {
|
|
59896
|
+
return getModeConfig(mode).color;
|
|
59897
|
+
}
|
|
59898
|
+
var permissionModeSchema, externalPermissionModeSchema, PERMISSION_MODE_MANUAL_ALIAS = "manual", PERMISSION_MODE_CONFIG;
|
|
59899
|
+
var init_PermissionMode = __esm(() => {
|
|
59900
|
+
init_featureFlags();
|
|
59901
|
+
init_v4();
|
|
59902
|
+
init_figures2();
|
|
59903
|
+
init_permissions();
|
|
59904
|
+
permissionModeSchema = lazySchema(() => v4_default.enum(PERMISSION_MODES));
|
|
59905
|
+
externalPermissionModeSchema = lazySchema(() => v4_default.enum(EXTERNAL_PERMISSION_MODES));
|
|
59906
|
+
PERMISSION_MODE_CONFIG = {
|
|
59907
|
+
default: {
|
|
59908
|
+
title: "Manual",
|
|
59909
|
+
shortTitle: "Manual",
|
|
59910
|
+
symbol: PAUSE_ICON,
|
|
59911
|
+
color: "text",
|
|
59912
|
+
external: "default",
|
|
59913
|
+
indicator: "manual mode"
|
|
59914
|
+
},
|
|
59915
|
+
plan: {
|
|
59916
|
+
title: "Plan Mode",
|
|
59917
|
+
shortTitle: "Plan",
|
|
59918
|
+
symbol: PAUSE_ICON,
|
|
59919
|
+
color: "planMode",
|
|
59920
|
+
external: "plan",
|
|
59921
|
+
indicator: "plan mode"
|
|
59922
|
+
},
|
|
59923
|
+
acceptEdits: {
|
|
59924
|
+
title: "Accept edits",
|
|
59925
|
+
shortTitle: "Accept",
|
|
59926
|
+
symbol: "\u23F5\u23F5",
|
|
59927
|
+
color: "autoAccept",
|
|
59928
|
+
external: "acceptEdits",
|
|
59929
|
+
indicator: "accept edits"
|
|
59930
|
+
},
|
|
59931
|
+
bypassPermissions: {
|
|
59932
|
+
title: "Bypass Permissions",
|
|
59933
|
+
shortTitle: "Bypass",
|
|
59934
|
+
symbol: "\u23F5\u23F5",
|
|
59935
|
+
color: "error",
|
|
59936
|
+
external: "bypassPermissions",
|
|
59937
|
+
indicator: "bypass permissions"
|
|
59938
|
+
},
|
|
59939
|
+
dontAsk: {
|
|
59940
|
+
title: "Don't Ask",
|
|
59941
|
+
shortTitle: "DontAsk",
|
|
59942
|
+
symbol: "\u23F5\u23F5",
|
|
59943
|
+
color: "error",
|
|
59944
|
+
external: "dontAsk",
|
|
59945
|
+
indicator: "don't ask"
|
|
59946
|
+
},
|
|
59947
|
+
...feature("TRANSCRIPT_CLASSIFIER") ? {
|
|
59948
|
+
auto: {
|
|
59949
|
+
title: "Auto mode",
|
|
59950
|
+
shortTitle: "Auto",
|
|
59951
|
+
symbol: "\u23F5\u23F5",
|
|
59952
|
+
color: "warning",
|
|
59953
|
+
external: "default",
|
|
59954
|
+
indicator: "auto mode"
|
|
59955
|
+
}
|
|
59956
|
+
} : {}
|
|
59957
|
+
};
|
|
59958
|
+
});
|
|
59959
|
+
|
|
59531
59960
|
// src/utils/settings/types.ts
|
|
59532
59961
|
function isMcpServerNameEntry(entry) {
|
|
59533
59962
|
return "serverName" in entry && entry.serverName !== undefined;
|
|
@@ -60111,6 +60540,20 @@ var init_validation2 = __esm(() => {
|
|
|
60111
60540
|
init_validationTips();
|
|
60112
60541
|
});
|
|
60113
60542
|
|
|
60543
|
+
// src/utils/settings/policySourceSanitizer.ts
|
|
60544
|
+
function sanitizePolicySourceData(data, sourcePath) {
|
|
60545
|
+
return [
|
|
60546
|
+
...filterInvalidPermissionRules(data, sourcePath),
|
|
60547
|
+
...sanitizeSecurityAllowlists(data, sourcePath),
|
|
60548
|
+
...sanitizeMarketplacePolicy(data, sourcePath)
|
|
60549
|
+
];
|
|
60550
|
+
}
|
|
60551
|
+
var init_policySourceSanitizer = __esm(() => {
|
|
60552
|
+
init_marketplacePolicySanitizer();
|
|
60553
|
+
init_sanitizeAllowlists();
|
|
60554
|
+
init_validation2();
|
|
60555
|
+
});
|
|
60556
|
+
|
|
60114
60557
|
// src/utils/settings/mdm/constants.ts
|
|
60115
60558
|
import { homedir as homedir9, userInfo } from "os";
|
|
60116
60559
|
import { join as join18 } from "path";
|
|
@@ -60259,17 +60702,18 @@ async function refreshMdmSettings() {
|
|
|
60259
60702
|
return consumeRawReadResult(raw);
|
|
60260
60703
|
}
|
|
60261
60704
|
function parseCommandOutputAsSettings(stdout, sourcePath) {
|
|
60262
|
-
const
|
|
60263
|
-
if (!
|
|
60705
|
+
const parsed = safeParseJSON(stdout, false);
|
|
60706
|
+
if (!parsed || typeof parsed !== "object") {
|
|
60264
60707
|
return { settings: {}, errors: [] };
|
|
60265
60708
|
}
|
|
60266
|
-
const
|
|
60709
|
+
const data = clone(parsed);
|
|
60710
|
+
const sanitizeWarnings = sanitizePolicySourceData(data, sourcePath);
|
|
60267
60711
|
const parseResult = SettingsSchema().safeParse(data);
|
|
60268
60712
|
if (!parseResult.success) {
|
|
60269
60713
|
const errors3 = formatZodError(parseResult.error, sourcePath);
|
|
60270
|
-
return { settings: {}, errors: [...
|
|
60714
|
+
return { settings: {}, errors: [...sanitizeWarnings, ...errors3] };
|
|
60271
60715
|
}
|
|
60272
|
-
return { settings: parseResult.data, errors:
|
|
60716
|
+
return { settings: parseResult.data, errors: sanitizeWarnings };
|
|
60273
60717
|
}
|
|
60274
60718
|
function parseRegQueryStdout(stdout, valueName = "Settings") {
|
|
60275
60719
|
const lines = stdout.split(/\r?\n/);
|
|
@@ -60346,8 +60790,10 @@ var init_settings = __esm(() => {
|
|
|
60346
60790
|
init_fileRead();
|
|
60347
60791
|
init_fsOperations();
|
|
60348
60792
|
init_json();
|
|
60793
|
+
init_slowOperations();
|
|
60349
60794
|
init_startupProfiler();
|
|
60350
60795
|
init_managedPath();
|
|
60796
|
+
init_policySourceSanitizer();
|
|
60351
60797
|
init_types2();
|
|
60352
60798
|
init_validation2();
|
|
60353
60799
|
init_constants4();
|
|
@@ -60355,435 +60801,6 @@ var init_settings = __esm(() => {
|
|
|
60355
60801
|
EMPTY_RESULT = Object.freeze({ settings: {}, errors: [] });
|
|
60356
60802
|
});
|
|
60357
60803
|
|
|
60358
|
-
// src/utils/plugins/marketplacePolicyValidation.ts
|
|
60359
|
-
function stripTrailingDots(host) {
|
|
60360
|
-
let end = host.length;
|
|
60361
|
-
while (end > 0 && host[end - 1] === ".")
|
|
60362
|
-
end--;
|
|
60363
|
-
return host.slice(0, end);
|
|
60364
|
-
}
|
|
60365
|
-
function normalizeHostname(raw) {
|
|
60366
|
-
const host = stripTrailingDots(raw.replace(/[\t\n\r]/g, "").toLowerCase());
|
|
60367
|
-
if (host === "" || INVALID_HOST_CHARS.test(host))
|
|
60368
|
-
return host;
|
|
60369
|
-
try {
|
|
60370
|
-
const parsed = new URL(`https://${host}`);
|
|
60371
|
-
if (parsed.username !== "" || parsed.password !== "" || parsed.port !== "" || parsed.pathname !== "/" || parsed.search !== "" || parsed.hash !== "")
|
|
60372
|
-
return host;
|
|
60373
|
-
return stripTrailingDots(parsed.hostname);
|
|
60374
|
-
} catch {
|
|
60375
|
-
return host;
|
|
60376
|
-
}
|
|
60377
|
-
}
|
|
60378
|
-
function normalizeHostForComparison(raw) {
|
|
60379
|
-
const cached2 = hostNormalizeCache.get(raw);
|
|
60380
|
-
if (cached2 !== undefined)
|
|
60381
|
-
return cached2;
|
|
60382
|
-
let host = normalizeHostname(raw);
|
|
60383
|
-
while (host.startsWith("www."))
|
|
60384
|
-
host = host.slice(4);
|
|
60385
|
-
if (hostNormalizeCache.size >= HOST_NORMALIZE_CACHE_LIMIT) {
|
|
60386
|
-
hostNormalizeCache.clear();
|
|
60387
|
-
}
|
|
60388
|
-
hostNormalizeCache.set(raw, host);
|
|
60389
|
-
return host;
|
|
60390
|
-
}
|
|
60391
|
-
function hostMatches(raw, expected) {
|
|
60392
|
-
return normalizeHostForComparison(raw) === expected;
|
|
60393
|
-
}
|
|
60394
|
-
function isGitHubHost(raw) {
|
|
60395
|
-
return hostMatches(raw, GITHUB_HOST);
|
|
60396
|
-
}
|
|
60397
|
-
function isGitHubOrSshGitHubHost(raw) {
|
|
60398
|
-
return isGitHubHost(raw) || normalizeHostname(raw) === GITHUB_SSH_HOST;
|
|
60399
|
-
}
|
|
60400
|
-
function hasSuspiciousHostChars(value) {
|
|
60401
|
-
return /[%\x00-\x1f\x7f-\u{10FFFF}]/u.test(value);
|
|
60402
|
-
}
|
|
60403
|
-
function hasBackslashSmuggling(raw) {
|
|
60404
|
-
const url3 = raw.replace(/^[\x00-\x20]+/, "");
|
|
60405
|
-
const schemeEnd = url3.indexOf("://");
|
|
60406
|
-
if (schemeEnd === -1)
|
|
60407
|
-
return false;
|
|
60408
|
-
let rest = url3.slice(schemeEnd + 3);
|
|
60409
|
-
const scheme = url3.slice(0, schemeEnd).toLowerCase();
|
|
60410
|
-
if (URL_LIKE_PROTOCOLS.has(scheme)) {
|
|
60411
|
-
const slashes = rest.match(/^[/\\]+/)?.[0] ?? "";
|
|
60412
|
-
if (slashes.includes("\\"))
|
|
60413
|
-
return true;
|
|
60414
|
-
rest = rest.slice(slashes.length);
|
|
60415
|
-
}
|
|
60416
|
-
const pathStart = rest.search(/[/?#]/);
|
|
60417
|
-
return (pathStart === -1 ? rest : rest.slice(0, pathStart)).includes("\\");
|
|
60418
|
-
}
|
|
60419
|
-
function isSuspiciousGitUrl(url3) {
|
|
60420
|
-
if (url3.includes("://")) {
|
|
60421
|
-
if (hasBackslashSmuggling(url3))
|
|
60422
|
-
return true;
|
|
60423
|
-
try {
|
|
60424
|
-
const parsed = new URL(url3);
|
|
60425
|
-
if (parsed.protocol === "http:" || parsed.protocol === "https:")
|
|
60426
|
-
return false;
|
|
60427
|
-
return hasSuspiciousHostChars(parsed.hostname);
|
|
60428
|
-
} catch {
|
|
60429
|
-
return true;
|
|
60430
|
-
}
|
|
60431
|
-
}
|
|
60432
|
-
const colonIndex = url3.indexOf(":");
|
|
60433
|
-
const atIndex = url3.indexOf("@");
|
|
60434
|
-
if (colonIndex >= 0 && atIndex > colonIndex)
|
|
60435
|
-
return true;
|
|
60436
|
-
const host = url3.match(/^(?:[^@]+@)?([^:]+):/)?.[1];
|
|
60437
|
-
return host ? hasSuspiciousHostChars(host) : false;
|
|
60438
|
-
}
|
|
60439
|
-
function normalizeGithubAwareHost(raw) {
|
|
60440
|
-
const host = normalizeHostname(raw);
|
|
60441
|
-
return isGitHubHost(host) ? GITHUB_HOST : host;
|
|
60442
|
-
}
|
|
60443
|
-
function normalizeGithubHostForUrl(raw) {
|
|
60444
|
-
const host = normalizeGithubAwareHost(raw);
|
|
60445
|
-
return host === GITHUB_SSH_HOST ? GITHUB_HOST : host;
|
|
60446
|
-
}
|
|
60447
|
-
function normalizePathSegments(path9) {
|
|
60448
|
-
const segments = [];
|
|
60449
|
-
for (const segment of path9.split("/")) {
|
|
60450
|
-
if (segment === ".")
|
|
60451
|
-
continue;
|
|
60452
|
-
if (segment === "..") {
|
|
60453
|
-
segments.pop();
|
|
60454
|
-
continue;
|
|
60455
|
-
}
|
|
60456
|
-
segments.push(segment);
|
|
60457
|
-
}
|
|
60458
|
-
return segments.filter((segment) => segment !== "").join("/");
|
|
60459
|
-
}
|
|
60460
|
-
function stripDotGitSuffix(path9) {
|
|
60461
|
-
let length = path9.length;
|
|
60462
|
-
for (;; ) {
|
|
60463
|
-
let end = length;
|
|
60464
|
-
while (end > 0 && path9.charCodeAt(end - 1) === 47)
|
|
60465
|
-
end--;
|
|
60466
|
-
if (end >= 4 && path9.startsWith(".git", end - 4))
|
|
60467
|
-
end -= 4;
|
|
60468
|
-
if (end === length)
|
|
60469
|
-
return length === path9.length ? path9 : path9.slice(0, length);
|
|
60470
|
-
length = end;
|
|
60471
|
-
}
|
|
60472
|
-
}
|
|
60473
|
-
function normalizeUrlForComparison(raw, options) {
|
|
60474
|
-
if (raw.includes("://")) {
|
|
60475
|
-
try {
|
|
60476
|
-
const parsed = new URL(raw);
|
|
60477
|
-
parsed.hostname = normalizeGithubHostForUrl(parsed.hostname);
|
|
60478
|
-
parsed.username = "";
|
|
60479
|
-
parsed.password = "";
|
|
60480
|
-
parsed.search = "";
|
|
60481
|
-
parsed.hash = "";
|
|
60482
|
-
try {
|
|
60483
|
-
parsed.pathname = decodeURIComponent(parsed.pathname);
|
|
60484
|
-
} catch {}
|
|
60485
|
-
const normalized = normalizePathSegments(parsed.pathname);
|
|
60486
|
-
parsed.pathname = options?.stripDotGit ? stripDotGitSuffix(normalized) : normalized;
|
|
60487
|
-
return parsed.toString();
|
|
60488
|
-
} catch {
|
|
60489
|
-
return raw;
|
|
60490
|
-
}
|
|
60491
|
-
}
|
|
60492
|
-
const scpLike = raw.match(/^[^@]+@([^:]+)(:.*)$/s);
|
|
60493
|
-
return scpLike ? `${normalizeGithubHostForUrl(scpLike[1] ?? "")}${scpLike[2]}` : raw;
|
|
60494
|
-
}
|
|
60495
|
-
function parseScpLikeGitUrl(raw) {
|
|
60496
|
-
const match = SCP_LIKE_GIT_URL_PATTERN.exec(raw);
|
|
60497
|
-
return match ? { user: match[1], host: match[2], path: match[3] } : null;
|
|
60498
|
-
}
|
|
60499
|
-
function normalizeGitUrl(raw) {
|
|
60500
|
-
if (isSuspiciousGitUrl(raw))
|
|
60501
|
-
return raw;
|
|
60502
|
-
if (raw.includes("://")) {
|
|
60503
|
-
try {
|
|
60504
|
-
const parsed = new URL(raw);
|
|
60505
|
-
parsed.hostname = normalizeGithubAwareHost(parsed.hostname);
|
|
60506
|
-
if (CREDENTIAL_STRIP_PROTOCOLS.has(parsed.protocol) || isGitHubHost(parsed.hostname)) {
|
|
60507
|
-
parsed.username = "";
|
|
60508
|
-
parsed.password = "";
|
|
60509
|
-
}
|
|
60510
|
-
return parsed.toString();
|
|
60511
|
-
} catch {
|
|
60512
|
-
return raw;
|
|
60513
|
-
}
|
|
60514
|
-
}
|
|
60515
|
-
const scpLike = parseScpLikeGitUrl(raw);
|
|
60516
|
-
if (!scpLike)
|
|
60517
|
-
return raw;
|
|
60518
|
-
const host = scpLike.host.toLowerCase().replace(/\.+$/, "");
|
|
60519
|
-
return isGitHubHost(host) ? `${GITHUB_HOST}:${scpLike.path}` : `${scpLike.user}@${host}:${scpLike.path}`;
|
|
60520
|
-
}
|
|
60521
|
-
function gitUrlHasWildcard(url3) {
|
|
60522
|
-
if (url3.includes("://")) {
|
|
60523
|
-
if (hasBackslashSmuggling(url3))
|
|
60524
|
-
return false;
|
|
60525
|
-
let hostname3;
|
|
60526
|
-
try {
|
|
60527
|
-
hostname3 = new URL(url3).hostname;
|
|
60528
|
-
} catch {
|
|
60529
|
-
return false;
|
|
60530
|
-
}
|
|
60531
|
-
if (!isGitHubOrSshGitHubHost(hostname3))
|
|
60532
|
-
return false;
|
|
60533
|
-
if (normalizeUrlForComparison(url3, { stripDotGit: true }).includes("*"))
|
|
60534
|
-
return true;
|
|
60535
|
-
const normalized = normalizeGitUrl(url3);
|
|
60536
|
-
try {
|
|
60537
|
-
const parsed = new URL(normalized);
|
|
60538
|
-
return parsed.hostname.includes("*") || parsed.pathname.includes("*");
|
|
60539
|
-
} catch {
|
|
60540
|
-
return normalized.includes("*");
|
|
60541
|
-
}
|
|
60542
|
-
}
|
|
60543
|
-
const match = url3.match(SCP_LIKE_HOST_PATTERN);
|
|
60544
|
-
const host = match?.[1];
|
|
60545
|
-
const path9 = match?.[2];
|
|
60546
|
-
if (!host || path9 === undefined || !isGitHubOrSshGitHubHost(host))
|
|
60547
|
-
return false;
|
|
60548
|
-
let decoded = path9;
|
|
60549
|
-
try {
|
|
60550
|
-
decoded = decodeURIComponent(path9);
|
|
60551
|
-
} catch {}
|
|
60552
|
-
return decoded.includes("*");
|
|
60553
|
-
}
|
|
60554
|
-
function regexCompiles(pattern) {
|
|
60555
|
-
try {
|
|
60556
|
-
new RegExp(pattern);
|
|
60557
|
-
return true;
|
|
60558
|
-
} catch {
|
|
60559
|
-
return false;
|
|
60560
|
-
}
|
|
60561
|
-
}
|
|
60562
|
-
function isValidWildcardOwner(owner) {
|
|
60563
|
-
return OWNER_CHARS_PATTERN.test(owner) && !owner.startsWith("-") && owner !== "." && owner !== "..";
|
|
60564
|
-
}
|
|
60565
|
-
function parseGitHubOwnerWildcard(repo) {
|
|
60566
|
-
if (!repo.endsWith("/*"))
|
|
60567
|
-
return null;
|
|
60568
|
-
const owner = repo.slice(0, -2);
|
|
60569
|
-
return isValidWildcardOwner(owner) ? owner : null;
|
|
60570
|
-
}
|
|
60571
|
-
function checkMarketplaceEntryEnforceability(entry) {
|
|
60572
|
-
const pattern = entry.source === "hostPattern" ? entry.hostPattern : entry.source === "pathPattern" ? entry.pathPattern : null;
|
|
60573
|
-
if (pattern !== null && !regexCompiles(pattern))
|
|
60574
|
-
return `${entry.source}: regex does not compile; the entry cannot be enforced`;
|
|
60575
|
-
if (entry.source === "github" && entry.repo.includes("*") && parseGitHubOwnerWildcard(entry.repo) === null)
|
|
60576
|
-
return 'github: an owner wildcard must be exactly "<owner>/*"; the entry cannot be enforced';
|
|
60577
|
-
if (entry.source === "git" && gitUrlHasWildcard(entry.url))
|
|
60578
|
-
return 'git: wildcards are only supported in github-form entries, as "<owner>/*"; the entry cannot be enforced';
|
|
60579
|
-
if ((entry.source === "github" || entry.source === "git") && entry.ref !== undefined && entry.ref.includes("*"))
|
|
60580
|
-
return `${entry.source}: ref contains "*", which git does not allow in ref names; the entry cannot be enforced`;
|
|
60581
|
-
return null;
|
|
60582
|
-
}
|
|
60583
|
-
var GITHUB_HOST = "github.com", GITHUB_SSH_HOST = "ssh.github.com", INVALID_HOST_CHARS, URL_LIKE_PROTOCOLS, CREDENTIAL_STRIP_PROTOCOLS, OWNER_CHARS_PATTERN, SCP_LIKE_GIT_URL_PATTERN, SCP_LIKE_HOST_PATTERN, HOST_NORMALIZE_CACHE_LIMIT = 50, hostNormalizeCache;
|
|
60584
|
-
var init_marketplacePolicyValidation = __esm(() => {
|
|
60585
|
-
INVALID_HOST_CHARS = /[:/\\?#@\s]/;
|
|
60586
|
-
URL_LIKE_PROTOCOLS = new Set(["http", "https", "ws", "wss", "ftp"]);
|
|
60587
|
-
CREDENTIAL_STRIP_PROTOCOLS = new Set([
|
|
60588
|
-
"http:",
|
|
60589
|
-
"https:",
|
|
60590
|
-
"git:",
|
|
60591
|
-
"git+http:",
|
|
60592
|
-
"git+https:"
|
|
60593
|
-
]);
|
|
60594
|
-
OWNER_CHARS_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
60595
|
-
SCP_LIKE_GIT_URL_PATTERN = /^([^@:/[\]]+)@([^@:/[\]]+):(.*)$/s;
|
|
60596
|
-
SCP_LIKE_HOST_PATTERN = /^(?:[^@]+@)?([^@:/]+):(.*)$/s;
|
|
60597
|
-
hostNormalizeCache = new Map;
|
|
60598
|
-
});
|
|
60599
|
-
|
|
60600
|
-
// src/utils/settings/marketplacePolicySanitizer.ts
|
|
60601
|
-
function firstIssueDetail(issues) {
|
|
60602
|
-
for (const issue2 of issues) {
|
|
60603
|
-
const prefix = issue2.path.length > 0 ? `${issue2.path.map(String).join(".")}: ` : "";
|
|
60604
|
-
if (issue2.code === "invalid_union") {
|
|
60605
|
-
for (const branch of issue2.errors) {
|
|
60606
|
-
const detail = firstIssueDetail(branch);
|
|
60607
|
-
if (detail !== null)
|
|
60608
|
-
return `${prefix}${detail}`;
|
|
60609
|
-
}
|
|
60610
|
-
const noted = issue2;
|
|
60611
|
-
if (typeof noted.note === "string" && noted.note !== "")
|
|
60612
|
-
return `${prefix}${noted.note}`;
|
|
60613
|
-
}
|
|
60614
|
-
if (issue2.message !== "")
|
|
60615
|
-
return `${prefix}${issue2.message}`;
|
|
60616
|
-
}
|
|
60617
|
-
return null;
|
|
60618
|
-
}
|
|
60619
|
-
function sanitizeMarketplacePolicy(data, filePath) {
|
|
60620
|
-
if (!data || typeof data !== "object")
|
|
60621
|
-
return [];
|
|
60622
|
-
const obj = data;
|
|
60623
|
-
const warnings = [];
|
|
60624
|
-
for (const key of POLICY_KEYS) {
|
|
60625
|
-
if (!(key in obj))
|
|
60626
|
-
continue;
|
|
60627
|
-
const raw = obj[key];
|
|
60628
|
-
if (raw === null) {
|
|
60629
|
-
delete obj[key];
|
|
60630
|
-
continue;
|
|
60631
|
-
}
|
|
60632
|
-
if (!Array.isArray(raw)) {
|
|
60633
|
-
if (key === "strictKnownMarketplaces") {
|
|
60634
|
-
obj[key] = [];
|
|
60635
|
-
} else {
|
|
60636
|
-
delete obj[key];
|
|
60637
|
-
}
|
|
60638
|
-
warnings.push({
|
|
60639
|
-
file: filePath,
|
|
60640
|
-
path: key,
|
|
60641
|
-
message: key === "strictKnownMarketplaces" ? STRICT_PRESENT_INVALID_MESSAGE : BLOCKED_PRESENT_INVALID_MESSAGE,
|
|
60642
|
-
invalidValue: raw
|
|
60643
|
-
});
|
|
60644
|
-
continue;
|
|
60645
|
-
}
|
|
60646
|
-
const kept = [];
|
|
60647
|
-
for (const [index2, entry] of raw.entries()) {
|
|
60648
|
-
const parsed = MarketplaceSourceSchema().safeParse(entry);
|
|
60649
|
-
if (!parsed.success) {
|
|
60650
|
-
warnings.push({
|
|
60651
|
-
file: filePath,
|
|
60652
|
-
path: `${key}[${index2}]`,
|
|
60653
|
-
message: `Invalid entry was ignored: ${firstIssueDetail(parsed.error.issues) ?? "failed validation"}`,
|
|
60654
|
-
invalidValue: entry
|
|
60655
|
-
});
|
|
60656
|
-
continue;
|
|
60657
|
-
}
|
|
60658
|
-
const problem = checkMarketplaceEntryEnforceability(parsed.data);
|
|
60659
|
-
if (problem === null) {
|
|
60660
|
-
kept.push(parsed.data);
|
|
60661
|
-
continue;
|
|
60662
|
-
}
|
|
60663
|
-
if (key === "blockedMarketplaces") {
|
|
60664
|
-
kept.push(parsed.data);
|
|
60665
|
-
warnings.push({
|
|
60666
|
-
file: filePath,
|
|
60667
|
-
path: `${key}[${index2}]`,
|
|
60668
|
-
message: `Unenforceable entry was kept: ${problem}; it can never match a marketplace source, but marketplace restrictions stay active`,
|
|
60669
|
-
invalidValue: entry
|
|
60670
|
-
});
|
|
60671
|
-
} else {
|
|
60672
|
-
warnings.push({
|
|
60673
|
-
file: filePath,
|
|
60674
|
-
path: `${key}[${index2}]`,
|
|
60675
|
-
message: `Invalid entry was ignored: ${problem}`,
|
|
60676
|
-
invalidValue: entry
|
|
60677
|
-
});
|
|
60678
|
-
}
|
|
60679
|
-
}
|
|
60680
|
-
obj[key] = kept;
|
|
60681
|
-
}
|
|
60682
|
-
return warnings;
|
|
60683
|
-
}
|
|
60684
|
-
var POLICY_KEYS, STRICT_PRESENT_INVALID_MESSAGE = '"strictKnownMarketplaces" was present but invalid; enforcing an empty allowlist (no marketplaces admitted) until it is fixed.', BLOCKED_PRESENT_INVALID_MESSAGE = '"blockedMarketplaces" was present but invalid and was dropped; its entries cannot be enforced until it is fixed.';
|
|
60685
|
-
var init_marketplacePolicySanitizer = __esm(() => {
|
|
60686
|
-
init_marketplacePolicyValidation();
|
|
60687
|
-
init_schemas3();
|
|
60688
|
-
POLICY_KEYS = ["strictKnownMarketplaces", "blockedMarketplaces"];
|
|
60689
|
-
});
|
|
60690
|
-
|
|
60691
|
-
// src/utils/settings/sanitizeAllowlists.ts
|
|
60692
|
-
function issueDetail(error49) {
|
|
60693
|
-
const issue2 = error49.issues[0];
|
|
60694
|
-
if (issue2 === undefined)
|
|
60695
|
-
return "failed validation";
|
|
60696
|
-
return issue2.path.length > 0 ? `${issue2.path.join(".")}: ${issue2.message}` : issue2.message;
|
|
60697
|
-
}
|
|
60698
|
-
function validateAllowlistEntry(key, entry) {
|
|
60699
|
-
if (key === "allowedChannelPlugins") {
|
|
60700
|
-
if (typeof entry === "string") {
|
|
60701
|
-
const at = entry.indexOf("@");
|
|
60702
|
-
const plugin = entry.slice(0, at);
|
|
60703
|
-
const marketplace = entry.slice(at + 1);
|
|
60704
|
-
if (at > 0 && marketplace.length > 0) {
|
|
60705
|
-
return {
|
|
60706
|
-
ok: true,
|
|
60707
|
-
value: { marketplace, plugin },
|
|
60708
|
-
notice: `"allowedChannelPlugins" entry "${entry}" was accepted; prefer the documented object form {"plugin": "${plugin}", "marketplace": "${marketplace}"}.`
|
|
60709
|
-
};
|
|
60710
|
-
}
|
|
60711
|
-
}
|
|
60712
|
-
const parsed2 = CHANNEL_PLUGIN_ENTRY.safeParse(entry);
|
|
60713
|
-
return parsed2.success ? { ok: true, value: parsed2.data } : { ok: false, detail: issueDetail(parsed2.error) };
|
|
60714
|
-
}
|
|
60715
|
-
const parsed = STRING_ENTRY.safeParse(entry);
|
|
60716
|
-
return parsed.success ? { ok: true, value: parsed.data } : { ok: false, detail: issueDetail(parsed.error) };
|
|
60717
|
-
}
|
|
60718
|
-
function sanitizeSecurityAllowlists(data, filePath) {
|
|
60719
|
-
if (!data || typeof data !== "object")
|
|
60720
|
-
return [];
|
|
60721
|
-
const obj = data;
|
|
60722
|
-
const warnings = [];
|
|
60723
|
-
for (const { key, emptyReason } of ALLOWLIST_SPECS) {
|
|
60724
|
-
if (!(key in obj))
|
|
60725
|
-
continue;
|
|
60726
|
-
const raw = obj[key];
|
|
60727
|
-
if (!Array.isArray(raw)) {
|
|
60728
|
-
obj[key] = [];
|
|
60729
|
-
warnings.push({
|
|
60730
|
-
file: filePath,
|
|
60731
|
-
path: key,
|
|
60732
|
-
message: `"${key}" was present but invalid; enforcing an empty allowlist (${emptyReason}) until it is fixed.`,
|
|
60733
|
-
invalidValue: raw
|
|
60734
|
-
});
|
|
60735
|
-
continue;
|
|
60736
|
-
}
|
|
60737
|
-
const valid = [];
|
|
60738
|
-
for (const [index2, entry] of raw.entries()) {
|
|
60739
|
-
const result = validateAllowlistEntry(key, entry);
|
|
60740
|
-
if (result.ok) {
|
|
60741
|
-
valid.push(result.value);
|
|
60742
|
-
if (result.notice !== undefined) {
|
|
60743
|
-
warnings.push({
|
|
60744
|
-
file: filePath,
|
|
60745
|
-
path: `${key}[${index2}]`,
|
|
60746
|
-
message: result.notice
|
|
60747
|
-
});
|
|
60748
|
-
}
|
|
60749
|
-
} else {
|
|
60750
|
-
warnings.push({
|
|
60751
|
-
file: filePath,
|
|
60752
|
-
path: `${key}[${index2}]`,
|
|
60753
|
-
message: `Invalid entry was ignored: ${result.detail}`,
|
|
60754
|
-
invalidValue: entry
|
|
60755
|
-
});
|
|
60756
|
-
}
|
|
60757
|
-
}
|
|
60758
|
-
if (raw.length > 0 && valid.length === 0) {
|
|
60759
|
-
warnings.push({
|
|
60760
|
-
file: filePath,
|
|
60761
|
-
path: key,
|
|
60762
|
-
message: `Every entry of "${key}" was invalid; enforcing an empty allowlist (${emptyReason}) until it is fixed.`
|
|
60763
|
-
});
|
|
60764
|
-
}
|
|
60765
|
-
obj[key] = valid;
|
|
60766
|
-
}
|
|
60767
|
-
return warnings;
|
|
60768
|
-
}
|
|
60769
|
-
var STRING_ENTRY, CHANNEL_PLUGIN_ENTRY, ALLOWLIST_SPECS;
|
|
60770
|
-
var init_sanitizeAllowlists = __esm(() => {
|
|
60771
|
-
init_v4();
|
|
60772
|
-
STRING_ENTRY = exports_external.string();
|
|
60773
|
-
CHANNEL_PLUGIN_ENTRY = exports_external.object({
|
|
60774
|
-
marketplace: exports_external.string(),
|
|
60775
|
-
plugin: exports_external.string()
|
|
60776
|
-
});
|
|
60777
|
-
ALLOWLIST_SPECS = [
|
|
60778
|
-
{ key: "allowedHttpHookUrls", emptyReason: "no HTTP hooks may run" },
|
|
60779
|
-
{
|
|
60780
|
-
key: "httpHookAllowedEnvVars",
|
|
60781
|
-
emptyReason: "no environment variables may be interpolated into HTTP hook headers"
|
|
60782
|
-
},
|
|
60783
|
-
{ key: "allowedChannelPlugins", emptyReason: "no channel plugins admitted" }
|
|
60784
|
-
];
|
|
60785
|
-
});
|
|
60786
|
-
|
|
60787
60804
|
// src/utils/settings/settings.ts
|
|
60788
60805
|
var exports_settings = {};
|
|
60789
60806
|
__export(exports_settings, {
|
|
@@ -60918,30 +60935,20 @@ function parseSettingsFileUncached(path9) {
|
|
|
60918
60935
|
if (content.trim() === "") {
|
|
60919
60936
|
return { settings: {}, errors: [] };
|
|
60920
60937
|
}
|
|
60921
|
-
const
|
|
60922
|
-
const
|
|
60923
|
-
const
|
|
60924
|
-
const marketplacePolicyWarnings = sanitizeMarketplacePolicy(data, path9);
|
|
60938
|
+
const parsed = safeParseJSON(content, false);
|
|
60939
|
+
const data = parsed && typeof parsed === "object" ? clone(parsed) : parsed;
|
|
60940
|
+
const sanitizeWarnings = sanitizePolicySourceData(data, path9);
|
|
60925
60941
|
const result = SettingsSchema().safeParse(data);
|
|
60926
60942
|
if (!result.success) {
|
|
60927
60943
|
const errors3 = formatZodError(result.error, path9);
|
|
60928
60944
|
return {
|
|
60929
60945
|
settings: null,
|
|
60930
|
-
errors: [
|
|
60931
|
-
...ruleWarnings,
|
|
60932
|
-
...allowlistWarnings,
|
|
60933
|
-
...marketplacePolicyWarnings,
|
|
60934
|
-
...errors3
|
|
60935
|
-
]
|
|
60946
|
+
errors: [...sanitizeWarnings, ...errors3]
|
|
60936
60947
|
};
|
|
60937
60948
|
}
|
|
60938
60949
|
return {
|
|
60939
60950
|
settings: result.data,
|
|
60940
|
-
errors:
|
|
60941
|
-
...ruleWarnings,
|
|
60942
|
-
...allowlistWarnings,
|
|
60943
|
-
...marketplacePolicyWarnings
|
|
60944
|
-
]
|
|
60951
|
+
errors: sanitizeWarnings
|
|
60945
60952
|
};
|
|
60946
60953
|
} catch (error49) {
|
|
60947
60954
|
handleFileSystemError(error49, path9);
|
|
@@ -61004,8 +61011,10 @@ function getSettingsForSource(source) {
|
|
|
61004
61011
|
}
|
|
61005
61012
|
function getSettingsForSourceUncached(source) {
|
|
61006
61013
|
if (source === "policySettings") {
|
|
61007
|
-
const
|
|
61008
|
-
if (
|
|
61014
|
+
const cachedRemote = getRemoteManagedSettingsSyncFromCache();
|
|
61015
|
+
if (cachedRemote && Object.keys(cachedRemote).length > 0) {
|
|
61016
|
+
const remoteSettings = clone(cachedRemote);
|
|
61017
|
+
sanitizePolicySourceData(remoteSettings, "remote managed settings");
|
|
61009
61018
|
return remoteSettings;
|
|
61010
61019
|
}
|
|
61011
61020
|
const mdmResult = getMdmSettings();
|
|
@@ -61202,13 +61211,16 @@ function loadSettingsFromDisk() {
|
|
|
61202
61211
|
if (source === "policySettings") {
|
|
61203
61212
|
let policySettings = null;
|
|
61204
61213
|
const policyErrors = [];
|
|
61205
|
-
const
|
|
61206
|
-
if (
|
|
61214
|
+
const cachedRemote = getRemoteManagedSettingsSyncFromCache();
|
|
61215
|
+
if (cachedRemote && Object.keys(cachedRemote).length > 0) {
|
|
61216
|
+
const remoteSettings = clone(cachedRemote);
|
|
61217
|
+
const remoteWarnings = sanitizePolicySourceData(remoteSettings, "remote managed settings");
|
|
61207
61218
|
const result = SettingsSchema().safeParse(remoteSettings);
|
|
61208
61219
|
if (result.success) {
|
|
61209
61220
|
policySettings = result.data;
|
|
61221
|
+
policyErrors.push(...remoteWarnings);
|
|
61210
61222
|
} else {
|
|
61211
|
-
policyErrors.push(...formatZodError(result.error, "remote managed settings"));
|
|
61223
|
+
policyErrors.push(...remoteWarnings, ...formatZodError(result.error, "remote managed settings"));
|
|
61212
61224
|
}
|
|
61213
61225
|
}
|
|
61214
61226
|
if (!policySettings) {
|
|
@@ -61568,8 +61580,7 @@ var init_settings2 = __esm(() => {
|
|
|
61568
61580
|
init_managedPath();
|
|
61569
61581
|
init_settings();
|
|
61570
61582
|
init_settingsCache();
|
|
61571
|
-
|
|
61572
|
-
init_sanitizeAllowlists();
|
|
61583
|
+
init_policySourceSanitizer();
|
|
61573
61584
|
init_types2();
|
|
61574
61585
|
init_validation2();
|
|
61575
61586
|
MAX_SETTINGS_FILE_BYTES = 2 * 1024 * 1024;
|
|
@@ -193323,6 +193334,8 @@ function resetGetMemoryFilesCache(reason = "session_start") {
|
|
|
193323
193334
|
hasLoggedAgentsMdMode = false;
|
|
193324
193335
|
hasLoggedAgentsMdLoad = false;
|
|
193325
193336
|
agentsMdNoticeRoot = undefined;
|
|
193337
|
+
lastAgentsMdNotice = undefined;
|
|
193338
|
+
lastAgentsMdDeprecation = undefined;
|
|
193326
193339
|
clearMemoryFileCaches();
|
|
193327
193340
|
}
|
|
193328
193341
|
function getLargeMemoryFiles(files, threshold = MIN_MEMORY_CHARACTER_COUNT) {
|
|
@@ -195005,6 +195018,23 @@ function getProjectDirsUpToHome(subdir, cwd2) {
|
|
|
195005
195018
|
}
|
|
195006
195019
|
return dirs;
|
|
195007
195020
|
}
|
|
195021
|
+
function addWorktreeMainRepoFallback(projectDirs, subdir, cwd2) {
|
|
195022
|
+
const gitRoot = findGitRoot(cwd2);
|
|
195023
|
+
const canonicalRoot = findCanonicalGitRoot(cwd2);
|
|
195024
|
+
if (!gitRoot || !canonicalRoot || canonicalRoot === gitRoot) {
|
|
195025
|
+
return projectDirs;
|
|
195026
|
+
}
|
|
195027
|
+
const worktreeSubdir = normalizePathForComparison(join34(gitRoot, ".claude", subdir));
|
|
195028
|
+
const worktreeHasSubdir = projectDirs.some((dir) => normalizePathForComparison(dir) === worktreeSubdir);
|
|
195029
|
+
if (worktreeHasSubdir) {
|
|
195030
|
+
return projectDirs;
|
|
195031
|
+
}
|
|
195032
|
+
const mainClaudeSubdir = join34(canonicalRoot, ".claude", subdir);
|
|
195033
|
+
if (projectDirs.includes(mainClaudeSubdir)) {
|
|
195034
|
+
return projectDirs;
|
|
195035
|
+
}
|
|
195036
|
+
return [...projectDirs, mainClaudeSubdir];
|
|
195037
|
+
}
|
|
195008
195038
|
async function findMarkdownFilesNative(dir, signal) {
|
|
195009
195039
|
const files = [];
|
|
195010
195040
|
const visitedDirs = new Set;
|
|
@@ -195122,19 +195152,7 @@ var init_markdownConfigLoader = __esm(() => {
|
|
|
195122
195152
|
const searchStartTime = Date.now();
|
|
195123
195153
|
const userDir = join34(getClaudeConfigHomeDir(), subdir);
|
|
195124
195154
|
const managedDir = join34(getManagedFilePath(), ".claude", subdir);
|
|
195125
|
-
const projectDirs = getProjectDirsUpToHome(subdir, cwd2);
|
|
195126
|
-
const gitRoot = findGitRoot(cwd2);
|
|
195127
|
-
const canonicalRoot = findCanonicalGitRoot(cwd2);
|
|
195128
|
-
if (gitRoot && canonicalRoot && canonicalRoot !== gitRoot) {
|
|
195129
|
-
const worktreeSubdir = normalizePathForComparison(join34(gitRoot, ".claude", subdir));
|
|
195130
|
-
const worktreeHasSubdir = projectDirs.some((dir) => normalizePathForComparison(dir) === worktreeSubdir);
|
|
195131
|
-
if (!worktreeHasSubdir) {
|
|
195132
|
-
const mainClaudeSubdir = join34(canonicalRoot, ".claude", subdir);
|
|
195133
|
-
if (!projectDirs.includes(mainClaudeSubdir)) {
|
|
195134
|
-
projectDirs.push(mainClaudeSubdir);
|
|
195135
|
-
}
|
|
195136
|
-
}
|
|
195137
|
-
}
|
|
195155
|
+
const projectDirs = addWorktreeMainRepoFallback(getProjectDirsUpToHome(subdir, cwd2), subdir, cwd2);
|
|
195138
195156
|
const [managedFiles, userFiles, projectFilesNested] = await Promise.all([
|
|
195139
195157
|
loadMarkdownFiles(managedDir).then((_2) => _2.map((file2) => ({
|
|
195140
195158
|
...file2,
|
|
@@ -612907,7 +612925,7 @@ var init_loadSkillsDir = __esm(() => {
|
|
|
612907
612925
|
getSkillDirCommands = memoize_default(async (cwd2) => {
|
|
612908
612926
|
const userSkillsDir = join117(getClaudeConfigHomeDir(), "skills");
|
|
612909
612927
|
const managedSkillsDir = join117(getManagedFilePath(), ".claude", "skills");
|
|
612910
|
-
const projectSkillsDirs = getProjectDirsUpToHome("skills", cwd2);
|
|
612928
|
+
const projectSkillsDirs = addWorktreeMainRepoFallback(getProjectDirsUpToHome("skills", cwd2), "skills", cwd2);
|
|
612911
612929
|
logForDebugging(`Loading skills from: managed=${managedSkillsDir}, user=${userSkillsDir}, project=[${projectSkillsDirs.join(", ")}]`);
|
|
612912
612930
|
const additionalDirs = getAdditionalDirectoriesForClaudeMd();
|
|
612913
612931
|
const skillsLocked = isRestrictedToPluginOnly("skills");
|
|
@@ -738754,7 +738772,6 @@ __export(exports_worktree, {
|
|
|
738754
738772
|
createTmuxSessionForWorktree: () => createTmuxSessionForWorktree,
|
|
738755
738773
|
createAgentWorktree: () => createAgentWorktree,
|
|
738756
738774
|
copyWorktreeIncludeFiles: () => copyWorktreeIncludeFiles,
|
|
738757
|
-
copyUntrackedProjectSkills: () => copyUntrackedProjectSkills,
|
|
738758
738775
|
cleanupWorktree: () => cleanupWorktree,
|
|
738759
738776
|
cleanupStaleAgentWorktrees: () => cleanupStaleAgentWorktrees
|
|
738760
738777
|
});
|
|
@@ -739001,33 +739018,6 @@ async function copyWorktreeIncludeFiles(repoRoot, worktreePath) {
|
|
|
739001
739018
|
}
|
|
739002
739019
|
return copied;
|
|
739003
739020
|
}
|
|
739004
|
-
async function copyUntrackedProjectSkills(repoRoot, worktreePath) {
|
|
739005
|
-
const skillsPathspec = ".claude/skills";
|
|
739006
|
-
const listed = await execFileNoThrowWithCwd(gitExe(), ["ls-files", "--others", "--exclude-standard", "--", skillsPathspec], { cwd: repoRoot });
|
|
739007
|
-
if (listed.code !== 0 || !listed.stdout.trim()) {
|
|
739008
|
-
return [];
|
|
739009
|
-
}
|
|
739010
|
-
const copied = [];
|
|
739011
|
-
for (const relativePath2 of listed.stdout.trim().split(`
|
|
739012
|
-
`).filter(Boolean)) {
|
|
739013
|
-
if (containsPathTraversal(relativePath2)) {
|
|
739014
|
-
continue;
|
|
739015
|
-
}
|
|
739016
|
-
const srcPath = join167(repoRoot, relativePath2);
|
|
739017
|
-
const destPath = join167(worktreePath, relativePath2);
|
|
739018
|
-
try {
|
|
739019
|
-
await mkdirRecursive(dirname74(destPath));
|
|
739020
|
-
await copyFile11(srcPath, destPath);
|
|
739021
|
-
copied.push(relativePath2);
|
|
739022
|
-
} catch (e4) {
|
|
739023
|
-
logForDebugging(`Failed to copy untracked skill ${relativePath2} to worktree: ${errorMessage(e4)}`, { level: "warn" });
|
|
739024
|
-
}
|
|
739025
|
-
}
|
|
739026
|
-
if (copied.length > 0) {
|
|
739027
|
-
logForDebugging(`Copied ${copied.length} untracked project skill file(s) into worktree: ${copied.join(", ")}`);
|
|
739028
|
-
}
|
|
739029
|
-
return copied;
|
|
739030
|
-
}
|
|
739031
739021
|
async function performPostCreationSetup(repoRoot, worktreePath) {
|
|
739032
739022
|
const localSettingsRelativePath = getRelativeSettingsFilePathForSource("localSettings");
|
|
739033
739023
|
const sourceSettingsLocal = join167(repoRoot, localSettingsRelativePath);
|
|
@@ -739075,7 +739065,6 @@ async function performPostCreationSetup(repoRoot, worktreePath) {
|
|
|
739075
739065
|
await symlinkDirectories(repoRoot, worktreePath, dirsToSymlink);
|
|
739076
739066
|
}
|
|
739077
739067
|
await copyWorktreeIncludeFiles(repoRoot, worktreePath);
|
|
739078
|
-
await copyUntrackedProjectSkills(repoRoot, worktreePath);
|
|
739079
739068
|
if (feature("COMMIT_ATTRIBUTION")) {
|
|
739080
739069
|
const worktreeHooksDir = hooksPath === huskyPath ? join167(worktreePath, ".husky") : undefined;
|
|
739081
739070
|
Promise.resolve().then(() => (init_postCommitAttribution(), exports_postCommitAttribution)).then((m5) => m5.installPrepareCommitMsgHook(worktreePath, worktreeHooksDir).catch((error52) => {
|
|
@@ -826546,13 +826535,13 @@ function canBatchWith(head, next2) {
|
|
|
826546
826535
|
return next2 !== undefined && next2.mode === "prompt" && next2.workload === head.workload && next2.isMeta === head.isMeta;
|
|
826547
826536
|
}
|
|
826548
826537
|
async function runHeadless(inputPrompt, getAppState, setAppState, commands7, tools, sdkMcpConfigs, agents2, options) {
|
|
826538
|
+
registerHeadlessCostSaveOnExit();
|
|
826549
826539
|
if (process.env.USER_TYPE === "ant" && isEnvTruthy(process.env.CLAUDE_CODE_EXIT_AFTER_FIRST_RENDER)) {
|
|
826550
826540
|
process.stderr.write(`
|
|
826551
826541
|
Startup time: ${Math.round(process.uptime() * 1000)}ms
|
|
826552
826542
|
`);
|
|
826553
826543
|
process.exit(0);
|
|
826554
826544
|
}
|
|
826555
|
-
registerHeadlessCostSaveOnExit();
|
|
826556
826545
|
if (typeof inputPrompt === "string" && shouldTriggerUltracodeFromPrompt(inputPrompt)) {
|
|
826557
826546
|
enableUltracodeForSession();
|
|
826558
826547
|
logEvent2("tengu_ultracode_keyword_triggered", {
|
|
@@ -836920,7 +836909,7 @@ var _FEATURE_ALLOWLIST = new Set([
|
|
|
836920
836909
|
var feature2 = (name3) => _FEATURE_ALLOWLIST.has(name3);
|
|
836921
836910
|
if (typeof globalThis.MACRO === "undefined") {
|
|
836922
836911
|
globalThis.MACRO = {
|
|
836923
|
-
VERSION: "2.1.
|
|
836912
|
+
VERSION: "2.1.278",
|
|
836924
836913
|
BINARY_NAME: "occ",
|
|
836925
836914
|
BUILD_TIME: new Date().toISOString(),
|
|
836926
836915
|
FEEDBACK_CHANNEL: "",
|