@minhpnq1807/contextos 0.5.25 → 0.5.27

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,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.27
4
+
5
+ - **Fix Windows `spawnSync`/`execFileSync` ENOENT across all modules:** Added `shell: true` to every remaining child-process invocation in `ruler-sync.js`, `skillshare-sync.js`, `passthrough.js`, and `measure.js`. Without this, Windows cannot resolve `.cmd`/`.ps1` shims (e.g. `npm.cmd`, `ruler.cmd`, `skillshare.cmd`) via PATH, causing `ctx setup` to crash during the Ruler/Skillshare installation step.
6
+
7
+ ## 0.5.26
8
+
9
+ - **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.
10
+ - **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).
11
+
3
12
  ## 0.5.25
4
13
 
5
14
  - **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.
package/bin/ctx.js CHANGED
@@ -41,47 +41,46 @@ 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
49
- ctx install --agent claude
50
- ctx install --agent agy
51
- ctx install --quiet
52
- ctx install --inject
53
- ctx install --copy
54
- ctx setup
55
- ctx setup --yes
56
- ctx setup --agents codex,claude,agy
57
- ctx setup --no-rules
58
- ctx setup --no-skills
59
- ctx setup --quiet
60
- ctx debug -- "task"
61
- ctx report
62
- ctx evidence
63
- ctx stats
64
- ctx benchmark -- "task"
65
- ctx sync --rules
66
- ctx sync --rules --agents codex,claude,antigravity
67
- ctx sync --rules --dry-run
68
- ctx sync --rules --no-import-codex-mcp
69
- ctx sync --skills
70
- ctx sync --workflows
71
- ctx sync --workflows --agents codex,claude,agy
72
- ctx sync --workflows --dry-run
73
- ctx sync --skills --dry-run
74
- ctx sync --skills --no-collect
75
- ctx sync --skills --no-embeddings
76
- ctx sync --skills --verbose
77
- ctx sync --skills --agents codex,claude,antigravity
78
- ctx embeddings warm -- "task"
79
- ctx ruler -- <ruler args>
80
- ctx skillshare -- <skillshare args>
81
- ctx --version
44
+ ctx install Interactive multi-select agent installer
45
+ ctx install --agent <name> Install a specific agent (codex|claude|agy)
46
+ ctx install --copy Legacy: copy plugin folder only (no hooks/mcp)
47
+ ctx setup Interactive full setup wizard
48
+ ctx setup --yes Auto-confirm all setup prompts
49
+ ctx setup --agents codex,claude,agy Pre-select agents to install
50
+ ctx setup --no-rules Skip AGENTS.md rule sync
51
+ ctx setup --no-skills Skip skill sync
52
+ ctx setup --quiet Quiet mode (minimal output)
53
+ ctx debug -- "task" Debug a task with ContextOS tracing
54
+ ctx report Show last ContextOS compliance report
55
+ ctx evidence Show evidence from last report
56
+ ctx stats Show workspace statistics
57
+ ctx benchmark -- "task" Benchmark workspace for a task
58
+ ctx sync --rules Sync AGENTS.md rules to all agents
59
+ ctx sync --rules --agents codex,claude,agy Sync rules to specific agents only
60
+ ctx sync --rules --dry-run Preview rule sync without writing
61
+ ctx sync --rules --no-import-codex-mcp Skip importing Codex MCP servers
62
+ ctx sync --skills Sync skills across agents
63
+ ctx sync --skills --agents codex,claude,agy Sync skills to specific agents only
64
+ ctx sync --skills --dry-run Preview skill sync without writing
65
+ ctx sync --skills --no-collect Skip collecting new skills
66
+ ctx sync --skills --no-embeddings Skip embedding generation
67
+ ctx sync --skills --verbose Verbose skill sync output
68
+ ctx sync --workflows Sync workflows across agents
69
+ ctx sync --workflows --agents codex,claude,agy Sync workflows to specific agents
70
+ ctx sync --workflows --dry-run Preview workflow sync without writing
71
+ ctx embeddings warm -- "task" Pre-warm embedding caches for a task
72
+ ctx ruler -- <ruler args> Passthrough to ruler CLI
73
+ ctx skillshare -- <skillshare args> Passthrough to skillshare CLI
74
+ ctx --version Show installed version
82
75
  `;
83
76
  }
84
77
 
78
+ const SUPPORTED_AGENTS = [
79
+ { label: "Codex", value: "codex", selected: true },
80
+ { label: "Claude Code", value: "claude", selected: true },
81
+ { label: "Antigravity (agy)", value: "agy", selected: true }
82
+ ];
83
+
85
84
  function normalizeInstallAgent(agent) {
86
85
  const normalized = String(agent || "").trim().toLowerCase();
87
86
  if (/[|/]/.test(normalized)) {
@@ -180,7 +179,8 @@ function agentInstallRoot(agent) {
180
179
  return path.join(contextOSDataDir(), "agents", agent, "contextos");
181
180
  }
182
181
 
183
- async function install({ copy = false, inject = true, agent = "codex" } = {}) {
182
+ async function install({ copy = false, agent = "codex" } = {}) {
183
+ const inject = true; // Prompt injection is always enabled
184
184
  agent = normalizeInstallAgent(agent);
185
185
  if (copy) {
186
186
  copyInstall();
@@ -513,7 +513,6 @@ async function setup({ args = [], cwd = process.cwd() } = {}) {
513
513
  options.agents = selected;
514
514
  const rl2 = readline.createInterface({ input, output });
515
515
  try {
516
- options.inject = await askSetupYesNo(rl2, "Enable prompt context injection?", options.inject);
517
516
  options.syncRules = await askSetupYesNo(rl2, "Sync project rules and MCP servers through Ruler?", options.syncRules);
518
517
  options.syncSkills = await askSetupYesNo(rl2, "Sync skills through skillshare?", options.syncSkills);
519
518
  } finally {
@@ -522,7 +521,6 @@ async function setup({ args = [], cwd = process.cwd() } = {}) {
522
521
  } else {
523
522
  try {
524
523
  console.log(`◇ Install for agents:\n│ ${options.agents.join(", ")}`);
525
- options.inject = await askSetupYesNo(rl, "Enable prompt context injection?", options.inject);
526
524
  options.syncRules = await askSetupYesNo(rl, "Sync project rules and MCP servers through Ruler?", options.syncRules);
527
525
  options.syncSkills = await askSetupYesNo(rl, "Sync skills through skillshare?", options.syncSkills);
528
526
  } finally {
@@ -540,7 +538,7 @@ async function setup({ args = [], cwd = process.cwd() } = {}) {
540
538
 
541
539
  for (const agent of options.agents) {
542
540
  console.log(`● Setting up ${agent}...`);
543
- await install({ agent, inject: options.inject, copy: false });
541
+ await install({ agent, copy: false });
544
542
  }
545
543
 
546
544
  if (options.syncRules) {
@@ -581,8 +579,7 @@ const command = args[0];
581
579
  function installAgentFromArgs(args) {
582
580
  const agentFlag = args.indexOf("--agent");
583
581
  if (agentFlag >= 0) return normalizeInstallAgent(args[agentFlag + 1] || "");
584
- const firstValue = args.slice(1).find((arg) => !arg.startsWith("--"));
585
- return normalizeInstallAgent(firstValue || "codex");
582
+ return null; // no --agent flag → interactive selection
586
583
  }
587
584
 
588
585
  try {
@@ -591,11 +588,27 @@ try {
591
588
  } else if (command === "--version" || command === "-v") {
592
589
  console.log(packageVersion());
593
590
  } else if (command === "install") {
594
- await install({
595
- copy: args.includes("--copy"),
596
- inject: args.includes("--inject") || !args.includes("--quiet"),
597
- agent: installAgentFromArgs(args)
598
- });
591
+ const copy = args.includes("--copy");
592
+ const explicitAgent = installAgentFromArgs(args);
593
+
594
+ if (explicitAgent) {
595
+ // Direct mode: ctx install --agent <name>
596
+ await install({ copy, agent: explicitAgent });
597
+ } else {
598
+ // Interactive mode: ctx install
599
+ const selected = await multiSelect({
600
+ message: "Select agents to install:",
601
+ options: SUPPORTED_AGENTS
602
+ });
603
+ if (!selected.length) {
604
+ console.log("No agents selected. Nothing to install.");
605
+ } else {
606
+ for (const agent of selected) {
607
+ await install({ copy, agent });
608
+ console.log("");
609
+ }
610
+ }
611
+ }
599
612
  } else if (command === "setup") {
600
613
  await setup({ args: args.slice(1), cwd: process.cwd() });
601
614
  } else if (command === "debug") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minhpnq1807/contextos",
3
- "version": "0.5.25",
3
+ "version": "0.5.27",
4
4
  "description": "Task-aware AGENTS.md context injection and compliance reporting for Codex, Claude Code, and Antigravity.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -53,7 +53,8 @@ export function readGitSnapshot({ cwd = process.cwd() } = {}) {
53
53
  cwd,
54
54
  encoding: "utf8",
55
55
  stdio: ["ignore", "pipe", "pipe"],
56
- timeout: 1000
56
+ timeout: 1000,
57
+ shell: true
57
58
  });
58
59
  return parseGitDiff(diff);
59
60
  } catch {
@@ -62,7 +63,8 @@ export function readGitSnapshot({ cwd = process.cwd() } = {}) {
62
63
  cwd,
63
64
  encoding: "utf8",
64
65
  stdio: ["ignore", "pipe", "pipe"],
65
- timeout: 1000
66
+ timeout: 1000,
67
+ shell: true
66
68
  });
67
69
  const changedFiles = parseStatusFiles(status);
68
70
  return {
@@ -33,7 +33,8 @@ export function runPassthrough({
33
33
  const result = spawn(command, args, {
34
34
  cwd,
35
35
  env,
36
- stdio: "inherit"
36
+ stdio: "inherit",
37
+ shell: true
37
38
  });
38
39
 
39
40
  if (result.error) {
@@ -24,7 +24,7 @@ function statusLine(label, value) {
24
24
 
25
25
  function runCommand(command, args, { cwd = process.cwd(), stdio = "pipe", dryRun = false } = {}) {
26
26
  if (dryRun) return { stdout: "", skipped: true };
27
- const stdout = execFileSync(command, args, { cwd, stdio, encoding: "utf8" });
27
+ const stdout = execFileSync(command, args, { cwd, stdio, encoding: "utf8", shell: true });
28
28
  return { stdout: stdout || "" };
29
29
  }
30
30
 
@@ -12,7 +12,6 @@ export function parseSetupArgs(args = []) {
12
12
  agentsProvided,
13
13
  yes: args.includes("--yes") || args.includes("-y"),
14
14
  quiet: args.includes("--quiet"),
15
- inject: !args.includes("--quiet") && !args.includes("--no-inject"),
16
15
  syncRules: !args.includes("--no-rules"),
17
16
  syncSkills: !args.includes("--no-skills")
18
17
  };
@@ -35,14 +34,13 @@ export function normalizeSetupAgent(agent) {
35
34
  export function setupSummaryLines({
36
35
  cwd = process.cwd(),
37
36
  agents = DEFAULT_AGENTS,
38
- inject = true,
39
37
  syncRules = true,
40
38
  syncSkills = true
41
39
  } = {}) {
42
40
  return [
43
41
  `Installation directory: ${cwd}`,
44
42
  `Agents: ${agents.join(", ") || "(none)"}`,
45
- `Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`,
43
+ `Prompt context injection: always enabled`,
46
44
  `Ruler rule/MCP sync: ${syncRules ? "enabled" : "skipped"}`,
47
45
  `skillshare skill sync: ${syncSkills ? "enabled" : "skipped"}`
48
46
  ];
@@ -21,7 +21,7 @@ function statusLine(label, value) {
21
21
 
22
22
  function runCommand(command, args = [], { cwd = process.cwd(), stdio = "pipe", dryRun = false } = {}) {
23
23
  if (dryRun) return { stdout: "", skipped: true };
24
- const stdout = execFileSync(command, args, { cwd, stdio, encoding: "utf8" });
24
+ const stdout = execFileSync(command, args, { cwd, stdio, encoding: "utf8", shell: true });
25
25
  return { stdout: stdout || "" };
26
26
  }
27
27