0xray 4.0.14 → 4.0.15
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/.opencode/skills/orchestrator/SKILL.md +19 -1
- package/.xray/features.json +2 -2
- package/AGENTS-consumer.md +10 -5
- package/AGENTS.md +10 -7
- package/README.md +8 -7
- package/SKILLS.md +3 -2
- package/dist/AGENTS.md +10 -7
- package/dist/CHANGELOG.md +48 -0
- package/dist/README.md +8 -7
- package/dist/SKILLS.md +3 -2
- package/dist/cli/commands/hermes-install.js +2 -1
- package/dist/cli/commands/openclaw-install.js +2 -1
- package/dist/cli/commands/opencode-install.js +2 -1
- package/dist/cli/index.js +2 -1
- package/dist/integrations/cursor/hooks/cursor-hook-utils.js +9 -0
- package/dist/integrations/grok/grok-cli.js +2 -1
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/reporting/log-parser.js +2 -2
- package/dist/skills/orchestrator/SKILL.md +19 -1
- package/llms.txt +8 -7
- package/package.json +2 -1
- package/scripts/foundry/CHANGELOG.md +33 -1
- package/scripts/foundry/README.md +12 -5
- package/scripts/foundry/assert-packed-dist-cli.mjs +6 -0
- package/scripts/foundry/blip-kapow.cjs +2 -0
- package/scripts/foundry/blip-looker.cjs +2 -0
- package/scripts/foundry/blip-render.cjs +2 -1237
- package/scripts/foundry/blip-rippel-organs.cjs +2 -0
- package/scripts/foundry/blip-rippel.cjs +2 -1963
- package/scripts/foundry/blip-scene.cjs +2 -0
- package/scripts/foundry/blip-stroke.cjs +2 -0
- package/scripts/foundry/blip-vibe.cjs +2 -0
- package/scripts/foundry/blip.mjs +23 -97
- package/scripts/foundry/cli.mjs +2 -2
- package/scripts/foundry/inspect.mjs +62 -19
- package/scripts/foundry/mill-plant.cjs +598 -0
- package/scripts/foundry/mint-suit.cjs +189 -99
- package/scripts/foundry/package.json +12 -1
- package/scripts/foundry/plant/agents/blip-inspect.yml +1 -1
- package/scripts/foundry/plant/agents/blip-looker.yml +5 -0
- package/scripts/foundry/plant/agents/blip-vibe.yml +5 -0
- package/scripts/foundry/plant/agents/blip.yml +1 -1
- 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 +1 -1
- package/scripts/foundry/plant/agents/sound-mixer.yml +5 -0
- package/scripts/foundry/plant/agents/sound.yml +1 -1
- package/scripts/foundry/plant/motions/MOTION-REGISTRY.md +15 -9
- package/scripts/foundry/plant/motions/registry.json +5 -4
- package/scripts/foundry/plant/skills/blip/SKILL.md +4 -4
- package/scripts/foundry/plant/skills/blip-inspect/SKILL.md +2 -2
- package/scripts/foundry/plant/skills/blip-looker/SKILL.md +30 -0
- package/scripts/foundry/plant/skills/blip-vibe/SKILL.md +30 -0
- package/scripts/foundry/plant/skills/inspect/SKILL.md +2 -2
- package/scripts/foundry/plant/skills/sound/SKILL.md +3 -1
- package/scripts/foundry/plant/skills/sound-inspect/SKILL.md +1 -1
- package/scripts/foundry/plant/skills/sound-mixer/SKILL.md +28 -0
- package/scripts/foundry/sound-bed.cjs +2 -454
- package/scripts/foundry/sound-mixer.cjs +2 -0
- package/scripts/foundry/sound-rippel.cjs +2 -1434
- package/scripts/foundry/sound-taste.cjs +2 -0
- package/scripts/foundry/sound-voice.cjs +2 -0
- package/scripts/foundry/sound.mjs +23 -81
- package/scripts/node/install-bridges.cjs +39 -4
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/src/skills/orchestrator/SKILL.md +19 -1
- package/xray/features.json +2 -2
package/scripts/foundry/blip.mjs
CHANGED
|
@@ -1,109 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* npx @0xray/foundry blip render
|
|
5
|
-
* npx @0xray/foundry blip inspect
|
|
3
|
+
* Shim: product mill lives in @0xray/blip.
|
|
4
|
+
* npx @0xray/foundry blip render|inspect|vibe|look [...]
|
|
6
5
|
*/
|
|
7
|
-
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
8
7
|
import { createRequire } from "node:module";
|
|
9
8
|
import path from "node:path";
|
|
10
|
-
import {
|
|
11
|
-
import { resolveMillRoot } from "./mill-root.mjs";
|
|
12
|
-
|
|
13
|
-
const require = createRequire(import.meta.url);
|
|
14
|
-
const blip = require("./blip-render.cjs");
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
"Usage: npx @0xray/foundry blip <render|inspect> [...args]\n" +
|
|
18
|
-
"\n" +
|
|
19
|
-
"Factory-blip plant, sibling to mill + sound. FOUNDRY_ROOT overrides cwd.\n" +
|
|
20
|
-
"render: brief → checksum seed → still|motion:<id> → 4.44s mp4 + audio bed → receipt.\n" +
|
|
21
|
-
"v0 ids: still, orb, swirl, snap, waves, spark (Rippel five are imports).\n" +
|
|
22
|
-
"Motions: Rippel VisualConfig.circles at ≥720p (default). --look focus|cage (seed picks if omitted).\n" +
|
|
23
|
-
"--engine wireframe is emergency only.\n" +
|
|
24
|
-
"Every mp4 muxes a 4.44s bed (--bed PATH or auto sound mill). Silent = inspect FAIL.\n" +
|
|
25
|
-
"kapow is a growth stub (FAIL until a renderer ships). Unknown id FAIL.\n" +
|
|
26
|
-
"still: Power Plant ident — plate dissolves over 4.44s at ≥720p, not a frozen poster.\n" +
|
|
27
|
-
"inspect: last .xray/blip/receipt.json PASS/FAIL (missing is FAIL). Lists live registry ids.\n";
|
|
28
|
-
|
|
29
|
-
function argValue(argv, name, fallback) {
|
|
30
|
-
const i = argv.indexOf(name);
|
|
31
|
-
if (i < 0 || i + 1 >= argv.length) return fallback;
|
|
32
|
-
return argv[i + 1];
|
|
33
|
-
}
|
|
11
|
+
export { inspectBlip } from "@0xray/blip";
|
|
34
12
|
|
|
35
|
-
|
|
36
|
-
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function inspectBlip(root) {
|
|
40
|
-
const motions = blip.listMotionIds();
|
|
41
|
-
const receipt = blip.readReceipt(root);
|
|
42
|
-
if (!receipt) {
|
|
43
|
-
return {
|
|
44
|
-
ok: false,
|
|
45
|
-
status: "FAIL",
|
|
46
|
-
failClosed: true,
|
|
47
|
-
plant: "blip",
|
|
48
|
-
motions,
|
|
49
|
-
detail: "missing .xray/blip/receipt.json",
|
|
50
|
-
receipt: null,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
const evaluated = blip.evaluateReceipt(root, receipt);
|
|
54
|
-
const status = evaluated.status === "PASS" ? "PASS" : "FAIL";
|
|
55
|
-
return {
|
|
56
|
-
ok: status === "PASS",
|
|
57
|
-
status,
|
|
58
|
-
failClosed: true,
|
|
59
|
-
plant: "blip",
|
|
60
|
-
motions,
|
|
61
|
-
mode: evaluated.mode || receipt.motionId || receipt.mode || null,
|
|
62
|
-
pictureMode: evaluated.pictureMode || receipt.pictureMode || null,
|
|
63
|
-
durationSec: evaluated.durationSec ?? receipt.durationSec ?? null,
|
|
64
|
-
receipt,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function main() {
|
|
69
|
-
const argv = process.argv.slice(2);
|
|
70
|
-
const cmd = argv[0];
|
|
71
|
-
const rest = argv.slice(1);
|
|
72
|
-
const root = resolveMillRoot();
|
|
73
|
-
|
|
74
|
-
if (!cmd || cmd === "--help" || cmd === "-h" || cmd === "help") {
|
|
75
|
-
process.stdout.write(HELP);
|
|
76
|
-
process.exit(cmd ? 0 : 1);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (cmd === "inspect") {
|
|
80
|
-
const report = inspectBlip(root);
|
|
81
|
-
writeJson(report);
|
|
82
|
-
process.exit(report.ok ? 0 : 1);
|
|
83
|
-
}
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
84
14
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
engine: argValue(rest, "--engine", "rippel"),
|
|
93
|
-
out: argValue(rest, "--out", null),
|
|
94
|
-
});
|
|
95
|
-
writeJson(result.receipt);
|
|
96
|
-
process.exit(result.receipt.status === "PASS" ? 0 : 1);
|
|
15
|
+
function runCli(args) {
|
|
16
|
+
let cli;
|
|
17
|
+
try {
|
|
18
|
+
cli = require.resolve("@0xray/blip/cli");
|
|
19
|
+
} catch {
|
|
20
|
+
process.stderr.write("Install @0xray/blip — the 4.44s mill moved off the OS foundry.\n");
|
|
21
|
+
process.exit(1);
|
|
97
22
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
23
|
+
const result = spawnSync(process.execPath, [cli, ...args], {
|
|
24
|
+
stdio: "inherit",
|
|
25
|
+
cwd: process.env.FOUNDRY_ROOT || process.cwd(),
|
|
26
|
+
env: process.env,
|
|
27
|
+
});
|
|
28
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
101
29
|
}
|
|
102
30
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
process.argv
|
|
107
|
-
if (isMain) {
|
|
108
|
-
main();
|
|
31
|
+
const invoked =
|
|
32
|
+
process.argv[1] && pathToFileURL(path.resolve(process.argv[1])).href === import.meta.url;
|
|
33
|
+
if (invoked) {
|
|
34
|
+
runCli(process.argv.slice(2));
|
|
109
35
|
}
|
package/scripts/foundry/cli.mjs
CHANGED
|
@@ -30,8 +30,8 @@ const HELP =
|
|
|
30
30
|
"release bumps/commits/pushes/publishes the milled cwd — pass --dry-run or --i-mean-it (or FOUNDRY_RELEASE=1).\n" +
|
|
31
31
|
"Mint fastens the requested factory plant (default mill; foundry.json plant: sound|blip turns mill off), then inspect.\n" +
|
|
32
32
|
"inspect runs mill checks plus, on a sound seat, last bed receipt PASS/FAIL; on a blip seat, last blip receipt.\n" +
|
|
33
|
-
"sound render|inspect is the factory-sound plant (brief → seed → genre → wav → metrics). Sibling to mill, not a mill copy.\n" +
|
|
34
|
-
"blip render|inspect is the factory-blip plant (brief → seed → still|motion:<id> → 4.44s mp4). Sibling to mill + sound.\n" +
|
|
33
|
+
"sound render|inspect|mix is the factory-sound plant (brief → seed → genre → wav → metrics; mix levels every variation). Sibling to mill, not a mill copy.\n" +
|
|
34
|
+
"blip render|inspect|vibe|look is the factory-blip plant (brief → seed → still|motion:<id> → 4.44s mp4; vibe is stamp density, look is the friend hitting replay, ship bar 8). Sibling to mill + sound.\n" +
|
|
35
35
|
"gate is build+test. docs-build is Docusaurus on the 0xray exo. ci reports GitHub Actions (no auto-push). hooks installs git pre/post hooks.\n";
|
|
36
36
|
|
|
37
37
|
const cmd = process.argv[2];
|
|
@@ -14,6 +14,7 @@ import { millPackageDir, resolveMillRoot } from "./mill-root.mjs";
|
|
|
14
14
|
|
|
15
15
|
const require = createRequire(import.meta.url);
|
|
16
16
|
const mint = require("./mint-suit.cjs");
|
|
17
|
+
const millProtocol = require("./mill-plant.cjs");
|
|
17
18
|
|
|
18
19
|
export function npmTarballUrl(name, version) {
|
|
19
20
|
if (typeof name !== "string" || !name || typeof version !== "string" || !version) return null;
|
|
@@ -81,20 +82,45 @@ function checkDiff(root) {
|
|
|
81
82
|
};
|
|
82
83
|
}
|
|
83
84
|
|
|
85
|
+
function emptyPlantFiles() {
|
|
86
|
+
return { skills: [], agents: [] };
|
|
87
|
+
}
|
|
88
|
+
|
|
84
89
|
function checkPlantVsWorn(root, millRoot) {
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
let seats;
|
|
91
|
+
try {
|
|
92
|
+
seats = millProtocol.resolvePlantSeats(root, millRoot);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
id: "plant-vs-worn",
|
|
96
|
+
ok: false,
|
|
97
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const kinds = millProtocol.plantKindsFromSeats(seats);
|
|
101
|
+
const millSeat = seats.find((seat) => seat.kind === "mill");
|
|
102
|
+
const soundSeat = seats.find((seat) => seat.kind === "sound");
|
|
103
|
+
const blipSeat = seats.find((seat) => seat.kind === "blip");
|
|
87
104
|
const millPlant = {
|
|
88
|
-
skills:
|
|
89
|
-
agents:
|
|
90
|
-
sound:
|
|
91
|
-
|
|
105
|
+
skills: millSeat ? millSeat.skills : [],
|
|
106
|
+
agents: millSeat ? millSeat.agents : [],
|
|
107
|
+
sound: soundSeat
|
|
108
|
+
? { skills: soundSeat.skills, agents: soundSeat.agents }
|
|
109
|
+
: emptyPlantFiles(),
|
|
110
|
+
blip: blipSeat ? { skills: blipSeat.skills, agents: blipSeat.agents } : emptyPlantFiles(),
|
|
111
|
+
plants: Object.fromEntries(
|
|
112
|
+
seats
|
|
113
|
+
.filter((seat) => !seat.builtin)
|
|
114
|
+
.map((seat) => [seat.kind, { skills: seat.skills, agents: seat.agents }]),
|
|
115
|
+
),
|
|
92
116
|
};
|
|
93
117
|
const params = mint.loadFoundryParams(root);
|
|
94
118
|
const tree = {
|
|
95
119
|
skills: mint.listConsumerSkillNames(root, params.skills),
|
|
96
120
|
agents: mint.listConsumerAgentFiles(root, params.agents),
|
|
97
121
|
plantKinds: kinds,
|
|
122
|
+
seats,
|
|
123
|
+
millPackageRoot: millRoot,
|
|
98
124
|
soundPlantSkills: millPlant.sound.skills,
|
|
99
125
|
soundPlantAgents: millPlant.sound.agents,
|
|
100
126
|
sound: millPlant.sound,
|
|
@@ -103,6 +129,7 @@ function checkPlantVsWorn(root, millRoot) {
|
|
|
103
129
|
blip: millPlant.blip,
|
|
104
130
|
};
|
|
105
131
|
const shopPlant = mint.loadShopPlant(root);
|
|
132
|
+
const allow = mint.factoryPlantAllowlist(millRoot, root);
|
|
106
133
|
try {
|
|
107
134
|
mint.assertNoCostumeDump(root, millPlant, tree);
|
|
108
135
|
return {
|
|
@@ -132,7 +159,7 @@ function checkPlantVsWorn(root, millRoot) {
|
|
|
132
159
|
}
|
|
133
160
|
}
|
|
134
161
|
|
|
135
|
-
function checkReceipt(root) {
|
|
162
|
+
function checkReceipt(root, millRoot) {
|
|
136
163
|
const file = path.join(root, ".xray", "foundry-inventory.json");
|
|
137
164
|
if (mint.isDogfood(millPackageDir(), root)) {
|
|
138
165
|
return { id: "receipt", ok: true, skipped: true, detail: "dogfood / exo — no consumer inventory" };
|
|
@@ -146,24 +173,40 @@ function checkReceipt(root) {
|
|
|
146
173
|
const blipPlantSkills = inventory.blipPlant?.skills || [];
|
|
147
174
|
const kinds = mint.inventoryPlantKinds(inventory);
|
|
148
175
|
const needMill = kinds.includes("mill");
|
|
149
|
-
const needSound = kinds.includes("sound");
|
|
150
|
-
const needBlip = kinds.includes("blip");
|
|
151
176
|
const millOk = !needMill || (millPlantSkills.includes("mill") && millPlantSkills.includes("inspect"));
|
|
152
|
-
const soundOk =
|
|
153
|
-
!needSound || (soundPlantSkills.includes("sound") && soundPlantSkills.includes("sound-inspect"));
|
|
154
|
-
const blipOk =
|
|
155
|
-
!needBlip || (blipPlantSkills.includes("blip") && blipPlantSkills.includes("blip-inspect"));
|
|
156
|
-
const ok = millOk && soundOk && blipOk && (needMill || needSound || needBlip);
|
|
157
177
|
let detail = null;
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
178
|
+
if (needMill && !millOk) detail = "millPlant.skills must include mill and inspect";
|
|
179
|
+
const packageKinds = kinds.filter((kind) => kind !== "mill");
|
|
180
|
+
if (!detail && packageKinds.length > 0) {
|
|
181
|
+
try {
|
|
182
|
+
const declared = millProtocol.declaredReceiptSeats(inventory, root, millRoot);
|
|
183
|
+
for (const seat of declared) {
|
|
184
|
+
if (seat.builtin) continue;
|
|
185
|
+
const have = millProtocol.inventoryFilesForKind(inventory, seat.kind);
|
|
186
|
+
const haveSkills = Array.isArray(have?.skills) ? have.skills : [];
|
|
187
|
+
if (!seat.skills || seat.skills.length === 0) {
|
|
188
|
+
detail = `${seat.kind} plant declared no skills`;
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
const missing = seat.skills.filter((name) => !haveSkills.includes(name));
|
|
192
|
+
if (missing.length > 0) {
|
|
193
|
+
detail = `${seat.kind}Plant.skills must include protocol skills (${missing.join(", ")})`;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch (err) {
|
|
198
|
+
detail = err instanceof Error ? err.message : String(err);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const ok = !detail && (needMill || packageKinds.length > 0);
|
|
202
|
+
if (!ok && !detail) detail = "inventory plant is empty";
|
|
162
203
|
return {
|
|
163
204
|
id: "receipt",
|
|
164
205
|
ok,
|
|
165
206
|
suit: inventory.suit,
|
|
166
207
|
mill: inventory.mill,
|
|
208
|
+
millPackage: inventory.millPackage || null,
|
|
209
|
+
millProtocol: inventory.millProtocol || null,
|
|
167
210
|
plant: kinds,
|
|
168
211
|
millPlant: millPlantSkills,
|
|
169
212
|
soundPlant: soundPlantSkills,
|
|
@@ -373,7 +416,7 @@ export async function inspectSuit(root, opts = {}) {
|
|
|
373
416
|
const checks = [];
|
|
374
417
|
checks.push(checkDiff(root));
|
|
375
418
|
checks.push(checkPlantVsWorn(root, millRoot));
|
|
376
|
-
checks.push(checkReceipt(root));
|
|
419
|
+
checks.push(checkReceipt(root, millRoot));
|
|
377
420
|
const soundBed = checkSoundBed(root);
|
|
378
421
|
if (soundBed) checks.push(soundBed);
|
|
379
422
|
const blip = checkBlip(root);
|