holycodex 0.7.0-dev.29549907491.1 → 0.7.0-dev.29581464491.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/dist/cli.js +97 -40
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { existsSync } from "node:fs";
|
|
|
7
7
|
import { pluginRoot } from "@holycodex/plugin";
|
|
8
8
|
import { Buffer } from "node:buffer";
|
|
9
9
|
//#region packages/cli/src/catalog.ts
|
|
10
|
-
var VERSION = "0.7.0-dev.
|
|
10
|
+
var VERSION = "0.7.0-dev.29581464491.1";
|
|
11
11
|
var SKILLS = [
|
|
12
12
|
"ast-grep",
|
|
13
13
|
"caveman",
|
|
@@ -97,7 +97,7 @@ function effectiveMcpServers(platform) {
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
function requiredPackageRuntimes(platform) {
|
|
100
|
-
return platform === "win32" ? GENERATED_RUNTIMES : GENERATED_RUNTIMES.filter((file) => file !== "git-bash.js"
|
|
100
|
+
return platform === "win32" ? GENERATED_RUNTIMES : GENERATED_RUNTIMES.filter((file) => file !== "git-bash.js");
|
|
101
101
|
}
|
|
102
102
|
//#endregion
|
|
103
103
|
//#region packages/git-bash-mcp/src/git-bash-resolver.ts
|
|
@@ -316,6 +316,69 @@ function rootTomlString(input, key) {
|
|
|
316
316
|
return;
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
|
+
function rootTomlStringArray(input, key) {
|
|
320
|
+
return parseRootTomlStringArray(input, key)?.items;
|
|
321
|
+
}
|
|
322
|
+
function rootTomlStringArraySource(input, key) {
|
|
323
|
+
return parseRootTomlStringArray(input, key)?.source;
|
|
324
|
+
}
|
|
325
|
+
function parseRootTomlStringArray(input, key) {
|
|
326
|
+
const table = TOML_TABLE.exec(input);
|
|
327
|
+
const root = table === null ? input : input.slice(0, table.index);
|
|
328
|
+
const assignment = new RegExp(String.raw`^[ \t]*${escapeRegExp(key)}[ \t]*=`, "m").exec(root);
|
|
329
|
+
if (assignment === null) return void 0;
|
|
330
|
+
const start = root.indexOf("[", assignment.index + assignment[0].length);
|
|
331
|
+
if (start < 0) return void 0;
|
|
332
|
+
const items = [];
|
|
333
|
+
let quote;
|
|
334
|
+
let raw = "";
|
|
335
|
+
let escaped = false;
|
|
336
|
+
let comment = false;
|
|
337
|
+
for (let index = start + 1; index < root.length; index += 1) {
|
|
338
|
+
const character = root[index];
|
|
339
|
+
if (comment) {
|
|
340
|
+
if (character === "\n") comment = false;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
if (quote === "\"") {
|
|
344
|
+
if (escaped) {
|
|
345
|
+
raw += character;
|
|
346
|
+
escaped = false;
|
|
347
|
+
} else if (character === "\\") {
|
|
348
|
+
raw += character;
|
|
349
|
+
escaped = true;
|
|
350
|
+
} else if (character === "\"") {
|
|
351
|
+
try {
|
|
352
|
+
const parsed = JSON.parse(`"${raw}"`);
|
|
353
|
+
if (typeof parsed !== "string") return void 0;
|
|
354
|
+
items.push(parsed);
|
|
355
|
+
} catch {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
quote = void 0;
|
|
359
|
+
raw = "";
|
|
360
|
+
} else raw += character;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (quote === "'") {
|
|
364
|
+
if (character === "'") {
|
|
365
|
+
items.push(raw);
|
|
366
|
+
quote = void 0;
|
|
367
|
+
raw = "";
|
|
368
|
+
} else raw += character;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
if (character === "#") comment = true;
|
|
372
|
+
else if (character === "\"" || character === "'") quote = character;
|
|
373
|
+
else if (character === "]") {
|
|
374
|
+
const suffix = /^[ \t]*(?:#.*)?(?=\r?\n|$)/.exec(root.slice(index + 1))?.[0] ?? "";
|
|
375
|
+
return {
|
|
376
|
+
source: root.slice(assignment.index, index + 1 + suffix.length),
|
|
377
|
+
items
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
319
382
|
function escapeRegExp(value) {
|
|
320
383
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
321
384
|
}
|
|
@@ -358,7 +421,8 @@ async function startContext7(platform) {
|
|
|
358
421
|
});
|
|
359
422
|
const diagnostic = `${result.stdout}\n${result.stderr}`.trim() || result.error || "";
|
|
360
423
|
return {
|
|
361
|
-
ok: result.matched,
|
|
424
|
+
ok: result.matched && !result.timedOut,
|
|
425
|
+
timedOut: result.timedOut,
|
|
362
426
|
packageFailure: /(?:404|failed to resolve|package.*not found|error: GET)/i.test(diagnostic),
|
|
363
427
|
detail: diagnostic
|
|
364
428
|
};
|
|
@@ -378,6 +442,14 @@ function check(id, status, code, detail, fix) {
|
|
|
378
442
|
...fix === void 0 ? {} : { fix }
|
|
379
443
|
};
|
|
380
444
|
}
|
|
445
|
+
function mcpConfigMatches(actual, expected) {
|
|
446
|
+
const expectedEntries = Object.entries(expected);
|
|
447
|
+
if (Object.keys(actual).length !== expectedEntries.length) return false;
|
|
448
|
+
return expectedEntries.every(([key, expectedValue]) => {
|
|
449
|
+
const actualValue = actual[key];
|
|
450
|
+
return Array.isArray(expectedValue) ? Array.isArray(actualValue) && actualValue.length === expectedValue.length && actualValue.every((value, index) => value === expectedValue[index]) : actualValue === expectedValue;
|
|
451
|
+
});
|
|
452
|
+
}
|
|
381
453
|
async function missingFiles(root, paths) {
|
|
382
454
|
const missing = [];
|
|
383
455
|
for (const path of paths) try {
|
|
@@ -424,13 +496,19 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
424
496
|
}
|
|
425
497
|
const servers = mcp?.mcpServers;
|
|
426
498
|
const requiredMcps = runtime.platform === "win32" ? ["git_bash", "lsp"] : ["lsp"];
|
|
427
|
-
|
|
499
|
+
const expectedMcps = effectiveMcpServers(runtime.platform);
|
|
500
|
+
for (const name of requiredMcps) {
|
|
501
|
+
const configured = servers?.[name];
|
|
502
|
+
const expected = expectedMcps[name];
|
|
503
|
+
checks.push(configured === void 0 ? check(`mcp-${name}`, "error", "missing-required-mcp", `${name} is not configured.`, "Reinstall HolyCodex.") : !mcpConfigMatches(configured, expected) ? check(`mcp-${name}`, "error", "invalid-required-mcp-config", `${name} configuration is stale or contains unsupported settings.`, "Reinstall HolyCodex.") : check(`mcp-${name}`, "ok", "required-mcp-ready", `${name} is configured locally.`));
|
|
504
|
+
}
|
|
428
505
|
const gitBashConfig = servers?.git_bash;
|
|
429
506
|
if (runtime.platform === "win32" && gitBashConfig !== void 0) {
|
|
430
507
|
const expected = effectiveMcpServers("win32").git_bash;
|
|
431
|
-
checks.push(
|
|
508
|
+
checks.push(mcpConfigMatches(gitBashConfig, expected) ? check("mcp-git_bash-config", "ok", "git-bash-mcp-config-ready", "Git Bash MCP exposes only run through the supported allowlist.") : check("mcp-git_bash-config", "error", "invalid-git-bash-mcp-config", "Git Bash MCP command or enabled_tools configuration is stale.", "Reinstall HolyCodex."));
|
|
432
509
|
} 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."));
|
|
433
510
|
const context7 = servers?.context7;
|
|
511
|
+
const expectedContext7 = effectiveMcpServers(runtime.platform).context7;
|
|
434
512
|
const obsoleteAuth = context7 !== void 0 && [
|
|
435
513
|
"headers",
|
|
436
514
|
"env",
|
|
@@ -440,7 +518,7 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
440
518
|
if (context7 === void 0) checks.push(check("context7-config", "error", "missing-context7", "Context7 is not configured.", "Reinstall HolyCodex."));
|
|
441
519
|
else if (typeof context7.url === "string") checks.push(check("context7-config", "error", "obsolete-context7-remote", "Context7 still uses a hosted URL.", "Reinstall to use local bunx Context7."));
|
|
442
520
|
else if (obsoleteAuth) checks.push(check("context7-config", "error", "obsolete-context7-auth", "Context7 contains obsolete authentication settings.", "Remove auth settings and reinstall."));
|
|
443
|
-
else if (
|
|
521
|
+
else if (!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."));
|
|
444
522
|
else checks.push(check("context7-config", "ok", "local-context7-config", "Local no-auth Context7 is configured."));
|
|
445
523
|
const bun = await runtime.command("bun", ["--version"]);
|
|
446
524
|
const bunx = await runtime.command("bunx", ["--version"]);
|
|
@@ -448,7 +526,7 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
448
526
|
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."));
|
|
449
527
|
if (bun.ok && bunx.ok && checks.some((item) => item.code === "local-context7-config")) {
|
|
450
528
|
const started = await runtime.context7();
|
|
451
|
-
checks.push(started.ok ? 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."));
|
|
529
|
+
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."));
|
|
452
530
|
}
|
|
453
531
|
if (runtime.platform === "win32") {
|
|
454
532
|
const gitBash = runtime.gitBash();
|
|
@@ -463,7 +541,7 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
|
|
|
463
541
|
const mode = autonomy(config);
|
|
464
542
|
checks.push(mode === "unknown" ? check("autonomy", "error", "invalid-autonomy-config", "Approval, 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."));
|
|
465
543
|
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."));
|
|
466
|
-
checks.push(
|
|
544
|
+
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."));
|
|
467
545
|
const codex = await runtime.command("codex", ["--version"]);
|
|
468
546
|
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."));
|
|
469
547
|
const agentModelFailures = [];
|
|
@@ -534,7 +612,7 @@ function removeLegacyOmo(input) {
|
|
|
534
612
|
}).join("").trimEnd();
|
|
535
613
|
}
|
|
536
614
|
function injectTableKey(input, table, key, value) {
|
|
537
|
-
const match = new RegExp(`^\\s*\\[${table.replaceAll(".", "\\.")}]\\s
|
|
615
|
+
const match = new RegExp(`^\\s*\\[${table.replaceAll(".", "\\.")}]\\s*(?:#.*)?$`, "m").exec(input);
|
|
538
616
|
const tail = match === null ? "" : input.slice(match.index + match[0].length);
|
|
539
617
|
const tableEnd = nextTableBoundary(tail);
|
|
540
618
|
const tableBody = tableEnd < 0 ? tail : tail.slice(0, tableEnd);
|
|
@@ -556,7 +634,7 @@ function nextTableBoundary(input) {
|
|
|
556
634
|
return Math.min(header, managedHeader);
|
|
557
635
|
}
|
|
558
636
|
function rootValue(input, key) {
|
|
559
|
-
if (key === "status_line") return
|
|
637
|
+
if (key === "status_line") return rootTomlStringArraySource(input, key);
|
|
560
638
|
return new RegExp(`^\\s*${key}\\s*=.*$`, "m").exec(input)?.[0];
|
|
561
639
|
}
|
|
562
640
|
function removeRootValue(input, value) {
|
|
@@ -580,37 +658,10 @@ function preserveManagedRootPreferences(input, base) {
|
|
|
580
658
|
}
|
|
581
659
|
function mergedStatusLine(original) {
|
|
582
660
|
if (original === void 0) return "[\"model-with-reasoning\", \"context-remaining\", \"current-dir\"]";
|
|
583
|
-
const items =
|
|
584
|
-
if (match[1] === void 0) return match[2] ?? "";
|
|
585
|
-
const parsed = JSON.parse(`"${match[1]}"`);
|
|
586
|
-
if (typeof parsed !== "string") throw new Error("Invalid status-line string");
|
|
587
|
-
return parsed;
|
|
588
|
-
});
|
|
661
|
+
const items = rootTomlStringArray(original, "status_line") ?? [];
|
|
589
662
|
if (!items.includes("context-remaining")) items.push("context-remaining");
|
|
590
663
|
return `[${items.map((item) => JSON.stringify(item)).join(", ")}]`;
|
|
591
664
|
}
|
|
592
|
-
function tomlArrayValue(input) {
|
|
593
|
-
const start = input.indexOf("[");
|
|
594
|
-
if (start < 0) return input;
|
|
595
|
-
let quote;
|
|
596
|
-
let escaped = false;
|
|
597
|
-
for (let index = start + 1; index < input.length; index += 1) {
|
|
598
|
-
const character = input[index];
|
|
599
|
-
if (quote === "\"") {
|
|
600
|
-
if (escaped) escaped = false;
|
|
601
|
-
else if (character === "\\") escaped = true;
|
|
602
|
-
else if (character === "\"") quote = void 0;
|
|
603
|
-
continue;
|
|
604
|
-
}
|
|
605
|
-
if (quote === "'") {
|
|
606
|
-
if (character === "'") quote = void 0;
|
|
607
|
-
continue;
|
|
608
|
-
}
|
|
609
|
-
if (character === "\"" || character === "'") quote = character;
|
|
610
|
-
else if (character === "]") return input.slice(start, index + 1);
|
|
611
|
-
}
|
|
612
|
-
return input.slice(start);
|
|
613
|
-
}
|
|
614
665
|
function installConfig(input, mode, _platform) {
|
|
615
666
|
const base = preserveManagedRootPreferences(input, removeLegacyOmo(removeManaged(input)));
|
|
616
667
|
const firstTable = base.search(/^\s*\[/m);
|
|
@@ -792,7 +843,7 @@ async function writePlatformAgents(root, platform) {
|
|
|
792
843
|
if (platform === "win32") return;
|
|
793
844
|
await Promise.all(AGENTS.map(async (agent) => {
|
|
794
845
|
const path = join(root, `${agent}.toml`);
|
|
795
|
-
await atomicWrite(path, (await readText(path)).replace(`${WINDOWS_SHELL_POLICY}\n\n`, ""));
|
|
846
|
+
await atomicWrite(path, (await readText(path)).replace(`${WINDOWS_SHELL_POLICY}\r\n\r\n`, "").replace(`${WINDOWS_SHELL_POLICY}\n\n`, ""));
|
|
796
847
|
}));
|
|
797
848
|
}
|
|
798
849
|
async function cleanup(_options) {
|
|
@@ -912,5 +963,11 @@ async function main() {
|
|
|
912
963
|
}
|
|
913
964
|
process$1.stdout.write(options.json ? `${JSON.stringify(result)}\n` : renderRunResult(result, stdoutColor));
|
|
914
965
|
}
|
|
915
|
-
|
|
966
|
+
try {
|
|
967
|
+
await main();
|
|
968
|
+
} catch (error) {
|
|
969
|
+
const stderrColor = supportsColor(process$1.stderr.isTTY, process$1.env.NO_COLOR);
|
|
970
|
+
process$1.stderr.write(renderError(error instanceof Error ? error.message : String(error), stderrColor));
|
|
971
|
+
process$1.exitCode = 1;
|
|
972
|
+
}
|
|
916
973
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "holycodex",
|
|
3
|
-
"version": "0.7.0-dev.
|
|
3
|
+
"version": "0.7.0-dev.29581464491.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.7.0-dev.
|
|
42
|
+
"@holycodex/plugin": "0.7.0-dev.29581464491.1"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=20"
|