holycodex 0.11.0 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +389 -457
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import process$1 from "node:process";
|
|
2
|
-
import { access, copyFile, cp, lstat, mkdir, readFile, readdir, readlink, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { access, copyFile, cp, lstat, mkdir, mkdtemp, readFile, readdir, readlink, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import { homedir, tmpdir } from "node:os";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
4
|
+
import { delimiter, dirname, join } from "node:path";
|
|
5
5
|
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { Buffer } from "node:buffer";
|
|
@@ -81,7 +81,6 @@ function cached(getter) {
|
|
|
81
81
|
Object.defineProperty(this, "value", { value });
|
|
82
82
|
return value;
|
|
83
83
|
}
|
|
84
|
-
throw new Error("cached value already set");
|
|
85
84
|
} };
|
|
86
85
|
}
|
|
87
86
|
function nullish(input) {
|
|
@@ -1907,115 +1906,6 @@ function handleIntersectionResults(result, left, right) {
|
|
|
1907
1906
|
result.value = merged.data;
|
|
1908
1907
|
return result;
|
|
1909
1908
|
}
|
|
1910
|
-
var $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
|
|
1911
|
-
$ZodType.init(inst, def);
|
|
1912
|
-
inst._zod.parse = (payload, ctx) => {
|
|
1913
|
-
const input = payload.value;
|
|
1914
|
-
if (!isPlainObject(input)) {
|
|
1915
|
-
payload.issues.push({
|
|
1916
|
-
expected: "record",
|
|
1917
|
-
code: "invalid_type",
|
|
1918
|
-
input,
|
|
1919
|
-
inst
|
|
1920
|
-
});
|
|
1921
|
-
return payload;
|
|
1922
|
-
}
|
|
1923
|
-
const proms = [];
|
|
1924
|
-
const values = def.keyType._zod.values;
|
|
1925
|
-
if (values) {
|
|
1926
|
-
payload.value = {};
|
|
1927
|
-
const recordKeys = /* @__PURE__ */ new Set();
|
|
1928
|
-
for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
|
|
1929
|
-
recordKeys.add(typeof key === "number" ? key.toString() : key);
|
|
1930
|
-
const keyResult = def.keyType._zod.run({
|
|
1931
|
-
value: key,
|
|
1932
|
-
issues: []
|
|
1933
|
-
}, ctx);
|
|
1934
|
-
if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
|
|
1935
|
-
if (keyResult.issues.length) {
|
|
1936
|
-
payload.issues.push({
|
|
1937
|
-
code: "invalid_key",
|
|
1938
|
-
origin: "record",
|
|
1939
|
-
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
|
|
1940
|
-
input: key,
|
|
1941
|
-
path: [key],
|
|
1942
|
-
inst
|
|
1943
|
-
});
|
|
1944
|
-
continue;
|
|
1945
|
-
}
|
|
1946
|
-
const outKey = keyResult.value;
|
|
1947
|
-
const result = def.valueType._zod.run({
|
|
1948
|
-
value: input[key],
|
|
1949
|
-
issues: []
|
|
1950
|
-
}, ctx);
|
|
1951
|
-
if (result instanceof Promise) proms.push(result.then((result) => {
|
|
1952
|
-
if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
|
|
1953
|
-
payload.value[outKey] = result.value;
|
|
1954
|
-
}));
|
|
1955
|
-
else {
|
|
1956
|
-
if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
|
|
1957
|
-
payload.value[outKey] = result.value;
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
let unrecognized;
|
|
1961
|
-
for (const key in input) if (!recordKeys.has(key)) {
|
|
1962
|
-
unrecognized = unrecognized ?? [];
|
|
1963
|
-
unrecognized.push(key);
|
|
1964
|
-
}
|
|
1965
|
-
if (unrecognized && unrecognized.length > 0) payload.issues.push({
|
|
1966
|
-
code: "unrecognized_keys",
|
|
1967
|
-
input,
|
|
1968
|
-
inst,
|
|
1969
|
-
keys: unrecognized
|
|
1970
|
-
});
|
|
1971
|
-
} else {
|
|
1972
|
-
payload.value = {};
|
|
1973
|
-
for (const key of Reflect.ownKeys(input)) {
|
|
1974
|
-
if (key === "__proto__") continue;
|
|
1975
|
-
if (!Object.prototype.propertyIsEnumerable.call(input, key)) continue;
|
|
1976
|
-
let keyResult = def.keyType._zod.run({
|
|
1977
|
-
value: key,
|
|
1978
|
-
issues: []
|
|
1979
|
-
}, ctx);
|
|
1980
|
-
if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
|
|
1981
|
-
if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) {
|
|
1982
|
-
const retryResult = def.keyType._zod.run({
|
|
1983
|
-
value: Number(key),
|
|
1984
|
-
issues: []
|
|
1985
|
-
}, ctx);
|
|
1986
|
-
if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
|
|
1987
|
-
if (retryResult.issues.length === 0) keyResult = retryResult;
|
|
1988
|
-
}
|
|
1989
|
-
if (keyResult.issues.length) {
|
|
1990
|
-
if (def.mode === "loose") payload.value[key] = input[key];
|
|
1991
|
-
else payload.issues.push({
|
|
1992
|
-
code: "invalid_key",
|
|
1993
|
-
origin: "record",
|
|
1994
|
-
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
|
|
1995
|
-
input: key,
|
|
1996
|
-
path: [key],
|
|
1997
|
-
inst
|
|
1998
|
-
});
|
|
1999
|
-
continue;
|
|
2000
|
-
}
|
|
2001
|
-
const result = def.valueType._zod.run({
|
|
2002
|
-
value: input[key],
|
|
2003
|
-
issues: []
|
|
2004
|
-
}, ctx);
|
|
2005
|
-
if (result instanceof Promise) proms.push(result.then((result) => {
|
|
2006
|
-
if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
|
|
2007
|
-
payload.value[keyResult.value] = result.value;
|
|
2008
|
-
}));
|
|
2009
|
-
else {
|
|
2010
|
-
if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
|
|
2011
|
-
payload.value[keyResult.value] = result.value;
|
|
2012
|
-
}
|
|
2013
|
-
}
|
|
2014
|
-
}
|
|
2015
|
-
if (proms.length) return Promise.all(proms).then(() => payload);
|
|
2016
|
-
return payload;
|
|
2017
|
-
};
|
|
2018
|
-
});
|
|
2019
1909
|
var $ZodEnum = /*@__PURE__*/ $constructor("$ZodEnum", (inst, def) => {
|
|
2020
1910
|
$ZodType.init(inst, def);
|
|
2021
1911
|
const values = getEnumValues(def.entries);
|
|
@@ -3281,39 +3171,6 @@ var intersectionProcessor = (schema, ctx, json, params) => {
|
|
|
3281
3171
|
const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
|
|
3282
3172
|
json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
|
|
3283
3173
|
};
|
|
3284
|
-
var recordProcessor = (schema, ctx, _json, params) => {
|
|
3285
|
-
const json = _json;
|
|
3286
|
-
const def = schema._zod.def;
|
|
3287
|
-
json.type = "object";
|
|
3288
|
-
const keyType = def.keyType;
|
|
3289
|
-
const patterns = keyType._zod.bag?.patterns;
|
|
3290
|
-
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
3291
|
-
const valueSchema = process$2(def.valueType, ctx, {
|
|
3292
|
-
...params,
|
|
3293
|
-
path: [
|
|
3294
|
-
...params.path,
|
|
3295
|
-
"patternProperties",
|
|
3296
|
-
"*"
|
|
3297
|
-
]
|
|
3298
|
-
});
|
|
3299
|
-
json.patternProperties = {};
|
|
3300
|
-
for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
|
|
3301
|
-
} else {
|
|
3302
|
-
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$2(def.keyType, ctx, {
|
|
3303
|
-
...params,
|
|
3304
|
-
path: [...params.path, "propertyNames"]
|
|
3305
|
-
});
|
|
3306
|
-
json.additionalProperties = process$2(def.valueType, ctx, {
|
|
3307
|
-
...params,
|
|
3308
|
-
path: [...params.path, "additionalProperties"]
|
|
3309
|
-
});
|
|
3310
|
-
}
|
|
3311
|
-
const keyValues = keyType._zod.values;
|
|
3312
|
-
if (keyValues) {
|
|
3313
|
-
const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
|
|
3314
|
-
if (validKeyValues.length > 0) json.required = validKeyValues;
|
|
3315
|
-
}
|
|
3316
|
-
};
|
|
3317
3174
|
var nullableProcessor = (schema, ctx, json, params) => {
|
|
3318
3175
|
const def = schema._zod.def;
|
|
3319
3176
|
const inner = process$2(def.innerType, ctx, params);
|
|
@@ -3965,14 +3822,6 @@ function strictObject(shape, params) {
|
|
|
3965
3822
|
...normalizeParams(params)
|
|
3966
3823
|
});
|
|
3967
3824
|
}
|
|
3968
|
-
function looseObject(shape, params) {
|
|
3969
|
-
return new ZodObject({
|
|
3970
|
-
type: "object",
|
|
3971
|
-
shape,
|
|
3972
|
-
catchall: unknown(),
|
|
3973
|
-
...normalizeParams(params)
|
|
3974
|
-
});
|
|
3975
|
-
}
|
|
3976
3825
|
var ZodUnion = /*@__PURE__*/ $constructor("ZodUnion", (inst, def) => {
|
|
3977
3826
|
$ZodUnion.init(inst, def);
|
|
3978
3827
|
ZodType.init(inst, def);
|
|
@@ -4010,27 +3859,6 @@ function intersection(left, right) {
|
|
|
4010
3859
|
right
|
|
4011
3860
|
});
|
|
4012
3861
|
}
|
|
4013
|
-
var ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
|
|
4014
|
-
$ZodRecord.init(inst, def);
|
|
4015
|
-
ZodType.init(inst, def);
|
|
4016
|
-
inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
|
|
4017
|
-
inst.keyType = def.keyType;
|
|
4018
|
-
inst.valueType = def.valueType;
|
|
4019
|
-
});
|
|
4020
|
-
function record(keyType, valueType, params) {
|
|
4021
|
-
if (!valueType || !valueType._zod) return new ZodRecord({
|
|
4022
|
-
type: "record",
|
|
4023
|
-
keyType: string(),
|
|
4024
|
-
valueType: keyType,
|
|
4025
|
-
...normalizeParams(valueType)
|
|
4026
|
-
});
|
|
4027
|
-
return new ZodRecord({
|
|
4028
|
-
type: "record",
|
|
4029
|
-
keyType,
|
|
4030
|
-
valueType,
|
|
4031
|
-
...normalizeParams(params)
|
|
4032
|
-
});
|
|
4033
|
-
}
|
|
4034
3862
|
var ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => {
|
|
4035
3863
|
$ZodEnum.init(inst, def);
|
|
4036
3864
|
ZodType.init(inst, def);
|
|
@@ -4252,13 +4080,13 @@ function superRefine(fn, params) {
|
|
|
4252
4080
|
}
|
|
4253
4081
|
//#endregion
|
|
4254
4082
|
//#region packages/cli/src/catalog.ts
|
|
4255
|
-
var VERSION = "0.11.
|
|
4083
|
+
var VERSION = "0.11.2";
|
|
4256
4084
|
var SKILLS = [
|
|
4257
4085
|
"ast-grep",
|
|
4258
4086
|
"babysit-ci",
|
|
4259
|
-
"caveman",
|
|
4260
4087
|
"code-review",
|
|
4261
4088
|
"compress",
|
|
4089
|
+
"context7-cli",
|
|
4262
4090
|
"debugging",
|
|
4263
4091
|
"handoff",
|
|
4264
4092
|
"lsp",
|
|
@@ -4740,36 +4568,112 @@ var GENERATED_RUNTIMES = [
|
|
|
4740
4568
|
"git-bash-resolver.js",
|
|
4741
4569
|
"LICENSE-LSP-MIT.txt",
|
|
4742
4570
|
"lsp.js",
|
|
4743
|
-
"mcp-stdio-core.js",
|
|
4744
4571
|
"rules.js"
|
|
4745
4572
|
];
|
|
4746
|
-
var WINDOWS_SHELL_POLICY = "On native Windows,
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
return {
|
|
4750
|
-
...platform === "win32" ? { git_bash: {
|
|
4751
|
-
command: "node",
|
|
4752
|
-
args: ["runtime/git-bash.js", "mcp"],
|
|
4753
|
-
cwd: ".",
|
|
4754
|
-
enabled_tools: ["run"]
|
|
4755
|
-
} } : {},
|
|
4756
|
-
lsp: {
|
|
4757
|
-
command: "node",
|
|
4758
|
-
args: ["runtime/lsp.js", "mcp"],
|
|
4759
|
-
cwd: "."
|
|
4760
|
-
},
|
|
4761
|
-
context7: {
|
|
4762
|
-
command: "bunx",
|
|
4763
|
-
args: ["@upstash/context7-mcp"]
|
|
4764
|
-
}
|
|
4765
|
-
};
|
|
4766
|
-
}
|
|
4573
|
+
var WINDOWS_SHELL_POLICY = "On native Windows, run every shell command through the bundled Git Bash launcher, including Git, package, build, test, script and POSIX commands. Never execute task commands through PowerShell or cmd. If Git Bash cannot be resolved, stop and report the blocker. On non-Windows, use the native shell normally.";
|
|
4574
|
+
var LITE_WRITING_POLICY = "Communicate grammatically and concisely. Omit filler, hedging, repetition, decoration, self-reference, style announcements and tool narration. Preserve exact technical terms, APIs, commands, paths, errors and commit keywords. Use fuller grammar for safety, ambiguity, clarification and ordered instructions. Apply this policy only to agent communication, never to literal authored or transformed content, UI or accessibility labels, help text, errors, logs, tests, fixtures, documentation, comments, commit or PR text, authored prompts, translations, quotations, generated content, public APIs, or existing repository and product voice.";
|
|
4575
|
+
var CONTEXT7_POLICY = "Within assigned scope, use the Context7 CLI skill first for current library, framework, SDK and API documentation. Use live web search for releases, dates, broader research, missing Context7 coverage and corroboration. Context7 does not authorize scope expansion.";
|
|
4767
4576
|
/** Returns packaged runtime files required on a platform. */
|
|
4768
4577
|
function requiredPackageRuntimes(platform) {
|
|
4769
4578
|
return platform === "win32" ? GENERATED_RUNTIMES : GENERATED_RUNTIMES.filter((file) => file !== "git-bash.js");
|
|
4770
4579
|
}
|
|
4771
4580
|
//#endregion
|
|
4772
|
-
//#region packages/
|
|
4581
|
+
//#region packages/cli/src/arguments.ts
|
|
4582
|
+
var INSTALL_FLAGS = /* @__PURE__ */ new Set([
|
|
4583
|
+
"--plan",
|
|
4584
|
+
"--max-subagents",
|
|
4585
|
+
"--codex-autonomous",
|
|
4586
|
+
"--no-codex-autonomous",
|
|
4587
|
+
"--dangerous-codex-autonomous",
|
|
4588
|
+
"--fast",
|
|
4589
|
+
"--fast-all",
|
|
4590
|
+
"--no-fast",
|
|
4591
|
+
"--json"
|
|
4592
|
+
]);
|
|
4593
|
+
var SHARED_FLAGS = /* @__PURE__ */ new Set(["--json"]);
|
|
4594
|
+
/** Strictly parses command-specific HolyCodex CLI arguments. */
|
|
4595
|
+
function parseCliArguments(args) {
|
|
4596
|
+
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") return base("help");
|
|
4597
|
+
if (args[0] === "--version" || args[0] === "-v") {
|
|
4598
|
+
if (args.length !== 1) throw new Error("--version does not accept other arguments.");
|
|
4599
|
+
return base("version");
|
|
4600
|
+
}
|
|
4601
|
+
const command = args[0];
|
|
4602
|
+
if (command !== "install" && command !== "doctor" && command !== "cleanup") throw new Error(`Unknown command: ${command ?? ""}`);
|
|
4603
|
+
if (args[1] === "--help" || args[1] === "-h") {
|
|
4604
|
+
if (args.length !== 2) throw new Error("--help does not accept other arguments.");
|
|
4605
|
+
return {
|
|
4606
|
+
...base("help"),
|
|
4607
|
+
command
|
|
4608
|
+
};
|
|
4609
|
+
}
|
|
4610
|
+
const allowed = command === "install" ? INSTALL_FLAGS : SHARED_FLAGS;
|
|
4611
|
+
const values = /* @__PURE__ */ new Map();
|
|
4612
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
4613
|
+
const token = args[index];
|
|
4614
|
+
if (token === void 0 || !token.startsWith("--")) throw new Error(`Unexpected positional argument: ${token ?? ""}`);
|
|
4615
|
+
const separator = token.indexOf("=");
|
|
4616
|
+
const name = separator < 0 ? token : token.slice(0, separator);
|
|
4617
|
+
if (!allowed.has(name)) throw new Error(`Option ${name} is not valid for ${command}.`);
|
|
4618
|
+
if (values.has(name)) throw new Error(`Repeated option: ${name}`);
|
|
4619
|
+
if (name !== "--plan" && name !== "--max-subagents") {
|
|
4620
|
+
if (separator >= 0) throw new Error(`${name} does not accept a value.`);
|
|
4621
|
+
values.set(name, true);
|
|
4622
|
+
continue;
|
|
4623
|
+
}
|
|
4624
|
+
const value = separator < 0 ? args[++index] : token.slice(separator + 1);
|
|
4625
|
+
if (value === void 0 || value === "" || separator < 0 && value.startsWith("--")) throw new Error(`Missing value for ${name}.`);
|
|
4626
|
+
values.set(name, value);
|
|
4627
|
+
}
|
|
4628
|
+
const autonomyFlags = [
|
|
4629
|
+
"--codex-autonomous",
|
|
4630
|
+
"--no-codex-autonomous",
|
|
4631
|
+
"--dangerous-codex-autonomous"
|
|
4632
|
+
].filter((flag) => values.has(flag));
|
|
4633
|
+
if (autonomyFlags.length > 1) throw new Error(`Conflicting autonomy flags: ${autonomyFlags.join(", ")}`);
|
|
4634
|
+
const fastFlags = [
|
|
4635
|
+
"--fast",
|
|
4636
|
+
"--fast-all",
|
|
4637
|
+
"--no-fast"
|
|
4638
|
+
].filter((flag) => values.has(flag));
|
|
4639
|
+
if (fastFlags.length > 1) throw new Error(`Conflicting Fast flags: ${fastFlags.join(", ")}`);
|
|
4640
|
+
const planValue = values.get("--plan") ?? "plus";
|
|
4641
|
+
const plan = PlanNameSchema.safeParse(planValue);
|
|
4642
|
+
if (!plan.success) throw new Error(`Unknown plan: ${String(planValue)}. Valid plans: ${PLAN_NAMES.join(", ")}.`);
|
|
4643
|
+
const maxValue = values.get("--max-subagents");
|
|
4644
|
+
if (maxValue !== void 0 && (typeof maxValue !== "string" || !/^\d+$/.test(maxValue) || Number(maxValue) > 3)) throw new Error(`Invalid --max-subagents value: ${String(maxValue)}. Expected an integer from 0 through 3.`);
|
|
4645
|
+
const autonomy = values.has("--dangerous-codex-autonomous") ? {
|
|
4646
|
+
requested: true,
|
|
4647
|
+
mode: "dangerous"
|
|
4648
|
+
} : values.has("--codex-autonomous") ? {
|
|
4649
|
+
requested: true,
|
|
4650
|
+
mode: "autonomous"
|
|
4651
|
+
} : values.has("--no-codex-autonomous") ? {
|
|
4652
|
+
requested: true,
|
|
4653
|
+
mode: "default"
|
|
4654
|
+
} : { requested: false };
|
|
4655
|
+
const fast = FastModeSchema.parse(values.has("--fast-all") ? "fast-all" : values.has("--fast") ? "fast" : "standard");
|
|
4656
|
+
return {
|
|
4657
|
+
action: "run",
|
|
4658
|
+
command,
|
|
4659
|
+
json: values.has("--json"),
|
|
4660
|
+
plan: plan.data,
|
|
4661
|
+
...maxValue === void 0 ? {} : { maxSubagents: Number(maxValue) },
|
|
4662
|
+
autonomy,
|
|
4663
|
+
fast
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4666
|
+
function base(action) {
|
|
4667
|
+
return {
|
|
4668
|
+
action,
|
|
4669
|
+
json: false,
|
|
4670
|
+
plan: DEFAULT_PLAN,
|
|
4671
|
+
autonomy: { requested: false },
|
|
4672
|
+
fast: "standard"
|
|
4673
|
+
};
|
|
4674
|
+
}
|
|
4675
|
+
//#endregion
|
|
4676
|
+
//#region packages/git-bash/src/git-bash-resolver.ts
|
|
4773
4677
|
var GIT_BASH_ENV_KEY = "HOLYCODEX_GIT_BASH_PATH";
|
|
4774
4678
|
var PROGRAM_FILES = "C:\\Program Files\\Git\\bin\\bash.exe";
|
|
4775
4679
|
var PROGRAM_FILES_X86 = "C:\\Program Files (x86)\\Git\\bin\\bash.exe";
|
|
@@ -4850,7 +4754,7 @@ function missing(checkedPaths) {
|
|
|
4850
4754
|
};
|
|
4851
4755
|
}
|
|
4852
4756
|
//#endregion
|
|
4853
|
-
//#region packages/
|
|
4757
|
+
//#region packages/runtime-core/src/process.ts
|
|
4854
4758
|
var TRUNCATED_MARKER = "\n... diagnostic output truncated ...\n";
|
|
4855
4759
|
var defaultManagedProcessRuntime = {
|
|
4856
4760
|
terminationGraceMs: 2e3,
|
|
@@ -4915,11 +4819,13 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4915
4819
|
let matched = false;
|
|
4916
4820
|
let settled = false;
|
|
4917
4821
|
let forceKillTimeout;
|
|
4822
|
+
let finalResolutionTimeout;
|
|
4918
4823
|
const finish = (exitCode, error, errorCode) => {
|
|
4919
4824
|
if (settled) return;
|
|
4920
4825
|
settled = true;
|
|
4921
4826
|
clearTimeout(timeout);
|
|
4922
4827
|
if (forceKillTimeout !== void 0) clearTimeout(forceKillTimeout);
|
|
4828
|
+
if (finalResolutionTimeout !== void 0) clearTimeout(finalResolutionTimeout);
|
|
4923
4829
|
resolve({
|
|
4924
4830
|
exitCode,
|
|
4925
4831
|
stdout: outputText(stdout),
|
|
@@ -4938,6 +4844,8 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4938
4844
|
runtime.kill(child, input.platform, "SIGKILL");
|
|
4939
4845
|
}, runtime.terminationGraceMs);
|
|
4940
4846
|
forceKillTimeout.unref();
|
|
4847
|
+
finalResolutionTimeout = setTimeout(() => finish(child.exitCode, "Managed process did not emit close after termination."), input.finalResolutionMs ?? runtime.terminationGraceMs * 2);
|
|
4848
|
+
finalResolutionTimeout.unref();
|
|
4941
4849
|
};
|
|
4942
4850
|
const inspectMatch = () => {
|
|
4943
4851
|
if (matched || input.matchOutput === void 0) return;
|
|
@@ -4968,7 +4876,9 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4968
4876
|
/** Terminates process tree. */
|
|
4969
4877
|
function killProcessTree(child, platform, signal = "SIGTERM", runTaskkill = (command, args) => spawnSync(command, [...args], {
|
|
4970
4878
|
stdio: "ignore",
|
|
4971
|
-
windowsHide: true
|
|
4879
|
+
windowsHide: true,
|
|
4880
|
+
timeout: 2e3,
|
|
4881
|
+
killSignal: "SIGKILL"
|
|
4972
4882
|
})) {
|
|
4973
4883
|
if (platform === "win32" && child.pid !== void 0) {
|
|
4974
4884
|
const result = runTaskkill("taskkill", [
|
|
@@ -5311,6 +5221,13 @@ function nextTableBoundary(input) {
|
|
|
5311
5221
|
if (managedHeader < 0) return header;
|
|
5312
5222
|
return Math.min(header, managedHeader);
|
|
5313
5223
|
}
|
|
5224
|
+
function tableSource(input, table) {
|
|
5225
|
+
const match = new RegExp(`^\\s*\\[${table.replaceAll(".", "\\.")}]\\s*(?:#.*)?$`, "m").exec(input);
|
|
5226
|
+
if (match === null) return void 0;
|
|
5227
|
+
const tail = input.slice(match.index + match[0].length);
|
|
5228
|
+
const end = nextTableBoundary(tail);
|
|
5229
|
+
return end < 0 ? tail : tail.slice(0, end);
|
|
5230
|
+
}
|
|
5314
5231
|
function rootValue(input, key) {
|
|
5315
5232
|
if (key === "status_line") return rootTomlStringArraySource(input, key);
|
|
5316
5233
|
return new RegExp(`^\\s*${key}\\s*=.*$`, "m").exec(input)?.[0];
|
|
@@ -5351,23 +5268,27 @@ function readPreservedRootOverrides(input) {
|
|
|
5351
5268
|
const managedRoot = new RegExp(`^${START}\\r?\\n([\\s\\S]*?)^${END}\\r?$`, "m").exec(input)?.[1];
|
|
5352
5269
|
if (managedRoot === void 0) return {
|
|
5353
5270
|
model: false,
|
|
5354
|
-
reasoningEffort: false
|
|
5271
|
+
reasoningEffort: false,
|
|
5272
|
+
webSearch: false
|
|
5355
5273
|
};
|
|
5356
5274
|
const plan = readManagedPlan(managedRoot);
|
|
5357
5275
|
const model = rootTomlString(input, "model");
|
|
5358
5276
|
const reasoningEffort = rootTomlString(input, "model_reasoning_effort");
|
|
5359
5277
|
if (plan === void 0 || model === void 0 || reasoningEffort === void 0) return {
|
|
5360
5278
|
model: false,
|
|
5361
|
-
reasoningEffort: false
|
|
5279
|
+
reasoningEffort: false,
|
|
5280
|
+
webSearch: false
|
|
5362
5281
|
};
|
|
5363
5282
|
if (MANAGED_ROOT_MODEL_HISTORY_BY_PLAN[plan].some((route) => route.model === model && route.reasoningEffort === reasoningEffort)) return {
|
|
5364
5283
|
model: false,
|
|
5365
|
-
reasoningEffort: false
|
|
5284
|
+
reasoningEffort: false,
|
|
5285
|
+
webSearch: rootTomlString(managedRoot, "web_search") !== "live"
|
|
5366
5286
|
};
|
|
5367
5287
|
const preset = MODEL_ROUTING_PLANS[plan].root;
|
|
5368
5288
|
return {
|
|
5369
5289
|
model: model !== preset.model,
|
|
5370
|
-
reasoningEffort: reasoningEffort !== preset.reasoningEffort
|
|
5290
|
+
reasoningEffort: reasoningEffort !== preset.reasoningEffort,
|
|
5291
|
+
webSearch: rootTomlString(managedRoot, "web_search") !== "live"
|
|
5371
5292
|
};
|
|
5372
5293
|
}
|
|
5373
5294
|
function preserveManagedRootPreferences(input, base) {
|
|
@@ -5378,7 +5299,11 @@ function preserveManagedRootPreferences(input, base) {
|
|
|
5378
5299
|
const tables = firstTable < 0 ? "" : base.slice(firstTable);
|
|
5379
5300
|
let updatedRoot = root.trim();
|
|
5380
5301
|
const overrides = readPreservedRootOverrides(input);
|
|
5381
|
-
for (const [key, preserve] of [
|
|
5302
|
+
for (const [key, preserve] of [
|
|
5303
|
+
["model", overrides.model],
|
|
5304
|
+
["model_reasoning_effort", overrides.reasoningEffort],
|
|
5305
|
+
["web_search", overrides.webSearch]
|
|
5306
|
+
]) {
|
|
5382
5307
|
const live = rootValue(managedRoot, key)?.trim();
|
|
5383
5308
|
if (!preserve || live === void 0) continue;
|
|
5384
5309
|
if (rootValue(root, key)?.trim() === live) continue;
|
|
@@ -5416,6 +5341,7 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
|
|
|
5416
5341
|
const hadOriginalRoot = /^# holycodex original root:/m.test(input);
|
|
5417
5342
|
const permissionLines = originalPermissionLines ?? (legacyGeneratedRoot !== void 0 && previousOriginalRoot === void 0 ? [] : previousOriginalRoot === void 0 ? hadManagedAutonomy && !hadOriginalRoot ? [] : readPermissionLines(root) : readPermissionLines(previousOriginalRoot));
|
|
5418
5343
|
const controlled = [
|
|
5344
|
+
"web_search",
|
|
5419
5345
|
"approval_policy",
|
|
5420
5346
|
"approvals_reviewer",
|
|
5421
5347
|
"sandbox_mode",
|
|
@@ -5426,6 +5352,7 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
|
|
|
5426
5352
|
...request.requested ? ["default_permissions"] : []
|
|
5427
5353
|
].map((key) => rootValue(root, key));
|
|
5428
5354
|
const preservedRoot = [
|
|
5355
|
+
"web_search",
|
|
5429
5356
|
"approval_policy",
|
|
5430
5357
|
"approvals_reviewer",
|
|
5431
5358
|
"sandbox_mode",
|
|
@@ -5446,72 +5373,131 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
|
|
|
5446
5373
|
const original = originalSource ? `${ORIGINAL_ROOT}${Buffer.from(originalSource).toString("base64")}\n` : "";
|
|
5447
5374
|
const maxSubagentsMetadata = maxSubagents === void 0 ? "" : `${MAX_SUBAGENTS_PREFIX}${maxSubagents}\n`;
|
|
5448
5375
|
const rootServiceTier = fastMode === "fast-all" ? "fast" : "default";
|
|
5449
|
-
const
|
|
5376
|
+
const priorManagedRoot = new RegExp(`^${START}\\r?\\n([\\s\\S]*?)^${END}\\r?$`, "m").exec(input)?.[1];
|
|
5377
|
+
const webSearch = readPreservedRootOverrides(input).webSearch ? rootTomlString(priorManagedRoot ?? "", "web_search") ?? "live" : "live";
|
|
5378
|
+
const statusLine = mergedStatusLine(rootValue(root, "status_line") ?? rootTomlStringArraySource(tableSource(base, "tui") ?? "", "status_line"));
|
|
5379
|
+
const rootBlock = `${START}\n${PLAN_PREFIX}${plan}\n${FAST_MODE_PREFIX}${fastMode}\n${AUTONOMY_METADATA_PREFIX}${effectiveAutonomy}\n${maxSubagentsMetadata}${original}${originalPermissionMetadata(permissionLines)}${model}${effort}web_search = ${JSON.stringify(webSearch)}\nmodel_verbosity = "low"\nservice_tier = "${rootServiceTier}"\n${rootPermissionLines.join("\n")}\n${END}`;
|
|
5450
5380
|
let configured = `${preservedRoot ? `${preservedRoot}\n` : ""}${rootBlock}${tables ? `\n\n${tables}` : ""}`;
|
|
5381
|
+
const legacyMultiAgentV2 = /\bmulti_agent_v2\s*=\s*(true|false)/.exec(configured)?.[1];
|
|
5451
5382
|
configured = injectTableKeys(configured, "features", [
|
|
5452
5383
|
["default_mode_request_user_input", "true"],
|
|
5453
5384
|
["multi_agent", "true"],
|
|
5454
|
-
["multi_agent_v2",
|
|
5385
|
+
...legacyMultiAgentV2 === void 0 ? [] : [["multi_agent_v2", legacyMultiAgentV2]]
|
|
5455
5386
|
]);
|
|
5456
5387
|
const usage = MODEL_ROUTING_PLANS[plan].usage;
|
|
5457
|
-
configured = injectTableKeys(configured, "agents", [["
|
|
5388
|
+
configured = injectTableKeys(configured, "agents", [["max_concurrent_threads_per_session", String(effectiveMaxSubagents + 1)], ["max_depth", String(usage.maxDepth)]]);
|
|
5389
|
+
configured = injectTableKeys(configured, "tui", [["status_line", statusLine]]);
|
|
5458
5390
|
if (effectiveAutonomy !== "dangerous") configured = injectTableKeys(configured, "sandbox_workspace_write", [["network_access", "true"]]);
|
|
5459
|
-
configured = injectTableKeys(configured, "desktop", [["
|
|
5391
|
+
configured = injectTableKeys(configured, "desktop", [["show-context-window-usage", "true"]]);
|
|
5460
5392
|
if (_platform === "win32") configured = injectTableKeys(configured, "windows", [["sandbox", "\"unelevated\""]]);
|
|
5461
5393
|
for (const agent of AGENTS) configured = injectTableKeys(configured, `agents.${agent}`, [["config_file", `"holycodex/agents/${agent}.toml"`]]);
|
|
5462
5394
|
const plugin = `${START}\n[plugins."holycodex@holycodex"]\nenabled = true\n${END}`;
|
|
5463
5395
|
return `${configured.trim()}\n\n${plugin}\n`;
|
|
5464
5396
|
}
|
|
5465
5397
|
//#endregion
|
|
5398
|
+
//#region packages/cli/src/context7.ts
|
|
5399
|
+
var RUNNERS = [
|
|
5400
|
+
{
|
|
5401
|
+
executable: "nubx",
|
|
5402
|
+
command: "nubx",
|
|
5403
|
+
prefix: ["-y"]
|
|
5404
|
+
},
|
|
5405
|
+
{
|
|
5406
|
+
executable: "nub",
|
|
5407
|
+
command: "nub",
|
|
5408
|
+
prefix: ["dlx"]
|
|
5409
|
+
},
|
|
5410
|
+
{
|
|
5411
|
+
executable: "bunx",
|
|
5412
|
+
command: "bunx",
|
|
5413
|
+
prefix: []
|
|
5414
|
+
},
|
|
5415
|
+
{
|
|
5416
|
+
executable: "bun",
|
|
5417
|
+
command: "bun",
|
|
5418
|
+
prefix: ["x"]
|
|
5419
|
+
},
|
|
5420
|
+
{
|
|
5421
|
+
executable: "pnpmx",
|
|
5422
|
+
command: "pnpmx",
|
|
5423
|
+
prefix: []
|
|
5424
|
+
},
|
|
5425
|
+
{
|
|
5426
|
+
executable: "pnpm",
|
|
5427
|
+
command: "pnpm",
|
|
5428
|
+
prefix: ["dlx"]
|
|
5429
|
+
},
|
|
5430
|
+
{
|
|
5431
|
+
executable: "npmx",
|
|
5432
|
+
command: "npmx",
|
|
5433
|
+
prefix: ["--yes"]
|
|
5434
|
+
},
|
|
5435
|
+
{
|
|
5436
|
+
executable: "npm",
|
|
5437
|
+
command: "npx",
|
|
5438
|
+
prefix: ["--yes"]
|
|
5439
|
+
},
|
|
5440
|
+
{
|
|
5441
|
+
executable: "yarn",
|
|
5442
|
+
command: "yarn",
|
|
5443
|
+
prefix: ["dlx"]
|
|
5444
|
+
}
|
|
5445
|
+
];
|
|
5446
|
+
/** Constructs the supported direct Context7 invocation for the first available runner. */
|
|
5447
|
+
function context7Command(args, executableExists = executableOnPath, env = process.env) {
|
|
5448
|
+
const runner = RUNNERS.find((candidate) => executableExists(candidate.executable));
|
|
5449
|
+
if (runner === void 0) return void 0;
|
|
5450
|
+
return {
|
|
5451
|
+
command: runner.command,
|
|
5452
|
+
args: [
|
|
5453
|
+
...runner.prefix,
|
|
5454
|
+
"ctx7@latest",
|
|
5455
|
+
...args
|
|
5456
|
+
],
|
|
5457
|
+
env: {
|
|
5458
|
+
...env,
|
|
5459
|
+
CI: env.CI ?? "1"
|
|
5460
|
+
}
|
|
5461
|
+
};
|
|
5462
|
+
}
|
|
5463
|
+
/** Reports whether an executable can be resolved from PATH. */
|
|
5464
|
+
function executableOnPath(name) {
|
|
5465
|
+
const path = process.env.PATH;
|
|
5466
|
+
if (path === void 0) return false;
|
|
5467
|
+
const extensions = process.platform === "win32" ? [
|
|
5468
|
+
".exe",
|
|
5469
|
+
".cmd",
|
|
5470
|
+
".bat",
|
|
5471
|
+
""
|
|
5472
|
+
] : [""];
|
|
5473
|
+
for (const directory of path.split(delimiter)) for (const extension of extensions) try {
|
|
5474
|
+
if (process.getBuiltinModule("node:fs").existsSync(`${directory}/${name}${extension}`)) return true;
|
|
5475
|
+
} catch {
|
|
5476
|
+
continue;
|
|
5477
|
+
}
|
|
5478
|
+
return false;
|
|
5479
|
+
}
|
|
5480
|
+
//#endregion
|
|
5466
5481
|
//#region packages/cli/src/doctor.ts
|
|
5467
|
-
var
|
|
5468
|
-
async function runCommand(name, args,
|
|
5482
|
+
var COMPATIBILITY_KEYS = ["desktop.show-context-window-usage"];
|
|
5483
|
+
async function runCommand(name, args, env) {
|
|
5469
5484
|
const result = await runManagedProcess({
|
|
5470
5485
|
command: name,
|
|
5471
5486
|
args,
|
|
5472
|
-
platform,
|
|
5473
|
-
timeoutMs:
|
|
5474
|
-
maxOutputChars: 64 * 1024
|
|
5487
|
+
platform: process.platform,
|
|
5488
|
+
timeoutMs: 15e3,
|
|
5489
|
+
maxOutputChars: 64 * 1024,
|
|
5490
|
+
...env === void 0 ? {} : { env }
|
|
5475
5491
|
});
|
|
5476
5492
|
return {
|
|
5477
5493
|
ok: result.exitCode === 0 && !result.timedOut && result.error === void 0,
|
|
5478
5494
|
output: `${result.stdout}\n${result.stderr}`.trim() || result.error || ""
|
|
5479
5495
|
};
|
|
5480
5496
|
}
|
|
5481
|
-
async function startContext7(platform) {
|
|
5482
|
-
const result = await runManagedProcess({
|
|
5483
|
-
command: "bunx",
|
|
5484
|
-
args: ["@upstash/context7-mcp"],
|
|
5485
|
-
platform,
|
|
5486
|
-
timeoutMs: 15e3,
|
|
5487
|
-
maxOutputChars: 128 * 1024,
|
|
5488
|
-
stdin: `${JSON.stringify({
|
|
5489
|
-
jsonrpc: "2.0",
|
|
5490
|
-
id: 1,
|
|
5491
|
-
method: "initialize",
|
|
5492
|
-
params: {
|
|
5493
|
-
protocolVersion: "2025-03-26",
|
|
5494
|
-
capabilities: {},
|
|
5495
|
-
clientInfo: {
|
|
5496
|
-
name: "holycodex-doctor",
|
|
5497
|
-
version: VERSION
|
|
5498
|
-
}
|
|
5499
|
-
}
|
|
5500
|
-
})}\n`,
|
|
5501
|
-
matchOutput: (output) => output.includes("\"serverInfo\"") || output.includes("\"capabilities\"")
|
|
5502
|
-
});
|
|
5503
|
-
const diagnostic = `${result.stdout}\n${result.stderr}`.trim() || result.error || "";
|
|
5504
|
-
return {
|
|
5505
|
-
ok: result.matched && !result.timedOut,
|
|
5506
|
-
timedOut: result.timedOut,
|
|
5507
|
-
packageFailure: /(?:404|failed to resolve|package.*not found|error: GET)/i.test(diagnostic),
|
|
5508
|
-
detail: diagnostic
|
|
5509
|
-
};
|
|
5510
|
-
}
|
|
5511
5497
|
var defaultRuntime$1 = {
|
|
5512
5498
|
platform: process.platform,
|
|
5513
|
-
command:
|
|
5514
|
-
|
|
5499
|
+
command: runCommand,
|
|
5500
|
+
executable: executableOnPath,
|
|
5515
5501
|
gitBash: resolveGitBashForCurrentProcess
|
|
5516
5502
|
};
|
|
5517
5503
|
function check(id, status, code, detail, fix) {
|
|
@@ -5523,14 +5509,6 @@ function check(id, status, code, detail, fix) {
|
|
|
5523
5509
|
...fix === void 0 ? {} : { fix }
|
|
5524
5510
|
};
|
|
5525
5511
|
}
|
|
5526
|
-
function mcpConfigMatches(actual, expected) {
|
|
5527
|
-
const expectedEntries = Object.entries(expected);
|
|
5528
|
-
if (Object.keys(actual).length !== expectedEntries.length) return false;
|
|
5529
|
-
return expectedEntries.every(([key, expectedValue]) => {
|
|
5530
|
-
const actualValue = actual[key];
|
|
5531
|
-
return Array.isArray(expectedValue) ? Array.isArray(actualValue) && actualValue.length === expectedValue.length && actualValue.every((value, index) => value === expectedValue[index]) : actualValue === expectedValue;
|
|
5532
|
-
});
|
|
5533
|
-
}
|
|
5534
5512
|
async function missingFiles(root, paths) {
|
|
5535
5513
|
const missing = [];
|
|
5536
5514
|
for (const path of paths) try {
|
|
@@ -5540,138 +5518,82 @@ async function missingFiles(root, paths) {
|
|
|
5540
5518
|
}
|
|
5541
5519
|
return missing;
|
|
5542
5520
|
}
|
|
5543
|
-
function
|
|
5544
|
-
|
|
5545
|
-
const value = body === void 0 ? void 0 : new RegExp(`^\\s*${key}\\s*=\\s*(true|false)`, "m").exec(body)?.[1];
|
|
5546
|
-
return value === void 0 ? void 0 : value === "true";
|
|
5547
|
-
}
|
|
5548
|
-
function tableString(config, table, key) {
|
|
5549
|
-
const body = new RegExp(`^\\s*\\[${table.replaceAll(".", "\\.")}]\\s*$([\\s\\S]*?)(?=^\\s*\\[|(?![\\s\\S]))`, "m").exec(config)?.[1];
|
|
5550
|
-
return body === void 0 ? void 0 : rootTomlString(body, key);
|
|
5521
|
+
function tableBody(config, table) {
|
|
5522
|
+
return new RegExp(`^\\s*\\[${table.replaceAll(".", "\\.")}]\\s*$([\\s\\S]*?)(?=^\\s*\\[|(?![\\s\\S]))`, "m").exec(config)?.[1];
|
|
5551
5523
|
}
|
|
5552
|
-
function
|
|
5553
|
-
const body =
|
|
5554
|
-
return body === void 0 ? void 0 :
|
|
5555
|
-
}
|
|
5556
|
-
function tableInteger(config, table, key) {
|
|
5557
|
-
const body = new RegExp(`^\\s*\\[${table.replaceAll(".", "\\.")}]\\s*$([\\s\\S]*?)(?=^\\s*\\[|(?![\\s\\S]))`, "m").exec(config)?.[1];
|
|
5558
|
-
const value = body === void 0 ? void 0 : new RegExp(`^\\s*${key}\\s*=\\s*(\\d+)`, "m").exec(body)?.[1];
|
|
5559
|
-
return value === void 0 ? void 0 : Number(value);
|
|
5524
|
+
function tableValue(config, table, key) {
|
|
5525
|
+
const body = tableBody(config, table);
|
|
5526
|
+
return body === void 0 ? void 0 : new RegExp(`^\\s*${key.replaceAll("-", "\\-")}\\s*=\\s*(.+?)\\s*$`, "m").exec(body)?.[1];
|
|
5560
5527
|
}
|
|
5561
5528
|
function autonomy(config) {
|
|
5562
5529
|
const approval = rootTomlString(config, "approval_policy");
|
|
5563
|
-
const
|
|
5530
|
+
const reviewer = rootTomlString(config, "approvals_reviewer");
|
|
5564
5531
|
const sandbox = rootTomlString(config, "sandbox_mode");
|
|
5565
|
-
const network =
|
|
5566
|
-
if (approval === "on-request" &&
|
|
5567
|
-
if (approval === "never" &&
|
|
5568
|
-
if (approval === "never" &&
|
|
5532
|
+
const network = tableValue(config, "sandbox_workspace_write", "network_access");
|
|
5533
|
+
if (approval === "on-request" && reviewer === "auto_review" && sandbox === "workspace-write" && network === "true") return "safe-workspace";
|
|
5534
|
+
if (approval === "never" && reviewer === void 0 && sandbox === "workspace-write" && network === "true") return "autonomous-workspace";
|
|
5535
|
+
if (approval === "never" && reviewer === void 0 && sandbox === "danger-full-access") return "dangerous";
|
|
5569
5536
|
return "unknown";
|
|
5570
5537
|
}
|
|
5571
|
-
/** Runs
|
|
5538
|
+
/** Runs installation, configuration, runtime, and override health checks. */
|
|
5572
5539
|
async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex"), runtime = defaultRuntime$1) {
|
|
5573
5540
|
const checks = [];
|
|
5574
5541
|
const pluginRoot = join(home, "plugins", "cache", "holycodex", "holycodex", VERSION);
|
|
5575
5542
|
const agentRoot = join(home, "holycodex", "agents");
|
|
5576
5543
|
const configPath = join(home, "config.toml");
|
|
5577
5544
|
let config = "";
|
|
5578
|
-
let configAvailable = true;
|
|
5579
5545
|
try {
|
|
5580
5546
|
config = await readFile(configPath, "utf8");
|
|
5581
5547
|
} catch {
|
|
5582
|
-
|
|
5548
|
+
checks.push(check("config", "error", "config-missing", `Missing ${configPath}.`, "Run holycodex install."));
|
|
5583
5549
|
}
|
|
5584
5550
|
const missing = await missingFiles(pluginRoot, [
|
|
5585
5551
|
".codex-plugin/plugin.json",
|
|
5586
|
-
".mcp.json",
|
|
5587
|
-
"LICENSE-OH-MY-OPENCODE-SLIM-MIT.txt",
|
|
5588
5552
|
"hooks/hooks.json",
|
|
5589
5553
|
...requiredPackageRuntimes(runtime.platform).map((file) => `runtime/${file}`),
|
|
5590
5554
|
...AGENTS.map((name) => `agents/${name}.toml`),
|
|
5591
5555
|
...SKILLS.map((name) => `skills/${name}/SKILL.md`)
|
|
5592
5556
|
]);
|
|
5593
|
-
checks.push(missing.length === 0 ? check("package", "ok", "package-ready", `Plugin ${VERSION},
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
const
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
} else if (runtime.platform !== "win32" && gitBashConfig !== void 0) checks.push(check("mcp-git_bash-config", "error", "unexpected-git-bash-mcp", "Git Bash MCP must not be installed on non-Windows platforms.", "Reinstall HolyCodex for this platform."));
|
|
5613
|
-
const context7 = servers?.context7;
|
|
5614
|
-
const expectedContext7 = effectiveMcpServers(runtime.platform).context7;
|
|
5615
|
-
const obsoleteAuth = context7 !== void 0 && [
|
|
5616
|
-
"headers",
|
|
5617
|
-
"env",
|
|
5618
|
-
"authorization",
|
|
5619
|
-
"apiKey"
|
|
5620
|
-
].some((key) => key in context7);
|
|
5621
|
-
if (context7 === void 0) checks.push(check("context7-config", "error", "missing-context7", "Context7 is not configured.", "Reinstall HolyCodex."));
|
|
5622
|
-
else if (string().safeParse(context7.url).success) checks.push(check("context7-config", "error", "obsolete-context7-remote", "Context7 still uses a hosted URL.", "Reinstall to use local bunx Context7."));
|
|
5623
|
-
else if (obsoleteAuth) checks.push(check("context7-config", "error", "obsolete-context7-auth", "Context7 contains obsolete authentication settings.", "Remove auth settings and reinstall."));
|
|
5624
|
-
else if (expectedContext7 === void 0 || !mcpConfigMatches(context7, expectedContext7)) checks.push(check("context7-config", "error", "invalid-context7-config", "Context7 launch configuration is stale or contains unsupported settings.", "Repair .mcp.json or reinstall."));
|
|
5625
|
-
else checks.push(check("context7-config", "ok", "local-context7-config", "Local no-auth Context7 is configured."));
|
|
5626
|
-
const bun = await runtime.command("bun", ["--version"]);
|
|
5627
|
-
const bunx = await runtime.command("bunx", ["--version"]);
|
|
5628
|
-
checks.push(bun.ok ? check("bun", "ok", "bun-ready", `Bun ${bun.output || "available"}.`) : check("bun", "error", "missing-bun", "Bun is unavailable.", "Install or repair Bun."));
|
|
5629
|
-
checks.push(bunx.ok ? check("bunx", "ok", "bunx-ready", `bunx ${bunx.output || "available"}.`) : check("bunx", "error", "missing-bunx", "bunx is unavailable.", "Repair the Bun installation."));
|
|
5630
|
-
if (bun.ok && bunx.ok && checks.some((item) => item.code === "local-context7-config")) {
|
|
5631
|
-
const started = await runtime.context7();
|
|
5632
|
-
checks.push(started.ok && !started.timedOut ? check("context7-startup", "ok", "context7-healthy", "Context7 completed a bounded MCP handshake.") : started.packageFailure ? check("context7-startup", "error", "context7-package-resolution-failed", started.detail || "Context7 package resolution failed.", "Check network/package availability.") : check("context7-startup", "error", "context7-startup-failed", started.detail || "Context7 did not complete an MCP handshake within 15 seconds.", runtime.platform === "win32" ? "Run bunx @upstash/context7-mcp in Git Bash." : "Run bunx @upstash/context7-mcp in the native shell."));
|
|
5633
|
-
}
|
|
5557
|
+
checks.push(missing.length === 0 ? check("package", "ok", "package-ready", `Plugin ${VERSION}, runtimes, agents, and ${SKILLS.length} skills are present.`) : check("package", "error", "package-incomplete", `Missing ${missing.join(", ")}.`, "Reinstall HolyCodex."));
|
|
5558
|
+
const webSearchOverride = readPreservedRootOverrides(config).webSearch;
|
|
5559
|
+
checks.push(rootTomlString(config, "web_search") === "live" ? check("web-search", "ok", "live-web-search", "Managed web search defaults to live.") : webSearchOverride ? check("web-search", "ok", "web-search-override", "An intentional user web-search override is preserved.") : check("web-search", "error", "web-search-not-live", "Managed web search is not live.", "Reinstall HolyCodex."));
|
|
5560
|
+
const status = rootTomlStringArray(config, "status_line") ?? rootTomlStringArray(tableBody(config, "tui") ?? "", "status_line");
|
|
5561
|
+
checks.push(status?.includes("context-remaining") ? check("context-visibility", "ok", "context-visible", "Context-window usage remains visible.") : check("context-visibility", "error", "context-hidden", "The status line does not show context remaining.", "Reinstall HolyCodex."));
|
|
5562
|
+
checks.push(check("screenshot", "ok", "screenshot-default-preserved", "HolyCodex does not override the enabled Codex screenshot default."));
|
|
5563
|
+
const context7 = context7Command(["--version"], runtime.executable);
|
|
5564
|
+
if (context7 === void 0) checks.push(check("context7", "error", "context7-runner-missing", "No supported direct Context7 runner is available.", "Install nub, Bun, pnpm, npm, or Yarn."));
|
|
5565
|
+
else checks.push(check("context7", "ok", "context7-cli-ready", `${context7.command} constructs a valid direct ctx7@latest command.`));
|
|
5566
|
+
const lsp = await runtime.command(process.execPath, [
|
|
5567
|
+
join(pluginRoot, "runtime", "lsp.js"),
|
|
5568
|
+
"status",
|
|
5569
|
+
"--json"
|
|
5570
|
+
], {
|
|
5571
|
+
...process.env,
|
|
5572
|
+
HOLYCODEX_LSP_IDLE_SHUTDOWN_MS: "0",
|
|
5573
|
+
HOLYCODEX_LSP_IDLE_CHECK_INTERVAL_MS: "50"
|
|
5574
|
+
});
|
|
5575
|
+
checks.push(lsp.ok ? check("lsp", "ok", "lsp-cli-ready", "The LSP CLI and daemon are reachable.") : check("lsp", "error", "lsp-cli-failed", lsp.output || "LSP CLI failed.", "Reinstall HolyCodex and inspect the reported daemon log."));
|
|
5634
5576
|
if (runtime.platform === "win32") {
|
|
5635
|
-
const
|
|
5636
|
-
checks.push(
|
|
5637
|
-
}
|
|
5638
|
-
if (!configAvailable) checks.push(check("codex-config", "error", "missing-codex-config", `Missing ${configPath}.`, "Run holycodex install."));
|
|
5639
|
-
const mode = autonomy(config);
|
|
5577
|
+
const resolution = runtime.gitBash();
|
|
5578
|
+
checks.push(resolution.found ? check("git-bash", "ok", "git-bash-launcher-ready", `Git Bash resolves at ${resolution.path}; the bundled launcher is present.`) : check("git-bash", "error", "git-bash-unavailable", resolution.installHint, resolution.installHint));
|
|
5579
|
+
}
|
|
5640
5580
|
const plan = readManagedPlan(config);
|
|
5641
|
-
|
|
5642
|
-
const
|
|
5643
|
-
const
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
checks.push(tableBoolean(config, "features", "default_mode_request_user_input") === true ? check("user-input", "ok", "user-input-ready", "default_mode_request_user_input is enabled.") : check("user-input", "error", "user-input-disabled", "default_mode_request_user_input is not enabled.", "Rerun holycodex install."));
|
|
5653
|
-
checks.push(tableStringArray(config, "desktop", "enabled-reasoning-efforts")?.join(",") === "low,medium,high,xhigh,max" ? check("desktop-reasoning", "ok", "desktop-reasoning-ready", "Desktop exposes low through max reasoning efforts.") : check("desktop-reasoning", "error", "desktop-reasoning-stale", "Desktop reasoning choices must include low through max.", "Reinstall HolyCodex."));
|
|
5654
|
-
checks.push(tableBoolean(config, "desktop", "show-context-window-usage") === true ? check("desktop-context-usage", "ok", "desktop-context-usage-ready", "Desktop context-window usage is visible.") : check("desktop-context-usage", "error", "desktop-context-usage-hidden", "Desktop context-window usage is not enabled.", "Reinstall HolyCodex."));
|
|
5655
|
-
checks.push(rootTomlStringArray(config, "status_line")?.includes("context-remaining") === true ? check("context-visibility", "warning", "context-visible-support-unverified", "status_line includes context-remaining. Current official Codex config documents this item, but publishes no minimum compatible Codex version.") : check("context-visibility", "error", "context-hidden", "status_line does not include context-remaining.", "Rerun holycodex install."));
|
|
5656
|
-
const codex = await runtime.command("codex", ["--version"]);
|
|
5657
|
-
checks.push(codex.ok ? check("codex", "ok", "codex-version", codex.output || "Codex is available.") : check("codex", "warning", "codex-version-unavailable", "Codex version could not be read; status-line compatibility cannot be independently confirmed."));
|
|
5658
|
-
if (runtime.platform === "win32") checks.push(tableString(config, "windows", "sandbox") === "unelevated" ? check("windows-sandbox", "ok", "windows-sandbox-ready", "Windows sandbox runs unelevated.") : check("windows-sandbox", "error", "windows-sandbox-stale", "Windows sandbox must run unelevated.", "Reinstall HolyCodex on Windows."));
|
|
5659
|
-
const agentModelFailures = [];
|
|
5660
|
-
const agentTierValues = [];
|
|
5661
|
-
for (const agent of AGENTS) try {
|
|
5662
|
-
const text = await readFile(join(agentRoot, `${agent}.toml`), "utf8");
|
|
5663
|
-
const expected = plan === void 0 ? void 0 : MODEL_ROUTING_PLANS[plan].agents[agent];
|
|
5664
|
-
if (expected === void 0 || rootTomlString(text, "model") !== expected.model || rootTomlString(text, "model_reasoning_effort") !== expected.reasoningEffort) agentModelFailures.push(agent);
|
|
5665
|
-
agentTierValues.push(rootTomlString(text, "service_tier"));
|
|
5666
|
-
} catch {
|
|
5667
|
-
agentModelFailures.push(agent);
|
|
5581
|
+
const overrides = readPreservedRootOverrides(config);
|
|
5582
|
+
const fast = readManagedFastMode(config);
|
|
5583
|
+
const max = readManagedMaxSubagents(config);
|
|
5584
|
+
checks.push(plan === void 0 ? check("routes", "error", "route-plan-missing", "Managed route plan metadata is missing.", "Reinstall HolyCodex.") : check("routes", "ok", "routes-ready", `${plan} routes are active${max.configured ? ` with max-subagents=${max.value ?? "invalid"}` : ""}.`));
|
|
5585
|
+
checks.push(overrides.model || overrides.reasoningEffort ? check("root-overrides", "ok", "root-overrides-preserved", "Intentional Root model or reasoning overrides are preserved and healthy.") : check("root-overrides", "ok", "root-managed-defaults", "Root uses managed route defaults."));
|
|
5586
|
+
if (plan !== void 0 && fast === void 0) checks.push(check("fast", "warning", "fast-metadata-missing", "Fast metadata is missing; doctor will not guess a service tier.", "Reinstall with an explicit Fast mode."));
|
|
5587
|
+
if (plan !== void 0) for (const agent of AGENTS) {
|
|
5588
|
+
const source = await readFile(join(agentRoot, `${agent}.toml`), "utf8").catch(() => "");
|
|
5589
|
+
const expected = MODEL_ROUTING_PLANS[plan].agents[agent];
|
|
5590
|
+
const overridden = rootTomlString(source, "model") !== expected.model || rootTomlString(source, "model_reasoning_effort") !== expected.reasoningEffort;
|
|
5591
|
+
checks.push(check(`agent-${agent}`, "ok", overridden ? "agent-override-preserved" : "agent-managed-default", overridden ? `${agent} has an intentional healthy route override.` : `${agent} uses managed route defaults.`));
|
|
5668
5592
|
}
|
|
5669
|
-
|
|
5670
|
-
const expectedAgentTier = managedFastMode === "standard" ? "default" : "fast";
|
|
5671
|
-
if (agentTierValues.some((value) => value !== void 0)) checks.push(agentTierValues.every((value) => value === expectedAgentTier) ? check("agent-service-tiers", "ok", "agent-service-tiers-ready", `Specialist service tiers use ${expectedAgentTier}.`) : check("agent-service-tiers", "error", "agent-service-tiers-stale", `Specialist service tiers must use ${expectedAgentTier}.`, "Reinstall HolyCodex."));
|
|
5593
|
+
for (const key of COMPATIBILITY_KEYS) if (config.includes(key.split(".")[1] ?? key)) checks.push(check(`compat-${key}`, "warning", "compatibility-sensitive-key", `${key} is compatibility-sensitive and isolated from supported managed Codex keys.`));
|
|
5672
5594
|
return {
|
|
5673
|
-
healthy:
|
|
5674
|
-
autonomy:
|
|
5595
|
+
healthy: checks.every((item) => item.status !== "error"),
|
|
5596
|
+
autonomy: autonomy(config),
|
|
5675
5597
|
checks
|
|
5676
5598
|
};
|
|
5677
5599
|
}
|
|
@@ -6363,6 +6285,7 @@ var defaultRuntime = {
|
|
|
6363
6285
|
gitBash: resolveGitBashForCurrentProcess,
|
|
6364
6286
|
runProcess: runManagedProcess
|
|
6365
6287
|
};
|
|
6288
|
+
var BACKUP_RETENTION = 5;
|
|
6366
6289
|
function paths(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")) {
|
|
6367
6290
|
const marketplaceCache = join(home, "plugins", "cache", "holycodex");
|
|
6368
6291
|
const cacheRoot = join(marketplaceCache, "holycodex");
|
|
@@ -6394,39 +6317,63 @@ async function install(options, runtime = defaultRuntime) {
|
|
|
6394
6317
|
const plan = options.plan ?? "plus";
|
|
6395
6318
|
const target = paths();
|
|
6396
6319
|
const root = backupRoot();
|
|
6320
|
+
const configBackup = await backup(target.config, root);
|
|
6321
|
+
const cacheBackup = await backup(target.marketplaceCache, root);
|
|
6322
|
+
const agentsBackup = await backup(target.agents, root);
|
|
6397
6323
|
const backups = [
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6324
|
+
configBackup,
|
|
6325
|
+
cacheBackup,
|
|
6326
|
+
agentsBackup,
|
|
6401
6327
|
...await Promise.all(target.legacy.map((path) => backup(path, root)))
|
|
6402
6328
|
].filter((path) => path !== void 0);
|
|
6403
6329
|
const existingConfig = await readText(target.config);
|
|
6404
6330
|
const previousPlan = readManagedPlan(existingConfig);
|
|
6405
6331
|
const fastMode = options.fast ?? "standard";
|
|
6406
6332
|
const config = installConfig(existingConfig, options.autonomy, runtime.platform, plan, options.maxSubagents, fastMode);
|
|
6407
|
-
await atomicWrite(target.config, config);
|
|
6408
|
-
await rm(target.cache, {
|
|
6409
|
-
recursive: true,
|
|
6410
|
-
force: true
|
|
6411
|
-
});
|
|
6412
|
-
await mkdir(dirname(target.cache), { recursive: true });
|
|
6413
|
-
await cp(pluginRoot, target.cache, { recursive: true });
|
|
6414
|
-
await writePlatformPlugin(target.cache, runtime.platform, plan, fastMode);
|
|
6415
6333
|
const existingAgentPreferences = await readAgentPreferences(target.agents, previousPlan);
|
|
6416
|
-
await
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
});
|
|
6420
|
-
await
|
|
6421
|
-
await
|
|
6422
|
-
await
|
|
6334
|
+
const staging = await mkdtemp(join(tmpdir(), "holycodex-stage-"));
|
|
6335
|
+
const stagedCache = join(staging, "cache");
|
|
6336
|
+
const stagedAgents = join(staging, "agents");
|
|
6337
|
+
await cp(pluginRoot, stagedCache, { recursive: true });
|
|
6338
|
+
await writeInstalledAgents(join(stagedCache, "agents"), runtime.platform, plan, fastMode);
|
|
6339
|
+
await cp(join(pluginRoot, "agents"), stagedAgents, { recursive: true });
|
|
6340
|
+
await writeInstalledAgents(stagedAgents, runtime.platform, plan, fastMode);
|
|
6341
|
+
await preserveAgentPreferences(stagedAgents, existingAgentPreferences, plan, fastMode);
|
|
6342
|
+
await validateStaging(stagedCache, stagedAgents);
|
|
6423
6343
|
const removedLegacy = [];
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
await
|
|
6427
|
-
|
|
6344
|
+
let codexSecurity;
|
|
6345
|
+
try {
|
|
6346
|
+
await atomicWrite(target.config, config);
|
|
6347
|
+
await rm(target.cache, {
|
|
6348
|
+
recursive: true,
|
|
6349
|
+
force: true
|
|
6350
|
+
});
|
|
6351
|
+
await mkdir(dirname(target.cache), { recursive: true });
|
|
6352
|
+
await cp(stagedCache, target.cache, { recursive: true });
|
|
6353
|
+
await rm(target.agents, {
|
|
6354
|
+
recursive: true,
|
|
6355
|
+
force: true
|
|
6356
|
+
});
|
|
6357
|
+
await cp(stagedAgents, target.agents, { recursive: true });
|
|
6358
|
+
for (const path of target.legacy) {
|
|
6359
|
+
if (!await exists(path)) continue;
|
|
6360
|
+
await rm(path, { recursive: true });
|
|
6361
|
+
removedLegacy.push(path);
|
|
6362
|
+
}
|
|
6363
|
+
codexSecurity = await installCodexSecurity(runtime.runProcess, runtime.platform, process.env);
|
|
6364
|
+
await removeObsoleteVersionCaches(target.cacheRoot);
|
|
6365
|
+
} catch (error) {
|
|
6366
|
+
await restoreTarget(target.config, configBackup);
|
|
6367
|
+
await restoreTarget(target.marketplaceCache, cacheBackup);
|
|
6368
|
+
await restoreTarget(target.agents, agentsBackup);
|
|
6369
|
+
throw error;
|
|
6370
|
+
} finally {
|
|
6371
|
+
await rm(staging, {
|
|
6372
|
+
recursive: true,
|
|
6373
|
+
force: true
|
|
6374
|
+
});
|
|
6428
6375
|
}
|
|
6429
|
-
|
|
6376
|
+
await pruneBackupHistory();
|
|
6430
6377
|
return {
|
|
6431
6378
|
action: "install",
|
|
6432
6379
|
changed: [
|
|
@@ -6441,6 +6388,40 @@ async function install(options, runtime = defaultRuntime) {
|
|
|
6441
6388
|
...options.maxSubagents === void 0 ? {} : { maxSubagents: options.maxSubagents }
|
|
6442
6389
|
};
|
|
6443
6390
|
}
|
|
6391
|
+
async function validateStaging(cache, agents) {
|
|
6392
|
+
const required = [
|
|
6393
|
+
join(cache, ".codex-plugin", "plugin.json"),
|
|
6394
|
+
join(cache, "skills", "context7-cli", "SKILL.md"),
|
|
6395
|
+
join(cache, "runtime", "lsp.js"),
|
|
6396
|
+
...AGENTS.map((agent) => join(agents, `${agent}.toml`))
|
|
6397
|
+
];
|
|
6398
|
+
const missing = [];
|
|
6399
|
+
for (const path of required) if (!await exists(path)) missing.push(path);
|
|
6400
|
+
if (missing.length > 0) throw new Error(`Staged HolyCodex installation is incomplete: ${missing.join(", ")}`);
|
|
6401
|
+
}
|
|
6402
|
+
async function restoreTarget(target, source) {
|
|
6403
|
+
await rm(target, {
|
|
6404
|
+
recursive: true,
|
|
6405
|
+
force: true
|
|
6406
|
+
});
|
|
6407
|
+
if (source !== void 0) await cp(source, target, { recursive: true });
|
|
6408
|
+
}
|
|
6409
|
+
async function removeObsoleteVersionCaches(cacheRoot) {
|
|
6410
|
+
if (!await exists(cacheRoot)) return;
|
|
6411
|
+
for (const entry of await readdir(cacheRoot)) if (entry !== "0.11.2") await rm(join(cacheRoot, entry), {
|
|
6412
|
+
recursive: true,
|
|
6413
|
+
force: true
|
|
6414
|
+
});
|
|
6415
|
+
}
|
|
6416
|
+
async function pruneBackupHistory() {
|
|
6417
|
+
const root = join(tmpdir(), "holycodex-backups");
|
|
6418
|
+
if (!await exists(root)) return;
|
|
6419
|
+
const entries = (await readdir(root)).sort().reverse();
|
|
6420
|
+
await Promise.allSettled(entries.slice(BACKUP_RETENTION, 6).map((entry) => rm(join(root, entry), {
|
|
6421
|
+
recursive: true,
|
|
6422
|
+
force: true
|
|
6423
|
+
})));
|
|
6424
|
+
}
|
|
6444
6425
|
var AGENT_MANAGED_KEYS = /* @__PURE__ */ new Set([
|
|
6445
6426
|
"model",
|
|
6446
6427
|
"model_reasoning_effort",
|
|
@@ -6448,7 +6429,6 @@ var AGENT_MANAGED_KEYS = /* @__PURE__ */ new Set([
|
|
|
6448
6429
|
"service_tier"
|
|
6449
6430
|
]);
|
|
6450
6431
|
var AGENT_BUNDLED_KEYS = /* @__PURE__ */ new Set(["description", "developer_instructions"]);
|
|
6451
|
-
var COMPACT_WINDOWS_SHELL_POLICY = /^On native Windows, resolve `mcp__git_bash__run` before shell use;[^\r\n]*never use PowerShell\/cmd\.\r?\n\r?\n/m;
|
|
6452
6432
|
async function readAgentPreferences(root, previousPlan) {
|
|
6453
6433
|
const preferences = {};
|
|
6454
6434
|
await Promise.all(AGENTS.map(async (agent) => {
|
|
@@ -6513,26 +6493,27 @@ function mergeCustomAgentSettings(input, custom) {
|
|
|
6513
6493
|
if (custom.tables !== void 0 && !output.includes(custom.tables)) output = `${output.trimEnd()}\n\n${custom.tables}`;
|
|
6514
6494
|
return `${output.trimEnd()}\n`;
|
|
6515
6495
|
}
|
|
6516
|
-
async function writePlatformPlugin(root, platform, plan, fastMode) {
|
|
6517
|
-
await atomicWrite(join(root, ".mcp.json"), `${JSON.stringify({ mcpServers: effectiveMcpServers(platform) }, null, 2)}\n`);
|
|
6518
|
-
await writeInstalledAgents(join(root, "agents"), platform, plan, fastMode);
|
|
6519
|
-
}
|
|
6520
6496
|
async function writeInstalledAgents(root, platform, plan, fastMode) {
|
|
6521
6497
|
await Promise.all(AGENTS.map(async (agent) => {
|
|
6522
6498
|
const path = join(root, `${agent}.toml`);
|
|
6523
6499
|
const route = MODEL_ROUTING_PLANS[plan].agents[agent];
|
|
6524
6500
|
let source = await readText(path);
|
|
6501
|
+
source = composeAgentPolicies(source, platform);
|
|
6525
6502
|
source = replaceTomlString(source, "model", route.model);
|
|
6526
6503
|
source = replaceTomlString(source, "model_reasoning_effort", route.reasoningEffort);
|
|
6527
6504
|
source = replaceTomlString(source, "model_verbosity", "low");
|
|
6528
6505
|
source = replaceOrAppendTomlString(source, "service_tier", fastMode === "standard" ? "default" : "fast");
|
|
6529
|
-
|
|
6530
|
-
await atomicWrite(path, source);
|
|
6531
|
-
return;
|
|
6532
|
-
}
|
|
6533
|
-
await atomicWrite(path, source.replace(`${WINDOWS_SHELL_POLICY}\r\n\r\n`, "").replace(`${WINDOWS_SHELL_POLICY}\n\n`, "").replace(COMPACT_WINDOWS_SHELL_POLICY, ""));
|
|
6506
|
+
await atomicWrite(path, source);
|
|
6534
6507
|
}));
|
|
6535
6508
|
}
|
|
6509
|
+
function composeAgentPolicies(input, platform) {
|
|
6510
|
+
const policy = [
|
|
6511
|
+
LITE_WRITING_POLICY,
|
|
6512
|
+
CONTEXT7_POLICY,
|
|
6513
|
+
...platform === "win32" ? [WINDOWS_SHELL_POLICY] : []
|
|
6514
|
+
].join("\n\n");
|
|
6515
|
+
return input.replace(/(developer_instructions\s*=\s*"""\r?\n)/, `$1${policy}\n\n`);
|
|
6516
|
+
}
|
|
6536
6517
|
/** Provides cleanup. */
|
|
6537
6518
|
async function cleanup(_options) {
|
|
6538
6519
|
const target = paths();
|
|
@@ -6652,88 +6633,39 @@ function renderNotice(kind, message, color) {
|
|
|
6652
6633
|
//#endregion
|
|
6653
6634
|
//#region packages/cli/src/cli.ts
|
|
6654
6635
|
async function main() {
|
|
6655
|
-
const
|
|
6636
|
+
const parsed = parseCliArguments(process$1.argv.slice(2));
|
|
6656
6637
|
const stdoutColor = supportsColor(process$1.stdout.isTTY, process$1.env.NO_COLOR);
|
|
6657
6638
|
const stderrColor = supportsColor(process$1.stderr.isTTY, process$1.env.NO_COLOR);
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
process$1.stdout.write(command === "install" ? renderInstallHelp(VERSION, stdoutColor) : renderHelp(VERSION, stdoutColor));
|
|
6639
|
+
if (parsed.action === "help") {
|
|
6640
|
+
process$1.stdout.write(parsed.command === "install" ? renderInstallHelp(VERSION, stdoutColor) : renderHelp(VERSION, stdoutColor));
|
|
6661
6641
|
return;
|
|
6662
6642
|
}
|
|
6663
|
-
if (
|
|
6643
|
+
if (parsed.action === "version") {
|
|
6664
6644
|
process$1.stdout.write(`${VERSION}\n`);
|
|
6665
6645
|
return;
|
|
6666
6646
|
}
|
|
6667
|
-
if (args.flatMap((arg, index) => arg === "--plan" ? [index] : []).length > 1) throw new Error("--plan may be specified only once.");
|
|
6668
|
-
const planFlagIndex = args.indexOf("--plan");
|
|
6669
|
-
const planValue = planFlagIndex < 0 ? DEFAULT_PLAN : args[planFlagIndex + 1];
|
|
6670
|
-
if (planValue === void 0 || planValue.startsWith("-") || planValue === command) throw new Error(`Missing --plan value. Valid plans: ${PLAN_NAMES.join(", ")}.`);
|
|
6671
|
-
const parsedPlan = PlanNameSchema.safeParse(planValue);
|
|
6672
|
-
if (!parsedPlan.success) throw new Error(`Unknown plan: ${planValue}. Valid plans: ${PLAN_NAMES.join(", ")}.`);
|
|
6673
|
-
const plan = parsedPlan.data;
|
|
6674
|
-
if (args.flatMap((arg, index) => arg === "--max-subagents" ? [index] : []).length > 1) throw new Error("--max-subagents may be specified only once.");
|
|
6675
|
-
const maxSubagentsIndex = args.indexOf("--max-subagents");
|
|
6676
|
-
const maxSubagentsValue = maxSubagentsIndex < 0 ? void 0 : args[maxSubagentsIndex + 1];
|
|
6677
|
-
if (maxSubagentsIndex >= 0 && (maxSubagentsValue === void 0 || maxSubagentsValue.startsWith("--") || maxSubagentsValue === command)) throw new Error("Missing --max-subagents value. Expected a nonnegative integer.");
|
|
6678
|
-
if (maxSubagentsValue !== void 0 && !/^\d+$/.test(maxSubagentsValue)) throw new Error(`Invalid --max-subagents value: ${maxSubagentsValue}. Expected a nonnegative integer.`);
|
|
6679
|
-
const maxSubagents = maxSubagentsValue === void 0 ? void 0 : Number(maxSubagentsValue);
|
|
6680
|
-
const autonomyFlags = args.filter((arg) => [
|
|
6681
|
-
"--codex-autonomous",
|
|
6682
|
-
"--no-codex-autonomous",
|
|
6683
|
-
"--dangerous-codex-autonomous"
|
|
6684
|
-
].includes(arg));
|
|
6685
|
-
if (autonomyFlags.length > 1) {
|
|
6686
|
-
process$1.stderr.write(renderError(`Conflicting autonomy flags: ${autonomyFlags.join(", ")}`, stderrColor));
|
|
6687
|
-
process$1.exitCode = 1;
|
|
6688
|
-
return;
|
|
6689
|
-
}
|
|
6690
|
-
const fastFlags = args.filter((arg) => [
|
|
6691
|
-
"--fast",
|
|
6692
|
-
"--fast-all",
|
|
6693
|
-
"--no-fast"
|
|
6694
|
-
].includes(arg));
|
|
6695
|
-
if (fastFlags.length > 1) {
|
|
6696
|
-
process$1.stderr.write(renderError(`Conflicting fast flags: ${fastFlags.join(", ")}`, stderrColor));
|
|
6697
|
-
process$1.exitCode = 1;
|
|
6698
|
-
return;
|
|
6699
|
-
}
|
|
6700
|
-
const autonomy = args.includes("--dangerous-codex-autonomous") ? {
|
|
6701
|
-
requested: true,
|
|
6702
|
-
mode: "dangerous"
|
|
6703
|
-
} : args.includes("--codex-autonomous") ? {
|
|
6704
|
-
requested: true,
|
|
6705
|
-
mode: "autonomous"
|
|
6706
|
-
} : args.includes("--no-codex-autonomous") ? {
|
|
6707
|
-
requested: true,
|
|
6708
|
-
mode: "default"
|
|
6709
|
-
} : { requested: false };
|
|
6710
6647
|
const options = {
|
|
6711
|
-
autonomy,
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
plan,
|
|
6715
|
-
...maxSubagents === void 0 ? {} : { maxSubagents }
|
|
6648
|
+
autonomy: parsed.autonomy,
|
|
6649
|
+
fast: parsed.fast,
|
|
6650
|
+
json: parsed.json,
|
|
6651
|
+
plan: parsed.plan,
|
|
6652
|
+
...parsed.maxSubagents === void 0 ? {} : { maxSubagents: parsed.maxSubagents }
|
|
6716
6653
|
};
|
|
6717
|
-
if (command === "doctor") {
|
|
6654
|
+
if (parsed.command === "doctor") {
|
|
6718
6655
|
const result = await doctor();
|
|
6719
|
-
process$1.stdout.write(
|
|
6656
|
+
process$1.stdout.write(parsed.json ? `${JSON.stringify(result)}\n` : renderDoctor(result, stdoutColor));
|
|
6720
6657
|
if (!result.healthy) process$1.exitCode = 1;
|
|
6721
6658
|
return;
|
|
6722
6659
|
}
|
|
6723
|
-
if (autonomy.requested && autonomy.mode === "dangerous") process$1.stderr.write(renderNotice("warning", "Dangerous autonomy disables approvals and filesystem sandboxing.", stderrColor));
|
|
6724
|
-
const result = command === "install" ? await install(options) :
|
|
6725
|
-
|
|
6726
|
-
process$1.stderr.write(renderError(`Unknown command: ${command ?? args[0] ?? ""}`, stderrColor));
|
|
6727
|
-
process$1.exitCode = 1;
|
|
6728
|
-
return;
|
|
6729
|
-
}
|
|
6730
|
-
process$1.stdout.write(options.json ? `${JSON.stringify(result)}\n` : renderRunResult(result, stdoutColor));
|
|
6660
|
+
if (parsed.autonomy.requested && parsed.autonomy.mode === "dangerous") process$1.stderr.write(renderNotice("warning", "Dangerous autonomy disables approvals and filesystem sandboxing.", stderrColor));
|
|
6661
|
+
const result = parsed.command === "install" ? await install(options) : await cleanup(options);
|
|
6662
|
+
process$1.stdout.write(parsed.json ? `${JSON.stringify(result)}\n` : renderRunResult(result, stdoutColor));
|
|
6731
6663
|
}
|
|
6732
6664
|
try {
|
|
6733
6665
|
await main();
|
|
6734
6666
|
} catch (error) {
|
|
6735
|
-
const
|
|
6736
|
-
process$1.stderr.write(renderError(formatCliError(error),
|
|
6667
|
+
const color = supportsColor(process$1.stderr.isTTY, process$1.env.NO_COLOR);
|
|
6668
|
+
process$1.stderr.write(renderError(formatCliError(error), color));
|
|
6737
6669
|
process$1.exitCode = 1;
|
|
6738
6670
|
}
|
|
6739
6671
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "holycodex",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "Lean Codex-only agent toolkit installer and doctor",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
7
7
|
"chatgpt",
|
|
8
8
|
"codex",
|
|
9
|
-
"
|
|
9
|
+
"developer-tools"
|
|
10
10
|
],
|
|
11
11
|
"homepage": "https://github.com/davidbasilefilho/holycodex#readme",
|
|
12
12
|
"bugs": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"prepack": "vp run --workspace-root build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@holycodex/plugin": "0.11.
|
|
42
|
+
"@holycodex/plugin": "0.11.2",
|
|
43
43
|
"zod": "^4.4.3"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
|
-
"node": ">=
|
|
46
|
+
"node": ">=26 <27"
|
|
47
47
|
}
|
|
48
48
|
}
|