0xray 4.0.30 → 4.0.32

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 (49) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.mcp.json +8 -0
  3. package/.opencode/skills/orchestrator/SKILL.md +12 -0
  4. package/.xray/features.json +1 -1
  5. package/dist/CHANGELOG.md +17 -0
  6. package/dist/cli/commands/status.d.ts +4 -2
  7. package/dist/cli/commands/status.js +6 -3
  8. package/dist/cli/commands/validate.js +9 -0
  9. package/dist/cli/goggles-status.d.ts +13 -0
  10. package/dist/cli/goggles-status.js +76 -0
  11. package/dist/cli/index.js +41 -2
  12. package/dist/integrations/grok/grok-cli.d.ts +3 -0
  13. package/dist/integrations/grok/grok-cli.js +41 -1
  14. package/dist/integrations/grok/hooks/grok-hook-utils.js +24 -4
  15. package/dist/integrations/grok/hooks/post-tool-use.js +2 -1
  16. package/dist/integrations/grok/hooks/pre-tool-use.js +90 -5
  17. package/dist/integrations/grok/hooks/session-start.js +7 -2
  18. package/dist/integrations/hooks/goggles-mcp.mjs +371 -0
  19. package/dist/integrations/hooks/goggles-pipeline.mjs +632 -0
  20. package/dist/integrations/hooks/goggles-planes.json +28 -0
  21. package/dist/integrations/hooks/plates.cjs +23 -0
  22. package/dist/integrations/hooks/station-hook-runtime.cjs +40 -11
  23. package/dist/integrations/hooks/station-memory-ingest.mjs +3 -0
  24. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  25. package/dist/mcps/orchestrator/config/agent-capabilities.js +7 -0
  26. package/dist/memory-routing/plates.d.ts +1 -1
  27. package/dist/memory-routing/plates.js +5 -0
  28. package/dist/memory-routing/provider-loader.js +2 -0
  29. package/dist/nucleus/thin-dispatch.d.ts +1 -0
  30. package/dist/nucleus/thin-dispatch.js +4 -2
  31. package/dist/skills/orchestrator/SKILL.md +12 -0
  32. package/docs-site/docs/plates/glossary.md +27 -0
  33. package/docs-site/docs/plates/goggles.md +18 -0
  34. package/docs-site/docs/plates/grokbot.md +41 -0
  35. package/docs-site/docs/plates/host-pack.md +32 -0
  36. package/docs-site/docs/plates/house.md +42 -39
  37. package/docs-site/docs/plates/index.md +13 -1
  38. package/docs-site/docs/plates/kits.md +28 -0
  39. package/docs-site/docs/plates/suit.md +40 -0
  40. package/package.json +2 -1
  41. package/scripts/foundry/assert-packed-dist-cli.mjs +9 -0
  42. package/scripts/mjs/run-goggles-mcp.mjs +41 -0
  43. package/scripts/node/bridge-mcp-wiring.cjs +61 -21
  44. package/scripts/node/consumer-install-smoke.mjs +5 -0
  45. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  46. package/src/mcps/orchestrator/config/agent-capabilities.ts +8 -0
  47. package/src/skills/orchestrator/SKILL.md +12 -0
  48. package/vendor/@0xray/repertoire/dist/paths.js +4 -0
  49. package/xray/features.json +1 -1
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CWD-proof Goggles MCP launcher.
4
+ * Resolves the organ server from this file, not from the caller's cwd.
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { existsSync } from 'node:fs';
8
+ import { dirname, join, resolve } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+
11
+ const xrayRoot = join(dirname(fileURLToPath(import.meta.url)), '../..');
12
+ const candidates = [
13
+ join(xrayRoot, 'dist', 'integrations', 'hooks', 'goggles-mcp.mjs'),
14
+ join(xrayRoot, 'src', 'integrations', 'hooks', 'goggles-mcp.mjs'),
15
+ ];
16
+ const server = candidates.find((file) => existsSync(file));
17
+ if (!server) {
18
+ process.stderr.write('goggles MCP missing\n');
19
+ process.exit(1);
20
+ }
21
+
22
+ const env = { ...process.env };
23
+ if (!env.GOGGLES_ROOT || env.GOGGLES_ROOT === '.') {
24
+ env.GOGGLES_ROOT = resolve(process.cwd());
25
+ }
26
+
27
+ const child = spawn(process.execPath, [server], {
28
+ stdio: 'inherit',
29
+ env,
30
+ });
31
+ child.on('error', (err) => {
32
+ process.stderr.write(`goggles MCP spawn failed: ${err.message}\n`);
33
+ process.exit(1);
34
+ });
35
+ child.on('exit', (code, signal) => {
36
+ if (signal) {
37
+ process.kill(process.pid, signal);
38
+ return;
39
+ }
40
+ process.exit(code ?? 1);
41
+ });
@@ -139,31 +139,70 @@ function enableMemoryRoutingIfResolves(features, targetDir) {
139
139
  };
