@minhpnq1807/contextos 0.5.5 → 0.5.6
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 +6 -0
- package/README.md +9 -4
- package/bin/ctx.js +146 -59
- package/package.json +1 -1
- package/plugins/ctx/lib/ruler-sync.js +22 -3
- package/plugins/ctx/lib/skillshare-sync.js +16 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.6
|
|
4
|
+
|
|
5
|
+
- Adds visible `ctx install` progress from 0-100 so long model/file/skill embedding warmups no longer look stalled.
|
|
6
|
+
- Accepts `agy` as the Antigravity alias for install, Ruler sync, and skillshare sync while still passing Ruler/skillshare their official `antigravity` agent id.
|
|
7
|
+
- Makes `ctx install --inject` explicitly override `--quiet` when both flags are present.
|
|
8
|
+
|
|
3
9
|
## 0.5.5
|
|
4
10
|
|
|
5
11
|
- Discovers all skill roots containing `SKILL.md` under global/project `.gemini`, `.codex`, and `.claude` directories before `ctx sync --skills`.
|
package/README.md
CHANGED
|
@@ -162,6 +162,8 @@ Restart Antigravity or `agy` after installing.
|
|
|
162
162
|
|
|
163
163
|
The embedding model is mandatory. `ctx install` checks `~/.ctx/contextos/models` first and downloads the MiniLM model only when the required local files are missing. It intentionally fails if the model cannot be prepared, because otherwise the first prompt hook would have to cold-load or download the model.
|
|
164
164
|
|
|
165
|
+
During install, ContextOS prints a 0-100 progress indicator. The longest stage is usually embedding warmup; if the model is already cached, install skips the download and only refreshes vectors.
|
|
166
|
+
|
|
165
167
|
Verify the published package in any project:
|
|
166
168
|
|
|
167
169
|
```bash
|
|
@@ -191,6 +193,7 @@ Useful variants:
|
|
|
191
193
|
ctx sync --skills --dry-run
|
|
192
194
|
ctx sync --skills --no-collect
|
|
193
195
|
ctx sync --skills --agents codex,claude
|
|
196
|
+
ctx sync --skills --agents codex,claude,agy
|
|
194
197
|
```
|
|
195
198
|
|
|
196
199
|
After this, `ctx debug -- "task"` and prompt hooks can suggest skills from `~/.config/skillshare/skills/` plus agent-specific skill folders.
|
|
@@ -235,11 +238,13 @@ Use Ruler when the project wants one rule/MCP source of truth for multiple agent
|
|
|
235
238
|
ctx sync --rules
|
|
236
239
|
```
|
|
237
240
|
|
|
238
|
-
Default agents are `codex`, `claude`, and `antigravity
|
|
241
|
+
Default agents are `codex`, `claude`, and `agy` (Antigravity). Ruler's official identifier is still `antigravity`, so ContextOS accepts both `agy` and `antigravity` and normalizes them before calling Ruler. You can target a subset:
|
|
239
242
|
|
|
240
243
|
```bash
|
|
241
244
|
ctx sync --rules --agents codex
|
|
242
245
|
ctx sync --rules --agents codex,claude
|
|
246
|
+
ctx sync --rules --agents codex,claude,agy
|
|
247
|
+
ctx sync --rules --agents codex,claude,antigravity
|
|
243
248
|
```
|
|
244
249
|
|
|
245
250
|
What it does:
|
|
@@ -302,7 +307,7 @@ This warning comes from a transitive dependency in the local embedding/WASM stac
|
|
|
302
307
|
| `ctx install agy` | Installs ContextOS into Antigravity. | You use the `agy` CLI or Antigravity app/editor. | Copies a stable package root to `~/.ctx/contextos/agents/agy/contextos`, writes hooks to `~/.gemini/config/hooks.json`, and registers `ctx-mcp` in Antigravity app, CLI, and legacy editor MCP config paths. |
|
|
303
308
|
| `ctx install --agent <name>` | Installs for a named agent. | You prefer explicit scripts. | Accepts `codex`, `claude`, or `agy`. |
|
|
304
309
|
| `ctx install --quiet` | Installs ContextOS in measurement-only mode. | You want reports and stats but do not want visible injected context. | Installs the same hooks, but prompt hooks return empty context. |
|
|
305
|
-
| `ctx install --inject` | Installs ContextOS with explicit injection mode. | You want to be explicit in scripts or docs. | Same runtime behavior as the default install mode. |
|
|
310
|
+
| `ctx install --inject` | Installs ContextOS with explicit injection mode. | You want to be explicit in scripts or docs. | Same runtime behavior as the default install mode; if combined with `--quiet`, `--inject` wins. |
|
|
306
311
|
| `ctx install --copy` | Copies only the plugin payload to `$CODEX_HOME/plugins/ctx`. | Local development or manual plugin experiments. | Does not register marketplace, MCP, or global hooks. |
|
|
307
312
|
| `ctx debug -- "task"` | Runs the scheduler locally for a fake prompt. | You want to see which AGENTS.md rules and files ContextOS would inject before using Codex. | Prints rule scores, scoring reasons, suggested files, and final `additionalContext`. |
|
|
308
313
|
| `ctx report` | Shows the last Stop-hook compliance report for the current workspace. | An agent task has finished and you want the summary again. | Reads `~/.ctx/contextos/workspaces/<workspace-id>/last-report.json`. |
|
|
@@ -310,12 +315,12 @@ This warning comes from a transitive dependency in the local embedding/WASM stac
|
|
|
310
315
|
| `ctx stats` | Shows aggregate runtime metrics for the current workspace. | You want to know whether ContextOS is active and useful over time. | Prints prompt count, report count, injected/quiet ratio, average prompt analysis time, efficiency, rule outcomes, hook events, and last suggested files for the current workspace only. |
|
|
311
316
|
| `ctx benchmark -- "task"` | Compares baseline AGENTS.md ordering with ContextOS task-aware scheduling. | You want a before/after signal for lost-in-the-middle risk. | Prints parsed/actionable/filtered rule counts, relevant rules in the middle of the original file, scheduled high/mid rules, and top scored rules. |
|
|
312
317
|
| `ctx sync --rules` | Syncs project rules and MCP servers through Ruler. | You want Codex, Claude Code, and Antigravity to share one project rule/MCP source of truth. | Ensures `.ruler/ruler.toml`, injects `ctx-mcp`, imports existing MCP servers from Codex and project `.mcp.json`, runs `ruler apply --agents codex,claude,antigravity`, mirrors MCP servers to Antigravity MCP configs, and verifies generated config. |
|
|
313
|
-
| `ctx sync --rules --agents <list>` | Syncs only selected agents through Ruler. | You want to update one or two agents without touching the others. | Accepts comma-separated values such as `codex`, `claude`, `antigravity`, or `codex,claude`. |
|
|
318
|
+
| `ctx sync --rules --agents <list>` | Syncs only selected agents through Ruler. | You want to update one or two agents without touching the others. | Accepts comma-separated values such as `codex`, `claude`, `agy`, `antigravity`, or `codex,claude,agy`; `agy` is normalized to Ruler's `antigravity`. |
|
|
314
319
|
| `ctx sync --rules --dry-run` | Previews Ruler sync without writing files or running apply. | You want to inspect behavior before changing project config. | Prints the same flow with dry-run status. |
|
|
315
320
|
| `ctx sync --rules --force` | Rewrites ContextOS-owned Ruler sections. | You changed the ContextOS install path or need to refresh `ctx-mcp`. | Removes and re-adds ContextOS-owned `mcp`, `mcp_servers.ctx-mcp`, and selected agent sections. |
|
|
316
321
|
| `ctx sync --rules --no-import-codex-mcp` | Skips Codex MCP import. | You only want ContextOS' own `ctx-mcp` in Ruler. | Does not read `~/.codex/config.toml`. |
|
|
317
322
|
| `ctx sync --skills` | Syncs agent skills through skillshare. | You want Codex, Claude Code, and Antigravity to share one skill source. | Installs or verifies `skillshare`, initializes it if needed, backs up and collects existing skills unless skipped, runs `skillshare sync`, and rebuilds ContextOS skill embeddings. |
|
|
318
|
-
| `ctx sync --skills --agents <list>` | Syncs skills only for selected agents. | You want to target a subset such as `codex,claude`. | Runs `skillshare sync --agents <list>`
|
|
323
|
+
| `ctx sync --skills --agents <list>` | Syncs skills only for selected agents. | You want to target a subset such as `codex,claude` or `codex,claude,agy`. | Runs `skillshare sync --agents <list>` with `agy` normalized to `antigravity`, then refreshes skill embeddings. |
|
|
319
324
|
| `ctx sync --skills --dry-run` | Previews skillshare sync. | You want to inspect behavior before changing skill directories. | Runs `skillshare sync --dry-run` and skips embedding rebuild. |
|
|
320
325
|
| `ctx sync --skills --no-collect` | Skips collecting existing agent skills into skillshare. | You already manage `~/.config/skillshare/skills` and only want to push it out. | Initializes/syncs skillshare without running `skillshare backup` or `skillshare collect --all`. |
|
|
321
326
|
| `ctx embeddings warm -- "task"` | Prepares local semantic embedding caches. | First install, CI smoke checks, or after changing AGENTS.md/project files/skills. | Loads/downloads `Xenova/all-MiniLM-L6-v2` and writes rule, file-path, and skill vectors to `~/.ctx/contextos/embeddings.db`. |
|
package/bin/ctx.js
CHANGED
|
@@ -59,6 +59,68 @@ Usage:
|
|
|
59
59
|
`;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
function normalizeInstallAgent(agent) {
|
|
63
|
+
const normalized = String(agent || "").trim().toLowerCase();
|
|
64
|
+
if (normalized === "antigravity") return "agy";
|
|
65
|
+
return normalized;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function createInstallProgress({ quiet = false } = {}) {
|
|
69
|
+
const enabled = !quiet && process.stderr.isTTY;
|
|
70
|
+
const frames = ["-", "\\", "|", "/"];
|
|
71
|
+
let percent = 0;
|
|
72
|
+
let label = "starting";
|
|
73
|
+
let frame = 0;
|
|
74
|
+
let timer = null;
|
|
75
|
+
|
|
76
|
+
function render() {
|
|
77
|
+
if (!enabled) return;
|
|
78
|
+
const text = `[ctx] install ${String(percent).padStart(3)}% ${frames[frame % frames.length]} ${label}`;
|
|
79
|
+
process.stderr.write(`\r${text.padEnd(92)}`);
|
|
80
|
+
frame += 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
start(initialLabel = "starting") {
|
|
85
|
+
label = initialLabel;
|
|
86
|
+
percent = 0;
|
|
87
|
+
if (enabled) {
|
|
88
|
+
render();
|
|
89
|
+
timer = setInterval(render, 120);
|
|
90
|
+
} else if (!quiet) {
|
|
91
|
+
console.log(`[ctx] install 0% ${label}`);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
step(nextPercent, nextLabel) {
|
|
95
|
+
percent = Math.max(percent, Math.min(100, nextPercent));
|
|
96
|
+
label = nextLabel;
|
|
97
|
+
if (enabled) render();
|
|
98
|
+
else if (!quiet) console.log(`[ctx] install ${percent}% ${label}`);
|
|
99
|
+
},
|
|
100
|
+
done(finalLabel = "done") {
|
|
101
|
+
percent = 100;
|
|
102
|
+
label = finalLabel;
|
|
103
|
+
if (timer) clearInterval(timer);
|
|
104
|
+
timer = null;
|
|
105
|
+
if (enabled) {
|
|
106
|
+
render();
|
|
107
|
+
process.stderr.write("\n");
|
|
108
|
+
} else if (!quiet) {
|
|
109
|
+
console.log(`[ctx] install 100% ${label}`);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
fail(errorLabel = "failed") {
|
|
113
|
+
label = errorLabel;
|
|
114
|
+
if (timer) clearInterval(timer);
|
|
115
|
+
timer = null;
|
|
116
|
+
if (enabled) {
|
|
117
|
+
render();
|
|
118
|
+
process.stderr.write("\n");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
62
124
|
function packageVersion() {
|
|
63
125
|
try {
|
|
64
126
|
const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf8"));
|
|
@@ -85,75 +147,100 @@ function agentInstallRoot(agent) {
|
|
|
85
147
|
}
|
|
86
148
|
|
|
87
149
|
async function install({ copy = false, inject = true, agent = "codex" } = {}) {
|
|
150
|
+
agent = normalizeInstallAgent(agent);
|
|
88
151
|
if (copy) {
|
|
89
152
|
copyInstall();
|
|
90
153
|
return;
|
|
91
154
|
}
|
|
155
|
+
const progress = createInstallProgress({ quiet: false });
|
|
156
|
+
progress.start(`installing ${agent || "codex"}`);
|
|
92
157
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
158
|
+
try {
|
|
159
|
+
if (agent === "claude") {
|
|
160
|
+
progress.step(10, "copying package");
|
|
161
|
+
const installRoot = copyPackageRoot({ rootDir, targetRoot: agentInstallRoot("claude") });
|
|
162
|
+
progress.step(25, "installing hooks");
|
|
163
|
+
const hooksPath = installClaudeHooks({ installRoot, injectPromptContext: inject });
|
|
164
|
+
progress.step(40, "installing mcp");
|
|
165
|
+
const mcpConfigPath = installClaudeMcp({ installRoot });
|
|
166
|
+
progress.step(55, "warming embeddings");
|
|
167
|
+
const warmResult = await warmInstallEmbeddings();
|
|
168
|
+
progress.done("claude installed");
|
|
169
|
+
console.log("Installed ctx hooks for Claude Code.");
|
|
170
|
+
console.log(`Stable install root: ${installRoot}`);
|
|
171
|
+
console.log(`Installed ContextOS hooks to ${hooksPath}`);
|
|
172
|
+
console.log(`Installed ctx-mcp MCP server to ${mcpConfigPath}`);
|
|
173
|
+
console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
|
|
174
|
+
console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
|
|
175
|
+
console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
|
|
176
|
+
console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
|
|
177
|
+
console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
|
|
178
|
+
console.log("Restart Claude Code if it was already running, then submit a task to trigger ContextOS.");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (agent === "agy") {
|
|
183
|
+
progress.step(10, "copying package");
|
|
184
|
+
const installRoot = copyPackageRoot({ rootDir, targetRoot: agentInstallRoot("agy") });
|
|
185
|
+
progress.step(25, "installing hooks");
|
|
186
|
+
const hooksPath = installAntigravityHooks({ installRoot, injectPromptContext: inject });
|
|
187
|
+
progress.step(40, "installing mcp");
|
|
188
|
+
const mcpConfigPaths = installAntigravityMcp({ installRoot });
|
|
189
|
+
progress.step(55, "warming embeddings");
|
|
190
|
+
const warmResult = await warmInstallEmbeddings();
|
|
191
|
+
progress.done("agy installed");
|
|
192
|
+
console.log("Installed ctx hooks for Antigravity.");
|
|
193
|
+
console.log(`Stable install root: ${installRoot}`);
|
|
194
|
+
console.log(`Installed ContextOS hooks to ${hooksPath}`);
|
|
195
|
+
console.log(`Installed ctx-mcp MCP server to ${mcpConfigPaths.join(", ")}`);
|
|
196
|
+
console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
|
|
197
|
+
console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
|
|
198
|
+
console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
|
|
199
|
+
console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
|
|
200
|
+
console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
|
|
201
|
+
console.log("Restart Antigravity or agy if it was already running, then submit a task to trigger ContextOS.");
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (agent !== "codex") {
|
|
206
|
+
throw new Error(`Unknown agent '${agent}'. Expected codex, claude, or agy.`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
progress.step(10, "copying marketplace");
|
|
210
|
+
const marketplaceRoot = path.join(codexHome(), "marketplaces", "contextos");
|
|
211
|
+
copyPackageRoot({ rootDir, targetRoot: marketplaceRoot });
|
|
110
212
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
213
|
+
progress.step(20, "refreshing codex plugin");
|
|
214
|
+
tryRunCodex(["plugin", "remove", "ctx@contextos"]);
|
|
215
|
+
tryRunCodex(["plugin", "marketplace", "remove", "contextos"]);
|
|
216
|
+
tryRunCodex(["mcp", "remove", "ctx-mcp"]);
|
|
217
|
+
runCodex(["plugin", "marketplace", "add", marketplaceRoot]);
|
|
218
|
+
runCodex(["plugin", "add", "ctx@contextos"]);
|
|
219
|
+
progress.step(40, "installing mcp");
|
|
220
|
+
runCodex(["mcp", "add", "ctx-mcp", "--", "node", path.join(marketplaceRoot, "plugins", "ctx", "mcp", "server.js")]);
|
|
221
|
+
progress.step(50, "installing telemetry proxies");
|
|
222
|
+
const proxyResult = installMcpTelemetryProxies({ codexHome: codexHome(), marketplaceRoot });
|
|
223
|
+
progress.step(60, "installing hooks");
|
|
224
|
+
const hooksPath = installGlobalHooks({ codexHome: codexHome(), marketplaceRoot, injectPromptContext: inject });
|
|
225
|
+
|
|
226
|
+
progress.step(70, "warming embeddings");
|
|
115
227
|
const warmResult = await warmInstallEmbeddings();
|
|
116
|
-
|
|
117
|
-
console.log(
|
|
118
|
-
console.log(`
|
|
119
|
-
console.log(`Installed
|
|
228
|
+
progress.done("codex installed");
|
|
229
|
+
console.log("Installed ctx through Codex plugin marketplace.");
|
|
230
|
+
console.log(`Stable marketplace root: ${marketplaceRoot}`);
|
|
231
|
+
console.log(`Installed ContextOS global hooks to ${hooksPath}`);
|
|
232
|
+
console.log("Installed ctx-mcp MCP server.");
|
|
233
|
+
console.log(`MCP telemetry proxies: ${proxyResult.wrapped.length ? proxyResult.wrapped.map((item) => item.name).join(", ") : "none changed"}`);
|
|
120
234
|
console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
|
|
121
235
|
console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
|
|
122
236
|
console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
|
|
123
237
|
console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
|
|
124
238
|
console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
|
|
125
|
-
console.log("Restart
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (agent !== "codex") {
|
|
130
|
-
throw new Error(`Unknown agent '${agent}'. Expected codex, claude, or agy.`);
|
|
239
|
+
console.log("Restart Codex if it was already running, then submit a task to trigger ContextOS.");
|
|
240
|
+
} catch (error) {
|
|
241
|
+
progress.fail("install failed");
|
|
242
|
+
throw error;
|
|
131
243
|
}
|
|
132
|
-
|
|
133
|
-
const marketplaceRoot = path.join(codexHome(), "marketplaces", "contextos");
|
|
134
|
-
copyPackageRoot({ rootDir, targetRoot: marketplaceRoot });
|
|
135
|
-
|
|
136
|
-
tryRunCodex(["plugin", "remove", "ctx@contextos"]);
|
|
137
|
-
tryRunCodex(["plugin", "marketplace", "remove", "contextos"]);
|
|
138
|
-
tryRunCodex(["mcp", "remove", "ctx-mcp"]);
|
|
139
|
-
runCodex(["plugin", "marketplace", "add", marketplaceRoot]);
|
|
140
|
-
runCodex(["plugin", "add", "ctx@contextos"]);
|
|
141
|
-
runCodex(["mcp", "add", "ctx-mcp", "--", "node", path.join(marketplaceRoot, "plugins", "ctx", "mcp", "server.js")]);
|
|
142
|
-
const proxyResult = installMcpTelemetryProxies({ codexHome: codexHome(), marketplaceRoot });
|
|
143
|
-
const hooksPath = installGlobalHooks({ codexHome: codexHome(), marketplaceRoot, injectPromptContext: inject });
|
|
144
|
-
|
|
145
|
-
const warmResult = await warmInstallEmbeddings();
|
|
146
|
-
console.log("Installed ctx through Codex plugin marketplace.");
|
|
147
|
-
console.log(`Stable marketplace root: ${marketplaceRoot}`);
|
|
148
|
-
console.log(`Installed ContextOS global hooks to ${hooksPath}`);
|
|
149
|
-
console.log("Installed ctx-mcp MCP server.");
|
|
150
|
-
console.log(`MCP telemetry proxies: ${proxyResult.wrapped.length ? proxyResult.wrapped.map((item) => item.name).join(", ") : "none changed"}`);
|
|
151
|
-
console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
|
|
152
|
-
console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
|
|
153
|
-
console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
|
|
154
|
-
console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
|
|
155
|
-
console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
|
|
156
|
-
console.log("Restart Codex if it was already running, then submit a task to trigger ContextOS.");
|
|
157
244
|
}
|
|
158
245
|
|
|
159
246
|
async function warmInstallEmbeddings() {
|
|
@@ -309,9 +396,9 @@ const command = args[0];
|
|
|
309
396
|
|
|
310
397
|
function installAgentFromArgs(args) {
|
|
311
398
|
const agentFlag = args.indexOf("--agent");
|
|
312
|
-
if (agentFlag >= 0) return args[agentFlag + 1] || "";
|
|
399
|
+
if (agentFlag >= 0) return normalizeInstallAgent(args[agentFlag + 1] || "");
|
|
313
400
|
const firstValue = args.slice(1).find((arg) => !arg.startsWith("--"));
|
|
314
|
-
return firstValue || "codex";
|
|
401
|
+
return normalizeInstallAgent(firstValue || "codex");
|
|
315
402
|
}
|
|
316
403
|
|
|
317
404
|
try {
|
|
@@ -322,7 +409,7 @@ try {
|
|
|
322
409
|
} else if (command === "install") {
|
|
323
410
|
await install({
|
|
324
411
|
copy: args.includes("--copy"),
|
|
325
|
-
inject: !args.includes("--quiet"),
|
|
412
|
+
inject: args.includes("--inject") || !args.includes("--quiet"),
|
|
326
413
|
agent: installAgentFromArgs(args)
|
|
327
414
|
});
|
|
328
415
|
} else if (command === "debug") {
|
package/package.json
CHANGED
|
@@ -7,6 +7,12 @@ import { execFileSync } from "node:child_process";
|
|
|
7
7
|
const DEFAULT_AGENTS = ["codex", "claude", "antigravity"];
|
|
8
8
|
const CTX_MCP_NAME = "ctx-mcp";
|
|
9
9
|
const CONTEXTOS_PROXY_MARKER = "/contextos/plugins/ctx/mcp/proxy.js";
|
|
10
|
+
const AGENT_ALIASES = new Map([
|
|
11
|
+
["agy", "antigravity"],
|
|
12
|
+
["antigravity", "antigravity"],
|
|
13
|
+
["codex", "codex"],
|
|
14
|
+
["claude", "claude"]
|
|
15
|
+
]);
|
|
10
16
|
|
|
11
17
|
function statusLine(label, value) {
|
|
12
18
|
return `[ctx] ${label.padEnd(38)} ${value}`;
|
|
@@ -21,7 +27,7 @@ function runCommand(command, args, { cwd = process.cwd(), stdio = "pipe", dryRun
|
|
|
21
27
|
export function parseSyncRulesArgs(args = []) {
|
|
22
28
|
const agentsFlag = args.indexOf("--agents");
|
|
23
29
|
const agents = agentsFlag >= 0
|
|
24
|
-
? String(args[agentsFlag + 1] || "").split(",")
|
|
30
|
+
? normalizeAgentList(String(args[agentsFlag + 1] || "").split(","))
|
|
25
31
|
: DEFAULT_AGENTS;
|
|
26
32
|
return {
|
|
27
33
|
rules: args.includes("--rules"),
|
|
@@ -33,6 +39,19 @@ export function parseSyncRulesArgs(args = []) {
|
|
|
33
39
|
};
|
|
34
40
|
}
|
|
35
41
|
|
|
42
|
+
export function normalizeAgentName(agent) {
|
|
43
|
+
const key = String(agent || "").trim().toLowerCase();
|
|
44
|
+
return AGENT_ALIASES.get(key) || key;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function normalizeAgentList(agents = []) {
|
|
48
|
+
return [...new Set(agents.map(normalizeAgentName).filter(Boolean))];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function displayAgentName(agent) {
|
|
52
|
+
return agent === "antigravity" ? "agy" : agent;
|
|
53
|
+
}
|
|
54
|
+
|
|
36
55
|
function codexConfigPath() {
|
|
37
56
|
return path.join(process.env.CODEX_HOME || path.join(process.env.HOME || process.cwd(), ".codex"), "config.toml");
|
|
38
57
|
}
|
|
@@ -378,7 +397,7 @@ export function injectCtxMcp({ tomlPath, mcpServerPath, agents = DEFAULT_AGENTS,
|
|
|
378
397
|
}
|
|
379
398
|
|
|
380
399
|
export function runRulerApply({ agents = DEFAULT_AGENTS, cwd = process.cwd(), run = runCommand, dryRun = false } = {}) {
|
|
381
|
-
run("ruler", ["apply", "--agents", agents.join(",")], { cwd, stdio: "inherit", dryRun });
|
|
400
|
+
run("ruler", ["apply", "--agents", normalizeAgentList(agents).join(",")], { cwd, stdio: "inherit", dryRun });
|
|
382
401
|
}
|
|
383
402
|
|
|
384
403
|
function fileContains(filePath, pattern) {
|
|
@@ -481,7 +500,7 @@ export async function syncRules({
|
|
|
481
500
|
logger("[ctx] Verifying sync...");
|
|
482
501
|
const checks = options.dryRun ? options.agents.map((agent) => ({ agent, ok: true, filePath: "(dry-run)" })) : verifySync({ cwd, agents: options.agents });
|
|
483
502
|
for (const check of checks) {
|
|
484
|
-
logger(` → ctx-mcp in ${check.agent.padEnd(12)} ${check.ok ? "✓" : "not found"}${check.filePath ? ` ${check.filePath}` : ""}`);
|
|
503
|
+
logger(` → ctx-mcp in ${displayAgentName(check.agent).padEnd(12)} ${check.ok ? "✓" : "not found"}${check.filePath ? ` ${check.filePath}` : ""}`);
|
|
485
504
|
}
|
|
486
505
|
|
|
487
506
|
const okCount = checks.filter((check) => check.ok).length;
|
|
@@ -8,6 +8,12 @@ import { execFileSync, execSync } from "node:child_process";
|
|
|
8
8
|
const DEFAULT_AGENTS = ["codex", "claude", "antigravity"];
|
|
9
9
|
const INSTALL_SH_URL = "https://raw.githubusercontent.com/runkids/skillshare/main/install.sh";
|
|
10
10
|
const INSTALL_PS_URL = "https://raw.githubusercontent.com/runkids/skillshare/main/install.ps1";
|
|
11
|
+
const AGENT_ALIASES = new Map([
|
|
12
|
+
["agy", "antigravity"],
|
|
13
|
+
["antigravity", "antigravity"],
|
|
14
|
+
["codex", "codex"],
|
|
15
|
+
["claude", "claude"]
|
|
16
|
+
]);
|
|
11
17
|
|
|
12
18
|
function statusLine(label, value) {
|
|
13
19
|
return `[ctx] ${label.padEnd(38)} ${value}`;
|
|
@@ -28,7 +34,7 @@ function runShell(command, { cwd = process.cwd(), stdio = "inherit", dryRun = fa
|
|
|
28
34
|
export function parseSyncSkillsArgs(args = []) {
|
|
29
35
|
const agentsFlag = args.indexOf("--agents");
|
|
30
36
|
const agents = agentsFlag >= 0
|
|
31
|
-
? String(args[agentsFlag + 1] || "").split(",")
|
|
37
|
+
? normalizeAgentList(String(args[agentsFlag + 1] || "").split(","))
|
|
32
38
|
: DEFAULT_AGENTS;
|
|
33
39
|
return {
|
|
34
40
|
skills: args.includes("--skills"),
|
|
@@ -39,6 +45,15 @@ export function parseSyncSkillsArgs(args = []) {
|
|
|
39
45
|
};
|
|
40
46
|
}
|
|
41
47
|
|
|
48
|
+
function normalizeAgentName(agent) {
|
|
49
|
+
const key = String(agent || "").trim().toLowerCase();
|
|
50
|
+
return AGENT_ALIASES.get(key) || key;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function normalizeAgentList(agents = []) {
|
|
54
|
+
return [...new Set(agents.map(normalizeAgentName).filter(Boolean))];
|
|
55
|
+
}
|
|
56
|
+
|
|
42
57
|
export function detectOS(platform = process.platform) {
|
|
43
58
|
if (platform === "darwin") return "mac";
|
|
44
59
|
if (platform === "win32") return "windows";
|