@minhpnq1807/contextos 0.5.24 → 0.5.26
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.26
|
|
4
|
+
|
|
5
|
+
- **Interactive `ctx install`:** Running `ctx install` without `--agent` now shows an interactive multi-select prompt (↑/↓ to navigate, Space to toggle, Enter to confirm) letting you pick which agents to install in one go.
|
|
6
|
+
- **Removed positional agent args:** `ctx install codex`, `ctx install claude`, `ctx install agy` no longer work as positional shortcuts. Use `ctx install` (interactive) or `ctx install --agent <name>` (direct).
|
|
7
|
+
|
|
8
|
+
## 0.5.25
|
|
9
|
+
|
|
10
|
+
- **Fix Windows JSON parse crash:** All `readJsonFile`/`readHooksFile` helpers now catch corrupt JSON and warn instead of crashing, allowing fresh config to be generated automatically.
|
|
11
|
+
- **Fix Windows shell quoting:** `shellQuote` now uses double-quotes on Windows (`process.platform === "win32"`) instead of POSIX single-quotes which are not recognized by cmd.exe/PowerShell.
|
|
12
|
+
- **Fix Codex CLI invocation on Windows:** `runCodex`/`tryRunCodex` now pass `shell: true` to `execFileSync` so Windows can resolve `codex.cmd` via PATH.
|
|
13
|
+
|
|
3
14
|
## 0.5.24
|
|
4
15
|
|
|
5
16
|
- **Interactive agent selection:** Replaces the comma-separated text input in `ctx setup` with an interactive multi-select prompt — use ↑/↓ to navigate, Space to toggle agents on/off, and Enter to confirm.
|
package/bin/ctx.js
CHANGED
|
@@ -41,11 +41,8 @@ function usage() {
|
|
|
41
41
|
return `ContextOS (ctx)
|
|
42
42
|
|
|
43
43
|
Usage:
|
|
44
|
-
ctx install
|
|
45
|
-
ctx install codex
|
|
46
|
-
ctx install claude
|
|
47
|
-
ctx install agy
|
|
48
|
-
ctx install --agent codex
|
|
44
|
+
ctx install (interactive agent selection)
|
|
45
|
+
ctx install --agent codex (direct install for a specific agent)
|
|
49
46
|
ctx install --agent claude
|
|
50
47
|
ctx install --agent agy
|
|
51
48
|
ctx install --quiet
|
|
@@ -82,6 +79,12 @@ Usage:
|
|
|
82
79
|
`;
|
|
83
80
|
}
|
|
84
81
|
|
|
82
|
+
const SUPPORTED_AGENTS = [
|
|
83
|
+
{ label: "Codex", value: "codex", selected: true },
|
|
84
|
+
{ label: "Claude Code", value: "claude", selected: true },
|
|
85
|
+
{ label: "Antigravity (agy)", value: "agy", selected: true }
|
|
86
|
+
];
|
|
87
|
+
|
|
85
88
|
function normalizeInstallAgent(agent) {
|
|
86
89
|
const normalized = String(agent || "").trim().toLowerCase();
|
|
87
90
|
if (/[|/]/.test(normalized)) {
|
|
@@ -332,7 +335,7 @@ async function warmInstallEmbeddings() {
|
|
|
332
335
|
|
|
333
336
|
function tryRunCodex(args) {
|
|
334
337
|
try {
|
|
335
|
-
execFileSync("codex", args, { stdio: "ignore" });
|
|
338
|
+
execFileSync("codex", args, { stdio: "ignore", shell: true });
|
|
336
339
|
} catch {
|
|
337
340
|
// Best effort cleanup for repeat installs.
|
|
338
341
|
}
|
|
@@ -340,7 +343,7 @@ function tryRunCodex(args) {
|
|
|
340
343
|
|
|
341
344
|
function runCodex(args) {
|
|
342
345
|
try {
|
|
343
|
-
execFileSync("codex", args, { stdio: "inherit" });
|
|
346
|
+
execFileSync("codex", args, { stdio: "inherit", shell: true });
|
|
344
347
|
} catch (error) {
|
|
345
348
|
const status = typeof error.status === "number" ? error.status : 1;
|
|
346
349
|
throw new Error(`codex ${args.join(" ")} failed with exit code ${status}. Make sure Codex CLI is installed and authenticated.`);
|
|
@@ -581,8 +584,7 @@ const command = args[0];
|
|
|
581
584
|
function installAgentFromArgs(args) {
|
|
582
585
|
const agentFlag = args.indexOf("--agent");
|
|
583
586
|
if (agentFlag >= 0) return normalizeInstallAgent(args[agentFlag + 1] || "");
|
|
584
|
-
|
|
585
|
-
return normalizeInstallAgent(firstValue || "codex");
|
|
587
|
+
return null; // no --agent flag → interactive selection
|
|
586
588
|
}
|
|
587
589
|
|
|
588
590
|
try {
|
|
@@ -591,11 +593,28 @@ try {
|
|
|
591
593
|
} else if (command === "--version" || command === "-v") {
|
|
592
594
|
console.log(packageVersion());
|
|
593
595
|
} else if (command === "install") {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
596
|
+
const copy = args.includes("--copy");
|
|
597
|
+
const inject = args.includes("--inject") || !args.includes("--quiet");
|
|
598
|
+
const explicitAgent = installAgentFromArgs(args);
|
|
599
|
+
|
|
600
|
+
if (explicitAgent) {
|
|
601
|
+
// Direct mode: ctx install --agent <name>
|
|
602
|
+
await install({ copy, inject, agent: explicitAgent });
|
|
603
|
+
} else {
|
|
604
|
+
// Interactive mode: ctx install
|
|
605
|
+
const selected = await multiSelect({
|
|
606
|
+
message: "Select agents to install:",
|
|
607
|
+
options: SUPPORTED_AGENTS
|
|
608
|
+
});
|
|
609
|
+
if (!selected.length) {
|
|
610
|
+
console.log("No agents selected. Nothing to install.");
|
|
611
|
+
} else {
|
|
612
|
+
for (const agent of selected) {
|
|
613
|
+
await install({ copy, inject, agent });
|
|
614
|
+
console.log("");
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
599
618
|
} else if (command === "setup") {
|
|
600
619
|
await setup({ args: args.slice(1), cwd: process.cwd() });
|
|
601
620
|
} else if (command === "debug") {
|
package/package.json
CHANGED
|
@@ -3,14 +3,23 @@ import os from "node:os";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
function shellQuote(value) {
|
|
6
|
-
|
|
6
|
+
const s = String(value);
|
|
7
|
+
if (process.platform === "win32") {
|
|
8
|
+
return `"${s.replaceAll('"', '\\"')}"`;
|
|
9
|
+
}
|
|
10
|
+
return `'${s.replaceAll("'", "'\\''")}'`;
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
function readJsonFile(filePath, fallback) {
|
|
10
14
|
if (!fs.existsSync(filePath)) return fallback;
|
|
11
15
|
const raw = fs.readFileSync(filePath, "utf8").trim();
|
|
12
16
|
if (!raw) return fallback;
|
|
13
|
-
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(raw);
|
|
19
|
+
} catch {
|
|
20
|
+
console.warn(`[ctx] warning: corrupt JSON in ${filePath}, overwriting with defaults`);
|
|
21
|
+
return fallback;
|
|
22
|
+
}
|
|
14
23
|
}
|
|
15
24
|
|
|
16
25
|
function commandFor(installRoot, scriptName, { injectPromptContext = true } = {}) {
|
|
@@ -6,7 +6,12 @@ function readJsonFile(filePath, fallback) {
|
|
|
6
6
|
if (!fs.existsSync(filePath)) return fallback;
|
|
7
7
|
const raw = fs.readFileSync(filePath, "utf8").trim();
|
|
8
8
|
if (!raw) return fallback;
|
|
9
|
-
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(raw);
|
|
11
|
+
} catch {
|
|
12
|
+
console.warn(`[ctx] warning: corrupt JSON in ${filePath}, overwriting with defaults`);
|
|
13
|
+
return fallback;
|
|
14
|
+
}
|
|
10
15
|
}
|
|
11
16
|
|
|
12
17
|
export function antigravityMcpConfigPaths() {
|
|
@@ -8,7 +8,12 @@ function readJsonFile(filePath, fallback) {
|
|
|
8
8
|
if (!fs.existsSync(filePath)) return fallback;
|
|
9
9
|
const raw = fs.readFileSync(filePath, "utf8").trim();
|
|
10
10
|
if (!raw) return fallback;
|
|
11
|
-
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(raw);
|
|
13
|
+
} catch {
|
|
14
|
+
console.warn(`[ctx] warning: corrupt JSON in ${filePath}, overwriting with defaults`);
|
|
15
|
+
return fallback;
|
|
16
|
+
}
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
export function claudeHome() {
|
|
@@ -6,16 +6,25 @@ const QUIET_CODE_REVIEW_GRAPH_STATUS_COMMAND =
|
|
|
6
6
|
"git rev-parse --git-dir >/dev/null 2>&1 && code-review-graph status >/dev/null 2>&1 || true";
|
|
7
7
|
|
|
8
8
|
function shellQuote(value) {
|
|
9
|
-
|
|
9
|
+
const s = String(value);
|
|
10
|
+
if (process.platform === "win32") {
|
|
11
|
+
return `"${s.replaceAll('"', '\\"')}"`;
|
|
12
|
+
}
|
|
13
|
+
return `'${s.replaceAll("'", "'\\''")}'`;
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
function readHooksFile(hooksPath) {
|
|
13
17
|
if (!fs.existsSync(hooksPath)) return { hooks: {} };
|
|
14
18
|
const raw = fs.readFileSync(hooksPath, "utf8").trim();
|
|
15
19
|
if (!raw) return { hooks: {} };
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(raw);
|
|
22
|
+
if (!parsed.hooks || typeof parsed.hooks !== "object") parsed.hooks = {};
|
|
23
|
+
return parsed;
|
|
24
|
+
} catch {
|
|
25
|
+
console.warn(`[ctx] warning: corrupt JSON in ${hooksPath}, overwriting with defaults`);
|
|
26
|
+
return { hooks: {} };
|
|
27
|
+
}
|
|
19
28
|
}
|
|
20
29
|
|
|
21
30
|
function isContextOSHookEntry(entry) {
|