@minhpnq1807/contextos 0.2.0 → 0.5.0
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 +46 -0
- package/README.md +149 -19
- package/bin/ctx.js +123 -38
- package/package.json +6 -3
- package/plugins/ctx/bin/on-antigravity-preinvocation.js +36 -0
- package/plugins/ctx/bin/on-antigravity-stop.js +28 -0
- package/plugins/ctx/bin/on-prompt.js +6 -5
- package/plugins/ctx/bin/on-session-start.js +5 -4
- package/plugins/ctx/bin/on-stop.js +6 -5
- package/plugins/ctx/lib/analyzer.js +4 -1
- package/plugins/ctx/lib/antigravity-adapter.js +56 -0
- package/plugins/ctx/lib/antigravity-hooks.js +53 -0
- package/plugins/ctx/lib/antigravity-mcp.js +43 -0
- package/plugins/ctx/lib/claude-hooks.js +27 -0
- package/plugins/ctx/lib/claude-mcp.js +33 -0
- package/plugins/ctx/lib/embedding-scorer.js +13 -0
- package/plugins/ctx/lib/file-embedding-retriever.js +2 -1
- package/plugins/ctx/lib/hook-io.js +16 -0
- package/plugins/ctx/lib/package-install.js +36 -0
- package/plugins/ctx/lib/prompt-hook.js +7 -3
- package/plugins/ctx/lib/ruler-sync.js +478 -0
- package/plugins/ctx/lib/scheduler.js +11 -1
- package/plugins/ctx/lib/score-context.js +13 -0
- package/plugins/ctx/lib/skill-discoverer.js +232 -0
- package/plugins/ctx/lib/skillshare-sync.js +239 -0
- package/plugins/ctx/lib/stop-hook.js +2 -1
- package/plugins/ctx/mcp/contextos-server.js +13 -3
- package/plugins/ctx/mcp/server.js +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
- Adds `ctx sync --skills` for skillshare-backed skill sync across Codex, Claude Code, and Antigravity.
|
|
6
|
+
- Detects existing global/project skill directories, backs them up, optionally collects them into skillshare, runs sync, and rebuilds skill embeddings.
|
|
7
|
+
- Adds `~/.config/skillshare/skills` to skill discovery roots so ContextOS ranks the shared source of truth after sync.
|
|
8
|
+
|
|
9
|
+
## 0.4.1
|
|
10
|
+
|
|
11
|
+
- Adds Antigravity skill discovery roots for `.gemini/skills`, `.gemini/antigravity/skills`, and `.gemini/antigravity-cli/skills`.
|
|
12
|
+
- Raises the skill catalog scan cap to cover large Antigravity skill catalogs before ranking.
|
|
13
|
+
|
|
14
|
+
## 0.4.0
|
|
15
|
+
|
|
16
|
+
- Adds prompt-aware skill discovery to `ctx_score_context`, returning `suggestedSkills` alongside rules and files.
|
|
17
|
+
- Scans project/global `.codex/skills`, `.claude/skills`, and Antigravity `.gemini/**/skills` catalogs, ranks skill `name` + `description`, and injects top skill hints into prompt context.
|
|
18
|
+
- Warms skill embeddings during `ctx install` and `ctx embeddings warm`.
|
|
19
|
+
|
|
20
|
+
## 0.3.0
|
|
21
|
+
|
|
22
|
+
- Adds `ctx sync --rules` for Ruler-backed project rule/MCP sync across Codex, Claude Code, and Antigravity.
|
|
23
|
+
- Supports `--agents`, `--dry-run`, `--force`, and `--yes` flags for targeted, previewable, idempotent Ruler sync.
|
|
24
|
+
- Injects `ctx-mcp` into `.ruler/ruler.toml` without deleting user-defined MCP servers or agent sections.
|
|
25
|
+
- Imports existing Codex MCP servers from `~/.codex/config.toml` into Ruler so servers like `code-review-graph` and `agentmemory` can propagate to Antigravity and Claude Code.
|
|
26
|
+
- Mirrors Ruler MCP servers into Antigravity app/CLI MCP config files after `ruler apply` so Antigravity receives all imported MCP servers.
|
|
27
|
+
- Imports project `.mcp.json` servers such as `mcp-rtk` so MCPs generated by Ruler or other agents are also propagated.
|
|
28
|
+
- Skips embedding model download during `ctx install` when the required MiniLM files are already present in `~/.ctx/contextos/models`.
|
|
29
|
+
- Writes Antigravity MCP config to the legacy editor path `~/.gemini/config/mcp_config.json` so older editor builds can show ContextOS under `@mcp`.
|
|
30
|
+
|
|
31
|
+
## 0.2.4
|
|
32
|
+
|
|
33
|
+
- Hardens workspace isolation for Claude Code, Codex, and Antigravity hooks by normalizing project cwd from hook payloads, `workspacePath(s)`, and `CLAUDE_PROJECT_DIR` before writing prompt/report telemetry.
|
|
34
|
+
|
|
35
|
+
## 0.2.3
|
|
36
|
+
|
|
37
|
+
- Registers `ctx-mcp` for Claude Code by writing a user-scoped MCP server into `~/.claude.json`.
|
|
38
|
+
|
|
39
|
+
## 0.2.2
|
|
40
|
+
|
|
41
|
+
- Registers `ctx-mcp` for Antigravity app and `agy` CLI by writing `~/.gemini/antigravity/mcp_config.json` and `~/.gemini/antigravity-cli/mcp_config.json`.
|
|
42
|
+
|
|
43
|
+
## 0.2.1
|
|
44
|
+
|
|
45
|
+
- Adds `ctx install claude` for Claude Code hooks in `~/.claude/settings.json`.
|
|
46
|
+
- Adds `ctx install agy` for Antigravity hooks in `~/.gemini/config/hooks.json`.
|
|
47
|
+
- Adds Antigravity `PreInvocation` and `Stop` adapters so prompt context can be injected through `ephemeralMessage` and reports remain available through `ctx report` / `ctx evidence`.
|
|
48
|
+
|
|
3
49
|
## 0.2.0
|
|
4
50
|
|
|
5
51
|
- Adds `ctx benchmark -- "task"` to compare baseline AGENTS.md ordering with ContextOS scheduling and estimate lost-in-the-middle risk.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ContextOS
|
|
2
2
|
|
|
3
|
-
ContextOS (`ctx`) is
|
|
3
|
+
ContextOS (`ctx`) is an agent companion for task-aware project context.
|
|
4
4
|
|
|
5
5
|
It reads `AGENTS.md` guidance, scores the rules against the current prompt, suggests relevant files, records what context would have been injected, and reports lightweight compliance evidence after the task finishes.
|
|
6
6
|
|
|
@@ -16,10 +16,19 @@ ctx install
|
|
|
16
16
|
|
|
17
17
|
Restart Codex after installing, then use Codex normally. ContextOS runs through Codex hooks and the `ctx-mcp` MCP server.
|
|
18
18
|
|
|
19
|
+
Claude Code and Antigravity are supported through their native hook systems:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ctx install claude
|
|
23
|
+
ctx install agy
|
|
24
|
+
```
|
|
25
|
+
|
|
19
26
|
You can also run without a global install:
|
|
20
27
|
|
|
21
28
|
```bash
|
|
22
29
|
npx @minhpnq1807/contextos@latest install
|
|
30
|
+
npx @minhpnq1807/contextos@latest install claude
|
|
31
|
+
npx @minhpnq1807/contextos@latest install agy
|
|
23
32
|
```
|
|
24
33
|
|
|
25
34
|
## Demo Flow
|
|
@@ -31,16 +40,16 @@ ctx install
|
|
|
31
40
|
codex
|
|
32
41
|
```
|
|
33
42
|
|
|
34
|
-
Prompt
|
|
43
|
+
Prompt the agent:
|
|
35
44
|
|
|
36
45
|
```text
|
|
37
|
-
|
|
46
|
+
Recheck authen flow
|
|
38
47
|
```
|
|
39
48
|
|
|
40
49
|
Expected result:
|
|
41
50
|
|
|
42
51
|
- `UserPromptSubmit` injects relevant AGENTS.md rules.
|
|
43
|
-
- ContextOS suggests
|
|
52
|
+
- ContextOS suggests auth/authentication files.
|
|
44
53
|
- `Stop` prints a ContextOS report with rule outcomes.
|
|
45
54
|
- `ctx evidence` shows the specific evidence behind the last report.
|
|
46
55
|
|
|
@@ -53,19 +62,22 @@ With ContextOS, each prompt gets a compact block:
|
|
|
53
62
|
```text
|
|
54
63
|
## Critical ContextOS rules
|
|
55
64
|
- Use code-review-graph before reading files.
|
|
56
|
-
-
|
|
65
|
+
- Recheck authentication flow before editing auth code.
|
|
57
66
|
|
|
58
67
|
## Suggested files to check
|
|
59
|
-
- services/
|
|
60
|
-
-
|
|
68
|
+
- services/auth-service/src/auth.controller.ts
|
|
69
|
+
- services/auth-service/src/auth.service.ts
|
|
61
70
|
```
|
|
62
71
|
|
|
63
72
|
## What It Does
|
|
64
73
|
|
|
65
74
|
- Hooks into Codex `UserPromptSubmit`, `SessionStart`, and `Stop`.
|
|
75
|
+
- Hooks into Claude Code `UserPromptSubmit`, `SessionStart`, and `Stop`.
|
|
76
|
+
- Hooks into Antigravity `PreInvocation` and `Stop` through the `agy` adapter.
|
|
66
77
|
- Registers a `ctx-mcp` MCP server that owns model loading and semantic scoring.
|
|
67
78
|
- Reads the active `AGENTS.md` chain for the current workspace.
|
|
68
79
|
- Scores rules by relevance to the user prompt.
|
|
80
|
+
- Scans project/global `.codex/skills`, `.claude/skills`, and Antigravity `.gemini/**/skills`, ranks skill descriptions by task relevance, and injects top skill hints.
|
|
69
81
|
- Filters host/session setup rules such as "run commands as user X" or `sudo -u user` because they are environment instructions, not project guidance.
|
|
70
82
|
- Finds likely relevant files with a hybrid retriever:
|
|
71
83
|
- first, local prompt/file heuristics create seed candidates;
|
|
@@ -98,7 +110,22 @@ From this repository during local development:
|
|
|
98
110
|
node bin/ctx.js install
|
|
99
111
|
```
|
|
100
112
|
|
|
101
|
-
|
|
113
|
+
Agent-specific installers:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
ctx install codex
|
|
117
|
+
ctx install claude
|
|
118
|
+
ctx install agy
|
|
119
|
+
ctx install --agent codex
|
|
120
|
+
ctx install --agent claude
|
|
121
|
+
ctx install --agent agy
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`ctx install` defaults to `ctx install codex`.
|
|
125
|
+
|
|
126
|
+
### Codex
|
|
127
|
+
|
|
128
|
+
`ctx install codex` does these things:
|
|
102
129
|
|
|
103
130
|
1. Copies this package into `$CODEX_HOME/marketplaces/contextos`.
|
|
104
131
|
2. Registers and installs `ctx@contextos` through Codex plugin marketplace commands.
|
|
@@ -109,15 +136,65 @@ node bin/ctx.js install
|
|
|
109
136
|
|
|
110
137
|
Restart Codex after installing.
|
|
111
138
|
|
|
112
|
-
|
|
139
|
+
### Claude Code
|
|
140
|
+
|
|
141
|
+
`ctx install claude` copies this package into `~/.ctx/contextos/agents/claude/contextos`, merges ContextOS hooks into `~/.claude/settings.json`, and registers `ctx-mcp` as a user-scoped Claude Code MCP server in `~/.claude.json`.
|
|
142
|
+
|
|
143
|
+
Claude Code receives prompt context through `UserPromptSubmit` using `hookSpecificOutput.additionalContext`, then ContextOS writes the same local workspace report files used by `ctx report`, `ctx evidence`, and `ctx stats`.
|
|
144
|
+
|
|
145
|
+
Restart Claude Code after installing.
|
|
146
|
+
|
|
147
|
+
### Antigravity
|
|
148
|
+
|
|
149
|
+
`ctx install agy` copies this package into `~/.ctx/contextos/agents/agy/contextos`, writes a `contextos` hook group into `~/.gemini/config/hooks.json`, and registers `ctx-mcp` in Antigravity MCP config locations:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
~/.gemini/antigravity/mcp_config.json
|
|
153
|
+
~/.gemini/antigravity-cli/mcp_config.json
|
|
154
|
+
~/.gemini/config/mcp_config.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The third path supports older Antigravity editor builds where `@mcp` reads the legacy Gemini config directory.
|
|
158
|
+
|
|
159
|
+
Antigravity does not use `UserPromptSubmit`; ContextOS injects context through `PreInvocation` as an `ephemeralMessage`. The `Stop` adapter stores the report locally, so use `ctx report` or `ctx evidence` after the task to inspect outcomes.
|
|
160
|
+
|
|
161
|
+
Restart Antigravity or `agy` after installing.
|
|
162
|
+
|
|
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.
|
|
113
164
|
|
|
114
165
|
Verify the published package in any project:
|
|
115
166
|
|
|
116
167
|
```bash
|
|
117
168
|
npm exec --yes --package=@minhpnq1807/contextos@latest -- ctx --version
|
|
118
|
-
npm exec --yes --package=@minhpnq1807/contextos@latest -- ctx debug -- "
|
|
169
|
+
npm exec --yes --package=@minhpnq1807/contextos@latest -- ctx debug -- "Recheck authen flow"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Skill Sync
|
|
173
|
+
|
|
174
|
+
Use skillshare when you want Codex, Claude Code, and Antigravity to share one skills catalog:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
ctx sync --skills
|
|
119
178
|
```
|
|
120
179
|
|
|
180
|
+
ContextOS checks for `skillshare`, initializes it when needed, backs up existing skills before collection, runs `skillshare collect --all` unless `--no-collect` is provided, then runs `skillshare sync`. After sync, ContextOS rebuilds skill embeddings so prompt-time skill discovery can rank the shared source immediately.
|
|
181
|
+
|
|
182
|
+
The shared source is:
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
~/.config/skillshare/skills/
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Useful variants:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
ctx sync --skills --dry-run
|
|
192
|
+
ctx sync --skills --no-collect
|
|
193
|
+
ctx sync --skills --agents codex,claude
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
After this, `ctx debug -- "task"` and prompt hooks can suggest skills from `~/.config/skillshare/skills/` plus agent-specific skill folders.
|
|
197
|
+
|
|
121
198
|
## Modes
|
|
122
199
|
|
|
123
200
|
Injection mode is the default:
|
|
@@ -150,6 +227,43 @@ ctx install --copy
|
|
|
150
227
|
|
|
151
228
|
Copies only the plugin payload into `$CODEX_HOME/plugins/ctx`. This is mostly for local experiments.
|
|
152
229
|
|
|
230
|
+
## Ruler Sync
|
|
231
|
+
|
|
232
|
+
Use Ruler when the project wants one rule/MCP source of truth for multiple agents:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
ctx sync --rules
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Default agents are `codex`, `claude`, and `antigravity`. You can target a subset:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
ctx sync --rules --agents codex
|
|
242
|
+
ctx sync --rules --agents codex,claude
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
What it does:
|
|
246
|
+
|
|
247
|
+
1. Checks that `ruler` is installed. If it is missing, ContextOS asks before running `npm install -g @intellectronica/ruler`; use `--yes` for non-interactive installs.
|
|
248
|
+
2. Runs `ruler init` when `.ruler/ruler.toml` is missing.
|
|
249
|
+
3. Adds `ctx-mcp` to `.ruler/ruler.toml` under `[mcp_servers.ctx-mcp]`.
|
|
250
|
+
4. Imports existing MCP servers from Codex `~/.codex/config.toml` and project `.mcp.json`, such as `code-review-graph`, `agentmemory`, and `mcp-rtk`, into `.ruler/ruler.toml`.
|
|
251
|
+
5. Adds enabled Ruler agent entries for Codex, Claude Code, and Antigravity using merge strategy.
|
|
252
|
+
6. Runs `ruler apply --agents ...`.
|
|
253
|
+
7. Mirrors the Ruler MCP server list into Antigravity app/CLI MCP configs because current Ruler versions do not emit every Antigravity MCP file consistently.
|
|
254
|
+
8. Verifies that generated agent config contains `ctx-mcp`.
|
|
255
|
+
|
|
256
|
+
Useful flags:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
ctx sync --rules --dry-run
|
|
260
|
+
ctx sync --rules --force
|
|
261
|
+
ctx sync --rules --yes
|
|
262
|
+
ctx sync --rules --no-import-codex-mcp
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
`ctx sync --rules` is project-scoped. It writes `.ruler/ruler.toml` in the current project and lets Ruler generate agent files from that project source of truth. ContextOS runtime history still follows the project-path isolation model described below.
|
|
266
|
+
|
|
153
267
|
## Troubleshooting
|
|
154
268
|
|
|
155
269
|
### `ctx-mcp bridge socket not found`
|
|
@@ -161,7 +275,7 @@ Restart Codex after `ctx install`. The bridge socket is owned by the long-runnin
|
|
|
161
275
|
Run:
|
|
162
276
|
|
|
163
277
|
```bash
|
|
164
|
-
ctx embeddings warm -- "
|
|
278
|
+
ctx embeddings warm -- "Recheck authen flow"
|
|
165
279
|
```
|
|
166
280
|
|
|
167
281
|
Then restart Codex.
|
|
@@ -182,16 +296,29 @@ This warning comes from a transitive dependency in the local embedding/WASM stac
|
|
|
182
296
|
|
|
183
297
|
| Command | Meaning | Use when | Output / side effect |
|
|
184
298
|
| --- | --- | --- | --- |
|
|
185
|
-
| `ctx install` | Installs ContextOS into Codex with prompt context injection enabled. | Normal setup after installing the npm package. |
|
|
186
|
-
| `ctx install
|
|
187
|
-
| `ctx install
|
|
299
|
+
| `ctx install` | Installs ContextOS into Codex with prompt context injection enabled. | Normal Codex setup after installing the npm package. | Same as `ctx install codex`. |
|
|
300
|
+
| `ctx install codex` | Installs ContextOS into Codex. | You use the `codex` CLI. | Copies the plugin into `$CODEX_HOME/marketplaces/contextos`, registers `ctx@contextos`, registers `ctx-mcp`, installs global hooks, downloads the embedding model, and warms caches. |
|
|
301
|
+
| `ctx install claude` | Installs ContextOS into Claude Code. | You use the `claude` CLI. | Copies a stable package root to `~/.ctx/contextos/agents/claude/contextos`, merges hooks into `~/.claude/settings.json`, and registers `ctx-mcp` in `~/.claude.json`. |
|
|
302
|
+
| `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
|
+
| `ctx install --agent <name>` | Installs for a named agent. | You prefer explicit scripts. | Accepts `codex`, `claude`, or `agy`. |
|
|
304
|
+
| `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. |
|
|
188
306
|
| `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. |
|
|
189
307
|
| `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`. |
|
|
190
|
-
| `ctx report` | Shows the last Stop-hook compliance report for the current workspace. |
|
|
308
|
+
| `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`. |
|
|
191
309
|
| `ctx evidence` | Shows detailed evidence behind the last report for the current workspace. | You want to inspect why a rule was marked `followed`, `ignored`, or `unknown`. | Prints rule text, source file, score, status, and evidence reason. |
|
|
192
310
|
| `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. |
|
|
193
311
|
| `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. |
|
|
194
|
-
| `ctx
|
|
312
|
+
| `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`. |
|
|
314
|
+
| `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
|
+
| `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
|
+
| `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
|
+
| `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>` and refreshes skill embeddings. |
|
|
319
|
+
| `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
|
+
| `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
|
+
| `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`. |
|
|
195
322
|
| `ctx --version` | Prints the installed ContextOS CLI version. | You want to confirm which npm version is being executed. | Prints the version from package metadata. |
|
|
196
323
|
|
|
197
324
|
## Runtime Files
|
|
@@ -228,6 +355,8 @@ The workspace id is stored in the target repo at:
|
|
|
228
355
|
|
|
229
356
|
ContextOS also adds `.contextos/` to the repo `.gitignore` so the local marker is not pushed. If the marker cannot be written, ContextOS falls back to a deterministic id generated from the workspace real path.
|
|
230
357
|
|
|
358
|
+
Codex, Claude Code, and Antigravity all write prompt context, reports, evidence, stats, and telemetry through this same workspace id. The same project shares one ContextOS runtime history across agents; different project paths get different workspace directories. Claude Code hooks also use `CLAUDE_PROJECT_DIR` when the hook payload does not include `cwd`, and Antigravity uses `workspacePath` / `workspacePaths` when present.
|
|
359
|
+
|
|
231
360
|
These files are local telemetry only. Hooks do not make network calls.
|
|
232
361
|
|
|
233
362
|
## Project Understanding
|
|
@@ -331,7 +460,7 @@ npm pack --dry-run
|
|
|
331
460
|
Smoke test prompt hook:
|
|
332
461
|
|
|
333
462
|
```bash
|
|
334
|
-
printf '%s' '{"prompt":"
|
|
463
|
+
printf '%s' '{"prompt":"Recheck authen flow","cwd":"'$PWD'","hook_event_name":"UserPromptSubmit"}' \
|
|
335
464
|
| node plugins/ctx/bin/on-prompt.js
|
|
336
465
|
```
|
|
337
466
|
|
|
@@ -367,9 +496,10 @@ contextos-plan.jsx implementation plan/reference
|
|
|
367
496
|
|
|
368
497
|
## Limitations
|
|
369
498
|
|
|
370
|
-
- Codex
|
|
499
|
+
- Codex and Claude Code get prompt context through `additionalContext`; Antigravity gets prompt context through `PreInvocation` `ephemeralMessage`.
|
|
500
|
+
- Antigravity Stop hooks store reports locally, but they do not display the full report inline unless Antigravity adds a non-continuing Stop message surface.
|
|
371
501
|
- Local marketplace plugin hooks may not fire reliably in current Codex builds, so `ctx install` also installs global hooks.
|
|
372
|
-
- Injection mode may show a visible
|
|
502
|
+
- Injection mode may show a visible hook context block in some agents.
|
|
373
503
|
- Quiet mode does not inject context into the model; it only records and measures.
|
|
374
504
|
- Compliance is heuristic and mostly based on git diff/status.
|
|
375
505
|
- Some rules can only be `unknown` unless ContextOS records richer telemetry such as tool calls or shell command metadata.
|
package/bin/ctx.js
CHANGED
|
@@ -10,12 +10,20 @@ import { scheduleContext } from "../plugins/ctx/lib/scheduler.js";
|
|
|
10
10
|
import { formatEvidence, formatReport } from "../plugins/ctx/lib/reporter.js";
|
|
11
11
|
import { installGlobalHooks } from "../plugins/ctx/lib/global-hooks.js";
|
|
12
12
|
import { formatStats, loadStats } from "../plugins/ctx/lib/stats.js";
|
|
13
|
-
import { modelCacheDir, warmRuleEmbeddings } from "../plugins/ctx/lib/embedding-scorer.js";
|
|
13
|
+
import { isModelCacheReady, modelCacheDir, warmRuleEmbeddings } from "../plugins/ctx/lib/embedding-scorer.js";
|
|
14
14
|
import { warmFileEmbeddings } from "../plugins/ctx/lib/file-embedding-retriever.js";
|
|
15
15
|
import { scoreContext } from "../plugins/ctx/lib/score-context.js";
|
|
16
16
|
import { defaultDataRoot, workspaceDataDir, workspaceMarkerPath } from "../plugins/ctx/lib/workspace-data.js";
|
|
17
17
|
import { installMcpTelemetryProxies } from "../plugins/ctx/lib/mcp-proxy-install.js";
|
|
18
18
|
import { benchmarkWorkspace, formatBenchmark } from "../plugins/ctx/lib/benchmark.js";
|
|
19
|
+
import { copyDir, copyPackageRoot } from "../plugins/ctx/lib/package-install.js";
|
|
20
|
+
import { installClaudeHooks } from "../plugins/ctx/lib/claude-hooks.js";
|
|
21
|
+
import { installClaudeMcp } from "../plugins/ctx/lib/claude-mcp.js";
|
|
22
|
+
import { installAntigravityHooks } from "../plugins/ctx/lib/antigravity-hooks.js";
|
|
23
|
+
import { installAntigravityMcp } from "../plugins/ctx/lib/antigravity-mcp.js";
|
|
24
|
+
import { syncRules } from "../plugins/ctx/lib/ruler-sync.js";
|
|
25
|
+
import { syncSkills } from "../plugins/ctx/lib/skillshare-sync.js";
|
|
26
|
+
import { scanSkills, warmSkillEmbeddings } from "../plugins/ctx/lib/skill-discoverer.js";
|
|
19
27
|
|
|
20
28
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
21
29
|
const rootDir = path.resolve(__dirname, "..");
|
|
@@ -26,6 +34,10 @@ function usage() {
|
|
|
26
34
|
|
|
27
35
|
Usage:
|
|
28
36
|
ctx install
|
|
37
|
+
ctx install codex
|
|
38
|
+
ctx install claude
|
|
39
|
+
ctx install agy
|
|
40
|
+
ctx install --agent codex|claude|agy
|
|
29
41
|
ctx install --quiet
|
|
30
42
|
ctx install --inject
|
|
31
43
|
ctx install --copy
|
|
@@ -34,6 +46,14 @@ Usage:
|
|
|
34
46
|
ctx evidence
|
|
35
47
|
ctx stats
|
|
36
48
|
ctx benchmark -- "task"
|
|
49
|
+
ctx sync --rules
|
|
50
|
+
ctx sync --rules --agents codex,claude,antigravity
|
|
51
|
+
ctx sync --rules --dry-run
|
|
52
|
+
ctx sync --rules --no-import-codex-mcp
|
|
53
|
+
ctx sync --skills
|
|
54
|
+
ctx sync --skills --dry-run
|
|
55
|
+
ctx sync --skills --no-collect
|
|
56
|
+
ctx sync --skills --agents codex,claude,antigravity
|
|
37
57
|
ctx embeddings warm -- "task"
|
|
38
58
|
ctx --version
|
|
39
59
|
`;
|
|
@@ -52,31 +72,6 @@ function codexHome() {
|
|
|
52
72
|
return process.env.CODEX_HOME || path.join(process.env.HOME || process.cwd(), ".codex");
|
|
53
73
|
}
|
|
54
74
|
|
|
55
|
-
function copyDir(src, dest) {
|
|
56
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
57
|
-
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
58
|
-
const srcPath = path.join(src, entry.name);
|
|
59
|
-
const destPath = path.join(dest, entry.name);
|
|
60
|
-
if (entry.isDirectory()) {
|
|
61
|
-
copyDir(srcPath, destPath);
|
|
62
|
-
} else if (entry.isFile()) {
|
|
63
|
-
fs.copyFileSync(srcPath, destPath);
|
|
64
|
-
fs.chmodSync(destPath, fs.statSync(srcPath).mode);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function copyPath(src, dest) {
|
|
70
|
-
const stat = fs.statSync(src);
|
|
71
|
-
if (stat.isDirectory()) {
|
|
72
|
-
copyDir(src, dest);
|
|
73
|
-
} else {
|
|
74
|
-
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
75
|
-
fs.copyFileSync(src, dest);
|
|
76
|
-
fs.chmodSync(dest, stat.mode);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
75
|
function copyInstall() {
|
|
81
76
|
const target = path.join(codexHome(), "plugins", "ctx");
|
|
82
77
|
fs.rmSync(target, { recursive: true, force: true });
|
|
@@ -85,19 +80,59 @@ function copyInstall() {
|
|
|
85
80
|
console.log("Restart Codex if it was already running, then submit a task to trigger ContextOS.");
|
|
86
81
|
}
|
|
87
82
|
|
|
88
|
-
|
|
83
|
+
function agentInstallRoot(agent) {
|
|
84
|
+
return path.join(contextOSDataDir(), "agents", agent, "contextos");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function install({ copy = false, inject = true, agent = "codex" } = {}) {
|
|
89
88
|
if (copy) {
|
|
90
89
|
copyInstall();
|
|
91
90
|
return;
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
93
|
+
if (agent === "claude") {
|
|
94
|
+
const installRoot = copyPackageRoot({ rootDir, targetRoot: agentInstallRoot("claude") });
|
|
95
|
+
const hooksPath = installClaudeHooks({ installRoot, injectPromptContext: inject });
|
|
96
|
+
const mcpConfigPath = installClaudeMcp({ installRoot });
|
|
97
|
+
const warmResult = await warmInstallEmbeddings();
|
|
98
|
+
console.log("Installed ctx hooks for Claude Code.");
|
|
99
|
+
console.log(`Stable install root: ${installRoot}`);
|
|
100
|
+
console.log(`Installed ContextOS hooks to ${hooksPath}`);
|
|
101
|
+
console.log(`Installed ctx-mcp MCP server to ${mcpConfigPath}`);
|
|
102
|
+
console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
|
|
103
|
+
console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
|
|
104
|
+
console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
|
|
105
|
+
console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
|
|
106
|
+
console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
|
|
107
|
+
console.log("Restart Claude Code if it was already running, then submit a task to trigger ContextOS.");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (agent === "agy") {
|
|
112
|
+
const installRoot = copyPackageRoot({ rootDir, targetRoot: agentInstallRoot("agy") });
|
|
113
|
+
const hooksPath = installAntigravityHooks({ installRoot, injectPromptContext: inject });
|
|
114
|
+
const mcpConfigPaths = installAntigravityMcp({ installRoot });
|
|
115
|
+
const warmResult = await warmInstallEmbeddings();
|
|
116
|
+
console.log("Installed ctx hooks for Antigravity.");
|
|
117
|
+
console.log(`Stable install root: ${installRoot}`);
|
|
118
|
+
console.log(`Installed ContextOS hooks to ${hooksPath}`);
|
|
119
|
+
console.log(`Installed ctx-mcp MCP server to ${mcpConfigPaths.join(", ")}`);
|
|
120
|
+
console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
|
|
121
|
+
console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
|
|
122
|
+
console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
|
|
123
|
+
console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
|
|
124
|
+
console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
|
|
125
|
+
console.log("Restart Antigravity or agy if it was already running, then submit a task to trigger ContextOS.");
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (agent !== "codex") {
|
|
130
|
+
throw new Error(`Unknown agent '${agent}'. Expected codex, claude, or agy.`);
|
|
99
131
|
}
|
|
100
132
|
|
|
133
|
+
const marketplaceRoot = path.join(codexHome(), "marketplaces", "contextos");
|
|
134
|
+
copyPackageRoot({ rootDir, targetRoot: marketplaceRoot });
|
|
135
|
+
|
|
101
136
|
tryRunCodex(["plugin", "remove", "ctx@contextos"]);
|
|
102
137
|
tryRunCodex(["plugin", "marketplace", "remove", "contextos"]);
|
|
103
138
|
tryRunCodex(["mcp", "remove", "ctx-mcp"]);
|
|
@@ -107,7 +142,6 @@ async function install({ copy = false, inject = true } = {}) {
|
|
|
107
142
|
const proxyResult = installMcpTelemetryProxies({ codexHome: codexHome(), marketplaceRoot });
|
|
108
143
|
const hooksPath = installGlobalHooks({ codexHome: codexHome(), marketplaceRoot, injectPromptContext: inject });
|
|
109
144
|
|
|
110
|
-
console.log("Preparing required local embedding model...");
|
|
111
145
|
const warmResult = await warmInstallEmbeddings();
|
|
112
146
|
console.log("Installed ctx through Codex plugin marketplace.");
|
|
113
147
|
console.log(`Stable marketplace root: ${marketplaceRoot}`);
|
|
@@ -117,12 +151,17 @@ async function install({ copy = false, inject = true } = {}) {
|
|
|
117
151
|
console.log(`Embedding model cache: ${modelCacheDir(contextOSDataDir())}`);
|
|
118
152
|
console.log(`Embedding vectors cache: ${warmResult.cachePath}`);
|
|
119
153
|
console.log(`File path embeddings warmed: ${warmResult.fileCount || 0}`);
|
|
154
|
+
console.log(`Skill embeddings warmed: ${warmResult.skillCount || 0}`);
|
|
120
155
|
console.log(`Prompt context injection: ${inject ? "enabled" : "quiet logging only"}`);
|
|
121
156
|
console.log("Restart Codex if it was already running, then submit a task to trigger ContextOS.");
|
|
122
157
|
}
|
|
123
158
|
|
|
124
159
|
async function warmInstallEmbeddings() {
|
|
125
160
|
const dataDir = contextOSDataDir();
|
|
161
|
+
const modelReady = isModelCacheReady(dataDir);
|
|
162
|
+
console.log(modelReady
|
|
163
|
+
? "Required local embedding model already cached."
|
|
164
|
+
: "Preparing required local embedding model...");
|
|
126
165
|
const result = await warmRuleEmbeddings({
|
|
127
166
|
rules: [
|
|
128
167
|
{ content: "Always use project rules that are semantically relevant to the user prompt." },
|
|
@@ -132,14 +171,19 @@ async function warmInstallEmbeddings() {
|
|
|
132
171
|
task: "kiểm duyệt upload moderation semantic code search",
|
|
133
172
|
dataDir,
|
|
134
173
|
sources: [],
|
|
135
|
-
allowRemote:
|
|
174
|
+
allowRemote: !modelReady
|
|
136
175
|
});
|
|
137
176
|
const fileResult = await warmFileEmbeddings({
|
|
138
177
|
cwd: process.cwd(),
|
|
139
178
|
dataDir,
|
|
140
|
-
allowRemote:
|
|
179
|
+
allowRemote: !modelReady
|
|
141
180
|
});
|
|
142
|
-
|
|
181
|
+
const skillResult = await warmSkillEmbeddings({
|
|
182
|
+
cwd: process.cwd(),
|
|
183
|
+
dataDir,
|
|
184
|
+
allowRemote: !modelReady
|
|
185
|
+
});
|
|
186
|
+
return { ...result, modelAlreadyCached: modelReady, fileCount: fileResult.count, skillCount: skillResult.count };
|
|
143
187
|
}
|
|
144
188
|
|
|
145
189
|
function tryRunCodex(args) {
|
|
@@ -196,7 +240,8 @@ async function debug(task) {
|
|
|
196
240
|
});
|
|
197
241
|
const rules = scored.scoredRules;
|
|
198
242
|
const relevantFiles = scored.suggestedFiles.slice(0, 3);
|
|
199
|
-
const
|
|
243
|
+
const suggestedSkills = (scored.suggestedSkills || []).slice(0, 3);
|
|
244
|
+
const scheduled = scheduleContext({ rules, relevantFiles, suggestedSkills });
|
|
200
245
|
|
|
201
246
|
console.log("ContextOS debug");
|
|
202
247
|
console.log(`cwd: ${cwd}`);
|
|
@@ -220,6 +265,14 @@ async function debug(task) {
|
|
|
220
265
|
}
|
|
221
266
|
if (!relevantFiles.length) console.log("(none)");
|
|
222
267
|
console.log("");
|
|
268
|
+
console.log("Suggested skills:");
|
|
269
|
+
for (const skill of suggestedSkills) {
|
|
270
|
+
const score = Number(skill.score || 0).toFixed(2);
|
|
271
|
+
const location = skill.path ? ` path:${skill.path}` : "";
|
|
272
|
+
console.log(`${score} ${skill.name}${location}`);
|
|
273
|
+
}
|
|
274
|
+
if (!suggestedSkills.length) console.log("(none)");
|
|
275
|
+
console.log("");
|
|
223
276
|
console.log("Final additionalContext:");
|
|
224
277
|
console.log(scheduled.additionalContext || "(empty)");
|
|
225
278
|
}
|
|
@@ -240,21 +293,38 @@ async function warmEmbeddings(task) {
|
|
|
240
293
|
dataDir: contextOSDataDir(),
|
|
241
294
|
allowRemote: true
|
|
242
295
|
});
|
|
296
|
+
const skillResult = await warmSkillEmbeddings({
|
|
297
|
+
cwd,
|
|
298
|
+
dataDir: contextOSDataDir(),
|
|
299
|
+
allowRemote: true
|
|
300
|
+
});
|
|
243
301
|
console.log(`Warmed ${result.count} embeddings`);
|
|
244
302
|
console.log(`Warmed ${fileResult.count} file path embeddings`);
|
|
303
|
+
console.log(`Warmed ${skillResult.count} skill embeddings`);
|
|
245
304
|
console.log(`Cache: ${result.cachePath}`);
|
|
246
305
|
}
|
|
247
306
|
|
|
248
307
|
const args = process.argv.slice(2);
|
|
249
308
|
const command = args[0];
|
|
250
309
|
|
|
310
|
+
function installAgentFromArgs(args) {
|
|
311
|
+
const agentFlag = args.indexOf("--agent");
|
|
312
|
+
if (agentFlag >= 0) return args[agentFlag + 1] || "";
|
|
313
|
+
const firstValue = args.slice(1).find((arg) => !arg.startsWith("--"));
|
|
314
|
+
return firstValue || "codex";
|
|
315
|
+
}
|
|
316
|
+
|
|
251
317
|
try {
|
|
252
318
|
if (!command || command === "--help" || command === "-h") {
|
|
253
319
|
console.log(usage());
|
|
254
320
|
} else if (command === "--version" || command === "-v") {
|
|
255
321
|
console.log(packageVersion());
|
|
256
322
|
} else if (command === "install") {
|
|
257
|
-
await install({
|
|
323
|
+
await install({
|
|
324
|
+
copy: args.includes("--copy"),
|
|
325
|
+
inject: !args.includes("--quiet"),
|
|
326
|
+
agent: installAgentFromArgs(args)
|
|
327
|
+
});
|
|
258
328
|
} else if (command === "debug") {
|
|
259
329
|
const marker = args.indexOf("--");
|
|
260
330
|
const task = marker >= 0 ? args.slice(marker + 1).join(" ") : args.slice(1).join(" ");
|
|
@@ -279,6 +349,21 @@ try {
|
|
|
279
349
|
const task = marker >= 0 ? args.slice(marker + 1).join(" ") : args.slice(1).join(" ");
|
|
280
350
|
if (!task.trim()) throw new Error('Usage: ctx benchmark -- "task"');
|
|
281
351
|
console.log(formatBenchmark(benchmarkWorkspace({ cwd: process.cwd(), task })));
|
|
352
|
+
} else if (command === "sync") {
|
|
353
|
+
if (args.includes("--skills")) {
|
|
354
|
+
await syncSkills({
|
|
355
|
+
cwd: process.cwd(),
|
|
356
|
+
args: args.slice(1),
|
|
357
|
+
rebuildSkillEmbeddings: async ({ cwd, sourceDir }) => warmSkillEmbeddings({
|
|
358
|
+
cwd,
|
|
359
|
+
dataDir: contextOSDataDir(),
|
|
360
|
+
allowRemote: !isModelCacheReady(contextOSDataDir()),
|
|
361
|
+
skills: scanSkills({ cwd, roots: [sourceDir] })
|
|
362
|
+
})
|
|
363
|
+
});
|
|
364
|
+
} else {
|
|
365
|
+
await syncRules({ cwd: process.cwd(), rootDir, args: args.slice(1) });
|
|
366
|
+
}
|
|
282
367
|
} else {
|
|
283
368
|
throw new Error(`Unknown command: ${command}\n\n${usage()}`);
|
|
284
369
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minhpnq1807/contextos",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Task-aware AGENTS.md context injection and compliance reporting for Codex.",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Task-aware AGENTS.md context injection and compliance reporting for Codex, Claude Code, and Antigravity.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"ctx": "bin/ctx.js"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"CHANGELOG.md"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test": "vitest run",
|
|
19
|
+
"test": "vitest run test",
|
|
20
20
|
"build": "node bin/ctx.js --version",
|
|
21
21
|
"validate:plugin": "node test/validate-plugin.js",
|
|
22
22
|
"test:mcp": "node test/mcp-protocol-smoke.js"
|
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
},
|
|
30
30
|
"keywords": [
|
|
31
31
|
"codex",
|
|
32
|
+
"claude-code",
|
|
33
|
+
"antigravity",
|
|
34
|
+
"agy",
|
|
32
35
|
"plugin",
|
|
33
36
|
"agents",
|
|
34
37
|
"context",
|