0xray 4.1.0 → 4.1.1

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 (76) hide show
  1. package/.gitignore.default +4 -1
  2. package/.grok-plugin/plugin.json +1 -1
  3. package/.opencode/skills/orchestrator/SKILL.md +1 -7
  4. package/.xray/features.json +4 -1
  5. package/.xray/features.schema.json +8 -0
  6. package/AGENTS-consumer.md +1 -1
  7. package/AGENTS.md +2 -2
  8. package/README.md +2 -2
  9. package/dist/.gitignore.default +4 -1
  10. package/dist/AGENTS.md +2 -2
  11. package/dist/CHANGELOG.md +27 -1
  12. package/dist/README.md +2 -2
  13. package/dist/cli/commands/opencode-install.js +3 -9
  14. package/dist/cli/commands/skill-install.js +10 -5
  15. package/dist/cli/goggles-status.d.ts +2 -5
  16. package/dist/cli/goggles-status.js +5 -53
  17. package/dist/cli/index.js +2 -2
  18. package/dist/enforcement/enforcer-tools.d.ts +1 -1
  19. package/dist/enforcement/enforcer-tools.js +1 -1
  20. package/dist/integrations/cursor/README.md +1 -1
  21. package/dist/integrations/cursor/hooks/pre-tool-use.js +4 -0
  22. package/dist/integrations/grok/grok-cli.js +5 -7
  23. package/dist/integrations/grok/hooks/grok-hook-utils.js +4 -1
  24. package/dist/integrations/grok/hooks/pre-tool-use.js +4 -18
  25. package/dist/integrations/grok/hooks/session-start.js +4 -2
  26. package/dist/integrations/hermes-agent/bridge.mjs +4 -1
  27. package/dist/integrations/hooks/goggles-mcp.mjs +20 -196
  28. package/dist/integrations/hooks/goggles-pipeline.mjs +606 -616
  29. package/dist/integrations/hooks/goggles-planes.json +88 -40
  30. package/dist/integrations/hooks/plates.cjs +84 -0
  31. package/dist/integrations/hooks/pre-tool-speak.mjs +2 -4
  32. package/dist/integrations/hooks/skill-seek.mjs +115 -0
  33. package/dist/integrations/hooks/station-hook-runtime.cjs +4 -1
  34. package/dist/integrations/openclaw/hooks/pre-tool-gate-runtime.mjs +4 -4
  35. package/dist/integrations/openclaw/plugin/xray-pre-tool/index.js +10 -1
  36. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  37. package/dist/memory-routing/plates.d.ts +1 -1
  38. package/dist/memory-routing/plates.js +14 -0
  39. package/dist/nucleus/thin-dispatch.d.ts +1 -1
  40. package/dist/nucleus/thin-dispatch.js +1 -1
  41. package/dist/nucleus/work-freshness.mjs +10 -0
  42. package/dist/plugin/xray-codex-injection.js +3 -1
  43. package/dist/skills/orchestrator/SKILL.md +1 -7
  44. package/docs-site/docs/plates/asides.md +35 -0
  45. package/docs-site/docs/plates/confer.md +35 -0
  46. package/docs-site/docs/plates/consumer-mcp.md +35 -0
  47. package/docs-site/docs/plates/delegation-gate.md +35 -0
  48. package/docs-site/docs/plates/dynamo.md +35 -0
  49. package/docs-site/docs/plates/foundry.md +35 -0
  50. package/docs-site/docs/plates/goggles.md +8 -8
  51. package/docs-site/docs/plates/ground.md +35 -0
  52. package/docs-site/docs/plates/hermes.md +35 -0
  53. package/docs-site/docs/plates/index.md +12 -5
  54. package/docs-site/docs/plates/inference-cycle.md +35 -0
  55. package/docs-site/docs/plates/lens-gate.md +6 -6
  56. package/docs-site/docs/plates/openclaw.md +35 -0
  57. package/docs-site/docs/plates/opencode.md +35 -0
  58. package/docs-site/docs/plates/repertoire.md +35 -0
  59. package/docs-site/docs/plates/synthesis.md +35 -0
  60. package/docs-site/docs/plates/temperament.md +35 -0
  61. package/docs-site/docs/plates/trail-state.md +1 -1
  62. package/package.json +1 -1
  63. package/scripts/foundry/README.md +3 -1
  64. package/scripts/foundry/mint-suit.cjs +120 -2
  65. package/scripts/foundry/plant/skills/mill/SKILL.md +1 -1
  66. package/scripts/foundry/reconcile-version.mjs +10 -3
  67. package/scripts/foundry/release.mjs +1 -1
  68. package/scripts/foundry/validate-release-docs.mjs +2 -2
  69. package/scripts/foundry/version-manager.mjs +12 -4
  70. package/scripts/node/install-bridges.cjs +63 -34
  71. package/scripts/node/pack-tmp-suit-proof.mjs +23 -4
  72. package/src/integrations/openclaw/plugin/xray-pre-tool/index.js +10 -1
  73. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  74. package/src/skills/orchestrator/SKILL.md +1 -7
  75. package/xray/features.json +4 -1
  76. package/xray/features.schema.json +8 -0
