holycodex 0.7.4 → 0.8.0
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/THIRD-PARTY-NOTICES.md +2 -0
- package/dist/cli.js +199 -133
- package/package.json +2 -2
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -9,3 +9,5 @@ The caveman communication concept is adapted from [juliusbrussee/caveman](https:
|
|
|
9
9
|
HolyCodex agent routing and orchestration instructions adapt bounded-role, task-ownership, non-overlapping-write, session-reuse, and verification-planning concepts from [alvinunreal/oh-my-opencode-slim](https://github.com/alvinunreal/oh-my-opencode-slim) at commit `7bc7b56856ee693812d87d68615757d4d1c2e218`, principally `src/agents/{orchestrator,explorer,librarian,fixer}.ts`, `src/skills/verification-planning/SKILL.md`, and `docs/background-orchestration.md`. OpenCode runtime APIs, hooks, council, ACP, companion, and background-session mechanics were not copied. Upstream material is MIT licensed; its license is preserved in `packages/plugin/plugin/LICENSE-OH-MY-OPENCODE-SLIM-MIT.txt`.
|
|
10
10
|
|
|
11
11
|
The bundled LSP runtime at `packages/plugin/plugin/runtime/lsp.js` is derived from `code-yeongyu/oh-my-openagent`'s `lsp-tools-mcp`. Copyright (c) 2026 Yeongyu Kim; used under the MIT License preserved at `packages/plugin/plugin/runtime/LICENSE-LSP-MIT.txt`.
|
|
12
|
+
|
|
13
|
+
The `codexslimedit` package and HolyCodex integration adapt compact-read and line-range edit behavior from [ASidorenkoCode/openslimedit](https://github.com/ASidorenkoCode/openslimedit) at commit `d5014929d6f66729b887df74a65ed6d22c3b522b`. Copyright (c) 2026 Artur; used under the MIT License preserved in both published packages. OpenCode hook APIs and token-saving claims were not copied.
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import process$1 from "node:process";
|
|
2
|
+
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
2
3
|
import { access, copyFile, cp, lstat, mkdir, readFile, readdir, readlink, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
4
|
import { homedir, tmpdir } from "node:os";
|
|
4
5
|
import { dirname, join } from "node:path";
|
|
5
|
-
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { Buffer } from "node:buffer";
|
|
8
8
|
import { pluginRoot } from "@holycodex/plugin";
|
|
@@ -3924,8 +3924,170 @@ function superRefine(fn, params) {
|
|
|
3924
3924
|
return /* @__PURE__ */ _superRefine(fn, params);
|
|
3925
3925
|
}
|
|
3926
3926
|
//#endregion
|
|
3927
|
+
//#region packages/mcp-stdio-core/src/process.ts
|
|
3928
|
+
var TRUNCATED_MARKER = "\n... diagnostic output truncated ...\n";
|
|
3929
|
+
var defaultManagedProcessRuntime = {
|
|
3930
|
+
terminationGraceMs: 2e3,
|
|
3931
|
+
kill: killProcessTree
|
|
3932
|
+
};
|
|
3933
|
+
/** Runs managed process. */
|
|
3934
|
+
async function runManagedProcess(input, runtime = defaultManagedProcessRuntime) {
|
|
3935
|
+
return await new Promise((resolve) => {
|
|
3936
|
+
const child = spawn(input.command, [...input.args], {
|
|
3937
|
+
...input.cwd === void 0 ? {} : { cwd: input.cwd },
|
|
3938
|
+
...input.env === void 0 ? {} : { env: input.env },
|
|
3939
|
+
stdio: [
|
|
3940
|
+
"pipe",
|
|
3941
|
+
"pipe",
|
|
3942
|
+
"pipe"
|
|
3943
|
+
],
|
|
3944
|
+
windowsHide: true,
|
|
3945
|
+
detached: input.platform !== "win32"
|
|
3946
|
+
});
|
|
3947
|
+
let stdout = {
|
|
3948
|
+
head: "",
|
|
3949
|
+
tail: "",
|
|
3950
|
+
truncated: false
|
|
3951
|
+
};
|
|
3952
|
+
let stderr = {
|
|
3953
|
+
head: "",
|
|
3954
|
+
tail: "",
|
|
3955
|
+
truncated: false
|
|
3956
|
+
};
|
|
3957
|
+
let timedOut = false;
|
|
3958
|
+
let matched = false;
|
|
3959
|
+
let settled = false;
|
|
3960
|
+
let forceKillTimeout;
|
|
3961
|
+
const finish = (exitCode, error) => {
|
|
3962
|
+
if (settled) return;
|
|
3963
|
+
settled = true;
|
|
3964
|
+
clearTimeout(timeout);
|
|
3965
|
+
if (forceKillTimeout !== void 0) clearTimeout(forceKillTimeout);
|
|
3966
|
+
resolve({
|
|
3967
|
+
exitCode,
|
|
3968
|
+
stdout: outputText(stdout),
|
|
3969
|
+
stderr: outputText(stderr),
|
|
3970
|
+
timedOut,
|
|
3971
|
+
matched,
|
|
3972
|
+
outputTruncated: stdout.truncated || stderr.truncated,
|
|
3973
|
+
...error === void 0 ? {} : { error }
|
|
3974
|
+
});
|
|
3975
|
+
};
|
|
3976
|
+
const terminate = () => {
|
|
3977
|
+
if (forceKillTimeout !== void 0) return;
|
|
3978
|
+
runtime.kill(child, input.platform, "SIGTERM");
|
|
3979
|
+
forceKillTimeout = setTimeout(() => {
|
|
3980
|
+
runtime.kill(child, input.platform, "SIGKILL");
|
|
3981
|
+
}, runtime.terminationGraceMs);
|
|
3982
|
+
forceKillTimeout.unref();
|
|
3983
|
+
};
|
|
3984
|
+
const inspectMatch = () => {
|
|
3985
|
+
if (matched || input.matchOutput === void 0) return;
|
|
3986
|
+
if (input.matchOutput(`${outputText(stdout)}\n${outputText(stderr)}`)) {
|
|
3987
|
+
matched = true;
|
|
3988
|
+
terminate();
|
|
3989
|
+
}
|
|
3990
|
+
};
|
|
3991
|
+
child.stdout.on("data", (chunk) => {
|
|
3992
|
+
stdout = appendOutput(stdout, chunk.toString(), input.maxOutputChars);
|
|
3993
|
+
inspectMatch();
|
|
3994
|
+
});
|
|
3995
|
+
child.stderr.on("data", (chunk) => {
|
|
3996
|
+
stderr = appendOutput(stderr, chunk.toString(), input.maxOutputChars);
|
|
3997
|
+
inspectMatch();
|
|
3998
|
+
});
|
|
3999
|
+
child.once("error", (error) => finish(null, error.message));
|
|
4000
|
+
child.once("close", (code) => finish(code));
|
|
4001
|
+
const timeout = setTimeout(() => {
|
|
4002
|
+
timedOut = true;
|
|
4003
|
+
terminate();
|
|
4004
|
+
}, input.timeoutMs);
|
|
4005
|
+
timeout.unref();
|
|
4006
|
+
if (input.stdin === void 0) child.stdin.end();
|
|
4007
|
+
else child.stdin.end(input.stdin);
|
|
4008
|
+
});
|
|
4009
|
+
}
|
|
4010
|
+
/** Terminates process tree. */
|
|
4011
|
+
function killProcessTree(child, platform, signal = "SIGTERM", runTaskkill = (command, args) => spawnSync(command, [...args], {
|
|
4012
|
+
stdio: "ignore",
|
|
4013
|
+
windowsHide: true
|
|
4014
|
+
})) {
|
|
4015
|
+
if (platform === "win32" && child.pid !== void 0) {
|
|
4016
|
+
const result = runTaskkill("taskkill", [
|
|
4017
|
+
"/pid",
|
|
4018
|
+
String(child.pid),
|
|
4019
|
+
"/f",
|
|
4020
|
+
"/t"
|
|
4021
|
+
]);
|
|
4022
|
+
if (result.error === void 0 && result.status === 0) return;
|
|
4023
|
+
}
|
|
4024
|
+
if (platform !== "win32" && child.pid !== void 0) try {
|
|
4025
|
+
process.kill(-child.pid, signal);
|
|
4026
|
+
return;
|
|
4027
|
+
} catch {}
|
|
4028
|
+
try {
|
|
4029
|
+
child.kill(signal);
|
|
4030
|
+
} catch {}
|
|
4031
|
+
}
|
|
4032
|
+
function appendOutput(state, chunk, limit) {
|
|
4033
|
+
const safeLimit = Math.max(1, limit);
|
|
4034
|
+
const headLimit = Math.ceil(safeLimit / 2);
|
|
4035
|
+
const tailLimit = Math.floor(safeLimit / 2);
|
|
4036
|
+
if (!state.truncated && state.head.length + chunk.length <= safeLimit) return {
|
|
4037
|
+
...state,
|
|
4038
|
+
head: state.head + chunk
|
|
4039
|
+
};
|
|
4040
|
+
const combined = state.truncated ? chunk : state.head + chunk;
|
|
4041
|
+
return {
|
|
4042
|
+
head: state.truncated ? state.head : combined.slice(0, headLimit),
|
|
4043
|
+
tail: `${state.tail}${combined.slice(state.truncated ? 0 : headLimit)}`.slice(-tailLimit),
|
|
4044
|
+
truncated: true
|
|
4045
|
+
};
|
|
4046
|
+
}
|
|
4047
|
+
function outputText(state) {
|
|
4048
|
+
return state.truncated ? `${state.head}${TRUNCATED_MARKER}${state.tail}` : state.head;
|
|
4049
|
+
}
|
|
4050
|
+
//#endregion
|
|
4051
|
+
//#region packages/cli/src/package-runner.ts
|
|
4052
|
+
var PACKAGE_INSTALL_TIMEOUT_MS = 12e4;
|
|
4053
|
+
var PACKAGE_INSTALL_OUTPUT_LIMIT = 4e3;
|
|
4054
|
+
/** Detects whether Bun or npm invoked HolyCodex. */
|
|
4055
|
+
function detectPackageRunner(env = process.env) {
|
|
4056
|
+
const executable = (env.npm_execpath ?? "").split(/[\\/]/).at(-1)?.toLowerCase().replace(/\.exe$/, "");
|
|
4057
|
+
const userAgent = env.npm_config_user_agent?.trim().split(/[\s/]/, 1)[0]?.toLowerCase();
|
|
4058
|
+
return executable === "bun" || userAgent === "bun" ? "bun" : "npm";
|
|
4059
|
+
}
|
|
4060
|
+
/** Builds the runner-specific codexslimedit invocation. */
|
|
4061
|
+
function codexSlimEditInvocation(input) {
|
|
4062
|
+
const args = [input.packageVersion.includes("-dev.") ? "codexslimedit@dev" : "codexslimedit@latest", ...input.includeVersion ? ["--version"] : []];
|
|
4063
|
+
return input.packageRunner === "bun" ? {
|
|
4064
|
+
command: "bunx",
|
|
4065
|
+
args
|
|
4066
|
+
} : {
|
|
4067
|
+
command: input.platform === "win32" ? "npx.cmd" : "npx",
|
|
4068
|
+
args: ["--yes", ...args]
|
|
4069
|
+
};
|
|
4070
|
+
}
|
|
4071
|
+
/** Pre-resolves codexslimedit through the invoking package runner. */
|
|
4072
|
+
async function installCodexSlimEdit(input, env = process.env) {
|
|
4073
|
+
if (env.NODE_ENV === "test" && env.HOLYCODEX_TEST_SKIP_PACKAGE_RESOLUTION === "1") return;
|
|
4074
|
+
const invocation = codexSlimEditInvocation({
|
|
4075
|
+
...input,
|
|
4076
|
+
includeVersion: true
|
|
4077
|
+
});
|
|
4078
|
+
const result = await runManagedProcess({
|
|
4079
|
+
...invocation,
|
|
4080
|
+
platform: input.platform,
|
|
4081
|
+
timeoutMs: PACKAGE_INSTALL_TIMEOUT_MS,
|
|
4082
|
+
maxOutputChars: PACKAGE_INSTALL_OUTPUT_LIMIT
|
|
4083
|
+
});
|
|
4084
|
+
if (result.exitCode === 0 && !result.timedOut) return;
|
|
4085
|
+
const detail = result.error ?? (result.stderr.trim() || result.stdout.trim() || "unknown package error");
|
|
4086
|
+
throw new Error(`Could not install codexslimedit with ${invocation.command}: ${detail}. Check package registry and network access, then retry HolyCodex installation.`);
|
|
4087
|
+
}
|
|
4088
|
+
//#endregion
|
|
3927
4089
|
//#region packages/cli/src/catalog.ts
|
|
3928
|
-
var VERSION = "0.
|
|
4090
|
+
var VERSION = "0.8.0";
|
|
3929
4091
|
var SKILLS = [
|
|
3930
4092
|
"ast-grep",
|
|
3931
4093
|
"caveman",
|
|
@@ -4057,7 +4219,7 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
|
|
|
4057
4219
|
}
|
|
4058
4220
|
},
|
|
4059
4221
|
usage: {
|
|
4060
|
-
maxThreads:
|
|
4222
|
+
maxThreads: 2,
|
|
4061
4223
|
maxDepth: 1
|
|
4062
4224
|
}
|
|
4063
4225
|
},
|
|
@@ -4286,19 +4448,26 @@ var MANAGED_ROOT_MODEL_HISTORY_BY_PLAN = {
|
|
|
4286
4448
|
"pro-20x": managedPlanRootModels("pro-20x")
|
|
4287
4449
|
};
|
|
4288
4450
|
var GENERATED_RUNTIMES = [
|
|
4451
|
+
"agent-capacity.js",
|
|
4289
4452
|
"bootstrap.js",
|
|
4290
4453
|
"core-instructions.js",
|
|
4291
4454
|
"detect-lsp.js",
|
|
4292
4455
|
"git-bash.js",
|
|
4293
4456
|
"git-bash-resolver.js",
|
|
4294
4457
|
"LICENSE-LSP-MIT.txt",
|
|
4458
|
+
"LICENSE-OPENSLIMEDIT-MIT.txt",
|
|
4295
4459
|
"lsp.js",
|
|
4296
4460
|
"mcp-stdio-core.js",
|
|
4297
4461
|
"rules.js"
|
|
4298
4462
|
];
|
|
4299
4463
|
var WINDOWS_SHELL_POLICY = "On native Windows, before the first shell action, inspect callable and deferred tools until `mcp__git_bash__run` is resolved. Use it for every shell command, including Git, Bash, POSIX, package, build, test, and script commands. If unavailable, stop and report the blocker. Never fall back to PowerShell or cmd.";
|
|
4300
4464
|
/** Provides effective mcp servers. */
|
|
4301
|
-
function effectiveMcpServers(platform) {
|
|
4465
|
+
function effectiveMcpServers(platform, packageRunner = "bun") {
|
|
4466
|
+
const codexSlimEdit = codexSlimEditInvocation({
|
|
4467
|
+
packageRunner,
|
|
4468
|
+
platform,
|
|
4469
|
+
packageVersion: VERSION
|
|
4470
|
+
});
|
|
4302
4471
|
return {
|
|
4303
4472
|
...platform === "win32" ? { git_bash: {
|
|
4304
4473
|
command: "node",
|
|
@@ -4311,6 +4480,10 @@ function effectiveMcpServers(platform) {
|
|
|
4311
4480
|
args: ["runtime/lsp.js", "mcp"],
|
|
4312
4481
|
cwd: "."
|
|
4313
4482
|
},
|
|
4483
|
+
codexslimedit: {
|
|
4484
|
+
...codexSlimEdit,
|
|
4485
|
+
enabled_tools: ["read_file", "apply_patch"]
|
|
4486
|
+
},
|
|
4314
4487
|
context7: {
|
|
4315
4488
|
command: "bunx",
|
|
4316
4489
|
args: ["@upstash/context7-mcp"]
|
|
@@ -4403,130 +4576,6 @@ function missing(checkedPaths) {
|
|
|
4403
4576
|
};
|
|
4404
4577
|
}
|
|
4405
4578
|
//#endregion
|
|
4406
|
-
//#region packages/mcp-stdio-core/src/process.ts
|
|
4407
|
-
var TRUNCATED_MARKER = "\n... diagnostic output truncated ...\n";
|
|
4408
|
-
var defaultManagedProcessRuntime = {
|
|
4409
|
-
terminationGraceMs: 2e3,
|
|
4410
|
-
kill: killProcessTree
|
|
4411
|
-
};
|
|
4412
|
-
/** Runs managed process. */
|
|
4413
|
-
async function runManagedProcess(input, runtime = defaultManagedProcessRuntime) {
|
|
4414
|
-
return await new Promise((resolve) => {
|
|
4415
|
-
const child = spawn(input.command, [...input.args], {
|
|
4416
|
-
...input.cwd === void 0 ? {} : { cwd: input.cwd },
|
|
4417
|
-
...input.env === void 0 ? {} : { env: input.env },
|
|
4418
|
-
stdio: [
|
|
4419
|
-
"pipe",
|
|
4420
|
-
"pipe",
|
|
4421
|
-
"pipe"
|
|
4422
|
-
],
|
|
4423
|
-
windowsHide: true,
|
|
4424
|
-
detached: input.platform !== "win32"
|
|
4425
|
-
});
|
|
4426
|
-
let stdout = {
|
|
4427
|
-
head: "",
|
|
4428
|
-
tail: "",
|
|
4429
|
-
truncated: false
|
|
4430
|
-
};
|
|
4431
|
-
let stderr = {
|
|
4432
|
-
head: "",
|
|
4433
|
-
tail: "",
|
|
4434
|
-
truncated: false
|
|
4435
|
-
};
|
|
4436
|
-
let timedOut = false;
|
|
4437
|
-
let matched = false;
|
|
4438
|
-
let settled = false;
|
|
4439
|
-
let forceKillTimeout;
|
|
4440
|
-
const finish = (exitCode, error) => {
|
|
4441
|
-
if (settled) return;
|
|
4442
|
-
settled = true;
|
|
4443
|
-
clearTimeout(timeout);
|
|
4444
|
-
if (forceKillTimeout !== void 0) clearTimeout(forceKillTimeout);
|
|
4445
|
-
resolve({
|
|
4446
|
-
exitCode,
|
|
4447
|
-
stdout: outputText(stdout),
|
|
4448
|
-
stderr: outputText(stderr),
|
|
4449
|
-
timedOut,
|
|
4450
|
-
matched,
|
|
4451
|
-
outputTruncated: stdout.truncated || stderr.truncated,
|
|
4452
|
-
...error === void 0 ? {} : { error }
|
|
4453
|
-
});
|
|
4454
|
-
};
|
|
4455
|
-
const terminate = () => {
|
|
4456
|
-
if (forceKillTimeout !== void 0) return;
|
|
4457
|
-
runtime.kill(child, input.platform, "SIGTERM");
|
|
4458
|
-
forceKillTimeout = setTimeout(() => {
|
|
4459
|
-
runtime.kill(child, input.platform, "SIGKILL");
|
|
4460
|
-
}, runtime.terminationGraceMs);
|
|
4461
|
-
forceKillTimeout.unref();
|
|
4462
|
-
};
|
|
4463
|
-
const inspectMatch = () => {
|
|
4464
|
-
if (matched || input.matchOutput === void 0) return;
|
|
4465
|
-
if (input.matchOutput(`${outputText(stdout)}\n${outputText(stderr)}`)) {
|
|
4466
|
-
matched = true;
|
|
4467
|
-
terminate();
|
|
4468
|
-
}
|
|
4469
|
-
};
|
|
4470
|
-
child.stdout.on("data", (chunk) => {
|
|
4471
|
-
stdout = appendOutput(stdout, chunk.toString(), input.maxOutputChars);
|
|
4472
|
-
inspectMatch();
|
|
4473
|
-
});
|
|
4474
|
-
child.stderr.on("data", (chunk) => {
|
|
4475
|
-
stderr = appendOutput(stderr, chunk.toString(), input.maxOutputChars);
|
|
4476
|
-
inspectMatch();
|
|
4477
|
-
});
|
|
4478
|
-
child.once("error", (error) => finish(null, error.message));
|
|
4479
|
-
child.once("close", (code) => finish(code));
|
|
4480
|
-
const timeout = setTimeout(() => {
|
|
4481
|
-
timedOut = true;
|
|
4482
|
-
terminate();
|
|
4483
|
-
}, input.timeoutMs);
|
|
4484
|
-
timeout.unref();
|
|
4485
|
-
if (input.stdin === void 0) child.stdin.end();
|
|
4486
|
-
else child.stdin.end(input.stdin);
|
|
4487
|
-
});
|
|
4488
|
-
}
|
|
4489
|
-
/** Terminates process tree. */
|
|
4490
|
-
function killProcessTree(child, platform, signal = "SIGTERM", runTaskkill = (command, args) => spawnSync(command, [...args], {
|
|
4491
|
-
stdio: "ignore",
|
|
4492
|
-
windowsHide: true
|
|
4493
|
-
})) {
|
|
4494
|
-
if (platform === "win32" && child.pid !== void 0) {
|
|
4495
|
-
const result = runTaskkill("taskkill", [
|
|
4496
|
-
"/pid",
|
|
4497
|
-
String(child.pid),
|
|
4498
|
-
"/f",
|
|
4499
|
-
"/t"
|
|
4500
|
-
]);
|
|
4501
|
-
if (result.error === void 0 && result.status === 0) return;
|
|
4502
|
-
}
|
|
4503
|
-
if (platform !== "win32" && child.pid !== void 0) try {
|
|
4504
|
-
process.kill(-child.pid, signal);
|
|
4505
|
-
return;
|
|
4506
|
-
} catch {}
|
|
4507
|
-
try {
|
|
4508
|
-
child.kill(signal);
|
|
4509
|
-
} catch {}
|
|
4510
|
-
}
|
|
4511
|
-
function appendOutput(state, chunk, limit) {
|
|
4512
|
-
const safeLimit = Math.max(1, limit);
|
|
4513
|
-
const headLimit = Math.ceil(safeLimit / 2);
|
|
4514
|
-
const tailLimit = Math.floor(safeLimit / 2);
|
|
4515
|
-
if (!state.truncated && state.head.length + chunk.length <= safeLimit) return {
|
|
4516
|
-
...state,
|
|
4517
|
-
head: state.head + chunk
|
|
4518
|
-
};
|
|
4519
|
-
const combined = state.truncated ? chunk : state.head + chunk;
|
|
4520
|
-
return {
|
|
4521
|
-
head: state.truncated ? state.head : combined.slice(0, headLimit),
|
|
4522
|
-
tail: `${state.tail}${combined.slice(state.truncated ? 0 : headLimit)}`.slice(-tailLimit),
|
|
4523
|
-
truncated: true
|
|
4524
|
-
};
|
|
4525
|
-
}
|
|
4526
|
-
function outputText(state) {
|
|
4527
|
-
return state.truncated ? `${state.head}${TRUNCATED_MARKER}${state.tail}` : state.head;
|
|
4528
|
-
}
|
|
4529
|
-
//#endregion
|
|
4530
4579
|
//#region packages/cli/src/toml.ts
|
|
4531
4580
|
var TOML_TABLE = /^[ \t]*(?:\[[^\]\r\n]+\]|\[\[[^\]\r\n]+\]\])[ \t]*(?:#.*)?$/m;
|
|
4532
4581
|
/** Reads a root TOML string value. */
|
|
@@ -4773,6 +4822,7 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN) {
|
|
|
4773
4822
|
let configured = `${`${START}\n${PLAN_PREFIX}${plan}\n${originalRoot ? `${ORIGINAL_ROOT}${Buffer.from(originalRoot).toString("base64")}\n` : ""}${model}${effort}${verbosity}${preservedRoot ? `${preservedRoot}\n` : ""}approval_policy = "${approval}"\nsandbox_mode = "${sandbox}"\nstatus_line = ${mergedStatusLine(controlled[3])}\n${END}`}${tables ? `\n\n${tables}` : ""}`;
|
|
4774
4823
|
configured = injectTableKey(configured, "features", "default_mode_request_user_input", "true");
|
|
4775
4824
|
configured = injectTableKey(configured, "features", "multi_agent", "true");
|
|
4825
|
+
configured = injectTableKey(configured, "features", "multi_agent_v2", "true");
|
|
4776
4826
|
const usage = MODEL_ROUTING_PLANS[plan].usage;
|
|
4777
4827
|
configured = injectTableKey(configured, "agents", "max_threads", String(usage.maxThreads));
|
|
4778
4828
|
configured = injectTableKey(configured, "agents", "max_depth", String(usage.maxDepth));
|
|
@@ -4829,7 +4879,10 @@ async function startContext7(platform) {
|
|
|
4829
4879
|
}
|
|
4830
4880
|
var defaultRuntime$1 = {
|
|
4831
4881
|
platform: process.platform,
|
|
4832
|
-
command: (name, args) =>
|
|
4882
|
+
command: (name, args) => process.env.NODE_ENV === "test" && process.env.HOLYCODEX_TEST_SKIP_PACKAGE_RESOLUTION === "1" && args.some((argument) => argument.startsWith("codexslimedit@")) ? Promise.resolve({
|
|
4883
|
+
ok: true,
|
|
4884
|
+
output: "package resolution skipped in tests"
|
|
4885
|
+
}) : runCommand(name, args, process.platform),
|
|
4833
4886
|
context7: () => startContext7(process.platform),
|
|
4834
4887
|
gitBash: resolveGitBashForCurrentProcess
|
|
4835
4888
|
};
|
|
@@ -4908,6 +4961,12 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
4908
4961
|
const expected = expectedMcps[name];
|
|
4909
4962
|
checks.push(configured === void 0 || expected === void 0 ? check(`mcp-${name}`, "error", "missing-required-mcp", `${name} is not configured.`, "Reinstall HolyCodex.") : !mcpConfigMatches(configured, expected) ? check(`mcp-${name}`, "error", "invalid-required-mcp-config", `${name} configuration is stale or contains unsupported settings.`, "Reinstall HolyCodex.") : check(`mcp-${name}`, "ok", "required-mcp-ready", `${name} is configured locally.`));
|
|
4910
4963
|
}
|
|
4964
|
+
const codexSlimEdit = servers?.codexslimedit;
|
|
4965
|
+
const codexSlimEditConfig = ["bun", "npm"].map((runner) => effectiveMcpServers(runtime.platform, runner).codexslimedit).find((expected) => {
|
|
4966
|
+
return expected !== void 0 && codexSlimEdit !== void 0 && mcpConfigMatches(codexSlimEdit, expected);
|
|
4967
|
+
});
|
|
4968
|
+
const codexSlimEditStarted = codexSlimEditConfig === void 0 ? void 0 : await runtime.command(codexSlimEditConfig.command, [...codexSlimEditConfig.args, "--version"]);
|
|
4969
|
+
checks.push(codexSlimEdit === void 0 ? check("mcp-codexslimedit", "error", "missing-codexslimedit", "codexslimedit is not configured.", "Reinstall HolyCodex.") : codexSlimEditStarted?.ok === true ? check("mcp-codexslimedit", "ok", "codexslimedit-ready", "codexslimedit is configured through npm or Bun.") : codexSlimEditConfig === void 0 ? check("mcp-codexslimedit", "error", "invalid-codexslimedit-config", "codexslimedit configuration is stale or uses an unsupported runner.", "Reinstall HolyCodex.") : check("mcp-codexslimedit", "error", "codexslimedit-unavailable", `codexslimedit could not start: ${codexSlimEditStarted?.output || "unknown runner error"}`, "Check the configured package runner and network access, then reinstall HolyCodex."));
|
|
4911
4970
|
const gitBashConfig = servers?.git_bash;
|
|
4912
4971
|
if (runtime.platform === "win32" && gitBashConfig !== void 0) {
|
|
4913
4972
|
const expected = effectiveMcpServers("win32").git_bash;
|
|
@@ -5019,7 +5078,13 @@ async function readText(path) {
|
|
|
5019
5078
|
//#region packages/cli/src/install.ts
|
|
5020
5079
|
var defaultRuntime = {
|
|
5021
5080
|
platform: process.platform,
|
|
5022
|
-
gitBash: resolveGitBashForCurrentProcess
|
|
5081
|
+
gitBash: resolveGitBashForCurrentProcess,
|
|
5082
|
+
packageRunner: detectPackageRunner(),
|
|
5083
|
+
installCodexSlimEdit: async (packageRunner) => installCodexSlimEdit({
|
|
5084
|
+
packageRunner,
|
|
5085
|
+
packageVersion: VERSION,
|
|
5086
|
+
platform: process.platform
|
|
5087
|
+
})
|
|
5023
5088
|
};
|
|
5024
5089
|
function paths(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")) {
|
|
5025
5090
|
const marketplaceCache = join(home, "plugins", "cache", "holycodex");
|
|
@@ -5049,6 +5114,7 @@ function assertGitBashReady(platform, resolution) {
|
|
|
5049
5114
|
/** Provides install. */
|
|
5050
5115
|
async function install(options, runtime = defaultRuntime) {
|
|
5051
5116
|
assertGitBashReady(runtime.platform, runtime.gitBash());
|
|
5117
|
+
await runtime.installCodexSlimEdit(runtime.packageRunner);
|
|
5052
5118
|
const plan = options.plan ?? "plus";
|
|
5053
5119
|
const target = paths();
|
|
5054
5120
|
const root = backupRoot();
|
|
@@ -5068,7 +5134,7 @@ async function install(options, runtime = defaultRuntime) {
|
|
|
5068
5134
|
});
|
|
5069
5135
|
await mkdir(dirname(target.cache), { recursive: true });
|
|
5070
5136
|
await cp(pluginRoot, target.cache, { recursive: true });
|
|
5071
|
-
await writePlatformPlugin(target.cache, runtime.platform, plan);
|
|
5137
|
+
await writePlatformPlugin(target.cache, runtime.platform, plan, runtime.packageRunner);
|
|
5072
5138
|
const existingAgentPreferences = await readAgentPreferences(target.agents, previousPlan);
|
|
5073
5139
|
await rm(target.agents, {
|
|
5074
5140
|
recursive: true,
|
|
@@ -5123,8 +5189,8 @@ async function preserveAgentPreferences(root, preferences) {
|
|
|
5123
5189
|
function replaceTomlString(input, key, value) {
|
|
5124
5190
|
return input.replace(new RegExp(`^${key}\\s*=.*$`, "m"), `${key} = ${JSON.stringify(value)}`);
|
|
5125
5191
|
}
|
|
5126
|
-
async function writePlatformPlugin(root, platform, plan) {
|
|
5127
|
-
await atomicWrite(join(root, ".mcp.json"), `${JSON.stringify({ mcpServers: effectiveMcpServers(platform) }, null, 2)}\n`);
|
|
5192
|
+
async function writePlatformPlugin(root, platform, plan, packageRunner) {
|
|
5193
|
+
await atomicWrite(join(root, ".mcp.json"), `${JSON.stringify({ mcpServers: effectiveMcpServers(platform, packageRunner) }, null, 2)}\n`);
|
|
5128
5194
|
await writeInstalledAgents(join(root, "agents"), platform, plan);
|
|
5129
5195
|
}
|
|
5130
5196
|
async function writeInstalledAgents(root, platform, plan) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "holycodex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Lean Codex-only agent toolkit installer and doctor",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"prepack": "vp run --workspace-root build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@holycodex/plugin": "0.
|
|
42
|
+
"@holycodex/plugin": "0.8.0",
|
|
43
43
|
"zod": "^4.4.3"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|