0xray 4.0.12 → 4.0.14

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.
Files changed (58) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.xray/features.json +1 -1
  3. package/.xray/features.schema.json +1 -1
  4. package/AGENTS-consumer.md +4 -2
  5. package/AGENTS.md +8 -1
  6. package/README.md +1 -1
  7. package/SKILLS.md +1 -1
  8. package/dist/AGENTS.md +8 -1
  9. package/dist/CHANGELOG.md +25 -1
  10. package/dist/README.md +1 -1
  11. package/dist/SKILLS.md +1 -1
  12. package/dist/integrations/cursor/README.md +61 -0
  13. package/dist/integrations/cursor/hooks/after-file-edit.js +38 -0
  14. package/dist/integrations/cursor/hooks/cursor-hook-utils.js +170 -0
  15. package/dist/integrations/cursor/hooks/cursor-usage-receipt.js +298 -0
  16. package/dist/integrations/cursor/hooks/hooks.json +20 -0
  17. package/dist/integrations/cursor/hooks/pre-compact.js +88 -0
  18. package/dist/integrations/cursor/hooks/pre-tool-use.js +105 -0
  19. package/dist/integrations/hooks/station-hook-runtime.cjs +89 -1
  20. package/dist/integrations/hooks/station-hook-runtime.mjs +2 -0
  21. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  22. package/dist/nucleus/suit-temperament.d.ts +2 -2
  23. package/dist/nucleus/suit-temperament.js +3 -1
  24. package/llms.txt +6 -4
  25. package/package.json +4 -2
  26. package/scripts/foundry/CHANGELOG.md +37 -1
  27. package/scripts/foundry/README.md +13 -1
  28. package/scripts/foundry/assert-packed-dist-cli.mjs +97 -0
  29. package/scripts/foundry/blip-render.cjs +1237 -0
  30. package/scripts/foundry/blip-rippel.cjs +1963 -0
  31. package/scripts/foundry/blip.mjs +109 -0
  32. package/scripts/foundry/cli.mjs +8 -4
  33. package/scripts/foundry/inspect.mjs +117 -7
  34. package/scripts/foundry/mint-suit.cjs +215 -14
  35. package/scripts/foundry/package.json +7 -1
  36. package/scripts/foundry/plant/agents/blip-inspect.yml +5 -0
  37. package/scripts/foundry/plant/agents/blip.yml +5 -0
  38. package/scripts/foundry/plant/agents/inspect.yml +1 -1
  39. package/scripts/foundry/plant/agents/mill.yml +1 -1
  40. package/scripts/foundry/plant/agents/sound-inspect.yml +5 -0
  41. package/scripts/foundry/plant/agents/sound.yml +5 -0
  42. package/scripts/foundry/plant/motions/MOTION-REGISTRY.md +35 -0
  43. package/scripts/foundry/plant/motions/registry.json +81 -0
  44. package/scripts/foundry/plant/skills/blip/SKILL.md +39 -0
  45. package/scripts/foundry/plant/skills/blip-inspect/SKILL.md +32 -0
  46. package/scripts/foundry/plant/skills/inspect/SKILL.md +2 -2
  47. package/scripts/foundry/plant/skills/sound/SKILL.md +29 -0
  48. package/scripts/foundry/plant/skills/sound-inspect/SKILL.md +28 -0
  49. package/scripts/foundry/release-gate.mjs +18 -10
  50. package/scripts/foundry/release.mjs +3 -0
  51. package/scripts/foundry/sound-bed.cjs +454 -0
  52. package/scripts/foundry/sound-rippel.cjs +1434 -0
  53. package/scripts/foundry/sound.mjs +93 -0
  54. package/scripts/node/assert-packed-dist-cli.mjs +4 -0
  55. package/scripts/node/consumer-install-smoke.mjs +20 -1
  56. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  57. package/xray/features.json +1 -1
  58. package/xray/features.schema.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xray",
3
- "version": "4.0.12",
3
+ "version": "4.0.14",
4
4
  "description": "0xRay suit for Grok, Hermes, OpenClaw, OpenCode: mill+inspect, Codex, 7 MCP servers. Costume 45/42 is opt-in foundry, not the default wear.",