@@ -2,7 +2,7 @@
2
2
  * Goggles MCP. Stdio. Server name `goggles`.
3
3
  * Tools: look, status_lens. Same organ as the CLI.
4
4
  */
5
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
5
+ import { existsSync, readFileSync, realpathSync } from 'node:fs';
6
6
  import { dirname, join, resolve } from 'node:path';
7
7
  import { pathToFileURL, fileURLToPath } from 'node:url';
8
8
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
@@ -14,32 +14,14 @@ const HERE = fileURLToPath(new URL('.', import.meta.url));
14
14
  const SERVER_NAME = 'goggles';
15
15
  /** Card planes come from the organ, not a hand-kept copy. */
16
16
  const CARD_PLANES = Array.isArray(bundled.CARD_PLANES) ? bundled.CARD_PLANES : [];
17
- const CARD_OUTERS = ['digest', 'triage'];
18
- const SCOPES = ['ecosystem', 'part', 'one flow', 'one artifact'];
19
17
 
20
18
  const LOOK_SCHEMA = {
21
19
  type: 'object',
22
20
  additionalProperties: false,
23
21
  properties: {
24
- kind: {
25
- type: 'string',
26
- description: 'Use "0" or "actuality" for the lens. Send kind, outer, or plane: an empty look is refused. Never with outer: kind and outer together is refused.',
27
- enum: ['0', 'actuality'],
28
- },
29
- outer: {
30
- type: 'string',
31
- description: 'One outer name. digest and triage return a card. The others return a reading.',
32
- enum: ['dichotomy', 'syncopate', 'synthesis', 'digest', 'triage', 'loop'],
33
- },
34
- scope: {
35
- type: 'string',
36
- description: 'Zoom only. Not a kind. One level.',
37
- enum: SCOPES,
38
- },
39
22
  plane: {
40
23
  type: 'string',
41
- description: 'Card plane for digest or triage only. Not the lens. A plane with any other outer is refused.',
42
- enum: CARD_PLANES,
24
+ description: 'A plane, or the card for one thing. Omit it to read the current card.',
43
25
  },
44
26
  },
45
27
  };
@@ -47,12 +29,12 @@ const LOOK_SCHEMA = {
47
29
  export const TOOLS = [
48
30
  {
49
31
  name: 'look',
50
- description: 'Kind 0 is quiet on a match. It checks the six outer names, then sweeps every card plane for missing shipped files and names the first drift. One outer is a reading. digest and triage return a card. Refused: an empty look; kind with outer; a plane with an outer other than digest or triage.',
32
+ description: 'The card for this plane, or for one thing on it. Entry and Exit, and the other rows, are in LENS.md. A missing plate names the stamp-plate skill.',
51
33
  inputSchema: LOOK_SCHEMA,
52
34
  },
53
35
  {
54
36
  name: 'status_lens',
55
- description: 'Whether the organ is worn, and the last Kind 0. Quiet is a match. A missing organ is not drift.',
37
+ description: 'Whether the organ is worn. A missing organ is not a card.',
56
38
  inputSchema: { type: 'object', additionalProperties: false, properties: {} },
57
39
  },
58
40
  ];
@@ -76,9 +58,6 @@ function deny(code, reason) {
76
58
  };
77
59
  }