140
140
  }
141
141
 
142
+ function resolveGogglesMcp(targetDir) {
143
+ const candidates = [
144
+ path.join(targetDir, "node_modules", "0xray", "scripts", "mjs", "run-goggles-mcp.mjs"),
145
+ path.join(targetDir, "scripts", "mjs", "run-goggles-mcp.mjs"),
146
+ ];
147
+ return candidates.find((file) => fs.existsSync(file)) || null;
148
+ }
149
+
150
+ function gogglesScopedLaunch(targetDir, launcher) {
151
+ return wrapScopedLaunch(
152
+ { command: "node", args: [launcher] },
153
+ mergeScopedEnv([
154
+ baseScopedEnv(targetDir),
155
+ { GOGGLES_ROOT: targetDir, GOGGLES_PLANES_PATH: "" },
156
+ ]),
157
+ );
158
+ }
159
+
142
160
  function detectConsumerExtraMcpServers(targetDir) {
143
161
  const extras = { hermes: {}, opencode: {}, openclaw: {} };
144
162
  try {
145
163
  const repertoireMcp = resolveRepertoireMcp(targetDir);
146
- if (!repertoireMcp) return extras;
147
- const launch = wrapScopedLaunch(
148
- { command: "node", args: [repertoireMcp] },
149
- baseScopedEnv(targetDir),
150
- );
151
- extras.hermes.repertoire = {
152
- command: launch.command,
153
- args: launch.args,
154
- env: launch.env,
155
- };
156
- extras.opencode.repertoire = {
157
- type: "local",
158
- command: launch.commandList,
159
- enabled: true,
160
- environment: launch.env,
161
- };
162
- extras.openclaw.repertoire = {
163
- command: launch.command,
164
- args: launch.args,
165
- env: launch.env,
166
- };
164
+ if (repertoireMcp) {
165
+ const launch = wrapScopedLaunch(
166
+ { command: "node", args: [repertoireMcp] },
167
+ baseScopedEnv(targetDir),
168
+ );
169
+ extras.hermes.repertoire = {
170
+ command: launch.command,
171
+ args: launch.args,
172
+ env: launch.env,
173
+ };
174
+ extras.opencode.repertoire = {
175
+ type: "local",
176
+ command: launch.commandList,
177
+ enabled: true,
178
+ environment: launch.env,
179
+ };
180
+ extras.openclaw.repertoire = {
181
+ command: launch.command,
182
+ args: launch.args,
183
+ env: launch.env,
184
+ };
185
+ }
186
+ const gogglesMcp = resolveGogglesMcp(targetDir);
187
+ if (gogglesMcp) {
188
+ const launch = gogglesScopedLaunch(targetDir, gogglesMcp);
189
+ extras.hermes.goggles = {
190
+ command: launch.command,
191
+ args: launch.args,
192
+ env: launch.env,
193
+ };
194
+ extras.opencode.goggles = {
195
+ type: "local",
196
+ command: launch.commandList,
197
+ enabled: true,
198
+ environment: launch.env,
199
+ };
200
+ extras.openclaw.goggles = {
201
+ command: launch.command,
202
+ args: launch.args,
203
+ env: launch.env,
204
+ };
205
+ }
167
206
  } catch {
168
207
  // best-effort
169
208
  }
@@ -880,6 +919,7 @@ module.exports = {
880
919
  detectConsumerExtraMcpServers,
881
920
  isRepertoirePackageRoot,
882
921
  resolveRepertoireMcp,
922
+ resolveGogglesMcp,
883
923
  resolveRepertoireProvider,
884
924
  isDefaultMemoryRoutingOff,
885
925
  enableMemoryRoutingIfResolves,
@@ -60,6 +60,11 @@ const REQUIRED_TARBALL_DIST = [
60
60
  "package/dist/integrations/hooks/plates.cjs",
61
61
  "package/docs-site/docs/plates/memory-recall.md",
62
62
  "package/docs-site/docs/plates/processor.md",
63
+ "package/docs-site/docs/plates/goggles.md",
64
+ "package/docs-site/docs/plates/suit.md",
65
+ "package/docs-site/docs/plates/kits.md",
66
+ "package/docs-site/docs/plates/host-pack.md",
67
+ "package/docs-site/docs/plates/glossary.md",
63
68
  ];
64
69
 
65
70
  function assertPackedDistCliInTarball(tarballPath) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xray-pre-tool",
3
- "version": "4.0.30",
3
+ "version": "4.0.32",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "0xRay constitution + temperament PreToolUse for OpenClaw",
@@ -14,6 +14,7 @@ import {
14
14
  fromMemoryCapabilityMap,
15
15
  } from './memory-routing-bridge.js';
16
16
  import { routeSubagent } from '../../../nucleus/autonomy-kernel.js';
17
+ import { scoreAndRoute } from '../../../nucleus/thin-dispatch.js';
17
18
 
18
19
  /** routeSubagent names → AGENT_REGISTRY keys */
19
20
  const ROUTE_AGENT_ALIASES: Record<string, string> = {
@@ -102,6 +103,13 @@ export class AgentCapabilitiesManager {
102
103
  operationDescription = '',
103
104
  taskType = '',
104
105
  ): string | null {
106
+ if (operationDescription.trim()) {
107
+ const routed = scoreAndRoute(operationDescription, {});
108
+ if (routed.memoryRouting?.overridden && this.capabilities.has(routed.agent)) {
109
+ return routed.agent;
110
+ }
111
+ }
112
+
105
113
  if (taskType.trim()) {
106
114
  const routed = routeSubagent(taskType);
107
115
  const resolved = resolveRoutedAgent(routed, this.capabilities);
@@ -53,6 +53,18 @@ When `multi_agent_orchestration.lead_dev_mode` is true in `features.json` (defau
53
53
  | Test failures | bug-triage |
54
54
  | Review | code-review |
55
55
 
56
+ ## Goggles
57
+
58
+ The command is `0xray look`. `0xray goggles` is the same organ. A pipe keeps the line card. A terminal shows that card as a pane. Chat seats without hooks use the `goggles` MCP tools `look` and `status_lens`. Same organ.
59
+
60
+ Kind 0 is actuality. It compares the list in the file to the same six names in the code. It speaks only when those lists differ. A match is quiet. It does not read the suit that is running. It is not a plate type.
61
+
62
+ Kind 1 names one plane: dichotomy, syncopate, synthesis, or loop. The lens holds that plane. An action on that plane is quiet. An action on another plane, or on a pipeline drawing, is stopped. A pipeline drawing is not a scope stop. Ground is not a scope stop. Scope, when named, is ecosystem, part, one flow, or one artifact, and an action wider than that scope is stopped. One kind and one scope level at a time. Two planes, calling, ground, and a pipeline name do not arm the lens. `outer` without one plane is `Name one plane.` After 1 is empty. Nothing is picked.
63
+
64
+ `digest` and `triage` return the card already built by `assemblePlane`. The fields are from, digest, plate, entry, exit, files, skills, setup, teardown, and worn. Empty stays empty. The rows are ground, routing, house, boot, governance, memory-recall, orchestration, processor, and reporting. Those nine are not Kind 0. `digest` fills the card. Entry and exit are the plate's input and output box titles when that plate has them. Setup and teardown stay empty unless the row names them. The mill path is `scripts/foundry`. `triage` adds the empty fields and whether the row holds. Zoom after the card is the same ladder: ecosystem, part, one flow, one artifact. One file is one artifact. Several files are not narrowed to a guessed file.
65
+
66
+ The hold lasts for the work that named the plane. It does not stop one tool and then forget. Work that says goggles clears the hold and stays quiet. The suit does not invent the plane.
67
+
56
68
  ## Hooks (rewired, not new MCPs)
57
69
 
58
70
  - **SessionStart** → `session-start.js` boots lead_dev_mode
@@ -421,6 +421,10 @@ export function reloadOpProc(cwd = process.cwd()) {
421
421
  }
422
422
  function mergeProjectOverlays(destPath) {
423
423
  mergeStackOverlay(destPath);
424
+ // Suit heat keeps repo-* off the project file. A wake that merges them
425
+ // and then prunes them records a fake 59 → 45 drop on every compact.
426
+ if (process.env.REPERTOIRE_SUBJECT_OVERLAY === '0')
427
+ return;
424
428
  mergeSubjectOverlay(destPath);
425
429
  }
426
430
  export function hydrateWritableSignals(seedPath, cwd = process.cwd()) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./features.schema.json",
3
- "version": "4.0.30",
3
+ "version": "4.0.32",
4
4
  "description": "0xRay Framework - Unified Feature Configuration",
5
5
  "suit_temperament": {
6
6
  "profile": "auto",