5
5
  "author": {
6
6
  "name": "0xRay AI",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./features.schema.json",
3
- "version": "4.0.12",
3
+ "version": "4.0.14",
4
4
  "description": "0xRay Framework - Unified Feature Configuration",
5
5
  "suit_temperament": {
6
6
  "profile": "auto",
@@ -104,7 +104,7 @@
104
104
  "profile": {
105
105
  "type": "string",
106
106
  "enum": ["auto", "frontier", "guided", "strict"],
107
- "description": "auto = host_defaults (grok→frontier, hermes/opencode/openclaw→guided)"
107
+ "description": "auto = host_defaults (grok/cursor→frontier, hermes/opencode/openclaw→guided)"
108
108
  },
109
109
  "host_defaults": {
110
110
  "type": "object",
@@ -19,7 +19,7 @@ Before other work, Read `.xray/state/STATION.md`. Compaction and host change are
19
19
  `npm install 0xray` runs `install-bridges.cjs` and:
20
20
 
21
21
  - Copies this file → **`AGENTS.md`** in your project root
22
- - Fastens mill plant (`mill` + `inspect`) then overlays **your** `src/skills` (same name wins). `npx @0xray/foundry inspect` runs the mill checks (chat is not a receipt). Does **not** dump 45/42 costume unless `foundry.json` `"costume": true`. Does **not** write root **`SKILLS.md`**
22
+ - Fastens mill plant (`mill` + `inspect`) then overlays **your** `src/skills` (same name wins). Sound seats: `foundry.json` `"plant": "sound"` fastens `sound` + `sound-inspect` (mill off). Blip seats: `foundry.json` `"plant": "blip"` fastens `blip` + `blip-inspect` (mill off). `npx @0xray/foundry inspect` runs the mill checks; on a sound seat it also reports the last bed receipt; on a blip seat the last 4.44s receipt. Chat is not a receipt. Does **not** dump 45/42 costume unless `foundry.json` `"costume": true`. Does **not** write root **`SKILLS.md`**
23
23
  - Factory shop plant (`shop-extract`, `shop-witness`, `shop-pin` from groover-hangar) is first-class with mill plant. Extra shops: `foundry.json` `"shopPlant"`. Not costume.
24
24
  - Seeds **`.gitignore`** (from template, if absent)
25
25
  - Deploys **`.xray/`** (`codex.json`, `features.json`, `config.json`) then overlays **your** mill SSOT (`xray/codex.json`, `xray/features.json`, `src/skills`, `src/opencode/agents`; remap with `foundry.json`)
@@ -59,7 +59,9 @@ Governance deliberation uses **code-review**, **security-audit** (via enforcer/s
59
59
  | `npx 0xray codex check` | Check codex rules |
60
60
  | `npx 0xray health` | Framework health check |
61
61
  | `npx 0xray mcp <server>` | Start an MCP server (stdio) |
62
- | `npx @0xray/foundry inspect` | Mill inspect (nested mill). Chat is not a receipt. |
62
+ | `npx @0xray/foundry inspect` | Mill inspect (nested mill). Sound seat: plant + last bed PASS/FAIL. Blip seat: last 4.44s PASS/FAIL. Chat is not a receipt. |
63
+ | `npx @0xray/foundry sound render` | Factory-sound bed: brief → seed → genre → crystal mill wav → metrics receipt. |
64
+ | `npx @0xray/foundry blip render` | Factory-blip plant: brief → seed → still\|motion:<id> → 4.44s mp4 + audio bed. Motions are Rippel v2 VisualConfig at ≥720p. Sparse seed mesh plus field accents (stars, grids, gradients, blinkers) are the NFT fingerprints. `still` is the Power Plant ident (plate dissolves, not a frozen poster). |
63
65
 
64
66
  ## Governance
65
67
 
package/AGENTS.md CHANGED
@@ -43,7 +43,7 @@ Governance deliberation: **code-review**, **security-audit**, **researcher** wit
43
43
  `postinstall.cjs` → `installAllBridges()`:
44
44
 
45
45
  1. `AGENTS-consumer.md` → `AGENTS.md` (does **not** write consumer-root `SKILLS.md`)
46
- 2. Fasten mill plant (`mill` + `inspect`). Not a 45-skill costume dump unless `foundry.json` `"costume": true`
46
+ 2. Fasten mill plant (`mill` + `inspect`). Sound seats: `foundry.json` `"plant": "sound"` fastens `sound` + `sound-inspect` and turns mill off. Blip seats: `foundry.json` `"plant": "blip"` fastens `blip` + `blip-inspect` and turns mill off. Not a 45-skill costume dump unless `foundry.json` `"costume": true`
47
47
  3. `.gitignore.default` → `.gitignore` (if absent)
48
48
  4. `.xray/` config (`codex.json`, `features.json`, `config.json`) then overlay their plant
49
49
  5. `.mcp.json` (7 servers)
@@ -52,8 +52,14 @@ Governance deliberation: **code-review**, **security-audit**, **researcher** wit
52
52
 
53
53
  **Shop plant:** `shop-extract`, `shop-witness`, `shop-pin` (groover-hangar) are first-class with mill plant. Extra shops: `foundry.json` `shopPlant`. Not `"costume": true`. `npx @0xray/foundry inspect --skip-live` is the receipt.
54
54
 
55
+ **Sound plant:** Dist audio beds get a real plant like mill. `"plant": "sound"` + `npx @0xray/foundry sound render` writes a crystal-clear wav (Rippel membrane/metal/mixer, not a sine toy) and a bed receipt. Inspect checks loudness/smoothness gates — not fake code-mill skills on a sound seat.
56
+
57
+ **Blip plant:** New factory plant sibling to mill + sound (not a mill copy). Hangar shop pair later. `"plant": "blip"` + `npx @0xray/foundry blip render --brief "..." --mode still|motion:orb` writes a 4.44s mp4 **with an audio bed**. Registry v0: still + Rippel five (`orb` `swirl` `snap` `waves` `spark`). Motions are Rippel v2 `VisualConfig.circles` at ≥720p — sharp look + tempo/frequency animation on all five (wireframe is `--engine wireframe` only). Auto bed syncopates to the motion grid. Each mint wears a sparse seed mesh plus field accents (stars, grids, gradients, blinkers); receipt `visualConfig.mesh` + `visualConfig.field` are the fingerprints. `kapow` is a growth stub. `still` is the Power Plant ident — plate dissolves over 4.44s at ≥720p (`#08090B` `#F5F7FA` `#3DE0E8` `#F5C518` `#4A7FD4`), not a frozen poster. Inspect checks duration / mode id / file / audio.
58
+
55
59
  ## Memory routing + Repertoire (v3.3+)
56
60
 
61
+ **Station is the successor card** (Read `.xray/state/STATION.md`). Repertoire 0.2 is a thin routing seed (8 factory names). 0.1.0–0.1.8 were the same judgment organ; do not pin 0.1.8 for mill wear. Split: `docs-site/docs/guides/station-vs-repertoire.md`.
62
+
57
63
  `xray/features.json` → `memory_routing` (schema: `features.schema.json`):
58
64
 
59
65
  ```json
@@ -216,6 +222,7 @@ Full skill mapping: [SKILLS.md](SKILLS.md).
216
222
  | Platform integrations | `docs-site/docs/guides/integrations.md` |
217
223
  | Memory routing | `docs-site/docs/guides/memory-routing.md` |
218
224
  | Repertoire | `docs-site/docs/guides/repertoire.md` |
225
+ | Station vs Repertoire 0.1 | `docs-site/docs/guides/station-vs-repertoire.md` |
219
226
  | AsideContext | `docs-site/docs/guides/aside-context.md` |
220
227
  | Consumer migration | `docs-site/docs/guides/consumer-migration.md` |
221
228
  | Docusaurus site | https://0xrayai.github.io/xray/ |
package/README.md CHANGED
@@ -103,7 +103,7 @@ Docs: [guides/autonomy-command](docs-site/docs/guides/autonomy-command.md) · Sk
103
103
  On `npm install 0xray` in a consumer project, postinstall automatically:
104
104
 
105
105
  1. Copies **`AGENTS-consumer.md` → `AGENTS.md`**. Does **not** write consumer-root **`SKILLS.md`**.
106
- 2. Fastens **mill plant** (`mill` + `inspect`). Not a 45-skill / 42-agent costume dump. `foundry.json` `"costume": true` is the opt-in dump.
106
+ 2. Fastens **mill plant** (`mill` + `inspect`). Sound seats: `foundry.json` `"plant": "sound"` fastens the bed factory (`sound` + `sound-inspect`) and turns mill off. Blip seats: `foundry.json` `"plant": "blip"` fastens the tiny-video factory (`blip` + `blip-inspect`) and turns mill off. Not a 45-skill / 42-agent costume dump. `foundry.json` `"costume": true` is the opt-in dump.
107
107
  3. Seeds **`.gitignore`** from `.gitignore.default` (if absent)
108
108
  4. Deploys **`.xray/`** config (`codex.json`, `features.json`, `config.json`) then overlays **their** plant
109
109
  5. Writes project **`.mcp.json`** with 7 MCPs servers (`npx -y 0xray mcp …`)
package/SKILLS.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **4.0** — a suit that survives the context window
4
4
 
5
- **45 skills** in this exo catalog. Default consumer plant is **`mill` + `inspect`**, not this dump. `npm install 0xray` does **not** sync 45 skills unless `foundry.json` `"costume": true`. Factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) coexists with mill plant when a hangar wears those shops. Extra shops: `foundry.json` `shopPlant`. Agent map: [llms.txt](llms.txt).
5
+ **45 skills** in this exo catalog. Default consumer plant is **`mill` + `inspect`**, not this dump. `npm install 0xray` does **not** sync 45 skills unless `foundry.json` `"costume": true`. Factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) coexists with mill plant when a hangar wears those shops. Extra shops: `foundry.json` `shopPlant`. Sound seats: `foundry.json` `"plant": "sound"` (foundry plant, not this catalog). Blip seats: `foundry.json` `"plant": "blip"` (foundry plant, not this catalog). Agent map: [llms.txt](llms.txt).
6
6
 
7
7
  xray ships 45 knowledge skills (`src/skills/<name>/SKILL.md`) as the **costume / self-plant catalog**. Lead-dev operating model lives in **`orchestrator`** skill + `multi_agent_orchestration.lead_dev_mode` in features.json. Skills load on demand via the **xray-skills** MCP server (`npx -y 0xray mcp skills`) or when you plant them. This file is the exo catalog — mill does **not** write it to the consumer root.
8
8
 
package/dist/AGENTS.md CHANGED
@@ -43,7 +43,7 @@ Governance deliberation: **code-review**, **security-audit**, **researcher** wit
43
43
  `postinstall.cjs` → `installAllBridges()`:
44
44
 
45
45
  1. `AGENTS-consumer.md` → `AGENTS.md` (does **not** write consumer-root `SKILLS.md`)
46
- 2. Fasten mill plant (`mill` + `inspect`). Not a 45-skill costume dump unless `foundry.json` `"costume": true`
46
+ 2. Fasten mill plant (`mill` + `inspect`). Sound seats: `foundry.json` `"plant": "sound"` fastens `sound` + `sound-inspect` and turns mill off. Blip seats: `foundry.json` `"plant": "blip"` fastens `blip` + `blip-inspect` and turns mill off. Not a 45-skill costume dump unless `foundry.json` `"costume": true`
47
47
  3. `.gitignore.default` → `.gitignore` (if absent)
48
48
  4. `.xray/` config (`codex.json`, `features.json`, `config.json`) then overlay their plant
49
49
  5. `.mcp.json` (7 servers)
@@ -52,8 +52,14 @@ Governance deliberation: **code-review**, **security-audit**, **researcher** wit
52
52
 
53
53
  **Shop plant:** `shop-extract`, `shop-witness`, `shop-pin` (groover-hangar) are first-class with mill plant. Extra shops: `foundry.json` `shopPlant`. Not `"costume": true`. `npx @0xray/foundry inspect --skip-live` is the receipt.
54
54
 
55
+ **Sound plant:** Dist audio beds get a real plant like mill. `"plant": "sound"` + `npx @0xray/foundry sound render` writes a crystal-clear wav (Rippel membrane/metal/mixer, not a sine toy) and a bed receipt. Inspect checks loudness/smoothness gates — not fake code-mill skills on a sound seat.
56
+
57
+ **Blip plant:** New factory plant sibling to mill + sound (not a mill copy). Hangar shop pair later. `"plant": "blip"` + `npx @0xray/foundry blip render --brief "..." --mode still|motion:orb` writes a 4.44s mp4 **with an audio bed**. Registry v0: still + Rippel five (`orb` `swirl` `snap` `waves` `spark`). Motions are Rippel v2 `VisualConfig.circles` at ≥720p — sharp look + tempo/frequency animation on all five (wireframe is `--engine wireframe` only). Auto bed syncopates to the motion grid. Each mint wears a sparse seed mesh plus field accents (stars, grids, gradients, blinkers); receipt `visualConfig.mesh` + `visualConfig.field` are the fingerprints. `kapow` is a growth stub. `still` is the Power Plant ident — plate dissolves over 4.44s at ≥720p (`#08090B` `#F5F7FA` `#3DE0E8` `#F5C518` `#4A7FD4`), not a frozen poster. Inspect checks duration / mode id / file / audio.
58
+
55
59
  ## Memory routing + Repertoire (v3.3+)
56
60
 
61
+ **Station is the successor card** (Read `.xray/state/STATION.md`). Repertoire 0.2 is a thin routing seed (8 factory names). 0.1.0–0.1.8 were the same judgment organ; do not pin 0.1.8 for mill wear. Split: `docs-site/docs/guides/station-vs-repertoire.md`.
62
+
57
63
  `xray/features.json` → `memory_routing` (schema: `features.schema.json`):
58
64
 
59
65
  ```json
@@ -216,6 +222,7 @@ Full skill mapping: [SKILLS.md](SKILLS.md).
216
222
  | Platform integrations | `docs-site/docs/guides/integrations.md` |
217
223
  | Memory routing | `docs-site/docs/guides/memory-routing.md` |
218
224
  | Repertoire | `docs-site/docs/guides/repertoire.md` |
225
+ | Station vs Repertoire 0.1 | `docs-site/docs/guides/station-vs-repertoire.md` |
219
226
  | AsideContext | `docs-site/docs/guides/aside-context.md` |
220
227
  | Consumer migration | `docs-site/docs/guides/consumer-migration.md` |
221
228
  | Docusaurus site | https://0xrayai.github.io/xray/ |
package/dist/CHANGELOG.md CHANGED
@@ -6,18 +6,36 @@ The format is based on [Conventional Commits](https://www.conventionalcommits.or
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ---
10
+
11
+ ## [4.0.14] - 2026-09-16
12
+
9
13
  ### ✨ Features
10
- - Mill inspect treats factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) as first-class with mill plant. `foundry.json` `shopPlant` names more shops. Not `"costume": true`. Nested mill stays **0.1.9**.
14
+ - **Factory-blip prod-grade phrase** — hook/turn/tag now crossfade (`hookEase`/`turnEase`/`tagEase`). Still plates dissolve (~300ms) instead of hard-cutting. Focus orb wears field + mesh mass so two briefs do not clone. Ambient bed writes a 3-section score (turn crash, tag stab, walk on turn). Mill stays deterministic — no LLM in the render loop. No `@0xray/foundry` bump.
15
+ - **Factory-blip Rippel v2** — 4.44s is a Short: hook → turn → tag on one motion grid for picture and bed. Two looks (`focus` disc-satellites | `cage` Wu+field). Stereo AAC bed with a written motif (not `pick()` soup), better voices, mix pocket. Missing stream or inaudible bed FAILs inspect. No `@0xray/foundry` bump.
16
+ - **Factory-blip plant** — new factory plant sibling to mill + sound (not a mill copy). `foundry.json` `"plant": "blip"` fastens `blip` + `blip-inspect`. Dynamic motion registry (not a frozen Rippel enum). v0: still + Rippel five (`still` `orb` `swirl` `snap` `waves` `spark`). `kapow` is a growth stub. Still generator wears the Power Plant intro plate (void `#08090B` · ink `#F5F7FA` · cyan `#3DE0E8` · gold `#F5C518` · agent blue `#4A7FD4`). Hangar shop pair later. Brief → seed → still|motion:<id> → 4.44s mp4 → `.xray/blip/receipt.json`. Unknown id FAIL. No `@0xray/foundry` bump.
17
+ - **Factory-sound crystal mill** — sound plant render locks Rippel SSOT numbers (Membrane octaves 10 / pitchDecay 0.08, Metal harmonicity 5.1, Duo bass, ProfessionalMixer) then mixes crystal-clear (rumble HP, mud cut, sidechain, one limiter). Prototype was the topology, not the quality bar. Tone.Offline blocked in Node. Metrics stay fail-closed. No `@0xray/foundry` bump.
18
+ - **Factory-sound Rippel retool** — sound plant render is membrane kick + metal hat + mixer (Rippel prototype topology). Tone.Offline blocked in Node (`OfflineAudioContext`). `phonk` is first-class. Metrics stay fail-closed. No `@0xray/foundry` bump.
19
+ - **Factory-sound plant** — `foundry.json` `"plant": "sound"` fastens `sound` + `sound-inspect` (mill optional/off). Brief → checksum seed → genre → headless wav → metrics gate → `.xray/sound-bed-receipt.json`. `npx @0xray/foundry sound render|inspect`. Foundry inspect reports sound plant + last bed PASS/FAIL. Not a mill copy. Not costume. No `@0xray/foundry` bump — dogfood from branch/pack.
20
+ - **Cursor cloud hooks adapter** — repo `.cursor/hooks.json` (version 1) runs `preToolUse` / `preCompact` / `afterFileEdit` against 0xRay gates + Station merge. No `sessionStart` (unavailable on managed cloud). Path C seed: `examples/cursor-cloud-compact/` (COMPACT-BEN-001).
21
+ - **Cursor cloud real-usage receipt** — `writeCursorUsageReceipt` records host `preCompact` fire from invoke-probe (Y/N, no hand-invoke) and accepts only host/MCP/dashboard usage fields. FILL / chars÷4 is `ok: false`. Station compact-row + `.xray/state/cursor-usage-receipt.json`. Killer-dual Arm S: `examples/killer-dual/`.
22
+ - Mill inspect treats factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) as first-class with mill plant. `foundry.json` `shopPlant` names more shops. Not `"costume": true`. Nested mill **0.1.10**.
11
23
  - Exo agent map: root `llms.txt` (mill+inspect plant, 7 MCPs, hangar/`shopPlant` coexistence, Codex 69, no costume dump). README / AGENTS / SKILLS / Docusaurus no longer claim default 45-skill sync.
12
24
  - Pack → tmp suit proof: `npm run pack:tmp-proof` (and consumer smoke) installs the packed tgz, runs `foundry mint --skip-live`, plants factory hangar shops, and inspects without costume dump. Playwright n/a (mill CLI).
13
25
 
14
26
  ### 🐛 Bug Fixes
27
+ - **Packed dist/cli gate** — `0xray@4.0.13` listed `dist/` in `files[]` but the npm tarball shipped **0 dist files** (`npx 0xray` fell back to 4.0.9). `npm pack` silently omits missing `files[]` entries. `prepack`, mill `release` / `gate`, and consumer smoke now fail unless the tarball contains `dist/cli/index.js`, `dist/mcps/orchestrator.server.js`, and Grok `session-start.js`. This PR does not publish; forge PUT is 4.0.14 after merge.
28
+ - **Station merge on compact** — PreCompact / PostCompact / SessionStart `writeStationMarkdown` updates stock heat (intent, repertoire, working, host) and **merges** unknown keys plus `## Durable` / `## Seed` blocks. COMPACT-AB-001: no wipe-then-write of ticket / seed / open cloud / unfinished path.
29
+ - **Cursor session-boot is runtime** — `.xray/state/session-boot.json` is gitignored with the Station projection. A tracked leftover Grok boot no longer resurrects on rebase and clobber live compact heat.
15
30
  - **Grok multi-seat wear** — last-mile dest is project `.grok/plugins/0xray`. Shared HOME (passwd `$HOME`) no longer writes machine `~/.grok/plugins/0xray`, so two seats (forge/critic/herald/blinky) cannot last-wins clobber each other's `XRAY_ROOT`. Isolated HOME may wear `$HOME/.grok/plugins/0xray` and still must not write the passwd machine plugin. Inspect reports project dest. Not a 45-skill dump.
31
+ - **Foundry inspect dest lag** — nested mill **0.1.10**. `npx @0xray/foundry inspect` isolated-home `dest` matches `resolveGrokPluginDests` (project `.grok/plugins/0xray` on shared HOME). Published `@0xray/foundry@0.1.9` still joined dest from `$HOME` after 4.0.12 / #29 wear. This PR does not publish the mill.
16
32
  - **Grok marketplace pack** — `package.json` `files` includes `.grok-plugin/` so `npm pack` ships the mill-default Grok manifest (`package/.grok-plugin/plugin.json`). Consumers no longer receive only stale `.plugin/plugin.json`.
17
33
  - **Grok marketplace manifest** — `.grok-plugin/plugin.json` matches `4.0.10`: `author` is an object, `mcpServers` is a flat path (not `components.mcpServers`), description is mill+inspect default wear (not a 45 knowledge-skills claim). Fixes `grok plugin validate`.
18
34
  - **Consumer install of packed `0xray`** — stop shipping `@0xray/repertoire` as `file:./vendor/@0xray/repertoire`. npm `--install-links`, pnpm, and yarn resolve that path from the **consumer** root (`ENOENT .../vendor/@0xray/repertoire/package.json`), not from `node_modules/0xray`. The organ stays in the tarball at `vendor/@0xray/repertoire/`; postinstall wears it into `node_modules/@0xray/repertoire`. Fresh `npm install 0xray` / `npm install 0xray-*.tgz` no longer needs a consumer-root `vendor/` tree. Mill plant (`mill`+`inspect`) unchanged.
19
35
 
20
36
  ### 🔧 Maintenance
37
+ - **HOST-FIRE Arm S** — first live `cursor-host-precompact` on `bc-cd19bb4e` (count=2). Survive receipt + compare: `examples/killer-dual/RECEIPT-HOST-PRECOMPACT.md`, `COMPARE.md`.
38
+ - **HOST-FIRE #3** — `examples/cursor-cloud-compact/RECEIPT-HOST-PRECOMPACT-3.md`: hooks bound at boot + live `preToolUse` spawn; host `preCompact` still did not fire (`cursor-host-precompact-FAIL`).
21
39
  - Foundry mill: one bumper (`reconcile-version.mjs`); `version-manager.mjs` is `--artifacts-only` (JSON + CHANGELOG). Bump and `--tag` are refused.
22
40
  - Docs mill verifies era kernel headers (`4.0`) and skill counts; it does not rewrite markdown prose.
23
41
  - Exo cannot ship: `executeReleaseWorkflow` is blocked (`FOUNDRY_EXO_CANNOT_SHIP`).
@@ -45,6 +63,12 @@ The format is based on [Conventional Commits](https://www.conventionalcommits.or
45
63
 
46
64
  ---
47
65
 
66
+ ## [4.0.13] - 2026-09-14
67
+
68
+ Station PreCompact merge keeps custom STATION.md keys.
69
+
70
+ ---
71
+
48
72
  ## [4.0.12] - 2026-09-12
49
73
 
50
74
  Public npm is still `0xray@4.0.11`, which predates #29. Isolation cannot be proven from `main` alone — bots dogfood the registry. This patch PUT wears project-scoped Grok plugin dest so multi-seat wear does not last-wins clobber machine `~/.grok/plugins/0xray`. Shared HOME writes project `.grok/plugins/0xray` only. Isolated HOME may wear `$HOME/.grok/plugins/0xray` and still must not write the passwd machine plugin. Mill+inspect default. Nested mill stays **0.1.9**. Not 5.0.0. This PR does not publish.
package/dist/README.md CHANGED
@@ -103,7 +103,7 @@ Docs: [guides/autonomy-command](docs-site/docs/guides/autonomy-command.md) · Sk
103
103
  On `npm install 0xray` in a consumer project, postinstall automatically:
104
104
 
105
105
  1. Copies **`AGENTS-consumer.md` → `AGENTS.md`**. Does **not** write consumer-root **`SKILLS.md`**.
106
- 2. Fastens **mill plant** (`mill` + `inspect`). Not a 45-skill / 42-agent costume dump. `foundry.json` `"costume": true` is the opt-in dump.
106
+ 2. Fastens **mill plant** (`mill` + `inspect`). Sound seats: `foundry.json` `"plant": "sound"` fastens the bed factory (`sound` + `sound-inspect`) and turns mill off. Blip seats: `foundry.json` `"plant": "blip"` fastens the tiny-video factory (`blip` + `blip-inspect`) and turns mill off. Not a 45-skill / 42-agent costume dump. `foundry.json` `"costume": true` is the opt-in dump.
107
107
  3. Seeds **`.gitignore`** from `.gitignore.default` (if absent)
108
108
  4. Deploys **`.xray/`** config (`codex.json`, `features.json`, `config.json`) then overlays **their** plant
109
109
  5. Writes project **`.mcp.json`** with 7 MCPs servers (`npx -y 0xray mcp …`)
package/dist/SKILLS.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **4.0** — a suit that survives the context window
4
4
 
5
- **45 skills** in this exo catalog. Default consumer plant is **`mill` + `inspect`**, not this dump. `npm install 0xray` does **not** sync 45 skills unless `foundry.json` `"costume": true`. Factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) coexists with mill plant when a hangar wears those shops. Extra shops: `foundry.json` `shopPlant`. Agent map: [llms.txt](llms.txt).
5
+ **45 skills** in this exo catalog. Default consumer plant is **`mill` + `inspect`**, not this dump. `npm install 0xray` does **not** sync 45 skills unless `foundry.json` `"costume": true`. Factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) coexists with mill plant when a hangar wears those shops. Extra shops: `foundry.json` `shopPlant`. Sound seats: `foundry.json` `"plant": "sound"` (foundry plant, not this catalog). Blip seats: `foundry.json` `"plant": "blip"` (foundry plant, not this catalog). Agent map: [llms.txt](llms.txt).
6
6
 
7
7
  xray ships 45 knowledge skills (`src/skills/<name>/SKILL.md`) as the **costume / self-plant catalog**. Lead-dev operating model lives in **`orchestrator`** skill + `multi_agent_orchestration.lead_dev_mode` in features.json. Skills load on demand via the **xray-skills** MCP server (`npx -y 0xray mcp skills`) or when you plant them. This file is the exo catalog — mill does **not** write it to the consumer root.
8
8
 
@@ -0,0 +1,61 @@
1
+ # Cursor cloud hooks (0xRay)
2
+
3
+ Thin adapter. Repo `.cursor/hooks.json` (schema **version 1**) calls 0xRay gates and the Station PreCompact writer. **sessionStart is not used** — managed Cursor cloud does not fire it.
4
+
5
+ Repertoire MCP is optional. Station + gates work without a full memory-routing rewire.
6
+
7
+ ## How cloud picks up project hooks
8
+
9
+ 1. Commit `.cursor/hooks.json` at the **project root** (this file, not `~/.cursor/hooks.json`).
10
+ 2. Cursor Cloud Agent clones the repo and loads **project** hooks. Desktop Agent Chat does the same when the folder is the workspace.
11
+ 3. Hook names are camelCase: `preToolUse`, `preCompact`, `afterFileEdit`. Commands are shell strings. Stdin is JSON; stdout is JSON.
12
+ 4. First `preToolUse` or `afterFileEdit` writes `.xray/state/session-boot.json` + `.xray/state/STATION.md`. After a compact, **Read STATION.md**. The host does not inject it.
13
+ 5. `preCompact` is observational (cannot block). It merges Station (stock heat updates; ticket / seed / Durable / unfinished keys stay).
14
+
15
+ Copy the consumer template from `src/integrations/cursor/hooks/hooks.json` (dist paths under `node_modules/0xray`) when wearing the published package. This exo repo wears `src/integrations/cursor/hooks/*.js` so a cloud can run before `npm run build`.
16
+
17
+ ## Contracts
18
+
19
+ | Hook | Stdin | Stdout |
20
+ |------|--------|--------|
21
+ | `preToolUse` | Cursor tool event (`tool_name`, `tool_input`, `cwd`, `workspace_roots`, `conversation_id`) | `{ "permission": "allow" \| "deny" }` plus `user_message` / `agent_message` on deny |
22
+ | `preCompact` | `{ trigger, context_tokens, … }` | `{ "user_message": "…" }` after Station write |
23
+ | `afterFileEdit` | file event | `{}` — boots Station only |
24
+
25
+ `preCompact` labels `event_class`:
26
+
27
+ - `cursor-host-precompact` — Cursor actually fired the hook
28
+ - `cursor-precompact-synthetic` — script invoked with `--event-class=cursor-precompact-synthetic` (Path C fallback)
29
+ - `cursor-host-precompact-FAIL` — HOST-FIRE fill ran; host did not spawn `preCompact` (see `RECEIPT-HOST-PRECOMPACT.md`, `-2.md`, `-3.md`)
30
+ - First live host fire (Arm S): `examples/killer-dual/RECEIPT-HOST-PRECOMPACT.md`
31
+
32
+ ## Real usage (replace FILL)
33
+
34
+ Do **not** prove window pressure with UTF-8 chars÷4. `src/integrations/cursor/hooks/cursor-usage-receipt.js` (`writeCursorUsageReceipt`) writes `.xray/state/cursor-usage-receipt.json` + Station `Compact:` / `Usage:` rows. Station `window=` prints host `context_window_size` when stdin sent it; ticket `windowCite` is fallback only. No `dist` required (unlike the constitution gate).
35
+
36
+ | Cite | Valid? |
37
+ |------|--------|
38
+ | `preCompact` stdin `context_tokens` / `context_usage_percent` / `context_window_size` | yes |
39
+ | `cursor-cloud` `run-info` / `get-events` / dashboard (model, bc-id, window) | yes — token MISS is honest |
40
+ | chars÷4, fill-only, `fillBytes` | **forbidden** (`ok: false`) |
41
+
42
+ Host `preCompact` fire is counted from `.xray/state/cursor-hook-invoke.log` (`event=preCompact`). Do not hand-invoke `pre-compact.js` to mint that Y.
43
+
44
+ Arm S landscape + receipt: `examples/killer-dual/`.
45
+
46
+ ## Friend test
47
+
48
+ From the repo root, after `npm run build` (or from `src/` on this exo):
49
+
50
+ ```bash
51
+ echo '{"tool_name":"Read","tool_input":{"path":"README.md"},"cwd":"'"$PWD"'"}' \
52
+ | node src/integrations/cursor/hooks/pre-tool-use.js
53
+ # → {"permission":"allow"}
54
+
55
+ echo '{"hook_event_name":"preCompact","trigger":"auto","context_tokens":1}' \
56
+ | node src/integrations/cursor/hooks/pre-compact.js --event-class=cursor-precompact-synthetic
57
+ # → user_message includes event_class=cursor-precompact-synthetic
58
+ # → Read .xray/state/STATION.md
59
+ ```
60
+
61
+ Path C seed + receipt: `examples/cursor-cloud-compact/`. Suited Arm S (real usage, no FILL): `examples/killer-dual/`.
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Cursor afterFileEdit — boot Station when sessionStart did not fire.
4
+ * Observational; file already written.
5
+ */
6
+
7
+ import {
8
+ appendHookActivity,
9
+ cursorSessionId,
10
+ cursorWorkspaceRoot,
11
+ ensureCursorSessionBoot,
12
+ readStdinJson,
13
+ } from './cursor-hook-utils.js';
14
+
15
+ async function main() {
16
+ const fallbackRoot = cursorWorkspaceRoot();
17
+ try {
18
+ const event = await readStdinJson();
19
+ const eventRoot = cursorWorkspaceRoot(event);
20
+ const bootPath = ensureCursorSessionBoot(eventRoot, '0xray/cursor-after-file-edit-boot', {
21
+ sessionId: cursorSessionId(event),
22
+ });
23
+ appendHookActivity(eventRoot, 'cursor-after-file-edit', 'session-boot', 'info', {
24
+ bootPath,
25
+ file: event.file_path || event.path || null,
26
+ });
27
+ console.log(JSON.stringify({}));
28
+ process.exit(0);
29
+ } catch (err) {
30
+ appendHookActivity(fallbackRoot, 'cursor-after-file-edit', 'hook-error', 'error', {
31
+ error: err.message,
32
+ });
33
+ console.log(JSON.stringify({}));
34
+ process.exit(0);
35
+ }
36
+ }
37
+
38
+ main();
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Cursor cloud hook utilities — normalize host stdin, reuse 0xRay gate + Station.
4
+ * sessionStart is unavailable on managed cloud; first preToolUse / afterFileEdit boots.
5
+ */
6
+
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import {
10
+ buildSessionBootPayload,
11
+ writeSessionBoot,
12
+ readStdinJson,
13
+ loadFeatures,
14
+ checkCodexPatterns,
15
+ checkFullTestSuite,
16
+ isWriteTool,
17
+ isShellTool,
18
+ sessionBootPath,
19
+ } from '../../grok/hooks/grok-hook-utils.js';
20
+ import {
21
+ evaluatePreToolGate,
22
+ loadDelegationGateFeatures,
23
+ } from '../../hooks/delegation-gate-runtime.mjs';
24
+ import { appendHookActivity } from '../../grok/hooks/grok-hook-activity.js';
25
+
26
+ export const CURSOR_HOST = 'cursor';
27
+ export const EVENT_CLASS_HOST = 'cursor-host-precompact';
28
+ export const EVENT_CLASS_SYNTHETIC = 'cursor-precompact-synthetic';
29
+
30
+ export {
31
+ readStdinJson,
32
+ writeSessionBoot,
33
+ buildSessionBootPayload,
34
+ loadFeatures,
35
+ checkCodexPatterns,
36
+ checkFullTestSuite,
37
+ isWriteTool,
38
+ isShellTool,
39
+ sessionBootPath,
40
+ evaluatePreToolGate,
41
+ loadDelegationGateFeatures,
42
+ appendHookActivity,
43
+ };
44
+
45
+ export {
46
+ FORBIDDEN_USAGE_METHODS,
47
+ invokeProbeLogPath,
48
+ cursorUsageReceiptPath,
49
+ parseInvokeProbeLog,
50
+ hostUsageFromPreCompactEvent,
51
+ classifyUsageCite,
52
+ buildRepertoireFastenedProof,
53
+ buildCursorUsageReceipt,
54
+ upsertStationCompactRow,
55
+ writeCursorUsageReceipt,
56
+ } from './cursor-usage-receipt.js';
57
+
58
+ export function cursorWorkspaceRoot(event = {}) {
59
+ const roots = event.workspace_roots || event.workspaceRoots;
60
+ const fromList = Array.isArray(roots) && roots[0] ? String(roots[0]) : '';
61
+ return (
62
+ event.cwd ||
63
+ event.workspaceRoot ||
64
+ fromList ||
65
+ process.env.CURSOR_PROJECT_DIR ||
66
+ process.env.XRAY_ROOT ||
67
+ process.env.GROK_WORKSPACE_ROOT ||
68
+ process.cwd()
69
+ );
70
+ }
71
+
72
+ export function cursorSessionId(event = {}) {
73
+ return (
74
+ event.conversation_id ||
75
+ event.session_id ||
76
+ event.sessionId ||
77
+ process.env.CURSOR_CONVERSATION_ID ||
78
+ process.env.CURSOR_SESSION_ID ||
79
+ null
80
+ );
81
+ }
82
+
83
+ export function cursorToolContext(event = {}) {
84
+ const toolName = event.tool_name || event.toolName || process.env.TOOL_NAME || 'unknown';
85
+ const toolInput = event.tool_input ?? event.toolInput ?? {};
86
+ const paths = [];
87
+ let content = '';
88
+
89
+ if (toolInput.path) paths.push(String(toolInput.path));
90
+ if (toolInput.file_path) paths.push(String(toolInput.file_path));
91
+ if (toolInput.target_notebook) paths.push(String(toolInput.target_notebook));
92
+ if (Array.isArray(toolInput.paths)) paths.push(...toolInput.paths.map(String));
93
+
94
+ if (toolInput.new_string) content += String(toolInput.new_string);
95
+ if (toolInput.contents) content += String(toolInput.contents);
96
+ if (toolInput.command) content += String(toolInput.command);
97
+ if (toolInput.prompt) content += String(toolInput.prompt);
98
+
99
+ return {
100
+ toolName,
101
+ toolInput,
102
+ paths,
103
+ content,
104
+ cmd: String(toolInput.command || event.command || ''),
105
+ };
106
+ }
107
+
108
+ function namedEventClass(value) {
109
+ if (value === EVENT_CLASS_HOST || value === EVENT_CLASS_SYNTHETIC) return value;
110
+ return null;
111
+ }
112
+
113
+ export function classifyPreCompactEvent(event = {}, argv = process.argv) {
114
+ const fromEnv = namedEventClass(process.env.XRAY_CURSOR_COMPACT_CLASS);
115
+ if (fromEnv) return fromEnv;
116
+ const flag = argv.find((a) => a.startsWith('--event-class='));
117
+ if (flag) {
118
+ const fromArg = namedEventClass(flag.slice('--event-class='.length));
119
+ if (fromArg) return fromArg;
120
+ }
121
+ const fromEvent = namedEventClass(event.event_class);
122
+ if (fromEvent) return fromEvent;
123
+
124
+ const named = event.hook_event_name || event.hookEventName || event.hook;
125
+ const looksHost =
126
+ named === 'preCompact' ||
127
+ named === 'pre_compact' ||
128
+ event.trigger === 'auto' ||
129
+ event.trigger === 'manual' ||
130
+ typeof event.context_tokens === 'number' ||
131
+ typeof event.context_usage_percent === 'number';
132
+ return looksHost ? EVENT_CLASS_HOST : EVENT_CLASS_SYNTHETIC;
133
+ }
134
+
135
+ export function cursorBootNeedsRefresh(existing, root) {
136
+ if (!existing || typeof existing !== 'object') return true;
137
+ if (existing.host !== CURSOR_HOST) return true;
138
+ if (!existing.suit_profile) return true;
139
+ if (existing.workspaceRoot && existing.workspaceRoot !== root) return true;
140
+ if (!existing.stationLine) return true;
141
+ return false;
142
+ }
143
+
144
+ export function ensureCursorSessionBoot(root, source = '0xray/cursor-pre-tool-use-boot', extra = {}) {
145
+ const bootPath = sessionBootPath(root);
146
+ if (fs.existsSync(bootPath)) {
147
+ try {
148
+ const existing = JSON.parse(fs.readFileSync(bootPath, 'utf8'));
149
+ if (!cursorBootNeedsRefresh(existing, root)) return bootPath;
150
+ } catch {
151
+ /* rewrite corrupt or host-mismatched boot */
152
+ }
153
+ }
154
+ const payload = buildSessionBootPayload(root, source, {
155
+ host: CURSOR_HOST,
156
+ ...extra,
157
+ });
158
+ return writeSessionBoot(root, payload) || bootPath;
159
+ }
160
+
161
+ export function writeCursorPrecompactReceipt(root, fields) {
162
+ try {
163
+ const dest = path.join(root, '.xray', 'state', 'cursor-precompact.json');
164
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
165
+ fs.writeFileSync(dest, JSON.stringify(fields, null, 2));
166
+ return dest;
167
+ } catch {
168
+ return null;
169
+ }
170
+ }