78
60
 
79
- function quiet(mode) {
80
- return { ok: true, quiet: true, mode, content: '' };
81
- }
82
61
 
83
62
  async function organApi() {
84
63
  const override = typeof process.env.GOGGLES_ORGAN_PATH === 'string'
@@ -96,123 +75,38 @@ function projectRoot(root) {
96
75
  return process.cwd();
97
76
  }
98
77
 
99
- function argvFrom(args) {
100
- const words = [];
101
- if (args.kind === '0') words.push('kind', '0');
102
- else if (args.kind === 'actuality') words.push('actuality');
103
- else if (args.kind === '1' || args.kind === '2') words.push('kind', String(args.kind));
104
- else if (typeof args.kind === 'string') words.push(args.kind);
105
- if (args.outer === 'outer loop') words.push('outer', 'loop');
106
- else if (typeof args.outer === 'string') words.push(args.outer);
107
- if (typeof args.plane === 'string') words.push(args.plane);
108
- if (args.scope === 'one flow') words.push('one', 'flow');
109
- else if (args.scope === 'one artifact') words.push('one', 'artifact');
110
- else if (typeof args.scope === 'string') words.push(args.scope);
111
- return words;
112
- }
113
-
114
- function pureKind0(args) {
115
- return (args.kind === '0' || args.kind === 'actuality')
116
- && args.outer == null
117
- && args.plane == null
118
- && args.scope == null;
119
- }
120
-
121
78
  function checkArgs(args) {
122
79
  if (!args || typeof args !== 'object' || Array.isArray(args)) {
123
80
  return deny('invalid_args', 'look takes an object.');
124
81
  }
125
- const allowed = new Set(['kind', 'outer', 'scope', 'plane']);
82
+ const allowed = new Set(['plane']);
126
83
  for (const key of Object.keys(args)) {
127
84
  if (!allowed.has(key)) return deny('invalid_args', 'Unknown argument.');
128
85
  }
129
- for (const key of ['kind', 'outer', 'scope', 'plane']) {
130
- if (args[key] != null && typeof args[key] !== 'string') {
131
- return deny('invalid_args', `${key} must be a string.`);
132
- }
133
- }
134
- if (args.kind != null && !['0', 'actuality', '1', '2'].includes(args.kind)) {
135
- return deny('invalid_args', 'kind is 0 or actuality.');
136
- }
137
- if (args.outer != null && !LOOK_SCHEMA.properties.outer.enum.includes(args.outer)) {
138
- const setName = args.outer === 'outer' || args.outer === 'outer-loop' || args.outer === 'outer loop';
139
- if (!setName) return deny('invalid_args', 'Name one outer.');
140
- }
141
- if (args.scope != null && !SCOPES.includes(args.scope)) {
142
- return deny('invalid_args', 'scope is one zoom level.');
143
- }
144
- if (args.plane != null && !CARD_PLANES.includes(args.plane)) {
145
- return deny('invalid_args', 'plane is a card plane.');
146
- }
147
- if (args.kind == null && args.outer == null && args.plane == null) {
148
- return deny('invalid_args', 'Name a kind, one outer, or one plane.');
149
- }
150
- if (args.kind != null && args.outer != null) {
151
- return deny('invalid_args', 'Send kind or outer, not both.');
152
- }
153
- if (args.plane != null && args.outer != null && !CARD_OUTERS.includes(args.outer)) {
154
- return deny('invalid_args', 'plane goes with digest or triage only.');
155
- }
86
+ if (args.plane == null) return null;
87
+ if (typeof args.plane !== 'string') return deny('invalid_args', 'plane must be a string.');
88
+ if (typeof bundled.isCardName !== 'function' || !bundled.isCardName(args.plane)) return deny('invalid_args', 'Name one plane.');
156
89
  return null;
157
90
  }
158
91
 
159
92
  function publicCard(view) {
160
93
  const notes = [];
161
- if (view.flavor === 'triage') {
162
- if (Array.isArray(view.empty) && view.empty.length) notes.push(`Empty: ${view.empty.join(', ')}`);
163
- if (view.exam) notes.push(view.exam);
164
- }
165
- const skills = view.skills ? String(view.skills) : '';
166
- const cascade = view.cascade
167
- ? {
168
- plane: view.cascade.plane,
169
- station: view.cascade.station,
170
- notesPage: view.cascade.notesPage,
171
- index: view.cascade.index,
172
- laws: Array.isArray(view.cascade.laws) ? view.cascade.laws : [],
173
- notes: Array.isArray(view.cascade.notes) ? view.cascade.notes : [],
174
- }
175
- : null;
176
- const sleeve = view.sleeve
177
- ? {
178
- on: Boolean(view.sleeve.on),
179
- missing: Array.isArray(view.sleeve.missing) ? view.sleeve.missing : [],
180
- stitches: Array.isArray(view.sleeve.stitches)
181
- ? view.sleeve.stitches.map((row) => ({
182
- name: String(row && row.name || ''),
183
- on: Boolean(row && row.on),
184
- at: Array.isArray(row && row.at) ? row.at.map((item) => String(item)) : [],
185
- }))
186
- : [],
187
- }
188
- : null;
189
- if (view.narrow) {
190
- return {
191
- plane: view.plane,
192
- flavor: view.flavor,
193
- digest: view.digest || '',
194
- files: Array.isArray(view.files) ? view.files : [],
195
- notes,
196
- ...(cascade ? { cascade } : {}),
197
- ...(sleeve ? { sleeve } : {}),
198
- };
199
- }
94
+ if (typeof view.exam === 'string' && view.exam.startsWith('Drift:')) notes.push(view.exam);
200
95
  return {
201
96
  plane: view.plane,
202
- flavor: view.flavor,
203
97
  from: view.from || '',
204
98
  digest: view.digest || '',
205
99
  plate: view.plate || '',
206
100
  entry: view.entry || '',
207
101
  exit: view.exit || '',
208
102
  files: Array.isArray(view.files) ? view.files : [],
209
- skills,
103
+ skills: view.skills ? String(view.skills) : '',
210
104
  setup: view.setup || '',
211
105
  teardown: view.teardown || '',
212
106
  worn: view.worn || '',
107
+ card: view.card || view.plane || '',
108
+ stamp: view.stamp || '',
213
109
  notes,
214
- ...(cascade ? { cascade } : {}),
215
- ...(sleeve ? { sleeve } : {}),
216
110
  };
217
111
  }
218
112
 
@@ -226,77 +120,24 @@ export async function answerLook(raw, root) {
226
120
  const api = await organApi();
227
121
  if (!api) return deny('invalid_args', 'Goggles organ not found.');
228
122
  const here = projectRoot(root);
229
- if (pureKind0(args)) {
230
- api.maintainLens(here);
231
- const line = api.actualityLine() || cardDrift(api, here);
232
- if (line) writeLens(api, here, line);
233
- if (!line) return quiet('kind0');
234
- return { ok: true, quiet: false, mode: 'kind0', content: line };
235
- }
236
- const argv = argvFrom(args);
123
+ const argv = args.plane == null ? [] : [args.plane];
237
124
  const text = api.look(argv, here).text;
238
125
  if (text === 'Name one plane.') return deny('name_one', 'Name one plane.');
239
126
  const cards = api.lookCards(argv, here);
240
- if (Array.isArray(cards) && cards.length) {
241
- const shown = cards.map(publicCard);
242
- if (shown.length === 1 && shown[0] && typeof shown[0].plane === 'string') {
243
- const dest = join(here, '.xray', 'state', 'goggles-plane.json');
244
- mkdirSync(dirname(dest), { recursive: true });
245
- writeFileSync(dest, `${JSON.stringify({ plane: shown[0].plane })}\n`);
246
- }
247
- return {
248
- ok: true,
249
- quiet: false,
250
- mode: 'card',
251
- content: shown.length === 1 ? shown[0] : shown,
252
- outer: args.outer,
253
- scope: args.scope || null,
254
- };
255
- }
256
- if (!text) {
257
- if (args.kind === '0' || args.kind === 'actuality') return quiet('kind0');
258
- if (args.outer === 'digest' || args.outer === 'triage') return quiet('card');
259
- return quiet('reading');
260
- }
261
- if (text.startsWith('Actuality. Drift:')) {
262
- return { ok: true, quiet: false, mode: 'kind0', content: text };
127
+ if (!Array.isArray(cards) || !cards.length) return deny('name_one', 'Name one plane.');
128
+ const shown = cards.map(publicCard);
129
+ if (shown.length === 1 && shown[0]) {
130
+ const heldName = shown[0].card || shown[0].plane;
131
+ if (heldName) api.holdPlane(here, heldName);
263
132
  }
264
133
  return {
265
134
  ok: true,
266
135
  quiet: false,
267
- mode: 'reading',
268
- content: text,
269
- outer: args.outer ?? null,
270
- scope: args.scope || null,
136
+ mode: 'card',
137
+ content: shown.length === 1 ? shown[0] : shown,
271
138
  };
272
139
  }
273
140
 
274
- /** Kind 0 card sweep: triage's file check on every card plane, shipped paths only. */
275
- function cardDrift(api, here) {
276
- if (typeof api.shippedDrift !== 'function') return '';
277
- try {
278
- return api.shippedDrift(here);
279
- } catch {
280
- return '';
281
- }
282
- }
283
-
284
- function writeLens(api, here, line) {
285
- const file = api.lensPath(here);
286
- mkdirSync(dirname(file), { recursive: true });
287
- writeFileSync(file, `${line}\n`);
288
- }
289
-
290
- function lensBody(root) {
291
- const file = join(root, '.xray', 'state', 'LENS.md');
292
- if (!existsSync(file)) return { found: false, text: '' };
293
- try {
294
- return { found: true, text: readFileSync(file, 'utf8').trim() };
295
- } catch {
296
- return { found: false, text: '' };
297
- }
298
- }
299
-
300
141
  export async function answerStatus(root) {
301
142
  const api = await organApi();
302
143
  const override = typeof process.env.GOGGLES_ORGAN_PATH === 'string'
@@ -307,28 +148,11 @@ export async function answerStatus(root) {
307
148
  const organOk = existsSync(organPath);
308
149
  const planesOk = Boolean(planesPath) && existsSync(planesPath);
309
150
  const worn = Boolean(api) && organOk && planesOk;
310
- const here = projectRoot(root);
311
- const lens = lensBody(here);
312
- let kind0 = 'none';
313
- let kind0Text = '';
314
- if (lens.found && (!lens.text || lens.text === 'quiet (match)')) kind0 = 'quiet';
315
- else if (lens.found) {
316
- kind0 = 'drift';
317
- kind0Text = lens.text;
318
- } else if (worn) {
319
- const line = api.actualityLine();
320
- if (line) {
321
- kind0 = 'drift';
322
- kind0Text = line;
323
- }
324
- }
325
151
  return {
326
152
  ok: true,
327
153
  organ: worn ? 'worn' : 'not_found',
328
154
  organPath: organOk ? organPath : '',
329
155
  planesPath: planesOk ? planesPath : '',
330
- kind0,
331
- kind0Text,
332
156
  lensPath: '.xray/state/LENS.md',
333
157
  };
334
158
  }