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.
- package/.grok-plugin/plugin.json +1 -1
- package/.xray/features.json +1 -1
- package/.xray/features.schema.json +1 -1
- package/AGENTS-consumer.md +4 -2
- package/AGENTS.md +8 -1
- package/README.md +1 -1
- package/SKILLS.md +1 -1
- package/dist/AGENTS.md +8 -1
- package/dist/CHANGELOG.md +25 -1
- package/dist/README.md +1 -1
- package/dist/SKILLS.md +1 -1
- package/dist/integrations/cursor/README.md +61 -0
- package/dist/integrations/cursor/hooks/after-file-edit.js +38 -0
- package/dist/integrations/cursor/hooks/cursor-hook-utils.js +170 -0
- package/dist/integrations/cursor/hooks/cursor-usage-receipt.js +298 -0
- package/dist/integrations/cursor/hooks/hooks.json +20 -0
- package/dist/integrations/cursor/hooks/pre-compact.js +88 -0
- package/dist/integrations/cursor/hooks/pre-tool-use.js +105 -0
- package/dist/integrations/hooks/station-hook-runtime.cjs +89 -1
- package/dist/integrations/hooks/station-hook-runtime.mjs +2 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/nucleus/suit-temperament.d.ts +2 -2
- package/dist/nucleus/suit-temperament.js +3 -1
- package/llms.txt +6 -4
- package/package.json +4 -2
- package/scripts/foundry/CHANGELOG.md +37 -1
- package/scripts/foundry/README.md +13 -1
- package/scripts/foundry/assert-packed-dist-cli.mjs +97 -0
- package/scripts/foundry/blip-render.cjs +1237 -0
- package/scripts/foundry/blip-rippel.cjs +1963 -0
- package/scripts/foundry/blip.mjs +109 -0
- package/scripts/foundry/cli.mjs +8 -4
- package/scripts/foundry/inspect.mjs +117 -7
- package/scripts/foundry/mint-suit.cjs +215 -14
- package/scripts/foundry/package.json +7 -1
- package/scripts/foundry/plant/agents/blip-inspect.yml +5 -0
- package/scripts/foundry/plant/agents/blip.yml +5 -0
- package/scripts/foundry/plant/agents/inspect.yml +1 -1
- package/scripts/foundry/plant/agents/mill.yml +1 -1
- package/scripts/foundry/plant/agents/sound-inspect.yml +5 -0
- package/scripts/foundry/plant/agents/sound.yml +5 -0
- package/scripts/foundry/plant/motions/MOTION-REGISTRY.md +35 -0
- package/scripts/foundry/plant/motions/registry.json +81 -0
- package/scripts/foundry/plant/skills/blip/SKILL.md +39 -0
- package/scripts/foundry/plant/skills/blip-inspect/SKILL.md +32 -0
- package/scripts/foundry/plant/skills/inspect/SKILL.md +2 -2
- package/scripts/foundry/plant/skills/sound/SKILL.md +29 -0
- package/scripts/foundry/plant/skills/sound-inspect/SKILL.md +28 -0
- package/scripts/foundry/release-gate.mjs +18 -10
- package/scripts/foundry/release.mjs +3 -0
- package/scripts/foundry/sound-bed.cjs +454 -0
- package/scripts/foundry/sound-rippel.cjs +1434 -0
- package/scripts/foundry/sound.mjs +93 -0
- package/scripts/node/assert-packed-dist-cli.mjs +4 -0
- package/scripts/node/consumer-install-smoke.mjs +20 -1
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/xray/features.json +1 -1
- package/xray/features.schema.json +1 -1
package/llms.txt
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**4.0** — mill+inspect plant, 7 MCPs, Codex 69. Constitution always on.
|
|
6
6
|
|
|
7
|
-
Default consumer wear is **mill plant** (`mill` + `inspect`), not a 45-skill / 42-agent costume dump. `foundry.json` `"costume": true` is the opt-in dump. Do not use costume to land hangar shops.
|
|
7
|
+
Default consumer wear is **mill plant** (`mill` + `inspect`), not a 45-skill / 42-agent costume dump. `foundry.json` `"costume": true` is the opt-in dump. Do not use costume to land hangar shops. Sound seats: `"plant": "sound"` fastens `sound` + `sound-inspect` (mill off). Blip seats: `"plant": "blip"` fastens `blip` + `blip-inspect` (mill off). Inspect reports the last bed or blip receipt. Not costume.
|
|
8
8
|
|
|
9
9
|
## Wear (what a stranger gets)
|
|
10
10
|
|
|
@@ -34,7 +34,7 @@ Registered in `.mcp.json` as `npx -y 0xray mcp <cmd>`:
|
|
|
34
34
|
| `xray-code-review` | Proposal quality |
|
|
35
35
|
| `xray-architect-tools` | System design |
|
|
36
36
|
|
|
37
|
-
Not an 8th `xray-*` server. Repertoire is a vendored organ (`npx @0xray/repertoire mcp`), enable-when-resolves.
|
|
37
|
+
Not an 8th `xray-*` server. Repertoire is a vendored organ (`npx @0xray/repertoire mcp`), enable-when-resolves. Survive compact is **Station** (Read `.xray/state/STATION.md`), not Repertoire 0.1.8.
|
|
38
38
|
|
|
39
39
|
## Codex 69 (always on)
|
|
40
40
|
|
|
@@ -42,8 +42,10 @@ Not an 8th `xray-*` server. Repertoire is a vendored organ (`npx @0xray/repertoi
|
|
|
42
42
|
|
|
43
43
|
## Agent map (exo, not dump)
|
|
44
44
|
|
|
45
|
-
- **Mill** — fasten their plant; factory discipline. Nested mill `@0xray/foundry` 0.1.
|
|
46
|
-
- **Inspect** — diffs, plant-vs-worn, mill receipt, CI, live tarball GET.
|
|
45
|
+
- **Mill** — fasten their plant; factory discipline. Nested mill `@0xray/foundry` 0.1.10.
|
|
46
|
+
- **Inspect** — diffs, plant-vs-worn, mill receipt, CI, live tarball GET. Sound seat: last bed PASS/FAIL. Blip seat: last 4.44s PASS/FAIL.
|
|
47
|
+
- **Sound** — factory-sound plant. Brief → seed → genre → crystal mill wav (Rippel membrane/metal/mixer) → metrics gate. Not a mill copy. Not a 3-sine toy.
|
|
48
|
+
- **Blip** — factory-blip plant (sibling to mill + sound, not a mill copy). Brief → seed → still|motion:<id> → 4.44s mp4 + audio bed. Motions are Rippel v2 VisualConfig at ≥720p (sharp look + tempo/frequency animation on all five). Sparse seed mesh plus field accents (stars, grids, gradients, blinkers) are the NFT fingerprints. v0: still + Rippel five. `kapow` is a growth stub. `still` is the Power Plant ident (plate dissolves, not a frozen poster). Hangar shop pair later.
|
|
47
49
|
- **Hangar** — plants factory shops on the four floors. Coexists with mill plant via shop plant allowlist.
|
|
48
50
|
- **42 YML / 45 SKILL.md** — exo catalog in this repo. Not default consumer wear.
|
|
49
51
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "0xray",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.14",
|
|
4
4
|
"description": "Multi-agent orchestration and Codex governance for OpenCode, Hermes, Grok Build, and OpenClaw",
|
|
5
5
|
"readme": "README.md",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,6 +61,8 @@
|
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"prepublishOnly": "node scripts/node/reconcile-version.mjs --check && npm run prepare-consumer && npm run build:all && find dist -name '*.js.map' -o -name '*.d.ts.map' | xargs rm -f 2>/dev/null || true",
|
|
64
|
+
"prepack": "node scripts/foundry/assert-packed-dist-cli.mjs",
|
|
65
|
+
"assert:packed-dist": "node scripts/foundry/assert-packed-dist-cli.mjs",
|
|
64
66
|
"version:bump": "node scripts/foundry/reconcile-version.mjs",
|
|
65
67
|
"version": "node scripts/foundry/version-manager.mjs",
|
|
66
68
|
"prebuild": "rm -rf dist tsconfig.tsbuildinfo tsconfig.*.tsbuildinfo",
|
|
@@ -79,7 +81,7 @@
|
|
|
79
81
|
"test:processors": "npm test -- src/__tests__/unit/processor-activation.test.ts src/__tests__/unit/typescript-compilation-processor.test.ts",
|
|
80
82
|
"test:miscellaneous": "npm test -- src/__tests__/unit/blocked-test.test.ts",
|
|
81
83
|
"test:quick": "npm test -- src/__tests__/integration/boot-orchestrator.integration.test.ts src/__tests__/unit/config-loader.test.ts src/__tests__/unit/state-manager.test.ts",
|
|
82
|
-
"test:comprehensive": "npm run typecheck && npm run test:unit && npm run test:core-framework && npm run test:security && npm run test:performance && npm run test:session-management && npm run test:code-analysis && npm run test:processors && npm run test:miscellaneous && npm test -- src/__tests__/unit/llm-governance-provider.test.ts src/__tests__/unit/mcp-server-smoke.test.ts",
|
|
84
|
+
"test:comprehensive": "npm run typecheck && npm run test:unit && npm run test:core-framework && npm run test:security && npm run test:performance && npm run test:session-management && npm run test:code-analysis && npm run test:processors && npm run test:miscellaneous && npm test -- src/__tests__/unit/llm-governance-provider.test.ts src/__tests__/unit/mcp-server-smoke.test.ts src/__tests__/unit/cursor-hooks.test.ts src/__tests__/unit/host-vs-mill-score.test.ts",
|
|
83
85
|
"test:integration-all": "npm test -- src/__tests__/integration/",
|
|
84
86
|
"test:performance-all": "npm test -- src/__tests__/performance/ src/__tests__/unit/performance-system.test.ts src/__tests__/unit/benchmark.test.ts src/__tests__/unit/analytics.test.ts",
|
|
85
87
|
"test:agents-all": "echo 'Legacy agents test entry retired'",
|
|
@@ -2,7 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Factory-blip phrase eases (hookEase/turnEase/tagEase). Still plates dissolve (~300ms). Focus orb wears field + mesh mass. Ambient bed is a 3-section score (turn crash, tag stab). Mill stays deterministic — no LLM in the render loop.
|
|
6
|
+
|
|
7
|
+
Factory-blip is a 4.44s Short: hook → turn → tag on the shared motion grid (picture + bed). Motif lines, pad in-key, bass an octave down. Voices: polyBLEP + biquad, layered kick, FM hat + noise, 2-op rhodes. Mix pocket + short plate on color/hat.
|
|
8
|
+
|
|
9
|
+
Factory-blip look variants: seed + `--look focus|cage`. `focus` restores the sharp-dogfood solid cyan disc + gold pupil + orbiting satellites. `cage` keeps Wu hairline + field. Receipt `visualConfig.lookKind`.
|
|
10
|
+
|
|
11
|
+
Factory-blip mux is stereo AAC. Inspect FAILs a missing stream or an inaudible bed (max volume ≤ −40 dB). A silent wav is no longer a PASS.
|
|
12
|
+
|
|
13
|
+
Factory-blip orb nucleus is orb-only (disc / eclipse / pulse, color + size on the grid). Swirl / snap / spark no longer stamp the same double circle.
|
|
14
|
+
|
|
15
|
+
Factory-blip audio syncopates to the motion grid: same seed + tempo + phase0=0. Downbeat kick locks to `kickAccent`; AND hat locks to `andAccent`. Not a flat bed under unrelated LFOs.
|
|
16
|
+
|
|
17
|
+
Factory-blip auto bed is the music — same seed / tempo / phase0 as the picture. 4.44s beds hit on the first downbeat (no 0.5s duck). Kick + AND hat + bass/rhodes on the grid. Pad sits under.
|
|
18
|
+
|
|
19
|
+
Factory-blip lines: Wu hairline (solid 1px core, coverage AA as the only glow). Cyan/gold/blue along the stroke. Vertex beads gone.
|
|
20
|
+
|
|
21
|
+
Factory-blip lines iridesce: cyan/gold/blue travel + glow + beat fireflies on the sparse cage. Field stars / grids / gradients / blinkers are luminous, not CAD ticks. Not more wire. Not a strobe.
|
|
22
|
+
|
|
23
|
+
Factory-blip field accents: uniqueness is stars / grids (`floor` `meridian` `ticks`) / gradients / blinkers around one sparse seed cage. Receipt `visualConfig.mesh` + `visualConfig.field`. Not more wire in the middle.
|
|
24
|
+
|
|
25
|
+
Factory-blip meshes: every mint gets a seed-unique polyhedron (12 families + gait). Worn by all five viz and the Power Plant ident.
|
|
26
|
+
|
|
27
|
+
Factory-blip Power Plant is a living ident (`look: power-plant-blip`) — titlecard / corridor / rain / endcard dissolve over 4.44s at ≥720p. Not a frozen 320×180 poster.
|
|
28
|
+
|
|
29
|
+
Factory-blip Rippel v2: the sharp orb look (`stampFocusDisc` opaque body + crisp rim + short glow) is now the look on **all five** viz — swirl / snap / waves / spark were still Phase 1 bokeh strokes. Animation is the complex Rippel set, paced as a 4.44s blip (fast abstract travel, soft gold tints — no hard strobe). Video LFOs share the crystal-mill genre tempo + `CircleConfig.frequency` with the audio bed. Mandatory 4.44s mux unchanged. No version bump.
|
|
30
|
+
|
|
31
|
+
Factory-blip Phase 1 (TICKET-BLIP-RENDERER-UPGRADE): default motion path is the Rippel converter spine (`VisualConfig.circles` → SimplifiedVisualConverter viz ids) at ≥720p, not ffmpeg geometry labeled as orb. `htafolla/rippel-synapse-flow@e5014cd`. Every Blip muxes a 4.44s audio bed (`--bed` or auto sound mill); silent mp4 = inspect FAIL. ffmpeg wireframe is `--engine wireframe` only. Still stays the Power Plant plate until Phase 2. No `@0xray/foundry` bump.
|
|
32
|
+
|
|
33
|
+
Factory-blip plant (`blip` + `blip-inspect`) — sibling to mill + sound, not a mill copy. `foundry.json` `"plant": "blip"` fastens the tiny-video factory and turns mill off. Dynamic motion registry (not a frozen Rippel enum). v0: still + Rippel five. `kapow` is a growth stub. Still generator wears the Power Plant intro plate (`#08090B` `#F5F7FA` `#3DE0E8` `#F5C518` `#4A7FD4`). Headless 4.44s mp4 + receipt. Inspect reports last blip PASS/FAIL. Not costume. No version bump — dogfood from branch / pack.
|
|
34
|
+
|
|
35
|
+
Sound plant retool: crystal-clear mill of Rippel SSOT chains (membrane / metal / duo-bass / mixer), not the Lovable volume-hack soup and not #62 sine beds. Tone.Offline blocked in Node. `phonk` first-class. No version bump.
|
|
36
|
+
|
|
37
|
+
Factory-sound plant (`sound` + `sound-inspect`). `foundry.json` `"plant": "sound"` fastens the bed factory and turns mill off. Headless render + metrics receipt. Inspect reports last bed PASS/FAIL. Not a mill copy. Not costume. No version bump — dogfood from branch / pack.
|
|
38
|
+
|
|
39
|
+
## [0.1.10] - 2026-09-12
|
|
40
|
+
|
|
41
|
+
Inspect isolated-home `dest` is `resolveGrokPluginDests` — on shared HOME that is project `.grok/plugins/0xray`, not machine `$HOME/.grok/plugins/0xray`. Published 0.1.9 still joined dest from `$HOME` (report/CLI lag after 0xray@4.0.12 / #29 wear). Shop plant is first-class with mill plant. `shop-extract`, `shop-witness`, `shop-pin` (and `foundry.json` `shopPlant`) are not a costume dump. `"costume": true` still required for 45/42. Isolated HOME must not write the passwd machine plugin. Not an 8th MCP. Not 5.0.
|
|
6
42
|
|
|
7
43
|
## [0.1.9] - 2026-09-09
|
|
8
44
|
|
|
@@ -24,6 +24,10 @@ npx @0xray/foundry release --publish-only --dry-run
|
|
|
24
24
|
npx @0xray/foundry release --publish-only --i-mean-it
|
|
25
25
|
npx @0xray/foundry mint
|
|
26
26
|
npx @0xray/foundry inspect [--skip-live]
|
|
27
|
+
npx @0xray/foundry sound render [--brief TEXT] [--genre ambient|techno|jazz]
|
|
28
|
+
npx @0xray/foundry sound inspect
|
|
29
|
+
npx @0xray/foundry blip render --brief TEXT --mode still|motion:<id> [--bed PATH] [--engine rippel|wireframe]
|
|
30
|
+
npx @0xray/foundry blip inspect
|
|
27
31
|
npx @0xray/foundry ci [--commit SHA] [--report]
|
|
28
32
|
npx @0xray/foundry hooks
|
|
29
33
|
```
|
|
@@ -55,9 +59,17 @@ After mill plant is fastened, overlay their plant (defaults; remap in `foundry.j
|
|
|
55
59
|
|
|
56
60
|
**Default mill plant:** `mill` + `inspect` (inspect AI work). Fastens a suit, not an empty one. Not 45/42 costume. `foundry.json` `"costume": true` copies that dump. Factory Repertoire still enable-when-resolves. PPE stays worn.
|
|
57
61
|
|
|
62
|
+
**Sound plant (factory-sound):** `foundry.json` `"plant": "sound"` fastens `sound` + `sound-inspect` and turns mill off. Spine: brief → checksum seed → genre (`ambient` | `techno` | `jazz` | `phonk`) → crystal-clear headless wav (Rippel membrane + metal + mixer, not a 3-sine toy) → metrics gate → `.xray/sound-bed-receipt.json`. Tone.Offline is blocked in Node (no `OfflineAudioContext`); `sound-rippel.cjs` is the lean mill port of `htafolla/rippel-synapse-flow`. Inspect reports the plant plus last bed `PASS`/`FAIL`. Not costume. No `@0xray/foundry` bump.
|
|
63
|
+
|
|
64
|
+
A friend would hear: the sound mill mills Dist beds like Rippel’s prototype grew up — kick membranes, metal hats, and a crystal-clear mixer, not a muddy toy and not a 3-sine pad.
|
|
65
|
+
|
|
66
|
+
**Blip plant (factory-blip):** sibling factory plant to mill + sound — not a mill copy. `foundry.json` `"plant": "blip"` fastens `blip` + `blip-inspect` and turns mill off. Motions live in `plant/motions/registry.json` (not a frozen Rippel enum). v0: `still` + Rippel five (`orb` `swirl` `snap` `waves` `spark`). `kapow` is a growth stub (FAIL until a renderer ships). Unknown id FAIL. Rippel v2 default motion path is the Rippel converter (`VisualConfig.circles` → canvas / 3d-sacred / neural / waveform / particles) at ≥720p — sharp look + tempo/frequency animation on all five. Audio syncopates to the motion grid (same seed, tempo, phase0=0). Each mint wears a sparse seed mesh plus field accents (stars, grids, gradients, blinkers) so 4.44s is unique blip art; receipt `visualConfig.mesh` + `visualConfig.field` are the fingerprints. ffmpeg wireframe is `--engine wireframe` only. `still` is the Power Plant ident (void `#08090B` · ink `#F5F7FA` · cyan `#3DE0E8` · gold `#F5C518` · agent blue `#4A7FD4`) — titlecard / corridor / rain / endcard dissolve over 4.44s at ≥720p, not a frozen poster. Every 4.44s mp4 muxes a stereo AAC bed (`--bed` or auto sound mill) → `.xray/blip/receipt.json`. Missing stream or inaudible bed = inspect FAIL. Inspect reports the plant, live ids, plus last blip `PASS`/`FAIL`. Not costume. No `@0xray/foundry` bump.
|
|
67
|
+
|
|
68
|
+
A friend would hear: Blips should look like Rippel living motions with sound, not a silent wireframe box.
|
|
69
|
+
|
|
58
70
|
**Shop plant:** `shop-extract`, `shop-witness`, `shop-pin` are first-class with mill plant. Inspect does not treat those worn names as a costume dump. `foundry.json` `"shopPlant"` names more shops (array), a plant dir (string), or `{ "skills": [...], "dir": "..." }`. This is not `"costume": true` and does not copy 45/42.
|
|
59
71
|
|
|
60
|
-
**4.0.9 mill target (0xray postinstall, not this mill package):** `install-bridges.cjs` does not mill npm global prefix or npx `_npx` as a consumer. Isolated HOME skips machine `~/.grok`. Shared HOME Grok last-mile is project `.grok/plugins/0xray` (two seats do not clobber machine plugin). Nested mill
|
|
72
|
+
**4.0.9 mill target (0xray postinstall, not this mill package):** `install-bridges.cjs` does not mill npm global prefix or npx `_npx` as a consumer. Isolated HOME skips machine `~/.grok`. Shared HOME Grok last-mile is project `.grok/plugins/0xray` (two seats do not clobber machine plugin). Nested mill **0.1.10** (inspect dest matches `resolveGrokPluginDests`; published 0.1.9 still reported machine `$HOME` dest).
|
|
61
73
|
|
|
62
74
|
## Publish this mill
|
|
63
75
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Fail if the tarball npm would publish does not contain dist/cli/index.js.
|
|
4
|
+
*
|
|
5
|
+
* 0xray@4.0.13 listed dist/ in package.json files[] but packed 0 dist files.
|
|
6
|
+
* npm pack silently omits missing files[] entries when dist/ is not on disk.
|
|
7
|
+
*
|
|
8
|
+
* Dry-run uses --ignore-scripts so this can run from prepack without recursion.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { isXrayExoRepo, resolveMillRoot } from "./mill-root.mjs";
|
|
16
|
+
|
|
17
|
+
export const REQUIRED_PACK_PATHS = [
|
|
18
|
+
"dist/cli/index.js",
|
|
19
|
+
"dist/mcps/orchestrator.server.js",
|
|
20
|
+
"dist/integrations/grok/hooks/session-start.js",
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export function packedFilePaths(files) {
|
|
24
|
+
if (!Array.isArray(files)) return [];
|
|
25
|
+
return files
|
|
26
|
+
.map((f) => (typeof f === "string" ? f : f && typeof f.path === "string" ? f.path : ""))
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.map((p) => p.replace(/^package\//, ""));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function parseNpmPackJson(raw) {
|
|
32
|
+
const text = String(raw ?? "");
|
|
33
|
+
const start = text.search(/[\[{]/);
|
|
34
|
+
if (start < 0) {
|
|
35
|
+
throw new Error("npm pack --json produced no JSON");
|
|
36
|
+
}
|
|
37
|
+
const parsed = JSON.parse(text.slice(start));
|
|
38
|
+
const entry = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
39
|
+
return packedFilePaths(entry?.files);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function assertPackedPaths(paths, required = REQUIRED_PACK_PATHS) {
|
|
43
|
+
const set = new Set((paths ?? []).map((p) => String(p).replace(/^package\//, "")));
|
|
44
|
+
const missing = required.filter((p) => !set.has(p));
|
|
45
|
+
if (missing.length > 0) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`npm pack omitted ${missing.join(", ")}. ` +
|
|
48
|
+
`package.json files[] lists dist/ but npm omits it when dist/ is missing on disk. ` +
|
|
49
|
+
`Run npm run build. Do not publish. (0xray@4.0.13 shipped 0 dist files.)`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function assertDistCliOnDisk(rootDir) {
|
|
55
|
+
const cli = path.join(rootDir, "dist", "cli", "index.js");
|
|
56
|
+
if (!fs.existsSync(cli)) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`dist/cli/index.js missing on disk at ${cli}. Run npm run build before pack/publish.`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function listPackedPathsDryRun(rootDir) {
|
|
64
|
+
const out = execSync("npm pack --dry-run --json --ignore-scripts", {
|
|
65
|
+
cwd: rootDir,
|
|
66
|
+
encoding: "utf8",
|
|
67
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
68
|
+
});
|
|
69
|
+
return parseNpmPackJson(out);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function assertPackedDistCli(rootDir = resolveMillRoot()) {
|
|
73
|
+
if (!isXrayExoRepo(rootDir)) {
|
|
74
|
+
return { skipped: true, reason: "not 0xray exo" };
|
|
75
|
+
}
|
|
76
|
+
assertDistCliOnDisk(rootDir);
|
|
77
|
+
const paths = listPackedPathsDryRun(rootDir);
|
|
78
|
+
assertPackedPaths(paths);
|
|
79
|
+
return { skipped: false, paths: REQUIRED_PACK_PATHS };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const isMain =
|
|
83
|
+
process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
84
|
+
|
|
85
|
+
if (isMain) {
|
|
86
|
+
try {
|
|
87
|
+
const result = assertPackedDistCli();
|
|
88
|
+
if (result.skipped) {
|
|
89
|
+
process.stdout.write(`ℹ️ packed dist/cli check skipped (${result.reason})\n`);
|
|
90
|
+
} else {
|
|
91
|
+
process.stdout.write(`✅ pack includes ${REQUIRED_PACK_PATHS.join(", ")}\n`);
|
|
92
|
+
}
|
|
93
|
+
} catch (err) {
|
|
94
|
+
process.stderr.write(`❌ ${err.message}\n`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|