holycodex 0.7.4-dev.29702371652.1 → 0.7.4
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 +0 -2
- package/dist/cli.js +132 -195
- package/package.json +2 -2
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -9,5 +9,3 @@ 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";
|
|
3
2
|
import { access, copyFile, cp, lstat, mkdir, readFile, readdir, readlink, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
4
3
|
import { homedir, tmpdir } from "node:os";
|
|
5
4
|
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,170 +3924,8 @@ 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
|
|
4089
3927
|
//#region packages/cli/src/catalog.ts
|
|
4090
|
-
var VERSION = "0.7.4
|
|
3928
|
+
var VERSION = "0.7.4";
|
|
4091
3929
|
var SKILLS = [
|
|
4092
3930
|
"ast-grep",
|
|
4093
3931
|
"caveman",
|
|
@@ -4219,7 +4057,7 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
|
|
|
4219
4057
|
}
|
|
4220
4058
|
},
|
|
4221
4059
|
usage: {
|
|
4222
|
-
maxThreads:
|
|
4060
|
+
maxThreads: 1,
|
|
4223
4061
|
maxDepth: 1
|
|
4224
4062
|
}
|
|
4225
4063
|
},
|
|
@@ -4448,26 +4286,19 @@ var MANAGED_ROOT_MODEL_HISTORY_BY_PLAN = {
|
|
|
4448
4286
|
"pro-20x": managedPlanRootModels("pro-20x")
|
|
4449
4287
|
};
|
|
4450
4288
|
var GENERATED_RUNTIMES = [
|
|
4451
|
-
"agent-capacity.js",
|
|
4452
4289
|
"bootstrap.js",
|
|
4453
4290
|
"core-instructions.js",
|
|
4454
4291
|
"detect-lsp.js",
|
|
4455
4292
|
"git-bash.js",
|
|
4456
4293
|
"git-bash-resolver.js",
|
|
4457
4294
|
"LICENSE-LSP-MIT.txt",
|
|
4458
|
-
"LICENSE-OPENSLIMEDIT-MIT.txt",
|
|
4459
4295
|
"lsp.js",
|
|
4460
4296
|
"mcp-stdio-core.js",
|
|
4461
4297
|
"rules.js"
|
|
4462
4298
|
];
|
|
4463
4299
|
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.";
|
|
4464
4300
|
/** Provides effective mcp servers. */
|
|
4465
|
-
function effectiveMcpServers(platform
|
|
4466
|
-
const codexSlimEdit = codexSlimEditInvocation({
|
|
4467
|
-
packageRunner,
|
|
4468
|
-
platform,
|
|
4469
|
-
packageVersion: VERSION
|
|
4470
|
-
});
|
|
4301
|
+
function effectiveMcpServers(platform) {
|
|
4471
4302
|
return {
|
|
4472
4303
|
...platform === "win32" ? { git_bash: {
|
|
4473
4304
|
command: "node",
|
|
@@ -4480,10 +4311,6 @@ function effectiveMcpServers(platform, packageRunner = "bun") {
|
|
|
4480
4311
|
args: ["runtime/lsp.js", "mcp"],
|
|
4481
4312
|
cwd: "."
|
|
4482
4313
|
},
|
|
4483
|
-
codexslimedit: {
|
|
4484
|
-
...codexSlimEdit,
|
|
4485
|
-
enabled_tools: ["read_file", "apply_patch"]
|
|
4486
|
-
},
|
|
4487
4314
|
context7: {
|
|
4488
4315
|
command: "bunx",
|
|
4489
4316
|
args: ["@upstash/context7-mcp"]
|
|
@@ -4576,6 +4403,130 @@ function missing(checkedPaths) {
|
|
|
4576
4403
|
};
|
|
4577
4404
|
}
|
|
4578
4405
|
//#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
|
|
4579
4530
|
//#region packages/cli/src/toml.ts
|
|
4580
4531
|
var TOML_TABLE = /^[ \t]*(?:\[[^\]\r\n]+\]|\[\[[^\]\r\n]+\]\])[ \t]*(?:#.*)?$/m;
|
|
4581
4532
|
/** Reads a root TOML string value. */
|
|
@@ -4822,7 +4773,6 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN) {
|
|
|
4822
4773
|
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}` : ""}`;
|
|
4823
4774
|
configured = injectTableKey(configured, "features", "default_mode_request_user_input", "true");
|
|
4824
4775
|
configured = injectTableKey(configured, "features", "multi_agent", "true");
|
|
4825
|
-
configured = injectTableKey(configured, "features", "multi_agent_v2", "true");
|
|
4826
4776
|
const usage = MODEL_ROUTING_PLANS[plan].usage;
|
|
4827
4777
|
configured = injectTableKey(configured, "agents", "max_threads", String(usage.maxThreads));
|
|
4828
4778
|
configured = injectTableKey(configured, "agents", "max_depth", String(usage.maxDepth));
|
|
@@ -4958,12 +4908,6 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
4958
4908
|
const expected = expectedMcps[name];
|
|
4959
4909
|
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.`));
|
|
4960
4910
|
}
|
|
4961
|
-
const codexSlimEdit = servers?.codexslimedit;
|
|
4962
|
-
const codexSlimEditReady = ["bun", "npm"].some((runner) => {
|
|
4963
|
-
const expected = effectiveMcpServers(runtime.platform, runner).codexslimedit;
|
|
4964
|
-
return expected !== void 0 && codexSlimEdit !== void 0 && mcpConfigMatches(codexSlimEdit, expected);
|
|
4965
|
-
});
|
|
4966
|
-
checks.push(codexSlimEdit === void 0 ? check("mcp-codexslimedit", "error", "missing-codexslimedit", "codexslimedit is not configured.", "Reinstall HolyCodex.") : codexSlimEditReady ? check("mcp-codexslimedit", "ok", "codexslimedit-ready", "codexslimedit is configured through npm or Bun.") : check("mcp-codexslimedit", "error", "invalid-codexslimedit-config", "codexslimedit configuration is stale or uses an unsupported runner.", "Reinstall HolyCodex."));
|
|
4967
4911
|
const gitBashConfig = servers?.git_bash;
|
|
4968
4912
|
if (runtime.platform === "win32" && gitBashConfig !== void 0) {
|
|
4969
4913
|
const expected = effectiveMcpServers("win32").git_bash;
|
|
@@ -5075,13 +5019,7 @@ async function readText(path) {
|
|
|
5075
5019
|
//#region packages/cli/src/install.ts
|
|
5076
5020
|
var defaultRuntime = {
|
|
5077
5021
|
platform: process.platform,
|
|
5078
|
-
gitBash: resolveGitBashForCurrentProcess
|
|
5079
|
-
packageRunner: detectPackageRunner(),
|
|
5080
|
-
installCodexSlimEdit: async (packageRunner) => installCodexSlimEdit({
|
|
5081
|
-
packageRunner,
|
|
5082
|
-
packageVersion: VERSION,
|
|
5083
|
-
platform: process.platform
|
|
5084
|
-
})
|
|
5022
|
+
gitBash: resolveGitBashForCurrentProcess
|
|
5085
5023
|
};
|
|
5086
5024
|
function paths(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")) {
|
|
5087
5025
|
const marketplaceCache = join(home, "plugins", "cache", "holycodex");
|
|
@@ -5111,7 +5049,6 @@ function assertGitBashReady(platform, resolution) {
|
|
|
5111
5049
|
/** Provides install. */
|
|
5112
5050
|
async function install(options, runtime = defaultRuntime) {
|
|
5113
5051
|
assertGitBashReady(runtime.platform, runtime.gitBash());
|
|
5114
|
-
await runtime.installCodexSlimEdit(runtime.packageRunner);
|
|
5115
5052
|
const plan = options.plan ?? "plus";
|
|
5116
5053
|
const target = paths();
|
|
5117
5054
|
const root = backupRoot();
|
|
@@ -5131,7 +5068,7 @@ async function install(options, runtime = defaultRuntime) {
|
|
|
5131
5068
|
});
|
|
5132
5069
|
await mkdir(dirname(target.cache), { recursive: true });
|
|
5133
5070
|
await cp(pluginRoot, target.cache, { recursive: true });
|
|
5134
|
-
await writePlatformPlugin(target.cache, runtime.platform, plan
|
|
5071
|
+
await writePlatformPlugin(target.cache, runtime.platform, plan);
|
|
5135
5072
|
const existingAgentPreferences = await readAgentPreferences(target.agents, previousPlan);
|
|
5136
5073
|
await rm(target.agents, {
|
|
5137
5074
|
recursive: true,
|
|
@@ -5186,8 +5123,8 @@ async function preserveAgentPreferences(root, preferences) {
|
|
|
5186
5123
|
function replaceTomlString(input, key, value) {
|
|
5187
5124
|
return input.replace(new RegExp(`^${key}\\s*=.*$`, "m"), `${key} = ${JSON.stringify(value)}`);
|
|
5188
5125
|
}
|
|
5189
|
-
async function writePlatformPlugin(root, platform, plan
|
|
5190
|
-
await atomicWrite(join(root, ".mcp.json"), `${JSON.stringify({ mcpServers: effectiveMcpServers(platform
|
|
5126
|
+
async function writePlatformPlugin(root, platform, plan) {
|
|
5127
|
+
await atomicWrite(join(root, ".mcp.json"), `${JSON.stringify({ mcpServers: effectiveMcpServers(platform) }, null, 2)}\n`);
|
|
5191
5128
|
await writeInstalledAgents(join(root, "agents"), platform, plan);
|
|
5192
5129
|
}
|
|
5193
5130
|
async function writeInstalledAgents(root, platform, plan) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "holycodex",
|
|
3
|
-
"version": "0.7.4
|
|
3
|
+
"version": "0.7.4",
|
|
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.7.4
|
|
42
|
+
"@holycodex/plugin": "0.7.4",
|
|
43
43
|
"zod": "^4.4.3"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|