context-mode 2.0.0-next.7 → 2.0.0-next.9
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -1
- package/.codex-plugin/plugin.json +2 -2
- package/SHA256SUMS +14 -14
- package/cli.mjs +2988 -684
- package/copilot/plugin.json +2 -1
- package/gemini-extension.json +2 -1
- package/hook.mjs +84 -82
- package/opencode/plugin.js +3050 -828
- package/package.json +24 -1
- package/pi/index.js +3001 -779
- package/qwen-extension.json +2 -1
- package/run.mjs +115 -43
- package/search.mjs +115 -43
- package/server.mjs +2965 -742
package/search.mjs
CHANGED
|
@@ -236,7 +236,7 @@ var EDIT_TOOLS = Object.freeze(["Write", "Edit"]);
|
|
|
236
236
|
var EDIT_PATH_KEYS = Object.freeze(["file_path", "path"]);
|
|
237
237
|
var STATS_COLUMNS = Object.freeze(["Scope", "Produced", "Returned", "Saved", "Reduction %"]);
|
|
238
238
|
var PURGE_SCOPES = Object.freeze(["session", "source", "project"]);
|
|
239
|
-
var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10"]);
|
|
239
|
+
var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10", "D11"]);
|
|
240
240
|
var DOCTOR_LABEL = Object.freeze({
|
|
241
241
|
D1: "version",
|
|
242
242
|
D2: "node",
|
|
@@ -248,7 +248,8 @@ var DOCTOR_LABEL = Object.freeze({
|
|
|
248
248
|
D7: "project and worktree",
|
|
249
249
|
D8: "context.db",
|
|
250
250
|
D9: "index",
|
|
251
|
-
D10: "enforcement mode"
|
|
251
|
+
D10: "enforcement mode",
|
|
252
|
+
D11: "shell"
|
|
252
253
|
});
|
|
253
254
|
var REPORT_TRUNCATED_LINE = `(report truncated at ${REPORT_CAP} B; run ctx_doctor again after the first fix)`;
|
|
254
255
|
var D2_NODE_FIX = `install Node ${NODE_MIN} or later`;
|
|
@@ -271,6 +272,9 @@ var GIT_HEAD_SHA_ARGS = Object.freeze(["rev-parse", "HEAD"]);
|
|
|
271
272
|
var UPGRADE_GIT_CHECKOUT_AGENTS = Object.freeze(["pi", "opencode"]);
|
|
272
273
|
var GIT_NO_PROMPT_ENV = Object.freeze({ GIT_TERMINAL_PROMPT: "0" });
|
|
273
274
|
var GIT_NO_CRLF_ENV = Object.freeze({ GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: "core.autocrlf", GIT_CONFIG_VALUE_0: "false" });
|
|
275
|
+
var GIT_BIN = "git";
|
|
276
|
+
var WIN_SHELL_LANGS = Object.freeze(["shell", "bash", "sh"]);
|
|
277
|
+
var GIT_BASH_RELATIVE = Object.freeze([["..", "bin", "bash.exe"], ["..", "..", "bin", "bash.exe"]]);
|
|
274
278
|
var OPS_SPLIT_FILES = Object.freeze([
|
|
275
279
|
"doctor-env.ts",
|
|
276
280
|
"doctor-config.ts",
|
|
@@ -287,10 +291,10 @@ var OPS_SPLIT_FILES = Object.freeze([
|
|
|
287
291
|
var HOOK_HOST_FILE = Object.freeze({
|
|
288
292
|
"claude-code": { root: "plugin", file: ["hooks", "claude-code.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
289
293
|
codex: { root: "home", file: [".codex", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
290
|
-
gemini: { root: "
|
|
291
|
-
qwen: { root: "
|
|
294
|
+
gemini: { root: "plugin", file: ["hooks", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: false },
|
|
295
|
+
qwen: { root: "plugin", file: ["hooks", "qwen.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
292
296
|
"copilot-cli": { root: "home", file: [".copilot", "hooks", "context-mode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeoutSec", matcher: false },
|
|
293
|
-
vscode: { root: "
|
|
297
|
+
vscode: { root: "home", file: [".copilot", "hooks", "context-mode-vscode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeout", matcher: false },
|
|
294
298
|
kiro: { root: "home", file: [".kiro", "hooks", "context-mode.json"], key: ["hooks"], shape: "kiro", timeoutKey: "timeout", matcher: false },
|
|
295
299
|
zcode: { root: "home", file: [".zcode", "cli", "config.json"], key: ["hooks", "events"], shape: "zcode", timeoutKey: "timeoutMs", matcher: true },
|
|
296
300
|
pi: null,
|
|
@@ -324,12 +328,16 @@ var V1_SCRIPT_NAMES = Object.freeze([
|
|
|
324
328
|
]);
|
|
325
329
|
var V1_CODEX_HOOKS_DIR = Object.freeze(["hooks", "codex"]);
|
|
326
330
|
var V1_CACHE_HEAL_EXTS = Object.freeze([".mjs", ".sh"]);
|
|
331
|
+
var VSCODE_USER_DIR_SEGMENTS = Object.freeze(["Code", "User"]);
|
|
332
|
+
var VSCODE_MCP_FILE = "mcp.json";
|
|
327
333
|
var KIRO_AGENT_FILE = Object.freeze(["agents", "default.json"]);
|
|
328
334
|
var KIRO_STEERING_FILE = Object.freeze(["steering", "KIRO.md"]);
|
|
329
335
|
var OPENCODE_CONFIG_FILES = Object.freeze(["opencode.jsonc", "opencode.json"]);
|
|
330
336
|
var V1_DATA_ROOT_ENTRIES = Object.freeze(["content", "platform.json"]);
|
|
331
337
|
var PI_ROLE = "custom";
|
|
332
338
|
var V1_PATH_SEPS = Object.freeze(["/", "\\"]);
|
|
339
|
+
var HOST_SEP_TOKEN = "${/}";
|
|
340
|
+
var HOOK_SCRIPT_SEPS = Object.freeze([...V1_PATH_SEPS, HOST_SEP_TOKEN]);
|
|
333
341
|
var V1_REASON = Object.freeze({
|
|
334
342
|
hook: "old context-mode hook entry: command contains context-mode and an old script name or context-mode hook",
|
|
335
343
|
cacheHealHook: "old context-mode cache-heal SessionStart hook entry",
|
|
@@ -360,7 +368,7 @@ var CODEX_APPROVAL_MODE_FIELD = "default_tools_approval_mode";
|
|
|
360
368
|
var CODEX_APPROVAL_APPROVE = "approve";
|
|
361
369
|
var OWN_MCP_ENTRY = Object.freeze({
|
|
362
370
|
codex: { file: [".codex", "config.toml"], key: ["mcp_servers", SERVER_KEY], fields: { [CODEX_OMIT_TOOLS_FROM_FIELD]: CODEX_OMIT_DEFERRED, [CODEX_APPROVAL_MODE_FIELD]: CODEX_APPROVAL_APPROVE } },
|
|
363
|
-
vscode: { file: [
|
|
371
|
+
vscode: { file: [VSCODE_MCP_FILE], key: ["servers", SERVER_KEY] },
|
|
364
372
|
kiro: { file: [".kiro", "settings", "mcp.json"], key: ["mcpServers", SERVER_KEY] },
|
|
365
373
|
zcode: {
|
|
366
374
|
file: [".zcode", "cli", "config.json"],
|
|
@@ -734,8 +742,14 @@ var VSCODE_EVENTS = ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostTool
|
|
|
734
742
|
var MCP_PREFIX2 = "mcp_";
|
|
735
743
|
var MCP_SEP2 = "_";
|
|
736
744
|
var SESSION_START_NEW = "new";
|
|
737
|
-
var
|
|
738
|
-
var
|
|
745
|
+
var SHELL_TOOL_NAMES = Object.freeze(["run_in_terminal", "runTerminalCommand", "bash", "powershell"]);
|
|
746
|
+
var READ_TOOL_NAMES = Object.freeze(["read_file", "view"]);
|
|
747
|
+
var WEBFETCH_TOOL_NAMES = Object.freeze(["fetch_webpage", "web_fetch"]);
|
|
748
|
+
var NATIVE_TO_CANONICAL4 = Object.fromEntries([
|
|
749
|
+
...SHELL_TOOL_NAMES.map((n) => [n, "Bash"]),
|
|
750
|
+
...READ_TOOL_NAMES.map((n) => [n, "Read"]),
|
|
751
|
+
...WEBFETCH_TOOL_NAMES.map((n) => [n, "WebFetch"])
|
|
752
|
+
]);
|
|
739
753
|
function canonicalName4(name) {
|
|
740
754
|
if (name.startsWith(TOOL_NAME_PREFIX6)) return name.slice(TOOL_NAME_PREFIX6.length);
|
|
741
755
|
if (Object.hasOwn(NATIVE_TO_CANONICAL4, name)) return NATIVE_TO_CANONICAL4[name];
|
|
@@ -745,6 +759,26 @@ function canonicalName4(name) {
|
|
|
745
759
|
if (sep3 <= 0 || sep3 === rest.length - 1) return name;
|
|
746
760
|
return "mcp:" + rest.slice(0, sep3) + ":" + rest.slice(sep3 + MCP_SEP2.length);
|
|
747
761
|
}
|
|
762
|
+
var isNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
763
|
+
function policyInput(name, canonical, input) {
|
|
764
|
+
if (canonical === "Read" && READ_TOOL_NAMES.includes(name)) {
|
|
765
|
+
const out = { ...input };
|
|
766
|
+
if (name === "read_file") {
|
|
767
|
+
if (typeof input.filePath === "string") out.file_path = input.filePath;
|
|
768
|
+
if (isNum(input.startLine)) out.offset = input.startLine;
|
|
769
|
+
if (isNum(input.startLine) && isNum(input.endLine) && input.endLine >= input.startLine) out.limit = input.endLine - input.startLine + 1;
|
|
770
|
+
} else if (Array.isArray(input.view_range) && isNum(input.view_range[0])) {
|
|
771
|
+
out.offset = input.view_range[0];
|
|
772
|
+
const end = input.view_range[1];
|
|
773
|
+
if (isNum(end) && end >= input.view_range[0]) out.limit = end - input.view_range[0] + 1;
|
|
774
|
+
}
|
|
775
|
+
return out;
|
|
776
|
+
}
|
|
777
|
+
if (canonical === "WebFetch" && name === "fetch_webpage" && Array.isArray(input.urls) && typeof input.urls[0] === "string") {
|
|
778
|
+
return { ...input, url: input.urls[0] };
|
|
779
|
+
}
|
|
780
|
+
return input;
|
|
781
|
+
}
|
|
748
782
|
function readResult4(resp) {
|
|
749
783
|
const text = resp === void 0 ? "" : typeof resp === "string" ? resp : JSON.stringify(resp);
|
|
750
784
|
const isError = typeof resp === "object" && resp !== null && resp.is_error === true;
|
|
@@ -792,7 +826,8 @@ function decodeCamel(p, name) {
|
|
|
792
826
|
if (event === "UserPromptSubmit" && typeof p.prompt === "string") ev.prompt = p.prompt;
|
|
793
827
|
if (event === "PreToolUse" || event === "PostToolUse") {
|
|
794
828
|
const toolName = String(p.toolName ?? "");
|
|
795
|
-
|
|
829
|
+
const canonical = canonicalName4(toolName);
|
|
830
|
+
ev.tool = { name: toolName, canonicalName: canonical, input: policyInput(toolName, canonical, readArgs2(p.toolArgs)) };
|
|
796
831
|
}
|
|
797
832
|
if (event === "PostToolUse") ev.result = readCamelResult(p.toolResult);
|
|
798
833
|
return ev;
|
|
@@ -814,7 +849,8 @@ function decode6(raw) {
|
|
|
814
849
|
if (event === "PreToolUse" || event === "PostToolUse") {
|
|
815
850
|
const name = String(p.tool_name ?? "");
|
|
816
851
|
const input = isRecord2(p.tool_input) ? p.tool_input : {};
|
|
817
|
-
|
|
852
|
+
const canonical = canonicalName4(name);
|
|
853
|
+
ev.tool = { name, canonicalName: canonical, input: policyInput(name, canonical, input) };
|
|
818
854
|
}
|
|
819
855
|
if (event === "PostToolUse") ev.result = readResult4(p.tool_response);
|
|
820
856
|
return ev;
|
|
@@ -838,8 +874,8 @@ var KIRO_EVENTS = {
|
|
|
838
874
|
};
|
|
839
875
|
var PROMPT_ENV = "USER_PROMPT";
|
|
840
876
|
var MCP_PREFIX3 = "mcp_";
|
|
841
|
-
var
|
|
842
|
-
var NATIVE_TO_CANONICAL5 = Object.fromEntries(
|
|
877
|
+
var SHELL_TOOL_NAMES2 = Object.freeze(["execute_bash", "execute_pwsh", "shell"]);
|
|
878
|
+
var NATIVE_TO_CANONICAL5 = Object.fromEntries(SHELL_TOOL_NAMES2.map((n) => [n, "Bash"]));
|
|
843
879
|
var MCP_SEP3 = "_";
|
|
844
880
|
var KIRO_SOURCES = { startup: "startup", resume: "resume", clear: "clear", compact: "compact" };
|
|
845
881
|
function canonicalName5(name) {
|
|
@@ -980,8 +1016,8 @@ var OPENCODE_EVENTS = {
|
|
|
980
1016
|
compaction: "PreCompact",
|
|
981
1017
|
"step-finish": "Usage"
|
|
982
1018
|
};
|
|
983
|
-
var
|
|
984
|
-
var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [
|
|
1019
|
+
var SHELL_TOOL_NAME = "bash";
|
|
1020
|
+
var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [SHELL_TOOL_NAME]: "Bash" };
|
|
985
1021
|
function toCanonicalTool(name) {
|
|
986
1022
|
if (name.startsWith(OWN_WIRE_PREFIX)) return name.slice(OWN_WIRE_PREFIX.length);
|
|
987
1023
|
return Object.prototype.hasOwnProperty.call(NATIVE_TO_CANONICAL7, name) ? NATIVE_TO_CANONICAL7[name] : name;
|
|
@@ -1130,7 +1166,8 @@ var ADAPTERS = Object.freeze([
|
|
|
1130
1166
|
projectSource: "arg:workspaceFolder",
|
|
1131
1167
|
toolNamePrefix: TOOL_NAME_PREFIX6,
|
|
1132
1168
|
// PreCompact sets the pending flag (ADR-0009 §6, DEVIATIONS D-M3-A4-1).
|
|
1133
|
-
nativeTools: { shell: [
|
|
1169
|
+
nativeTools: { shell: [...SHELL_TOOL_NAMES], read: [...READ_TOOL_NAMES], webfetch: [...WEBFETCH_TOOL_NAMES] },
|
|
1170
|
+
// D-HF-VSCODE-PROJECT-1, D-N7-VSCODE-TOOLS-1
|
|
1134
1171
|
execReadOnlyHint: false,
|
|
1135
1172
|
eventMap: { ...CLAUDE_EVENTS, PreCompact: "PreCompact" },
|
|
1136
1173
|
compactDelivery: "pending-flag",
|
|
@@ -1148,7 +1185,7 @@ var ADAPTERS = Object.freeze([
|
|
|
1148
1185
|
installMode: "mcp-entry",
|
|
1149
1186
|
projectSource: "arg:--agent+cwd",
|
|
1150
1187
|
toolNamePrefix: TOOL_NAME_PREFIX7,
|
|
1151
|
-
nativeTools: { shell: [...
|
|
1188
|
+
nativeTools: { shell: [...SHELL_TOOL_NAMES2] },
|
|
1152
1189
|
execReadOnlyHint: false,
|
|
1153
1190
|
// D-HF-KIRO-SHELL-1, D-N7-KIRO-1
|
|
1154
1191
|
eventMap: { SessionStart: "SessionStart", UserPromptSubmit: "UserPromptSubmit", PreToolUse: "PreToolUse", PostToolUse: "PostToolUse" },
|
|
@@ -1205,7 +1242,7 @@ var ADAPTERS = Object.freeze([
|
|
|
1205
1242
|
installMode: "in-process",
|
|
1206
1243
|
projectSource: "spawn-cwd",
|
|
1207
1244
|
toolNamePrefix: TOOL_NAME_PREFIX10,
|
|
1208
|
-
nativeTools: { shell: [
|
|
1245
|
+
nativeTools: { shell: [SHELL_TOOL_NAME] },
|
|
1209
1246
|
execReadOnlyHint: false,
|
|
1210
1247
|
// D-HF-OPENCODE-SHELL-1
|
|
1211
1248
|
// Usage: step-finish cost row (DEVIATIONS D-M5-arch-2).
|
|
@@ -1243,6 +1280,8 @@ var ERROR_TEXT = Object.freeze({
|
|
|
1243
1280
|
NO_PROJECT: "Project source <kind> is missing. Fix: run ctx_doctor.",
|
|
1244
1281
|
UNKNOWN_FIELD: 'Unknown field "<f>". Fix: use "queries".',
|
|
1245
1282
|
TIMEOUT: "Timed out after <ms> ms. Fix: pass background: true.",
|
|
1283
|
+
NO_GIT_BASH: "Git Bash not found. Fix: install Git for Windows.",
|
|
1284
|
+
// D-VT-WINBASH-1
|
|
1246
1285
|
NO_RUNTIME: "No <lang> runtime on PATH. Fix: install it or pick another language.",
|
|
1247
1286
|
FETCH_FAILED: "Fetch failed: <code>. Fix: check the URL or proxy.",
|
|
1248
1287
|
SSRF: "Blocked private address <host>. Fix: use a public URL.",
|
|
@@ -4247,22 +4286,25 @@ function parseShell(cmd) {
|
|
|
4247
4286
|
import { join as join2 } from "node:path";
|
|
4248
4287
|
|
|
4249
4288
|
// src/core/project/config-dir.ts
|
|
4250
|
-
import { join } from "node:path";
|
|
4289
|
+
import { join, posix, win32 } from "node:path";
|
|
4251
4290
|
var { mkdirSync: mkdirSync2, realpathSync } = process.getBuiltinModule("node:fs");
|
|
4252
|
-
function homeDirOf(env) {
|
|
4253
|
-
const
|
|
4254
|
-
if (
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
}
|
|
4259
|
-
|
|
4260
|
-
|
|
4291
|
+
function homeDirOf(env, platform = process.platform) {
|
|
4292
|
+
const set = (v) => v !== void 0 && v !== "";
|
|
4293
|
+
if (platform === "win32") {
|
|
4294
|
+
if (set(env.USERPROFILE)) return env.USERPROFILE;
|
|
4295
|
+
if (set(env.HOMEDRIVE) && set(env.HOMEPATH)) return env.HOMEDRIVE + env.HOMEPATH;
|
|
4296
|
+
return set(env.HOME) ? env.HOME : null;
|
|
4297
|
+
}
|
|
4298
|
+
if (set(env.HOME)) return env.HOME;
|
|
4299
|
+
return set(env.USERPROFILE) ? env.USERPROFILE : null;
|
|
4300
|
+
}
|
|
4301
|
+
function requireHomeDir(env, platform = process.platform) {
|
|
4302
|
+
const home = homeDirOf(env, platform);
|
|
4261
4303
|
if (home !== null) return home;
|
|
4262
|
-
throw new CtxError("NO_HOME", { name:
|
|
4304
|
+
throw new CtxError("NO_HOME", { name: platform === "win32" ? "USERPROFILE" : "HOME" });
|
|
4263
4305
|
}
|
|
4264
4306
|
function resolveConfigDir(env) {
|
|
4265
|
-
const dir = join(
|
|
4307
|
+
const dir = join(requireHomeDir(env), DATA_ROOT.slice(1));
|
|
4266
4308
|
mkdirSync2(dir, { recursive: true });
|
|
4267
4309
|
return realpathSync.native(dir);
|
|
4268
4310
|
}
|
|
@@ -4965,14 +5007,15 @@ function gitDirs(dir) {
|
|
|
4965
5007
|
} catch {
|
|
4966
5008
|
throw new CtxError("NO_GIT_DIR", { path: dir });
|
|
4967
5009
|
}
|
|
5010
|
+
const start = cur;
|
|
4968
5011
|
for (; ; ) {
|
|
4969
5012
|
const gitDir = gitDirAt(join4(cur, GIT_DIR_NAME));
|
|
4970
5013
|
if (gitDir !== null) {
|
|
4971
5014
|
const common = firstLine(join4(gitDir, GIT_COMMONDIR_FILE));
|
|
4972
|
-
return { commonDir: realpathSync3.native(common === null ? gitDir : resolve2(gitDir, common)), worktree: cur };
|
|
5015
|
+
return { commonDir: realpathSync3.native(common === null ? gitDir : resolve2(gitDir, common)), worktree: cur, start };
|
|
4973
5016
|
}
|
|
4974
5017
|
const up = dirname2(cur);
|
|
4975
|
-
if (up === cur) return null;
|
|
5018
|
+
if (up === cur) return { commonDir: null, start };
|
|
4976
5019
|
cur = up;
|
|
4977
5020
|
}
|
|
4978
5021
|
}
|
|
@@ -5004,7 +5047,7 @@ function firstLine(file) {
|
|
|
5004
5047
|
}
|
|
5005
5048
|
function git(dir, args) {
|
|
5006
5049
|
const { spawnSync } = process.getBuiltinModule("node:child_process");
|
|
5007
|
-
const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
5050
|
+
const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
|
|
5008
5051
|
if (r.error !== void 0 || r.status !== 0) throw new CtxError("NO_GIT_DIR", { path: dir });
|
|
5009
5052
|
return r.stdout.split("\n").filter((l) => l !== "");
|
|
5010
5053
|
}
|
|
@@ -5018,16 +5061,24 @@ function resolveProject(agent, src) {
|
|
|
5018
5061
|
const dir = dirOf(source, src);
|
|
5019
5062
|
if (dir === void 0) throw new CtxError("NO_PROJECT", { kind: source });
|
|
5020
5063
|
const repo = gitDirs(dir);
|
|
5021
|
-
const plain = repo === null ?
|
|
5022
|
-
const commonDir = repo
|
|
5023
|
-
const worktree = repo
|
|
5024
|
-
|
|
5025
|
-
|
|
5064
|
+
const plain = repo.commonDir === null ? repo.start : void 0;
|
|
5065
|
+
const commonDir = repo.commonDir ?? repo.start;
|
|
5066
|
+
const worktree = repo.commonDir === null ? repo.start : repo.worktree;
|
|
5067
|
+
let key;
|
|
5068
|
+
let pdir;
|
|
5026
5069
|
let root;
|
|
5027
5070
|
return {
|
|
5028
|
-
projectKey
|
|
5029
|
-
|
|
5030
|
-
|
|
5071
|
+
get projectKey() {
|
|
5072
|
+
key ??= sha256Hex(commonDir).slice(0, PROJECT_KEY_HEX_LEN);
|
|
5073
|
+
return key;
|
|
5074
|
+
},
|
|
5075
|
+
get projectDir() {
|
|
5076
|
+
pdir ??= join4(resolveConfigDir(process.env), PROJECTS_DIR_NAME, this.projectKey);
|
|
5077
|
+
return pdir;
|
|
5078
|
+
},
|
|
5079
|
+
get dbPath() {
|
|
5080
|
+
return join4(this.projectDir, DB_FILE_NAME);
|
|
5081
|
+
},
|
|
5031
5082
|
worktree,
|
|
5032
5083
|
get containmentRoot() {
|
|
5033
5084
|
root ??= plain ?? containmentRootOf(dir, commonDir);
|
|
@@ -5079,6 +5130,14 @@ function buildChildEnv(parent, extra) {
|
|
|
5079
5130
|
// src/core/sandbox/runtimes.ts
|
|
5080
5131
|
import { accessSync, constants as fsConstants, statSync as statSync3 } from "node:fs";
|
|
5081
5132
|
import path from "node:path";
|
|
5133
|
+
|
|
5134
|
+
// src/core/sandbox/path-entries.ts
|
|
5135
|
+
function pathEntries(value, platform = process.platform, delimiter = platform === "win32" ? ";" : ":") {
|
|
5136
|
+
const win = platform === "win32";
|
|
5137
|
+
return value.split(delimiter).map((e) => win && e.length >= 2 && e.startsWith('"') && e.endsWith('"') ? e.slice(1, -1) : e).filter(Boolean);
|
|
5138
|
+
}
|
|
5139
|
+
|
|
5140
|
+
// src/core/sandbox/runtimes.ts
|
|
5082
5141
|
var PATHEXT_SEPARATOR = ";";
|
|
5083
5142
|
var WIN_STARTABLE_EXT = Object.freeze([".exe", ".com"]);
|
|
5084
5143
|
function isWin() {
|
|
@@ -5088,7 +5147,7 @@ function candidates(lang) {
|
|
|
5088
5147
|
const win = isWin();
|
|
5089
5148
|
switch (lang) {
|
|
5090
5149
|
case "shell":
|
|
5091
|
-
return win ? [
|
|
5150
|
+
return win ? [] : ["sh"];
|
|
5092
5151
|
case "powershell":
|
|
5093
5152
|
return ["pwsh", "pwsh.exe", "powershell.exe"];
|
|
5094
5153
|
case "javascript":
|
|
@@ -5119,7 +5178,8 @@ function isRunnable(full) {
|
|
|
5119
5178
|
}
|
|
5120
5179
|
}
|
|
5121
5180
|
function findRuntime(lang, env = process.env) {
|
|
5122
|
-
|
|
5181
|
+
if (isWin() && WIN_SHELL_LANGS.includes(lang)) return findGitBash(env);
|
|
5182
|
+
const dirs = pathEntries(env.PATH ?? "", process.platform, path.delimiter);
|
|
5123
5183
|
const pathExt = isWin() ? (env.PATHEXT ?? PATHEXT_DEFAULT).split(PATHEXT_SEPARATOR).filter((e) => e !== "") : [];
|
|
5124
5184
|
const names = candidates(lang);
|
|
5125
5185
|
let shim = null;
|
|
@@ -5135,6 +5195,18 @@ function findRuntime(lang, env = process.env) {
|
|
|
5135
5195
|
}
|
|
5136
5196
|
return shim;
|
|
5137
5197
|
}
|
|
5198
|
+
function findGitBash(env) {
|
|
5199
|
+
const git2 = findRuntime(GIT_BIN, env);
|
|
5200
|
+
if (git2 === null) return null;
|
|
5201
|
+
for (const rel of GIT_BASH_RELATIVE) {
|
|
5202
|
+
const full = path.resolve(path.dirname(git2), ...rel);
|
|
5203
|
+
if (isRunnable(full)) return full;
|
|
5204
|
+
}
|
|
5205
|
+
return null;
|
|
5206
|
+
}
|
|
5207
|
+
function noRuntimeError(lang) {
|
|
5208
|
+
return isWin() && WIN_SHELL_LANGS.includes(lang) ? new CtxError("NO_GIT_BASH") : new CtxError("NO_RUNTIME", { lang });
|
|
5209
|
+
}
|
|
5138
5210
|
|
|
5139
5211
|
// src/core/sandbox/spawn.ts
|
|
5140
5212
|
import { spawn } from "node:child_process";
|
|
@@ -5641,7 +5713,7 @@ async function runWrapperMain(argv, env) {
|
|
|
5641
5713
|
if (d.kind === "deny" && userPolicyDeny(d.reason)) return exit(RUN_FAIL_EXIT, "", d.reason + "\n");
|
|
5642
5714
|
try {
|
|
5643
5715
|
const runtime = findRuntime(SHELL);
|
|
5644
|
-
if (runtime === null) throw
|
|
5716
|
+
if (runtime === null) throw noRuntimeError(SHELL);
|
|
5645
5717
|
const project = projectOf(argv, cwd);
|
|
5646
5718
|
const r = await runProcess([runtime, "-c", command], {
|
|
5647
5719
|
cwd,
|