holycodex 0.10.4 → 0.10.6-dev.30770925419.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/cli.js +732 -183
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,10 +7,10 @@ bunx holycodex@dev install
|
|
|
7
7
|
bunx holycodex@dev doctor
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
Use `holycodex --help` for commands, autonomy options, and service tiers. `--fast` selects
|
|
10
|
+
Use `holycodex --help` for commands, autonomy options, routing plans, and service tiers. `--fast` selects Fast for generated agents, `--fast-all` selects Fast for Root and generated agents, and `--no-fast` or omitting Fast flags selects Standard. Fast uses `2.5×` subscription usage for about `1.5×` output-token speed without a quality gain. Stable releases use `bunx holycodex`; development releases use npm's `dev` dist-tag.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
On a fresh installation, omitting autonomy flags seeds Codex Approve for me semantics: `approval_policy = "on-request"`, `approvals_reviewer = "auto_review"`, and `sandbox_mode = "workspace-write"`. On an existing installation, omitting autonomy flags preserves the complete current permission selection. `--no-codex-autonomous`, `--codex-autonomous`, and `--dangerous-codex-autonomous` explicitly replace that selection with their documented modes. HolyCodex never generates `default_permissions` or selects a named permission profile.
|
|
13
13
|
|
|
14
|
-
Install also attempts to add or enable the official `codex-security@openai-curated` plugin through structured Codex CLI commands. External availability failures are non-fatal and reported in human and JSON results. Cleanup leaves this independent official plugin installed. Build Web Apps remains separately managed by Codex.
|
|
14
|
+
Install also attempts to add or enable the official `codex-security@openai-curated` plugin through structured Codex CLI commands. If no global Codex CLI is available, HolyCodex can use the active Bun executable or a supported npm/pnpm package runner. External availability failures are non-fatal and reported in human and JSON results. Cleanup leaves this independent official plugin installed. Build Web Apps remains separately managed by Codex.
|
|
15
15
|
|
|
16
16
|
Repository, documentation, license, and security notices: https://github.com/davidbasilefilho/holycodex
|
package/dist/cli.js
CHANGED
|
@@ -614,7 +614,6 @@ var string$1 = (params) => {
|
|
|
614
614
|
};
|
|
615
615
|
var integer = /^-?\d+$/;
|
|
616
616
|
var number$1 = /^-?\d+(?:\.\d+)?$/;
|
|
617
|
-
var boolean$1 = /^(?:true|false)$/i;
|
|
618
617
|
var lowercase = /^[^A-Z]*$/;
|
|
619
618
|
var uppercase = /^[^a-z]*$/;
|
|
620
619
|
//#endregion
|
|
@@ -1409,24 +1408,6 @@ var $ZodNumberFormat = /*@__PURE__*/ $constructor("$ZodNumberFormat", (inst, def
|
|
|
1409
1408
|
$ZodCheckNumberFormat.init(inst, def);
|
|
1410
1409
|
$ZodNumber.init(inst, def);
|
|
1411
1410
|
});
|
|
1412
|
-
var $ZodBoolean = /*@__PURE__*/ $constructor("$ZodBoolean", (inst, def) => {
|
|
1413
|
-
$ZodType.init(inst, def);
|
|
1414
|
-
inst._zod.pattern = boolean$1;
|
|
1415
|
-
inst._zod.parse = (payload, _ctx) => {
|
|
1416
|
-
if (def.coerce) try {
|
|
1417
|
-
payload.value = Boolean(payload.value);
|
|
1418
|
-
} catch (_) {}
|
|
1419
|
-
const input = payload.value;
|
|
1420
|
-
if (typeof input === "boolean") return payload;
|
|
1421
|
-
payload.issues.push({
|
|
1422
|
-
expected: "boolean",
|
|
1423
|
-
code: "invalid_type",
|
|
1424
|
-
input,
|
|
1425
|
-
inst
|
|
1426
|
-
});
|
|
1427
|
-
return payload;
|
|
1428
|
-
};
|
|
1429
|
-
});
|
|
1430
1411
|
var $ZodUnknown = /*@__PURE__*/ $constructor("$ZodUnknown", (inst, def) => {
|
|
1431
1412
|
$ZodType.init(inst, def);
|
|
1432
1413
|
inst._zod.parse = (payload) => payload;
|
|
@@ -2642,13 +2623,6 @@ function _int(Class, params) {
|
|
|
2642
2623
|
});
|
|
2643
2624
|
}
|
|
2644
2625
|
// @__NO_SIDE_EFFECTS__
|
|
2645
|
-
function _boolean(Class, params) {
|
|
2646
|
-
return new Class({
|
|
2647
|
-
type: "boolean",
|
|
2648
|
-
...normalizeParams(params)
|
|
2649
|
-
});
|
|
2650
|
-
}
|
|
2651
|
-
// @__NO_SIDE_EFFECTS__
|
|
2652
2626
|
function _unknown(Class) {
|
|
2653
2627
|
return new Class({ type: "unknown" });
|
|
2654
2628
|
}
|
|
@@ -3194,9 +3168,6 @@ var numberProcessor = (schema, ctx, _json, _params) => {
|
|
|
3194
3168
|
else if (typeof maximum === "number") json.maximum = maximum;
|
|
3195
3169
|
if (typeof multipleOf === "number") json.multipleOf = multipleOf;
|
|
3196
3170
|
};
|
|
3197
|
-
var booleanProcessor = (_schema, _ctx, json, _params) => {
|
|
3198
|
-
json.type = "boolean";
|
|
3199
|
-
};
|
|
3200
3171
|
var neverProcessor = (_schema, _ctx, json, _params) => {
|
|
3201
3172
|
json.not = {};
|
|
3202
3173
|
};
|
|
@@ -3880,14 +3851,6 @@ var ZodNumberFormat = /*@__PURE__*/ $constructor("ZodNumberFormat", (inst, def)
|
|
|
3880
3851
|
function int(params) {
|
|
3881
3852
|
return /* @__PURE__ */ _int(ZodNumberFormat, params);
|
|
3882
3853
|
}
|
|
3883
|
-
var ZodBoolean = /*@__PURE__*/ $constructor("ZodBoolean", (inst, def) => {
|
|
3884
|
-
$ZodBoolean.init(inst, def);
|
|
3885
|
-
ZodType.init(inst, def);
|
|
3886
|
-
inst._zod.processJSONSchema = (ctx, json, params) => booleanProcessor(inst, ctx, json, params);
|
|
3887
|
-
});
|
|
3888
|
-
function boolean(params) {
|
|
3889
|
-
return /* @__PURE__ */ _boolean(ZodBoolean, params);
|
|
3890
|
-
}
|
|
3891
3854
|
var ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => {
|
|
3892
3855
|
$ZodUnknown.init(inst, def);
|
|
3893
3856
|
ZodType.init(inst, def);
|
|
@@ -4289,7 +4252,7 @@ function superRefine(fn, params) {
|
|
|
4289
4252
|
}
|
|
4290
4253
|
//#endregion
|
|
4291
4254
|
//#region packages/cli/src/catalog.ts
|
|
4292
|
-
var VERSION = "0.10.
|
|
4255
|
+
var VERSION = "0.10.6-dev.30770925419.1";
|
|
4293
4256
|
var SKILLS = [
|
|
4294
4257
|
"ast-grep",
|
|
4295
4258
|
"caveman",
|
|
@@ -4325,7 +4288,8 @@ var ReasoningEffortSchema = _enum([
|
|
|
4325
4288
|
"low",
|
|
4326
4289
|
"medium",
|
|
4327
4290
|
"high",
|
|
4328
|
-
"xhigh"
|
|
4291
|
+
"xhigh",
|
|
4292
|
+
"max"
|
|
4329
4293
|
]);
|
|
4330
4294
|
var FastModeSchema = _enum([
|
|
4331
4295
|
"standard",
|
|
@@ -4370,21 +4334,21 @@ var DEFAULT_PLAN = "plus";
|
|
|
4370
4334
|
var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
|
|
4371
4335
|
go: {
|
|
4372
4336
|
root: {
|
|
4373
|
-
model: "gpt-5.6-
|
|
4374
|
-
reasoningEffort: "
|
|
4337
|
+
model: "gpt-5.6-luna",
|
|
4338
|
+
reasoningEffort: "xhigh"
|
|
4375
4339
|
},
|
|
4376
4340
|
agents: {
|
|
4377
4341
|
explorer: {
|
|
4378
|
-
model: "gpt-5.6-
|
|
4379
|
-
reasoningEffort: "
|
|
4342
|
+
model: "gpt-5.6-luna",
|
|
4343
|
+
reasoningEffort: "high"
|
|
4380
4344
|
},
|
|
4381
4345
|
librarian: {
|
|
4382
|
-
model: "gpt-5.6-
|
|
4383
|
-
reasoningEffort: "
|
|
4346
|
+
model: "gpt-5.6-luna",
|
|
4347
|
+
reasoningEffort: "high"
|
|
4384
4348
|
},
|
|
4385
4349
|
worker: {
|
|
4386
|
-
model: "gpt-5.6-
|
|
4387
|
-
reasoningEffort: "
|
|
4350
|
+
model: "gpt-5.6-luna",
|
|
4351
|
+
reasoningEffort: "xhigh"
|
|
4388
4352
|
}
|
|
4389
4353
|
},
|
|
4390
4354
|
usage: {
|
|
@@ -4456,7 +4420,7 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
|
|
|
4456
4420
|
},
|
|
4457
4421
|
worker: {
|
|
4458
4422
|
model: "gpt-5.6-luna",
|
|
4459
|
-
reasoningEffort: "
|
|
4423
|
+
reasoningEffort: "max"
|
|
4460
4424
|
}
|
|
4461
4425
|
},
|
|
4462
4426
|
usage: {
|
|
@@ -4480,7 +4444,7 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
|
|
|
4480
4444
|
},
|
|
4481
4445
|
worker: {
|
|
4482
4446
|
model: "gpt-5.6-luna",
|
|
4483
|
-
reasoningEffort: "
|
|
4447
|
+
reasoningEffort: "max"
|
|
4484
4448
|
}
|
|
4485
4449
|
},
|
|
4486
4450
|
usage: {
|
|
@@ -4496,15 +4460,15 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
|
|
|
4496
4460
|
agents: {
|
|
4497
4461
|
explorer: {
|
|
4498
4462
|
model: "gpt-5.6-luna",
|
|
4499
|
-
reasoningEffort: "
|
|
4463
|
+
reasoningEffort: "max"
|
|
4500
4464
|
},
|
|
4501
4465
|
librarian: {
|
|
4502
4466
|
model: "gpt-5.6-luna",
|
|
4503
|
-
reasoningEffort: "
|
|
4467
|
+
reasoningEffort: "max"
|
|
4504
4468
|
},
|
|
4505
4469
|
worker: {
|
|
4506
4470
|
model: "gpt-5.6-luna",
|
|
4507
|
-
reasoningEffort: "
|
|
4471
|
+
reasoningEffort: "max"
|
|
4508
4472
|
}
|
|
4509
4473
|
},
|
|
4510
4474
|
usage: {
|
|
@@ -4520,14 +4484,23 @@ var LEGACY_MANAGED_AGENT_MODEL_HISTORY = {
|
|
|
4520
4484
|
explorer: [{
|
|
4521
4485
|
model: "gpt-5.6-luna",
|
|
4522
4486
|
reasoningEffort: "low"
|
|
4487
|
+
}, {
|
|
4488
|
+
model: "gpt-5.6-terra",
|
|
4489
|
+
reasoningEffort: "low"
|
|
4523
4490
|
}],
|
|
4524
4491
|
librarian: [{
|
|
4525
4492
|
model: "gpt-5.6-luna",
|
|
4526
4493
|
reasoningEffort: "low"
|
|
4494
|
+
}, {
|
|
4495
|
+
model: "gpt-5.6-terra",
|
|
4496
|
+
reasoningEffort: "low"
|
|
4527
4497
|
}],
|
|
4528
4498
|
worker: [{
|
|
4529
4499
|
model: "gpt-5.6-terra",
|
|
4530
4500
|
reasoningEffort: "low"
|
|
4501
|
+
}, {
|
|
4502
|
+
model: "gpt-5.6-terra",
|
|
4503
|
+
reasoningEffort: "medium"
|
|
4531
4504
|
}]
|
|
4532
4505
|
},
|
|
4533
4506
|
"plus-low": {
|
|
@@ -4690,6 +4663,9 @@ var LEGACY_MANAGED_ROOT_MODEL_HISTORY = {
|
|
|
4690
4663
|
go: [{
|
|
4691
4664
|
model: "gpt-5.6-sol",
|
|
4692
4665
|
reasoningEffort: "low"
|
|
4666
|
+
}, {
|
|
4667
|
+
model: "gpt-5.6-terra",
|
|
4668
|
+
reasoningEffort: "medium"
|
|
4693
4669
|
}],
|
|
4694
4670
|
"plus-low": [],
|
|
4695
4671
|
plus: [],
|
|
@@ -4856,6 +4832,7 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4856
4832
|
detached: input.platform !== "win32"
|
|
4857
4833
|
});
|
|
4858
4834
|
} catch (error) {
|
|
4835
|
+
const code = errorCode(error);
|
|
4859
4836
|
resolve({
|
|
4860
4837
|
exitCode: null,
|
|
4861
4838
|
stdout: "",
|
|
@@ -4863,7 +4840,8 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4863
4840
|
timedOut: false,
|
|
4864
4841
|
matched: false,
|
|
4865
4842
|
outputTruncated: false,
|
|
4866
|
-
error: error instanceof Error ? error.message : String(error)
|
|
4843
|
+
error: error instanceof Error ? error.message : String(error),
|
|
4844
|
+
...code === void 0 ? {} : { errorCode: code }
|
|
4867
4845
|
});
|
|
4868
4846
|
return;
|
|
4869
4847
|
}
|
|
@@ -4896,7 +4874,7 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4896
4874
|
let matched = false;
|
|
4897
4875
|
let settled = false;
|
|
4898
4876
|
let forceKillTimeout;
|
|
4899
|
-
const finish = (exitCode, error) => {
|
|
4877
|
+
const finish = (exitCode, error, errorCode) => {
|
|
4900
4878
|
if (settled) return;
|
|
4901
4879
|
settled = true;
|
|
4902
4880
|
clearTimeout(timeout);
|
|
@@ -4908,7 +4886,8 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4908
4886
|
timedOut,
|
|
4909
4887
|
matched,
|
|
4910
4888
|
outputTruncated: stdout.truncated || stderr.truncated,
|
|
4911
|
-
...error === void 0 ? {} : { error }
|
|
4889
|
+
...error === void 0 ? {} : { error },
|
|
4890
|
+
...errorCode === void 0 ? {} : { errorCode }
|
|
4912
4891
|
});
|
|
4913
4892
|
};
|
|
4914
4893
|
const terminate = () => {
|
|
@@ -4934,7 +4913,7 @@ async function runManagedProcess(input, runtime = defaultManagedProcessRuntime)
|
|
|
4934
4913
|
stderr = appendOutput(stderr, chunk.toString(), input.maxOutputChars);
|
|
4935
4914
|
inspectMatch();
|
|
4936
4915
|
});
|
|
4937
|
-
child.once("error", (error) => finish(null, error.message));
|
|
4916
|
+
child.once("error", (error) => finish(null, error.message, errorCode(error)));
|
|
4938
4917
|
child.once("close", (code) => finish(code));
|
|
4939
4918
|
const timeout = setTimeout(() => {
|
|
4940
4919
|
timedOut = true;
|
|
@@ -4985,6 +4964,11 @@ function appendOutput(state, chunk, limit) {
|
|
|
4985
4964
|
function outputText(state) {
|
|
4986
4965
|
return state.truncated ? `${state.head}${TRUNCATED_MARKER}${state.tail}` : state.head;
|
|
4987
4966
|
}
|
|
4967
|
+
function errorCode(value) {
|
|
4968
|
+
if (typeof value !== "object" || value === null || !("code" in value)) return void 0;
|
|
4969
|
+
const code = value.code;
|
|
4970
|
+
return typeof code === "string" ? code : void 0;
|
|
4971
|
+
}
|
|
4988
4972
|
//#endregion
|
|
4989
4973
|
//#region packages/cli/src/toml.ts
|
|
4990
4974
|
var TOML_TABLE = /^[ \t]*(?:\[[^\]\r\n]+\]|\[\[[^\]\r\n]+\]\])[ \t]*(?:#.*)?$/m;
|
|
@@ -4992,7 +4976,7 @@ var TOML_TABLE = /^[ \t]*(?:\[[^\]\r\n]+\]|\[\[[^\]\r\n]+\]\])[ \t]*(?:#.*)?$/m;
|
|
|
4992
4976
|
function rootTomlString(input, key) {
|
|
4993
4977
|
const table = TOML_TABLE.exec(input);
|
|
4994
4978
|
const root = table === null ? input : input.slice(0, table.index);
|
|
4995
|
-
const match = new RegExp(String.raw`^[ \t]*${escapeRegExp(key)}[ \t]*=[ \t]*(?:"((?:\\.|[^"\\\r\n])*)"|'([^'\r\n]*)')[ \t]*(?:#.*)?$`, "m").exec(root);
|
|
4979
|
+
const match = new RegExp(String.raw`^[ \t]*${escapeRegExp$1(key)}[ \t]*=[ \t]*(?:"((?:\\.|[^"\\\r\n])*)"|'([^'\r\n]*)')[ \t]*(?:#.*)?$`, "m").exec(root);
|
|
4996
4980
|
if (match === null) return void 0;
|
|
4997
4981
|
if (match[2] !== void 0) return match[2];
|
|
4998
4982
|
try {
|
|
@@ -5012,7 +4996,7 @@ function rootTomlStringArraySource(input, key) {
|
|
|
5012
4996
|
function parseRootTomlStringArray(input, key) {
|
|
5013
4997
|
const table = TOML_TABLE.exec(input);
|
|
5014
4998
|
const root = table === null ? input : input.slice(0, table.index);
|
|
5015
|
-
const assignment = new RegExp(String.raw`^[ \t]*${escapeRegExp(key)}[ \t]*=`, "m").exec(root);
|
|
4999
|
+
const assignment = new RegExp(String.raw`^[ \t]*${escapeRegExp$1(key)}[ \t]*=`, "m").exec(root);
|
|
5016
5000
|
if (assignment === null) return void 0;
|
|
5017
5001
|
const start = root.indexOf("[", assignment.index + assignment[0].length);
|
|
5018
5002
|
if (start < 0) return void 0;
|
|
@@ -5066,6 +5050,128 @@ function parseRootTomlStringArray(input, key) {
|
|
|
5066
5050
|
}
|
|
5067
5051
|
}
|
|
5068
5052
|
}
|
|
5053
|
+
function escapeRegExp$1(value) {
|
|
5054
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5055
|
+
}
|
|
5056
|
+
//#endregion
|
|
5057
|
+
//#region packages/cli/src/permission-selection.ts
|
|
5058
|
+
var PERMISSION_KEYS = [
|
|
5059
|
+
"default_permissions",
|
|
5060
|
+
"approval_policy",
|
|
5061
|
+
"approvals_reviewer",
|
|
5062
|
+
"sandbox_mode"
|
|
5063
|
+
];
|
|
5064
|
+
var AUTONOMY_PREFIX = "# holycodex autonomy: ";
|
|
5065
|
+
var ORIGINAL_PERMISSION_PREFIX = "# holycodex original permissions: ";
|
|
5066
|
+
/** Normalizes legacy string callers while preserving an omitted request. */
|
|
5067
|
+
function normalizeRequestedAutonomy(value) {
|
|
5068
|
+
if (value === void 0) return { requested: false };
|
|
5069
|
+
if (typeof value === "string") return {
|
|
5070
|
+
requested: true,
|
|
5071
|
+
mode: value
|
|
5072
|
+
};
|
|
5073
|
+
return value;
|
|
5074
|
+
}
|
|
5075
|
+
/** Reads the raw root permission selection without filling missing values. */
|
|
5076
|
+
function readRawPermissionSelection(input) {
|
|
5077
|
+
const defaultPermissions = rootTomlString(input, "default_permissions");
|
|
5078
|
+
const approvalPolicy = rootTomlString(input, "approval_policy");
|
|
5079
|
+
const approvalsReviewer = rootTomlString(input, "approvals_reviewer");
|
|
5080
|
+
const sandboxMode = rootTomlString(input, "sandbox_mode");
|
|
5081
|
+
return {
|
|
5082
|
+
...defaultPermissions === void 0 ? {} : { defaultPermissions },
|
|
5083
|
+
...approvalPolicy === void 0 ? {} : { approvalPolicy },
|
|
5084
|
+
...approvalsReviewer === void 0 ? {} : { approvalsReviewer },
|
|
5085
|
+
...sandboxMode === void 0 ? {} : { sandboxMode }
|
|
5086
|
+
};
|
|
5087
|
+
}
|
|
5088
|
+
/** Returns root assignment lines for permission keys in source order. */
|
|
5089
|
+
function readPermissionLines(input) {
|
|
5090
|
+
const firstTable = input.search(/^\s*\[/m);
|
|
5091
|
+
const root = firstTable < 0 ? input : input.slice(0, firstTable);
|
|
5092
|
+
const keys = new Set(PERMISSION_KEYS);
|
|
5093
|
+
return root.split(/\r?\n/).filter((line) => {
|
|
5094
|
+
const key = /^\s*([A-Za-z0-9_-]+)\s*=/.exec(line)?.[1];
|
|
5095
|
+
return key !== void 0 && keys.has(key);
|
|
5096
|
+
});
|
|
5097
|
+
}
|
|
5098
|
+
/** Removes all root permission assignment lines while preserving other text. */
|
|
5099
|
+
function removePermissionLines(input) {
|
|
5100
|
+
const firstTable = input.search(/^\s*\[/m);
|
|
5101
|
+
const root = firstTable < 0 ? input : input.slice(0, firstTable);
|
|
5102
|
+
const tables = firstTable < 0 ? "" : input.slice(firstTable);
|
|
5103
|
+
const keys = PERMISSION_KEYS.map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
5104
|
+
return `${root.split(/\r?\n/).filter((line) => !new RegExp(`^\\s*(?:${keys.join("|")})\\s*=`).test(line)).join("\n").trim()}${tables ? `\n${tables.trimStart()}` : ""}`.trim();
|
|
5105
|
+
}
|
|
5106
|
+
/** Returns the exact tuple represented by an explicit autonomy mode. */
|
|
5107
|
+
function permissionSelectionForMode(mode) {
|
|
5108
|
+
if (mode === "default") return {
|
|
5109
|
+
approvalPolicy: "on-request",
|
|
5110
|
+
approvalsReviewer: "auto_review",
|
|
5111
|
+
sandboxMode: "workspace-write"
|
|
5112
|
+
};
|
|
5113
|
+
if (mode === "autonomous") return {
|
|
5114
|
+
approvalPolicy: "never",
|
|
5115
|
+
sandboxMode: "workspace-write"
|
|
5116
|
+
};
|
|
5117
|
+
return {
|
|
5118
|
+
approvalPolicy: "never",
|
|
5119
|
+
sandboxMode: "danger-full-access"
|
|
5120
|
+
};
|
|
5121
|
+
}
|
|
5122
|
+
/** Identifies generated tuples from current and historical installers. */
|
|
5123
|
+
function permissionSelectionMatchesMode(selection, mode) {
|
|
5124
|
+
if (permissionSelectionsEqual(selection, permissionSelectionForMode(mode))) return true;
|
|
5125
|
+
return mode === "default" && permissionSelectionsEqual(selection, {
|
|
5126
|
+
approvalPolicy: "on-request",
|
|
5127
|
+
sandboxMode: "workspace-write"
|
|
5128
|
+
});
|
|
5129
|
+
}
|
|
5130
|
+
/** Compares all raw permission fields, including intentional omissions. */
|
|
5131
|
+
function permissionSelectionsEqual(left, right) {
|
|
5132
|
+
return PERMISSION_KEYS.every((key) => {
|
|
5133
|
+
const field = permissionField(key);
|
|
5134
|
+
return left[field] === right[field];
|
|
5135
|
+
});
|
|
5136
|
+
}
|
|
5137
|
+
/** Identifies a historical generated tuple, if one is exact. */
|
|
5138
|
+
function inferAutonomyMode(selection) {
|
|
5139
|
+
for (const mode of [
|
|
5140
|
+
"default",
|
|
5141
|
+
"autonomous",
|
|
5142
|
+
"dangerous"
|
|
5143
|
+
]) if (permissionSelectionMatchesMode(selection, mode)) return mode;
|
|
5144
|
+
return "custom";
|
|
5145
|
+
}
|
|
5146
|
+
/** Reads deterministic autonomy metadata from a managed block. */
|
|
5147
|
+
function readAutonomyMetadata(input) {
|
|
5148
|
+
const value = new RegExp(`^${escapeRegExp(AUTONOMY_PREFIX)}(.+)$`, "m").exec(input)?.[1]?.trim();
|
|
5149
|
+
if (value === "default" || value === "autonomous" || value === "dangerous" || value === "custom") return value;
|
|
5150
|
+
}
|
|
5151
|
+
/** Encodes durable original root permission assignment provenance. */
|
|
5152
|
+
function originalPermissionMetadata(lines) {
|
|
5153
|
+
return `${ORIGINAL_PERMISSION_PREFIX}${lines.length === 0 ? "-" : Buffer.from(lines.join("\n"), "utf8").toString("base64")}\n`;
|
|
5154
|
+
}
|
|
5155
|
+
/** Reads durable original root permission assignment provenance. */
|
|
5156
|
+
function readOriginalPermissionMetadata(input) {
|
|
5157
|
+
const encoded = new RegExp(`^${escapeRegExp(ORIGINAL_PERMISSION_PREFIX)}([A-Za-z0-9+/=_-]+)$`, "m").exec(input)?.[1];
|
|
5158
|
+
if (encoded === void 0) return void 0;
|
|
5159
|
+
if (encoded === "-") return [];
|
|
5160
|
+
return Buffer.from(encoded, "base64").toString("utf8").split(/\r?\n/).filter(Boolean);
|
|
5161
|
+
}
|
|
5162
|
+
/** Returns a generated tuple for an explicit request or preserves a live omitted selection. */
|
|
5163
|
+
function selectPermissionSelection(live, request) {
|
|
5164
|
+
if (request.requested) return permissionSelectionForMode(request.mode);
|
|
5165
|
+
if (Object.keys(live).length > 0) return live;
|
|
5166
|
+
return permissionSelectionForMode("default");
|
|
5167
|
+
}
|
|
5168
|
+
var AUTONOMY_METADATA_PREFIX = AUTONOMY_PREFIX;
|
|
5169
|
+
function permissionField(key) {
|
|
5170
|
+
if (key === "default_permissions") return "defaultPermissions";
|
|
5171
|
+
if (key === "approval_policy") return "approvalPolicy";
|
|
5172
|
+
if (key === "approvals_reviewer") return "approvalsReviewer";
|
|
5173
|
+
return "sandboxMode";
|
|
5174
|
+
}
|
|
5069
5175
|
function escapeRegExp(value) {
|
|
5070
5176
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5071
5177
|
}
|
|
@@ -5078,7 +5184,6 @@ var ORIGINAL_TABLE_KEY = "# holycodex original table key: ";
|
|
|
5078
5184
|
var PLAN_PREFIX = "# holycodex plan: ";
|
|
5079
5185
|
var FAST_MODE_PREFIX = "# holycodex fast: ";
|
|
5080
5186
|
var MAX_SUBAGENTS_PREFIX = "# holycodex max-subagents: ";
|
|
5081
|
-
var MANAGED_PERMISSION_PROFILE = "holycodex-config";
|
|
5082
5187
|
var OLD_NAMESPACES = [
|
|
5083
5188
|
"marketplaces.sisyphuslabs",
|
|
5084
5189
|
"plugins.\"omo@sisyphuslabs\"",
|
|
@@ -5098,13 +5203,35 @@ var OLD_NAMESPACES = [
|
|
|
5098
5203
|
"hooks.state.\"omo@lazycodex",
|
|
5099
5204
|
"hooks.state.\"omo@code-yeongyu-codex-plugins"
|
|
5100
5205
|
];
|
|
5101
|
-
|
|
5102
|
-
|
|
5206
|
+
function readOriginalRootMetadata(input) {
|
|
5207
|
+
const encoded = input.match(/^# holycodex original root: ([A-Za-z0-9+/=]+)$/m)?.[1];
|
|
5208
|
+
return encoded === void 0 ? void 0 : Buffer.from(encoded, "base64").toString("utf8");
|
|
5209
|
+
}
|
|
5210
|
+
function readLegacyGeneratedRoot(input) {
|
|
5211
|
+
const body = input.match(/^# >>> holycodex managed >>>\r?\n([\s\S]*?)^# <<< holycodex managed <<</m)?.[1];
|
|
5212
|
+
if (body === void 0 || readPermissionLines(body).length === 0) return void 0;
|
|
5213
|
+
return inferAutonomyMode(readRawPermissionSelection(body)) === "custom" ? void 0 : body;
|
|
5214
|
+
}
|
|
5215
|
+
/** Removes managed configuration and restores durable original values. */
|
|
5216
|
+
function removeManaged(input, preserveGeneratedPermissions = false) {
|
|
5103
5217
|
const escapedStart = START.replaceAll(">", "\\>");
|
|
5104
5218
|
const escapedEnd = END.replaceAll("<", "\\<");
|
|
5105
5219
|
return input.replace(new RegExp(`${escapedStart}([\\s\\S]*?)${escapedEnd}(?:\\r?\\n){0,2}`, "g"), (_match, body) => {
|
|
5106
|
-
const
|
|
5107
|
-
|
|
5220
|
+
const original = readOriginalRootMetadata(body);
|
|
5221
|
+
const originalPermissions = readOriginalPermissionMetadata(body);
|
|
5222
|
+
const currentPermissions = readPermissionLines(body);
|
|
5223
|
+
const currentSelection = readRawPermissionSelection(body);
|
|
5224
|
+
const metadata = readAutonomyMetadata(body);
|
|
5225
|
+
const expected = metadata === void 0 || metadata === "custom" ? originalPermissions === void 0 ? void 0 : readRawPermissionSelection(originalPermissions.join("\n")) : permissionSelectionForMode(metadata);
|
|
5226
|
+
const generated = metadata !== void 0 && metadata !== "custom" ? permissionSelectionMatchesMode(currentSelection, metadata) : expected !== void 0 ? permissionSelectionsEqual(currentSelection, expected) : metadata === void 0 && [
|
|
5227
|
+
"default",
|
|
5228
|
+
"autonomous",
|
|
5229
|
+
"dangerous"
|
|
5230
|
+
].some((mode) => permissionSelectionMatchesMode(currentSelection, mode));
|
|
5231
|
+
const preserveCurrent = preserveGeneratedPermissions || !generated;
|
|
5232
|
+
if (original !== void 0) return `${preserveCurrent ? `${removePermissionLines(original)}${currentPermissions.length === 0 ? "" : `\n${currentPermissions.join("\n")}`}`.trim() : `${removePermissionLines(original)}${(originalPermissions ?? readPermissionLines(original)).length === 0 ? "" : `\n${(originalPermissions ?? readPermissionLines(original)).join("\n")}`}`.trim()}\n`;
|
|
5233
|
+
if (!preserveCurrent && originalPermissions !== void 0) return `${originalPermissions.join("\n")}\n`;
|
|
5234
|
+
if (preserveCurrent && currentPermissions.length > 0) return `${currentPermissions.join("\n")}\n`;
|
|
5108
5235
|
const tableKeys = [...body.matchAll(/^# holycodex original table key: ([A-Za-z0-9+/=]+)$/gm)].flatMap((match) => match[1] === void 0 ? [] : [match[1]]);
|
|
5109
5236
|
return tableKeys.length === 0 ? "" : `${tableKeys.map((key) => Buffer.from(key, "base64").toString("utf8")).join("\n")}\n`;
|
|
5110
5237
|
}).trim();
|
|
@@ -5228,10 +5355,25 @@ function mergedStatusLine(original) {
|
|
|
5228
5355
|
}
|
|
5229
5356
|
/** Installs config. */
|
|
5230
5357
|
function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents, fastMode = "standard") {
|
|
5231
|
-
const
|
|
5358
|
+
const request = normalizeRequestedAutonomy(mode);
|
|
5359
|
+
const priorAutonomy = readAutonomyMetadata(input);
|
|
5360
|
+
const previousOriginalRoot = readOriginalRootMetadata(input);
|
|
5361
|
+
const legacyGeneratedRoot = readLegacyGeneratedRoot(input);
|
|
5362
|
+
const originalPermissionLines = readOriginalPermissionMetadata(input);
|
|
5363
|
+
const base = preserveManagedRootPreferences(input, removeLegacyOmo(removeManaged(input, !request.requested)));
|
|
5232
5364
|
const firstTable = base.search(/^\s*\[/m);
|
|
5233
5365
|
const root = firstTable < 0 ? base : base.slice(0, firstTable);
|
|
5234
5366
|
const tables = firstTable < 0 ? "" : base.slice(firstTable);
|
|
5367
|
+
const permissions = selectPermissionSelection(readRawPermissionSelection(root), request);
|
|
5368
|
+
const effectiveAutonomy = request.requested ? inferAutonomyMode(permissions) : priorAutonomy ?? inferAutonomyMode(permissions);
|
|
5369
|
+
const rootPermissionLines = [
|
|
5370
|
+
permissions.approvalPolicy === void 0 ? void 0 : `approval_policy = ${JSON.stringify(permissions.approvalPolicy)}`,
|
|
5371
|
+
permissions.approvalsReviewer === void 0 ? void 0 : `approvals_reviewer = ${JSON.stringify(permissions.approvalsReviewer)}`,
|
|
5372
|
+
permissions.sandboxMode === void 0 ? void 0 : `sandbox_mode = ${JSON.stringify(permissions.sandboxMode)}`
|
|
5373
|
+
].filter((line) => line !== void 0);
|
|
5374
|
+
const hadManagedAutonomy = readAutonomyMetadata(input) !== void 0;
|
|
5375
|
+
const hadOriginalRoot = /^# holycodex original root:/m.test(input);
|
|
5376
|
+
const permissionLines = originalPermissionLines ?? (legacyGeneratedRoot !== void 0 && previousOriginalRoot === void 0 ? [] : previousOriginalRoot === void 0 ? hadManagedAutonomy && !hadOriginalRoot ? [] : readPermissionLines(root) : readPermissionLines(previousOriginalRoot));
|
|
5235
5377
|
const controlled = [
|
|
5236
5378
|
"approval_policy",
|
|
5237
5379
|
"approvals_reviewer",
|
|
@@ -5239,7 +5381,8 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
|
|
|
5239
5381
|
"max_concurrent_threads_per_session",
|
|
5240
5382
|
"status_line",
|
|
5241
5383
|
"model_verbosity",
|
|
5242
|
-
"service_tier"
|
|
5384
|
+
"service_tier",
|
|
5385
|
+
...request.requested ? ["default_permissions"] : []
|
|
5243
5386
|
].map((key) => rootValue(root, key));
|
|
5244
5387
|
const preservedRoot = [
|
|
5245
5388
|
"approval_policy",
|
|
@@ -5248,7 +5391,8 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
|
|
|
5248
5391
|
"max_concurrent_threads_per_session",
|
|
5249
5392
|
"status_line",
|
|
5250
5393
|
"model_verbosity",
|
|
5251
|
-
"service_tier"
|
|
5394
|
+
"service_tier",
|
|
5395
|
+
...request.requested ? ["default_permissions"] : []
|
|
5252
5396
|
].reduce(removeRootKey, root).trim();
|
|
5253
5397
|
const originalControlled = controlled.filter((value) => value !== void 0).sort((left, right) => root.indexOf(left) - root.indexOf(right)).join("\n");
|
|
5254
5398
|
const hasModel = /^\s*model\s*=/m.test(preservedRoot);
|
|
@@ -5257,14 +5401,12 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
|
|
|
5257
5401
|
const effectiveMaxSubagents = maxSubagents ?? MODEL_ROUTING_PLANS[plan].usage.maxSubagents;
|
|
5258
5402
|
const model = hasModel ? "" : `model = "${rootRoute.model}"\n`;
|
|
5259
5403
|
const effort = hasEffort ? "" : `model_reasoning_effort = "${rootRoute.reasoningEffort}"\n`;
|
|
5260
|
-
const
|
|
5261
|
-
const
|
|
5262
|
-
const
|
|
5263
|
-
const
|
|
5264
|
-
const rootBlock = `${START}\n${PLAN_PREFIX}${plan}\n${FAST_MODE_PREFIX}${fastMode}\n${
|
|
5404
|
+
const originalSource = previousOriginalRoot === void 0 ? priorAutonomy === void 0 && legacyGeneratedRoot === void 0 ? originalControlled : "" : removePermissionLines(previousOriginalRoot);
|
|
5405
|
+
const original = originalSource ? `${ORIGINAL_ROOT}${Buffer.from(originalSource).toString("base64")}\n` : "";
|
|
5406
|
+
const maxSubagentsMetadata = maxSubagents === void 0 ? "" : `${MAX_SUBAGENTS_PREFIX}${maxSubagents}\n`;
|
|
5407
|
+
const rootServiceTier = fastMode === "fast-all" ? "fast" : "default";
|
|
5408
|
+
const rootBlock = `${START}\n${PLAN_PREFIX}${plan}\n${FAST_MODE_PREFIX}${fastMode}\n${AUTONOMY_METADATA_PREFIX}${effectiveAutonomy}\n${maxSubagentsMetadata}${original}${originalPermissionMetadata(permissionLines)}${model}${effort}model_verbosity = "low"\nservice_tier = "${rootServiceTier}"\n${rootPermissionLines.join("\n")}\nstatus_line = ${mergedStatusLine(rootValue(root, "status_line"))}\n${END}`;
|
|
5265
5409
|
let configured = `${preservedRoot ? `${preservedRoot}\n` : ""}${rootBlock}${tables ? `\n\n${tables}` : ""}`;
|
|
5266
|
-
configured = injectTableKeys(configured, `permissions.${MANAGED_PERMISSION_PROFILE}`, [["description", "\"HolyCodex config.toml permissions.\""], ["extends", "\":workspace\""]]);
|
|
5267
|
-
configured = injectTableKeys(configured, `permissions.${MANAGED_PERMISSION_PROFILE}.network`, [["enabled", "true"]]);
|
|
5268
5410
|
configured = injectTableKeys(configured, "features", [
|
|
5269
5411
|
["default_mode_request_user_input", "true"],
|
|
5270
5412
|
["multi_agent", "true"],
|
|
@@ -5272,8 +5414,8 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
|
|
|
5272
5414
|
]);
|
|
5273
5415
|
const usage = MODEL_ROUTING_PLANS[plan].usage;
|
|
5274
5416
|
configured = injectTableKeys(configured, "agents", [["max_threads", String(effectiveMaxSubagents + 1)], ["max_depth", String(usage.maxDepth)]]);
|
|
5275
|
-
if (
|
|
5276
|
-
configured = injectTableKeys(configured, "desktop", [["enabled-reasoning-efforts", "[\"low\", \"medium\", \"high\"]"], ["show-context-window-usage", "true"]]);
|
|
5417
|
+
if (effectiveAutonomy !== "dangerous") configured = injectTableKeys(configured, "sandbox_workspace_write", [["network_access", "true"]]);
|
|
5418
|
+
configured = injectTableKeys(configured, "desktop", [["enabled-reasoning-efforts", "[\"low\", \"medium\", \"high\", \"xhigh\", \"max\"]"], ["show-context-window-usage", "true"]]);
|
|
5277
5419
|
if (_platform === "win32") configured = injectTableKeys(configured, "windows", [["sandbox", "\"unelevated\""]]);
|
|
5278
5420
|
for (const agent of AGENTS) configured = injectTableKeys(configured, `agents.${agent}`, [["config_file", `"holycodex/agents/${agent}.toml"`]]);
|
|
5279
5421
|
const plugin = `${START}\n[plugins."holycodex@holycodex"]\nenabled = true\n${END}`;
|
|
@@ -5467,7 +5609,7 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
5467
5609
|
checks.push(preset === void 0 || expectedMaxSubagents === void 0 || tableInteger(config, "agents", "max_threads") !== expectedMaxSubagents + 1 || tableInteger(config, "agents", "max_depth") !== preset.usage.maxDepth ? check("agent-usage", "error", "agent-usage-stale", "Agent concurrency configuration does not match the selected routing plan or explicit override.", "Reinstall HolyCodex.") : check("agent-usage", "ok", "agent-usage-ready", `Agent concurrency allows ${expectedMaxSubagents} direct subagent${expectedMaxSubagents === 1 ? "" : "s"}.`));
|
|
5468
5610
|
checks.push(mode === "unknown" ? check("autonomy", "error", "invalid-autonomy-config", "Approval policy, approval reviewer, sandbox, and network settings do not match a supported mode.", "Rerun install with the intended autonomy flag.") : mode === "dangerous" ? check("autonomy", "warning", "dangerous-autonomy", "Explicit dangerous autonomy is active; workspace containment is removed.") : check("autonomy", "ok", `${mode}-ready`, mode === "safe-workspace" ? "Safe workspace autonomy is active." : "Approval-free workspace autonomy is active."));
|
|
5469
5611
|
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."));
|
|
5470
|
-
checks.push(tableStringArray(config, "desktop", "enabled-reasoning-efforts")?.join(",") === "low,medium,high" ? check("desktop-reasoning", "ok", "desktop-reasoning-ready", "Desktop exposes low
|
|
5612
|
+
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."));
|
|
5471
5613
|
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."));
|
|
5472
5614
|
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."));
|
|
5473
5615
|
const codex = await runtime.command("codex", ["--version"]);
|
|
@@ -5493,60 +5635,264 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
5493
5635
|
};
|
|
5494
5636
|
}
|
|
5495
5637
|
//#endregion
|
|
5638
|
+
//#region packages/cli/src/codex-launcher.ts
|
|
5639
|
+
var CODEX_PACKAGE_SPEC = "@openai/codex@latest";
|
|
5640
|
+
/** Derives safe process facts for the default installation flow. */
|
|
5641
|
+
function defaultCodexLauncherRuntimeFacts(platform = process.platform, env = process.env) {
|
|
5642
|
+
const bun = typeof process.versions.bun === "string";
|
|
5643
|
+
const allowPackageResolution = env.HOLYCODEX_TEST_SKIP_PACKAGE_RESOLUTION !== "1";
|
|
5644
|
+
const npmExecPath = bun ? void 0 : env.npm_execpath;
|
|
5645
|
+
return {
|
|
5646
|
+
allowPackageResolution,
|
|
5647
|
+
platform,
|
|
5648
|
+
execPath: process.execPath,
|
|
5649
|
+
runtime: bun ? "bun" : "node",
|
|
5650
|
+
...npmExecPath === void 0 ? {} : { npmExecPath },
|
|
5651
|
+
availableRunners: ["npm", "pnpm"],
|
|
5652
|
+
npm: platform === "win32" ? "npm.cmd" : "npm",
|
|
5653
|
+
pnpm: platform === "win32" ? "pnpm.cmd" : "pnpm"
|
|
5654
|
+
};
|
|
5655
|
+
}
|
|
5656
|
+
/** Builds ordered Codex launcher candidates once for an installation. */
|
|
5657
|
+
function createCodexLauncherCandidates(input = {}) {
|
|
5658
|
+
const facts = input.runtimeFacts ?? {};
|
|
5659
|
+
const candidates = [];
|
|
5660
|
+
const injected = input.injected === void 0 ? [] : toArray(input.injected);
|
|
5661
|
+
for (const candidate of injected) {
|
|
5662
|
+
const launcher = normalizeLauncher(candidate, "injected");
|
|
5663
|
+
if (launcher !== void 0) candidates.push(launcher);
|
|
5664
|
+
}
|
|
5665
|
+
const pathLauncher = normalizeLauncher(facts.pathCodex ?? "codex", "path");
|
|
5666
|
+
if (pathLauncher !== void 0) candidates.push(pathLauncher);
|
|
5667
|
+
if (facts.allowPackageResolution === false) return deduplicate(candidates);
|
|
5668
|
+
if ((facts.runtime ?? (typeof process.versions.bun === "string" ? "bun" : "node")) === "bun") {
|
|
5669
|
+
const bunLauncher = normalizeLauncher({
|
|
5670
|
+
command: facts.execPath ?? process.execPath,
|
|
5671
|
+
argsPrefix: ["x", CODEX_PACKAGE_SPEC],
|
|
5672
|
+
source: "bunx"
|
|
5673
|
+
}, "bunx");
|
|
5674
|
+
if (bunLauncher !== void 0) candidates.push(bunLauncher);
|
|
5675
|
+
}
|
|
5676
|
+
const nodeRunner = facts.nodeRunner ?? activeNodeRunner(facts);
|
|
5677
|
+
if (nodeRunner !== void 0) {
|
|
5678
|
+
const launcher = normalizeLauncher(nodeRunner, nodeRunnerSource(nodeRunner));
|
|
5679
|
+
if (launcher !== void 0) candidates.push(launcher);
|
|
5680
|
+
}
|
|
5681
|
+
const availableRunners = facts.availableRunners ?? [];
|
|
5682
|
+
if (facts.npm !== false && (facts.npm !== void 0 || availableRunners.includes("npm"))) candidates.push(packageLauncher(facts.npm, facts.platform, "npm-exec"));
|
|
5683
|
+
if (facts.pnpm !== false && (facts.pnpm !== void 0 || availableRunners.includes("pnpm"))) candidates.push(packageLauncher(facts.pnpm, facts.platform, "pnpm-exec"));
|
|
5684
|
+
return deduplicate(candidates);
|
|
5685
|
+
}
|
|
5686
|
+
/** Appends command arguments to a launcher prefix without mutating either array. */
|
|
5687
|
+
function codexLauncherArgs(launcher, args) {
|
|
5688
|
+
return [...launcher.argsPrefix, ...args];
|
|
5689
|
+
}
|
|
5690
|
+
function activeNodeRunner(facts) {
|
|
5691
|
+
if (facts.npmExecPath === void 0 || facts.execPath === void 0) return void 0;
|
|
5692
|
+
const source = packageRunnerSource(facts.npmExecPath);
|
|
5693
|
+
if (source === void 0) return void 0;
|
|
5694
|
+
return {
|
|
5695
|
+
command: facts.execPath,
|
|
5696
|
+
argsPrefix: source === "npm-exec" ? [
|
|
5697
|
+
facts.npmExecPath,
|
|
5698
|
+
"exec",
|
|
5699
|
+
"--yes",
|
|
5700
|
+
"--package",
|
|
5701
|
+
CODEX_PACKAGE_SPEC,
|
|
5702
|
+
"--",
|
|
5703
|
+
"codex"
|
|
5704
|
+
] : [
|
|
5705
|
+
facts.npmExecPath,
|
|
5706
|
+
"dlx",
|
|
5707
|
+
CODEX_PACKAGE_SPEC
|
|
5708
|
+
],
|
|
5709
|
+
source
|
|
5710
|
+
};
|
|
5711
|
+
}
|
|
5712
|
+
function packageRunnerSource(path) {
|
|
5713
|
+
const basename = path.replaceAll("\\", "/").split("/").pop()?.toLowerCase() ?? "";
|
|
5714
|
+
if ([
|
|
5715
|
+
"npm",
|
|
5716
|
+
"npm.cmd",
|
|
5717
|
+
"npm-cli.js",
|
|
5718
|
+
"npm-cli.cjs"
|
|
5719
|
+
].includes(basename)) return "npm-exec";
|
|
5720
|
+
if ([
|
|
5721
|
+
"pnpm",
|
|
5722
|
+
"pnpm.cmd",
|
|
5723
|
+
"pnpm.js",
|
|
5724
|
+
"pnpm.cjs"
|
|
5725
|
+
].includes(basename)) return "pnpm-exec";
|
|
5726
|
+
}
|
|
5727
|
+
function nodeRunnerSource(value) {
|
|
5728
|
+
if (typeof value === "object" && value !== null && "source" in value) {
|
|
5729
|
+
if (value.source === "pnpm-exec") return "pnpm-exec";
|
|
5730
|
+
if (value.source === "npm-exec") return "npm-exec";
|
|
5731
|
+
}
|
|
5732
|
+
return "npm-exec";
|
|
5733
|
+
}
|
|
5734
|
+
function packageLauncher(command, platform, source) {
|
|
5735
|
+
return {
|
|
5736
|
+
command: typeof command === "string" ? command : source === "npm-exec" ? platform === "win32" ? "npm.cmd" : "npm" : platform === "win32" ? "pnpm.cmd" : "pnpm",
|
|
5737
|
+
argsPrefix: source === "npm-exec" ? [
|
|
5738
|
+
"exec",
|
|
5739
|
+
"--yes",
|
|
5740
|
+
"--package",
|
|
5741
|
+
CODEX_PACKAGE_SPEC,
|
|
5742
|
+
"--",
|
|
5743
|
+
"codex"
|
|
5744
|
+
] : ["dlx", CODEX_PACKAGE_SPEC],
|
|
5745
|
+
source
|
|
5746
|
+
};
|
|
5747
|
+
}
|
|
5748
|
+
function toArray(value) {
|
|
5749
|
+
return Array.isArray(value) ? value : [value];
|
|
5750
|
+
}
|
|
5751
|
+
function normalizeLauncher(value, source) {
|
|
5752
|
+
if (typeof value === "string") {
|
|
5753
|
+
const command = value.trim();
|
|
5754
|
+
return command === "" ? void 0 : {
|
|
5755
|
+
command,
|
|
5756
|
+
argsPrefix: [],
|
|
5757
|
+
source
|
|
5758
|
+
};
|
|
5759
|
+
}
|
|
5760
|
+
if (typeof value !== "object" || value === null || typeof value.command !== "string") return void 0;
|
|
5761
|
+
const command = value.command.trim();
|
|
5762
|
+
if (command === "" || !Array.isArray(value.argsPrefix)) return void 0;
|
|
5763
|
+
if (!value.argsPrefix.every((arg) => typeof arg === "string")) return void 0;
|
|
5764
|
+
return {
|
|
5765
|
+
command,
|
|
5766
|
+
argsPrefix: [...value.argsPrefix],
|
|
5767
|
+
source
|
|
5768
|
+
};
|
|
5769
|
+
}
|
|
5770
|
+
function deduplicate(candidates) {
|
|
5771
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5772
|
+
const result = [];
|
|
5773
|
+
for (const candidate of candidates) {
|
|
5774
|
+
const key = JSON.stringify([candidate.command, candidate.argsPrefix]);
|
|
5775
|
+
if (seen.has(key)) continue;
|
|
5776
|
+
seen.add(key);
|
|
5777
|
+
result.push(candidate);
|
|
5778
|
+
}
|
|
5779
|
+
return result;
|
|
5780
|
+
}
|
|
5781
|
+
//#endregion
|
|
5496
5782
|
//#region packages/cli/src/codex-security.ts
|
|
5497
5783
|
var CODEX_SECURITY_PLUGIN = "codex-security@openai-curated";
|
|
5498
|
-
var
|
|
5784
|
+
var CODEX_PLUGIN_OPERATIONAL_TIMEOUT_MS = 15e3;
|
|
5785
|
+
var CODEX_PACKAGE_BOOTSTRAP_TIMEOUT_MS = 12e4;
|
|
5499
5786
|
var MAX_CODEX_OUTPUT_CHARS = 64 * 1024;
|
|
5500
|
-
var
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
var
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5787
|
+
var SPAWN_UNAVAILABLE_CODES = /* @__PURE__ */ new Set([
|
|
5788
|
+
"EACCES",
|
|
5789
|
+
"ENOENT",
|
|
5790
|
+
"EPERM"
|
|
5791
|
+
]);
|
|
5792
|
+
var FATAL_AUTH_CODES = /* @__PURE__ */ new Set([
|
|
5793
|
+
"401",
|
|
5794
|
+
"UNAUTHENTICATED",
|
|
5795
|
+
"AUTHENTICATION_REQUIRED"
|
|
5796
|
+
]);
|
|
5797
|
+
var FATAL_ACCOUNT_CODES = /* @__PURE__ */ new Set(["ACCOUNT_REQUIRED", "ACCOUNT_NOT_FOUND"]);
|
|
5798
|
+
var FATAL_MARKETPLACE_CODES = /* @__PURE__ */ new Set([
|
|
5799
|
+
"502",
|
|
5800
|
+
"503",
|
|
5801
|
+
"504",
|
|
5802
|
+
"MARKETPLACE_UNAVAILABLE",
|
|
5803
|
+
"MARKETPLACE_LOAD_FAILED",
|
|
5804
|
+
"CATALOG_UNAVAILABLE"
|
|
5805
|
+
]);
|
|
5806
|
+
var FATAL_PLUGIN_CODES = /* @__PURE__ */ new Set([
|
|
5807
|
+
"404",
|
|
5808
|
+
"PLUGIN_NOT_FOUND",
|
|
5809
|
+
"PLUGIN_UNAVAILABLE"
|
|
5810
|
+
]);
|
|
5811
|
+
var FATAL_POLICY_CODES = /* @__PURE__ */ new Set([
|
|
5812
|
+
"403",
|
|
5813
|
+
"ACCOUNT_RESTRICTED",
|
|
5814
|
+
"ACCOUNT_UNAVAILABLE",
|
|
5815
|
+
"ACCOUNT_SUSPENDED",
|
|
5816
|
+
"ACCOUNT_DISABLED",
|
|
5817
|
+
"INSTALLATION_REJECTED",
|
|
5818
|
+
"PERMISSION_DENIED",
|
|
5819
|
+
"POLICY_REJECTED"
|
|
5820
|
+
]);
|
|
5510
5821
|
/** Installs or enables the official Codex Security plugin without failing HolyCodex installation. */
|
|
5511
|
-
async function installCodexSecurity(runProcess = runManagedProcess, platform = process.platform, env = process.env) {
|
|
5512
|
-
const
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
const
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
"
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5822
|
+
async function installCodexSecurity(runProcess = runManagedProcess, platform = process.platform, env = process.env, options = {}) {
|
|
5823
|
+
const runtimeFacts = options.runtimeFacts ?? (runProcess === runManagedProcess ? defaultCodexLauncherRuntimeFacts(platform) : void 0);
|
|
5824
|
+
const candidates = createCodexLauncherCandidates({
|
|
5825
|
+
...options.injected === void 0 ? {} : { injected: options.injected },
|
|
5826
|
+
...runtimeFacts === void 0 ? {} : { runtimeFacts }
|
|
5827
|
+
});
|
|
5828
|
+
const attemptedLaunchers = [];
|
|
5829
|
+
const fallbackReasons = [];
|
|
5830
|
+
for (const launcher of candidates) {
|
|
5831
|
+
attemptedLaunchers.push(launcher.source);
|
|
5832
|
+
const listOutcome = inspectListResult(await runCodexPlugin(runProcess, launcher, [
|
|
5833
|
+
"plugin",
|
|
5834
|
+
"list",
|
|
5835
|
+
"--available",
|
|
5836
|
+
"--json"
|
|
5837
|
+
], platform, env, "list"), launcher);
|
|
5838
|
+
if (listOutcome.kind === "fallback") {
|
|
5839
|
+
fallbackReasons.push(listOutcome.reason);
|
|
5840
|
+
continue;
|
|
5841
|
+
}
|
|
5842
|
+
if (listOutcome.kind === "fatal") return skipped(listOutcome.reason, attemptedLaunchers);
|
|
5843
|
+
const plugin = listOutcome.catalog.plugins.find(({ id }) => id === CODEX_SECURITY_PLUGIN);
|
|
5844
|
+
if (plugin?.installed === true && plugin.enabled === true) return {
|
|
5845
|
+
status: "already-installed",
|
|
5846
|
+
launcherSource: launcher.source
|
|
5847
|
+
};
|
|
5848
|
+
const wasDisabled = plugin?.installed === true;
|
|
5849
|
+
const addOutcome = inspectAddResult(await runCodexPlugin(runProcess, launcher, [
|
|
5850
|
+
"plugin",
|
|
5851
|
+
"add",
|
|
5852
|
+
CODEX_SECURITY_PLUGIN,
|
|
5853
|
+
"--json"
|
|
5854
|
+
], platform, env, "add"), launcher);
|
|
5855
|
+
if (addOutcome.kind === "fallback") {
|
|
5856
|
+
fallbackReasons.push(addOutcome.reason);
|
|
5857
|
+
continue;
|
|
5858
|
+
}
|
|
5859
|
+
if (addOutcome.kind === "fatal") return skipped(addOutcome.reason, attemptedLaunchers);
|
|
5860
|
+
const verification = inspectListResult(await runCodexPlugin(runProcess, launcher, [
|
|
5861
|
+
"plugin",
|
|
5862
|
+
"list",
|
|
5863
|
+
"--available",
|
|
5864
|
+
"--json"
|
|
5865
|
+
], platform, env, "list"), launcher);
|
|
5866
|
+
if (verification.kind === "fallback") {
|
|
5867
|
+
fallbackReasons.push(verification.reason);
|
|
5868
|
+
continue;
|
|
5869
|
+
}
|
|
5870
|
+
if (verification.kind === "fatal") return skipped(verification.reason, attemptedLaunchers);
|
|
5871
|
+
const verifiedPlugin = verification.catalog.plugins.find(({ id }) => id === CODEX_SECURITY_PLUGIN);
|
|
5872
|
+
if (verifiedPlugin?.installed !== true || verifiedPlugin.enabled !== true) {
|
|
5873
|
+
fallbackReasons.push("plugin-unavailable");
|
|
5874
|
+
continue;
|
|
5875
|
+
}
|
|
5876
|
+
return {
|
|
5877
|
+
status: wasDisabled ? "enabled" : "installed",
|
|
5878
|
+
launcherSource: launcher.source
|
|
5879
|
+
};
|
|
5880
|
+
}
|
|
5881
|
+
return skipped(finalFallbackReason(fallbackReasons), attemptedLaunchers);
|
|
5882
|
+
}
|
|
5883
|
+
async function runCodexPlugin(runProcess, launcher, args, platform, env, operation) {
|
|
5539
5884
|
try {
|
|
5540
5885
|
return await runProcess({
|
|
5541
|
-
command:
|
|
5542
|
-
args,
|
|
5886
|
+
command: launcher.command,
|
|
5887
|
+
args: codexLauncherArgs(launcher, args),
|
|
5543
5888
|
platform,
|
|
5544
|
-
timeoutMs:
|
|
5889
|
+
timeoutMs: timeoutFor(launcher, operation),
|
|
5545
5890
|
maxOutputChars: MAX_CODEX_OUTPUT_CHARS,
|
|
5546
5891
|
env
|
|
5547
5892
|
});
|
|
5548
5893
|
} catch (error) {
|
|
5549
|
-
|
|
5894
|
+
const code = thrownErrorCode(error);
|
|
5895
|
+
if (!isUnavailableThrownError(error) && !(isPackageLauncher(launcher) && isBootstrapThrownError(error))) throw error;
|
|
5550
5896
|
return {
|
|
5551
5897
|
exitCode: null,
|
|
5552
5898
|
stdout: "",
|
|
@@ -5554,69 +5900,213 @@ async function runCodexPlugin(runProcess, args, platform, env) {
|
|
|
5554
5900
|
timedOut: false,
|
|
5555
5901
|
matched: false,
|
|
5556
5902
|
outputTruncated: false,
|
|
5557
|
-
error: "Codex
|
|
5903
|
+
error: "Codex launcher could not be started.",
|
|
5904
|
+
...code === void 0 ? {} : { errorCode: code }
|
|
5558
5905
|
};
|
|
5559
5906
|
}
|
|
5560
5907
|
}
|
|
5561
|
-
function
|
|
5562
|
-
if (result.timedOut) return
|
|
5563
|
-
|
|
5908
|
+
function inspectListResult(result, launcher) {
|
|
5909
|
+
if (result.timedOut) return {
|
|
5910
|
+
kind: "fallback",
|
|
5911
|
+
reason: "timeout"
|
|
5912
|
+
};
|
|
5913
|
+
const failure = classifyFailure(result, launcher);
|
|
5914
|
+
if (failure !== void 0) return failure;
|
|
5915
|
+
const catalog = parsePluginCatalog(result.stdout);
|
|
5916
|
+
if (catalog === void 0) return {
|
|
5917
|
+
kind: "fallback",
|
|
5918
|
+
reason: "invalid-response"
|
|
5919
|
+
};
|
|
5920
|
+
return {
|
|
5921
|
+
kind: "selected",
|
|
5922
|
+
catalog
|
|
5923
|
+
};
|
|
5924
|
+
}
|
|
5925
|
+
function inspectAddResult(result, launcher) {
|
|
5926
|
+
if (result.timedOut) return {
|
|
5927
|
+
kind: "fallback",
|
|
5928
|
+
reason: "timeout"
|
|
5929
|
+
};
|
|
5930
|
+
const failure = classifyFailure(result, launcher);
|
|
5931
|
+
if (failure !== void 0) return failure;
|
|
5932
|
+
if (!isRecord(parseUnknownJson(result.stdout))) return {
|
|
5933
|
+
kind: "fallback",
|
|
5934
|
+
reason: "invalid-response"
|
|
5935
|
+
};
|
|
5936
|
+
return { kind: "added" };
|
|
5937
|
+
}
|
|
5938
|
+
function classifyFailure(result, launcher) {
|
|
5939
|
+
if (result.error !== void 0) {
|
|
5940
|
+
if (isUnavailableProcessError(result)) return {
|
|
5941
|
+
kind: "fallback",
|
|
5942
|
+
reason: "codex-unavailable"
|
|
5943
|
+
};
|
|
5944
|
+
return {
|
|
5945
|
+
kind: "fallback",
|
|
5946
|
+
reason: isPackageLauncher(launcher) ? "download-failed" : "invalid-response"
|
|
5947
|
+
};
|
|
5948
|
+
}
|
|
5564
5949
|
if (result.exitCode === 0) return void 0;
|
|
5565
|
-
const
|
|
5566
|
-
if (
|
|
5567
|
-
|
|
5950
|
+
const failureReason = classifyFailureReason(structuredErrorCode(parseUnknownJson(result.stderr) ?? parseUnknownJson(result.stdout)), sanitizeDiagnostic(result.stderr));
|
|
5951
|
+
if (failureReason === "unauthenticated" || failureReason === "installation-rejected") return {
|
|
5952
|
+
kind: "fatal",
|
|
5953
|
+
reason: failureReason
|
|
5954
|
+
};
|
|
5955
|
+
return {
|
|
5956
|
+
kind: "fallback",
|
|
5957
|
+
reason: failureReason
|
|
5958
|
+
};
|
|
5568
5959
|
}
|
|
5569
|
-
function
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
"
|
|
5574
|
-
"
|
|
5575
|
-
"
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
"
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
if (
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
if (
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
"PERMISSION_DENIED",
|
|
5594
|
-
"POLICY_REJECTED",
|
|
5595
|
-
"ACCOUNT_RESTRICTED"
|
|
5596
|
-
].includes(code)) return "installation-rejected";
|
|
5960
|
+
function classifyFailureReason(code, diagnostic) {
|
|
5961
|
+
if (code !== void 0) {
|
|
5962
|
+
if (FATAL_AUTH_CODES.has(code) || FATAL_ACCOUNT_CODES.has(code)) return "unauthenticated";
|
|
5963
|
+
if (FATAL_MARKETPLACE_CODES.has(code)) return "marketplace-unavailable";
|
|
5964
|
+
if (FATAL_PLUGIN_CODES.has(code)) return "plugin-unavailable";
|
|
5965
|
+
if (FATAL_POLICY_CODES.has(code)) return "installation-rejected";
|
|
5966
|
+
if (SPAWN_UNAVAILABLE_CODES.has(code)) return "codex-unavailable";
|
|
5967
|
+
if ([
|
|
5968
|
+
"ETIMEDOUT",
|
|
5969
|
+
"ECONNRESET",
|
|
5970
|
+
"ECONNREFUSED",
|
|
5971
|
+
"EAI_AGAIN",
|
|
5972
|
+
"ENETUNREACH"
|
|
5973
|
+
].includes(code)) return "download-failed";
|
|
5974
|
+
}
|
|
5975
|
+
const lower = diagnostic.toLowerCase();
|
|
5976
|
+
if (/unknown (?:command|subcommand)|unrecognized (?:command|subcommand)|invalid subcommand/.test(lower)) return "unsupported";
|
|
5977
|
+
if (/not supported on (?:this )?platform|unsupported (?:platform|architecture)|no matching (?:binary|package)|platform package|not compatible/.test(lower)) return "unsupported";
|
|
5978
|
+
if (/unauthenticated|authentication required|not logged in|account (?:required|not found)/.test(lower)) return "unauthenticated";
|
|
5979
|
+
if (/account (?:restricted|unavailable|suspended|disabled)/.test(lower)) return "installation-rejected";
|
|
5980
|
+
if (/marketplace|catalog/.test(lower)) return "marketplace-unavailable";
|
|
5981
|
+
if (/eai_again|enetwork|network|timed out|timeout|download|fetch|resolve package/.test(lower)) return "download-failed";
|
|
5982
|
+
if (/plugin (?:not found|unavailable|missing)/.test(lower)) return "plugin-unavailable";
|
|
5983
|
+
if (/permission denied|policy|rejected|forbidden/.test(lower)) return "installation-rejected";
|
|
5597
5984
|
return "invalid-response";
|
|
5598
5985
|
}
|
|
5599
|
-
function
|
|
5986
|
+
function finalFallbackReason(reasons) {
|
|
5987
|
+
if (reasons.includes("timeout")) return "timeout";
|
|
5988
|
+
if (reasons.includes("unsupported")) return "unsupported";
|
|
5989
|
+
if (reasons.includes("download-failed")) return "download-failed";
|
|
5990
|
+
if (reasons.includes("marketplace-unavailable")) return "marketplace-unavailable";
|
|
5991
|
+
if (reasons.includes("plugin-unavailable")) return "plugin-unavailable";
|
|
5992
|
+
if (reasons.includes("invalid-response")) return "invalid-response";
|
|
5993
|
+
return "codex-unavailable";
|
|
5994
|
+
}
|
|
5995
|
+
function timeoutFor(launcher, operation) {
|
|
5996
|
+
return operation === "list" && isPackageLauncher(launcher) ? CODEX_PACKAGE_BOOTSTRAP_TIMEOUT_MS : CODEX_PLUGIN_OPERATIONAL_TIMEOUT_MS;
|
|
5997
|
+
}
|
|
5998
|
+
function isPackageLauncher(launcher) {
|
|
5999
|
+
return launcher.source === "bunx" || launcher.source === "npm-exec" || launcher.source === "pnpm-exec";
|
|
6000
|
+
}
|
|
6001
|
+
/** Normalizes supported flat and marketplace-oriented Codex catalogs. */
|
|
6002
|
+
function parsePluginCatalog(input) {
|
|
6003
|
+
const value = parseUnknownJson(input);
|
|
6004
|
+
if (value === void 0) return void 0;
|
|
6005
|
+
const plugins = parseCatalogValue(value);
|
|
6006
|
+
return plugins === void 0 ? void 0 : { plugins };
|
|
6007
|
+
}
|
|
6008
|
+
function parseCatalogValue(value) {
|
|
6009
|
+
if (Array.isArray(value)) return parseMarketplaceEntries(value);
|
|
5600
6010
|
if (!isRecord(value)) return void 0;
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
const
|
|
5604
|
-
|
|
6011
|
+
if ("installed" in value || "available" in value) {
|
|
6012
|
+
if (!Array.isArray(value.installed) || !Array.isArray(value.available)) return void 0;
|
|
6013
|
+
const installed = parsePluginEntries(value.installed, void 0, true);
|
|
6014
|
+
const available = parsePluginEntries(value.available, void 0, false);
|
|
6015
|
+
return installed === void 0 || available === void 0 ? void 0 : [...installed, ...available];
|
|
5605
6016
|
}
|
|
5606
|
-
|
|
5607
|
-
|
|
6017
|
+
if ("marketplaces" in value) return Array.isArray(value.marketplaces) ? parseMarketplaceEntries(value.marketplaces) : void 0;
|
|
6018
|
+
if ("plugins" in value) return parseMarketplaceEntry(value);
|
|
6019
|
+
}
|
|
6020
|
+
function parseMarketplaceEntries(entries) {
|
|
6021
|
+
const plugins = [];
|
|
6022
|
+
for (const entry of entries) {
|
|
6023
|
+
const parsed = parseMarketplaceEntry(entry);
|
|
6024
|
+
if (parsed === void 0) return void 0;
|
|
6025
|
+
plugins.push(...parsed);
|
|
6026
|
+
}
|
|
6027
|
+
return plugins;
|
|
6028
|
+
}
|
|
6029
|
+
function parseMarketplaceEntry(value) {
|
|
6030
|
+
if (!isRecord(value) || !Array.isArray(value.plugins)) return void 0;
|
|
6031
|
+
const marketplace = stringField(value, [
|
|
6032
|
+
"marketplace",
|
|
6033
|
+
"marketplaceId",
|
|
6034
|
+
"marketplaceName",
|
|
6035
|
+
"id",
|
|
6036
|
+
"name"
|
|
6037
|
+
]);
|
|
6038
|
+
if (marketplace === void 0) return void 0;
|
|
6039
|
+
return parsePluginEntries(value.plugins, marketplace);
|
|
6040
|
+
}
|
|
6041
|
+
function parsePluginEntries(entries, parentMarketplace, defaultInstalled) {
|
|
6042
|
+
const plugins = [];
|
|
6043
|
+
for (const value of entries) {
|
|
6044
|
+
const plugin = parsePluginEntry(value, parentMarketplace, defaultInstalled);
|
|
6045
|
+
if (plugin === void 0) return void 0;
|
|
6046
|
+
plugins.push(plugin);
|
|
6047
|
+
}
|
|
6048
|
+
return plugins;
|
|
6049
|
+
}
|
|
6050
|
+
function parsePluginEntry(value, parentMarketplace, defaultInstalled = false) {
|
|
6051
|
+
if (!isRecord(value)) return void 0;
|
|
6052
|
+
const rawId = stringField(value, [
|
|
6053
|
+
"pluginId",
|
|
6054
|
+
"id",
|
|
6055
|
+
"name"
|
|
6056
|
+
]);
|
|
6057
|
+
if (rawId === void 0) return void 0;
|
|
6058
|
+
const marketplace = stringField(value, [
|
|
6059
|
+
"marketplace",
|
|
6060
|
+
"marketplaceId",
|
|
6061
|
+
"marketplaceName"
|
|
6062
|
+
]) ?? parentMarketplace;
|
|
6063
|
+
const id = rawId.includes("@") ? rawId : marketplace === void 0 ? rawId : `${rawId}@${marketplace}`;
|
|
6064
|
+
const state = stringField(value, [
|
|
6065
|
+
"installationState",
|
|
6066
|
+
"installState",
|
|
5608
6067
|
"status",
|
|
5609
|
-
"
|
|
5610
|
-
])
|
|
6068
|
+
"state"
|
|
6069
|
+
]);
|
|
6070
|
+
const policy = isRecord(value.policy) ? stringField(value.policy, ["installation"]) : void 0;
|
|
6071
|
+
return {
|
|
6072
|
+
id,
|
|
6073
|
+
installed: booleanField(value.installed) ?? installedFromState(state ?? policy) ?? defaultInstalled,
|
|
6074
|
+
enabled: booleanField(value.enabled) ?? enabledFromState(state) ?? false
|
|
6075
|
+
};
|
|
6076
|
+
}
|
|
6077
|
+
function stringField(value, keys) {
|
|
6078
|
+
for (const key of keys) {
|
|
5611
6079
|
const candidate = value[key];
|
|
5612
|
-
if (typeof candidate === "string"
|
|
6080
|
+
if (typeof candidate === "string" && candidate.trim() !== "") return candidate.trim();
|
|
5613
6081
|
}
|
|
5614
6082
|
}
|
|
5615
|
-
function
|
|
5616
|
-
|
|
6083
|
+
function booleanField(value) {
|
|
6084
|
+
if (typeof value === "boolean") return value;
|
|
6085
|
+
if (typeof value !== "string") return void 0;
|
|
6086
|
+
if (value.toLowerCase() === "true") return true;
|
|
6087
|
+
if (value.toLowerCase() === "false") return false;
|
|
6088
|
+
}
|
|
6089
|
+
function installedFromState(value) {
|
|
6090
|
+
if (value === void 0) return void 0;
|
|
6091
|
+
const state = value.toLowerCase().replaceAll("-", "_");
|
|
6092
|
+
if ([
|
|
6093
|
+
"installed",
|
|
6094
|
+
"enabled",
|
|
6095
|
+
"disabled",
|
|
6096
|
+
"installed_by_default"
|
|
6097
|
+
].includes(state)) return true;
|
|
6098
|
+
if ([
|
|
6099
|
+
"available",
|
|
6100
|
+
"not_installed",
|
|
6101
|
+
"uninstalled",
|
|
6102
|
+
"not_available"
|
|
6103
|
+
].includes(state)) return false;
|
|
6104
|
+
}
|
|
6105
|
+
function enabledFromState(value) {
|
|
5617
6106
|
if (value === void 0) return void 0;
|
|
5618
|
-
const
|
|
5619
|
-
|
|
6107
|
+
const state = value.toLowerCase();
|
|
6108
|
+
if (state === "enabled") return true;
|
|
6109
|
+
if (state === "disabled") return false;
|
|
5620
6110
|
}
|
|
5621
6111
|
function parseUnknownJson(input) {
|
|
5622
6112
|
try {
|
|
@@ -5625,21 +6115,58 @@ function parseUnknownJson(input) {
|
|
|
5625
6115
|
return;
|
|
5626
6116
|
}
|
|
5627
6117
|
}
|
|
6118
|
+
function structuredErrorCode(value) {
|
|
6119
|
+
if (!isRecord(value)) return void 0;
|
|
6120
|
+
if (value.error !== void 0) {
|
|
6121
|
+
const nestedCode = structuredErrorCode(value.error);
|
|
6122
|
+
if (nestedCode !== void 0) return nestedCode;
|
|
6123
|
+
}
|
|
6124
|
+
for (const key of [
|
|
6125
|
+
"code",
|
|
6126
|
+
"status",
|
|
6127
|
+
"statusCode"
|
|
6128
|
+
]) {
|
|
6129
|
+
const candidate = value[key];
|
|
6130
|
+
if (typeof candidate === "string" || typeof candidate === "number") return String(candidate).trim().toUpperCase();
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
6133
|
+
function sanitizeDiagnostic(input) {
|
|
6134
|
+
return input.replaceAll(/(?:[A-Za-z]:)?[\\/][^\s"']+/g, "<path>").replaceAll(/(token|secret|password|authorization)\s*[:=]\s*[^\s,}]+/gi, "$1=<redacted>").slice(0, 2048);
|
|
6135
|
+
}
|
|
5628
6136
|
function isRecord(value) {
|
|
5629
6137
|
return typeof value === "object" && value !== null;
|
|
5630
6138
|
}
|
|
5631
|
-
function isUnavailableProcessError(
|
|
5632
|
-
if (
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
6139
|
+
function isUnavailableProcessError(result) {
|
|
6140
|
+
if (result.errorCode !== void 0 && SPAWN_UNAVAILABLE_CODES.has(result.errorCode.toUpperCase())) return true;
|
|
6141
|
+
const error = result.error?.toUpperCase() ?? "";
|
|
6142
|
+
return [...SPAWN_UNAVAILABLE_CODES].some((code) => new RegExp(`(?:^|\\s)${code}(?:$|\\s)`).test(error));
|
|
6143
|
+
}
|
|
6144
|
+
function isUnavailableThrownError(value) {
|
|
6145
|
+
const code = thrownErrorCode(value);
|
|
6146
|
+
return code !== void 0 && SPAWN_UNAVAILABLE_CODES.has(code.toUpperCase());
|
|
6147
|
+
}
|
|
6148
|
+
function isBootstrapThrownError(value) {
|
|
6149
|
+
const code = thrownErrorCode(value)?.toUpperCase();
|
|
6150
|
+
if (code !== void 0 && [
|
|
6151
|
+
"ETIMEDOUT",
|
|
6152
|
+
"ECONNRESET",
|
|
6153
|
+
"ECONNREFUSED",
|
|
6154
|
+
"EAI_AGAIN",
|
|
6155
|
+
"ENETUNREACH"
|
|
6156
|
+
].includes(code)) return true;
|
|
6157
|
+
if (!(value instanceof Error)) return false;
|
|
6158
|
+
return /bootstrap|network|download|fetch|timeout|timed out/i.test(value.message);
|
|
6159
|
+
}
|
|
6160
|
+
function thrownErrorCode(value) {
|
|
6161
|
+
if (typeof value !== "object" || value === null || !("code" in value)) return void 0;
|
|
6162
|
+
const code = value.code;
|
|
6163
|
+
return typeof code === "string" ? code : void 0;
|
|
6164
|
+
}
|
|
6165
|
+
function skipped(reason, attemptedLaunchers) {
|
|
5640
6166
|
return {
|
|
5641
6167
|
status: "skipped",
|
|
5642
|
-
reason
|
|
6168
|
+
reason,
|
|
6169
|
+
attemptedLaunchers: [...attemptedLaunchers]
|
|
5643
6170
|
};
|
|
5644
6171
|
}
|
|
5645
6172
|
//#endregion
|
|
@@ -5778,6 +6305,7 @@ var AGENT_MANAGED_KEYS = /* @__PURE__ */ new Set([
|
|
|
5778
6305
|
"service_tier"
|
|
5779
6306
|
]);
|
|
5780
6307
|
var AGENT_BUNDLED_KEYS = /* @__PURE__ */ new Set(["description", "developer_instructions"]);
|
|
6308
|
+
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;
|
|
5781
6309
|
async function readAgentPreferences(root, previousPlan) {
|
|
5782
6310
|
const preferences = {};
|
|
5783
6311
|
await Promise.all(AGENTS.map(async (agent) => {
|
|
@@ -5859,7 +6387,7 @@ async function writeInstalledAgents(root, platform, plan, fastMode) {
|
|
|
5859
6387
|
await atomicWrite(path, source);
|
|
5860
6388
|
return;
|
|
5861
6389
|
}
|
|
5862
|
-
await atomicWrite(path, source.replace(`${WINDOWS_SHELL_POLICY}\r\n\r\n`, "").replace(`${WINDOWS_SHELL_POLICY}\n\n`, ""));
|
|
6390
|
+
await atomicWrite(path, source.replace(`${WINDOWS_SHELL_POLICY}\r\n\r\n`, "").replace(`${WINDOWS_SHELL_POLICY}\n\n`, "").replace(COMPACT_WINDOWS_SHELL_POLICY, ""));
|
|
5863
6391
|
}));
|
|
5864
6392
|
}
|
|
5865
6393
|
/** Provides cleanup. */
|
|
@@ -5958,8 +6486,19 @@ function renderCodexSecurity(result) {
|
|
|
5958
6486
|
if (result.codexSecurity.status === "installed") return "\n Installed official Codex Security plugin.";
|
|
5959
6487
|
if (result.codexSecurity.status === "enabled") return "\n Enabled existing official Codex Security plugin.";
|
|
5960
6488
|
if (result.codexSecurity.status === "already-installed") return "\n Official Codex Security plugin is already installed and enabled.";
|
|
5961
|
-
return `\n Skipped official Codex Security plugin: ${result.codexSecurity.reason}
|
|
5962
|
-
}
|
|
6489
|
+
return `\n Skipped official Codex Security plugin: ${CODEX_SECURITY_SKIP_MESSAGES[result.codexSecurity.reason]}`;
|
|
6490
|
+
}
|
|
6491
|
+
var CODEX_SECURITY_SKIP_MESSAGES = {
|
|
6492
|
+
"codex-unavailable": "no usable Codex launcher was found.",
|
|
6493
|
+
unauthenticated: "Codex authentication is required.",
|
|
6494
|
+
"marketplace-unavailable": "the plugin marketplace could not be reached.",
|
|
6495
|
+
"plugin-unavailable": "the plugin was unavailable from every usable Codex launcher.",
|
|
6496
|
+
"installation-rejected": "the account or workspace policy rejected installation.",
|
|
6497
|
+
timeout: "all usable Codex launchers timed out.",
|
|
6498
|
+
"invalid-response": "Codex returned an unsupported or malformed response.",
|
|
6499
|
+
unsupported: "the available Codex launchers do not support plugin installation.",
|
|
6500
|
+
"download-failed": "the latest Codex package could not be downloaded."
|
|
6501
|
+
};
|
|
5963
6502
|
/** Renders notice. */
|
|
5964
6503
|
function renderNotice(kind, message, color) {
|
|
5965
6504
|
return `${paint(color, kind === "warning" ? RED : YELLOW, `! ${kind === "warning" ? "WARNING" : "NOTICE"}`)} ${message}\n`;
|
|
@@ -6012,8 +6551,18 @@ async function main() {
|
|
|
6012
6551
|
process$1.exitCode = 1;
|
|
6013
6552
|
return;
|
|
6014
6553
|
}
|
|
6554
|
+
const autonomy = args.includes("--dangerous-codex-autonomous") ? {
|
|
6555
|
+
requested: true,
|
|
6556
|
+
mode: "dangerous"
|
|
6557
|
+
} : args.includes("--codex-autonomous") ? {
|
|
6558
|
+
requested: true,
|
|
6559
|
+
mode: "autonomous"
|
|
6560
|
+
} : args.includes("--no-codex-autonomous") ? {
|
|
6561
|
+
requested: true,
|
|
6562
|
+
mode: "default"
|
|
6563
|
+
} : { requested: false };
|
|
6015
6564
|
const options = {
|
|
6016
|
-
autonomy
|
|
6565
|
+
autonomy,
|
|
6017
6566
|
json: args.includes("--json"),
|
|
6018
6567
|
fast: args.includes("--fast-all") ? "fast-all" : args.includes("--fast") ? "fast" : "standard",
|
|
6019
6568
|
plan,
|
|
@@ -6025,7 +6574,7 @@ async function main() {
|
|
|
6025
6574
|
if (!result.healthy) process$1.exitCode = 1;
|
|
6026
6575
|
return;
|
|
6027
6576
|
}
|
|
6028
|
-
if (
|
|
6577
|
+
if (autonomy.requested && autonomy.mode === "dangerous") process$1.stderr.write(renderNotice("warning", "Dangerous autonomy disables approvals and filesystem sandboxing.", stderrColor));
|
|
6029
6578
|
const result = command === "install" ? await install(options) : command === "cleanup" ? await cleanup(options) : void 0;
|
|
6030
6579
|
if (result === void 0) {
|
|
6031
6580
|
process$1.stderr.write(renderError(`Unknown command: ${command ?? args[0] ?? ""}`, stderrColor));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "holycodex",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.6-dev.30770925419.1",
|
|
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.10.
|
|
42
|
+
"@holycodex/plugin": "0.10.6-dev.30770925419.1",
|
|
43
43
|
"zod": "^4.4.3"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|