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.
- package/.grok-plugin/plugin.json +1 -1
- package/.mcp.json +8 -0
- package/.opencode/skills/orchestrator/SKILL.md +12 -0
- package/.xray/features.json +1 -1
- package/dist/CHANGELOG.md +17 -0
- package/dist/cli/commands/status.d.ts +4 -2
- package/dist/cli/commands/status.js +6 -3
- package/dist/cli/commands/validate.js +9 -0
- package/dist/cli/goggles-status.d.ts +13 -0
- package/dist/cli/goggles-status.js +76 -0
- package/dist/cli/index.js +41 -2
- package/dist/integrations/grok/grok-cli.d.ts +3 -0
- package/dist/integrations/grok/grok-cli.js +41 -1
- package/dist/integrations/grok/hooks/grok-hook-utils.js +24 -4
- package/dist/integrations/grok/hooks/post-tool-use.js +2 -1
- package/dist/integrations/grok/hooks/pre-tool-use.js +90 -5
- package/dist/integrations/grok/hooks/session-start.js +7 -2
- package/dist/integrations/hooks/goggles-mcp.mjs +371 -0
- package/dist/integrations/hooks/goggles-pipeline.mjs +632 -0
- package/dist/integrations/hooks/goggles-planes.json +28 -0
- package/dist/integrations/hooks/plates.cjs +23 -0
- package/dist/integrations/hooks/station-hook-runtime.cjs +40 -11
- package/dist/integrations/hooks/station-memory-ingest.mjs +3 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/mcps/orchestrator/config/agent-capabilities.js +7 -0
- package/dist/memory-routing/plates.d.ts +1 -1
- package/dist/memory-routing/plates.js +5 -0
- package/dist/memory-routing/provider-loader.js +2 -0
- package/dist/nucleus/thin-dispatch.d.ts +1 -0
- package/dist/nucleus/thin-dispatch.js +4 -2
- package/dist/skills/orchestrator/SKILL.md +12 -0
- package/docs-site/docs/plates/glossary.md +27 -0
- package/docs-site/docs/plates/goggles.md +18 -0
- package/docs-site/docs/plates/grokbot.md +41 -0
- package/docs-site/docs/plates/host-pack.md +32 -0
- package/docs-site/docs/plates/house.md +42 -39
- package/docs-site/docs/plates/index.md +13 -1
- package/docs-site/docs/plates/kits.md +28 -0
- package/docs-site/docs/plates/suit.md +40 -0
- package/package.json +2 -1
- package/scripts/foundry/assert-packed-dist-cli.mjs +9 -0
- package/scripts/mjs/run-goggles-mcp.mjs +41 -0
- package/scripts/node/bridge-mcp-wiring.cjs +61 -21
- package/scripts/node/consumer-install-smoke.mjs +5 -0
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/src/mcps/orchestrator/config/agent-capabilities.ts +8 -0
- package/src/skills/orchestrator/SKILL.md +12 -0
- package/vendor/@0xray/repertoire/dist/paths.js +4 -0
- package/xray/features.json +1 -1
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Goggles. Kind 0 name-checks the six outer names.
|
|
3
|
+
* Digest and triage return one card. Empty stays empty.
|
|
4
|
+
* A held plane stays quiet. A leave is denied.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { dirname, join, resolve } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
const FIELD_ORDER = ['plate', 'entry', 'exit', 'files', 'skills', 'setup', 'teardown', 'worn'];
|
|
11
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const WORN_PLANES = ['dichotomy', 'syncopate', 'synthesis', 'digest', 'triage', 'loop'];
|
|
13
|
+
const CARD_PLANES = ['ground', 'routing', 'house', 'boot', 'governance', 'memory-recall', 'orchestration', 'processor', 'reporting'];
|
|
14
|
+
const CARD_FLAVORS = ['digest', 'triage'];
|
|
15
|
+
const SCOPE_ZOOM = ['ecosystem', 'part', 'one flow', 'one artifact'];
|
|
16
|
+
|
|
17
|
+
/** Empty GOGGLES_PLANES_PATH keeps the file beside the organ. */
|
|
18
|
+
export function planesFile() {
|
|
19
|
+
const override = process.env.GOGGLES_PLANES_PATH;
|
|
20
|
+
if (typeof override === 'string' && override.trim()) return override.trim();
|
|
21
|
+
return join(HERE, 'goggles-planes.json');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function drawnPlanes() {
|
|
25
|
+
try {
|
|
26
|
+
const data = JSON.parse(readFileSync(planesFile(), 'utf8'));
|
|
27
|
+
return Array.isArray(data.planes) ? data.planes.map((name) => String(name)) : [];
|
|
28
|
+
} catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function actualityOf(map, worn) {
|
|
34
|
+
const left = Array.isArray(map) ? map : [];
|
|
35
|
+
const right = Array.isArray(worn) ? worn : [];
|
|
36
|
+
const same = left.length === right.length && left.every((name, index) => name === right[index]);
|
|
37
|
+
return same ? '' : 'Actuality. Drift: worn is not the map.';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function actualityLine() {
|
|
41
|
+
return actualityOf(drawnPlanes(), WORN_PLANES);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function acceptedPlanes() {
|
|
45
|
+
const map = new Set(drawnPlanes());
|
|
46
|
+
return WORN_PLANES.filter((name) => map.has(name));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function readingLine(name, scope) {
|
|
50
|
+
return scope ? `The reading is ${name}. Scope is ${scope}.` : `The reading is ${name}.`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function organDeny(reason) {
|
|
54
|
+
return { gate: 'goggles', decision: 'deny', reason };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function planeWord(name, text) {
|
|
58
|
+
return new RegExp(`(?:^|[^A-Za-z0-9-])${String(name).replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?:[^A-Za-z0-9-]|$)`, 'i').test(String(text || ''));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function withoutPaths(text) {
|
|
62
|
+
return String(text || '').replace(/(?:[\w.@~-]+\/)+[\w.-]+/g, ' ');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function organStop(held, action) {
|
|
66
|
+
if (!held) return null;
|
|
67
|
+
if (held.drift) return organDeny(held.drift);
|
|
68
|
+
const plane = held.plane;
|
|
69
|
+
if (!plane) return null;
|
|
70
|
+
const text = String(action?.text || '');
|
|
71
|
+
const paths = (action?.paths || []).map(String).filter(Boolean);
|
|
72
|
+
const tool = String(action?.tool || '');
|
|
73
|
+
if (/docs-site\/docs\/plates\/[a-z0-9-]+\.md/i.test([text, ...paths].join('\n'))) {
|
|
74
|
+
return organDeny(`The reading is ${plane}. That drawing is not the plane.`);
|
|
75
|
+
}
|
|
76
|
+
const stripped = withoutPaths(text);
|
|
77
|
+
const others = acceptedPlanes().filter((name) => name !== plane && planeWord(name, stripped));
|
|
78
|
+
const namesThis = planeWord(plane, stripped);
|
|
79
|
+
if (others.length > 1 || (others.length === 1 && namesThis)) {
|
|
80
|
+
return organDeny(`The reading is ${plane}. The action names two planes.`);
|
|
81
|
+
}
|
|
82
|
+
if (others.length === 1) {
|
|
83
|
+
return organDeny(`The reading is ${plane}. The action is ${others[0]}.`);
|
|
84
|
+
}
|
|
85
|
+
return scopeStop(plane, held.scope, tool, paths);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function scopeStop(plane, scope, tool, paths) {
|
|
89
|
+
if (!scope || scope === 'ecosystem') return null;
|
|
90
|
+
if (scope === 'part') {
|
|
91
|
+
const dirs = new Set(paths.map((file) => dirname(file)));
|
|
92
|
+
if (dirs.size > 1) return organDeny(`The reading is ${plane}. Scope is part. This action crosses parts.`);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (scope === 'one flow') {
|
|
96
|
+
if (/grep|search|glob|read|open/i.test(tool) && paths.length !== 1) {
|
|
97
|
+
return organDeny(`The reading is ${plane}. Scope is one flow. This action is not one flow.`);
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
if (scope === 'one artifact') {
|
|
102
|
+
if (/bash|shell/i.test(tool) || paths.length !== 1) {
|
|
103
|
+
return organDeny(`The reading is ${plane}. Scope is one artifact. This action is wider.`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function readingPath(root) {
|
|
110
|
+
return join(root, '.xray', 'state', 'goggles-reading.json');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function loadReading(root) {
|
|
114
|
+
try {
|
|
115
|
+
const data = JSON.parse(readFileSync(readingPath(root), 'utf8'));
|
|
116
|
+
if (!data || typeof data !== 'object') return null;
|
|
117
|
+
if (typeof data.drift === 'string' && data.drift) return { drift: data.drift };
|
|
118
|
+
if (typeof data.plane !== 'string' || !data.plane) return null;
|
|
119
|
+
return { plane: data.plane, scope: typeof data.scope === 'string' ? data.scope : '' };
|
|
120
|
+
} catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function saveReading(root, rec) {
|
|
126
|
+
const file = readingPath(root);
|
|
127
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
128
|
+
writeFileSync(file, `${JSON.stringify(rec)}\n`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function clearReading(root) {
|
|
132
|
+
const file = readingPath(root);
|
|
133
|
+
if (existsSync(file)) unlinkSync(file);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function findScopes(words) {
|
|
137
|
+
let rest = ` ${words.join(' ').toLowerCase()} `;
|
|
138
|
+
const hits = [];
|
|
139
|
+
const ordered = [...SCOPE_ZOOM].sort((a, b) => b.length - a.length);
|
|
140
|
+
for (const scope of ordered) {
|
|
141
|
+
const needle = ` ${scope} `;
|
|
142
|
+
if (!rest.includes(needle)) continue;
|
|
143
|
+
hits.push(scope);
|
|
144
|
+
rest = rest.split(needle).join(' ');
|
|
145
|
+
}
|
|
146
|
+
return hits;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function kindPastOne(words) {
|
|
150
|
+
const lower = words.map((word) => word.toLowerCase());
|
|
151
|
+
if (lower.length === 1 && /^\d+$/.test(lower[0]) && Number(lower[0]) > 1) return true;
|
|
152
|
+
for (let i = 0; i < lower.length; i += 1) {
|
|
153
|
+
if (!/^(kind|pull|pull-up|level)$/.test(lower[i])) continue;
|
|
154
|
+
const next = lower[i + 1];
|
|
155
|
+
if (next && /^\d+$/.test(next) && Number(next) > 1) return true;
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function isKindZero(lower) {
|
|
161
|
+
if (lower.includes('actuality')) return true;
|
|
162
|
+
if (lower.length === 1 && lower[0] === '0') return true;
|
|
163
|
+
for (let i = 0; i < lower.length; i += 1) {
|
|
164
|
+
if ((lower[i] === 'kind' || lower[i] === 'level') && lower[i + 1] === '0') return true;
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function namesTheSet(lower) {
|
|
170
|
+
const joined = lower.join(' ');
|
|
171
|
+
if (joined === 'kind 1' || joined === 'level 1') return true;
|
|
172
|
+
const mentionsSet = lower.includes('outer') || lower.includes('outer-loop');
|
|
173
|
+
if (!mentionsSet) return false;
|
|
174
|
+
const planes = acceptedPlanes().filter((name) => lower.includes(name));
|
|
175
|
+
if (planes.length === 0) return true;
|
|
176
|
+
return planes.length === 1 && planes[0] === 'loop' && findScopes(lower).length === 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function gogglesAnswer(argv) {
|
|
180
|
+
const words = [];
|
|
181
|
+
for (const raw of argv || []) {
|
|
182
|
+
const arg = String(raw || '').trim();
|
|
183
|
+
if (!arg || arg.toLowerCase() === 'pop') continue;
|
|
184
|
+
words.push(arg);
|
|
185
|
+
}
|
|
186
|
+
const lower = words.map((word) => word.toLowerCase());
|
|
187
|
+
const none = (text) => ({ text, cards: null });
|
|
188
|
+
if (lower.includes('calling')) return none('');
|
|
189
|
+
if (kindPastOne(words)) return none('');
|
|
190
|
+
if (words.length === 0) return none('');
|
|
191
|
+
if (namesTheSet(lower)) return none('Name one plane.');
|
|
192
|
+
if (isKindZero(lower)) {
|
|
193
|
+
if (findScopes(words).length) return none('');
|
|
194
|
+
if (acceptedPlanes().some((name) => lower.includes(name))) return none('');
|
|
195
|
+
return none(actualityLine());
|
|
196
|
+
}
|
|
197
|
+
const flavors = CARD_FLAVORS.filter((name) => lower.includes(name));
|
|
198
|
+
if (flavors.length > 1) return none('');
|
|
199
|
+
if (flavors.length === 1) {
|
|
200
|
+
const others = acceptedPlanes().filter((name) => name !== flavors[0] && lower.includes(name));
|
|
201
|
+
if (others.length) return none('');
|
|
202
|
+
const cards = collectCards(flavors[0], lower);
|
|
203
|
+
if (!cards) return none('');
|
|
204
|
+
return { text: cards.map((card) => formatCardText(card)).join('\n\n'), cards };
|
|
205
|
+
}
|
|
206
|
+
const planes = acceptedPlanes().filter((name) => lower.includes(name));
|
|
207
|
+
if (planes.length !== 1) return none('');
|
|
208
|
+
const scopes = findScopes(words.filter((word) => word.toLowerCase() !== planes[0]));
|
|
209
|
+
if (scopes.length > 1) return none('');
|
|
210
|
+
return none(readingLine(planes[0], scopes[0] || ''));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function readGoggles(argv) {
|
|
214
|
+
return ok(gogglesAnswer(argv).text);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function lookCards(argv) {
|
|
218
|
+
return gogglesAnswer(argv).cards;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function cardPlanesNamed(lower) {
|
|
222
|
+
return CARD_PLANES.filter((name) => lower.includes(name));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function listedFiles(plane, scope) {
|
|
226
|
+
const files = Array.isArray(plane.files) ? plane.files.map(String) : [];
|
|
227
|
+
if (scope === 'one artifact') return files.length === 1 ? [files[0]] : null;
|
|
228
|
+
const unpathed = Array.isArray(plane.unpathed) ? plane.unpathed : [];
|
|
229
|
+
const parts = files.slice();
|
|
230
|
+
for (const name of unpathed) parts.push(name === 'mill' ? 'mill has no path' : String(name));
|
|
231
|
+
return parts;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function cardView(plane, scope, flavor, root) {
|
|
235
|
+
const listed = listedFiles(plane, scope);
|
|
236
|
+
if (!listed) return null;
|
|
237
|
+
const view = {
|
|
238
|
+
plane: plane.id,
|
|
239
|
+
flavor,
|
|
240
|
+
scope: scope || '',
|
|
241
|
+
from: plane.id === 'ground' ? '' : 'ground',
|
|
242
|
+
digest: plane.digest || '',
|
|
243
|
+
plate: plane.plate || '',
|
|
244
|
+
entry: plane.entry || '',
|
|
245
|
+
exit: plane.exit || '',
|
|
246
|
+
files: listed,
|
|
247
|
+
skills: plane.skills || '',
|
|
248
|
+
setup: plane.setup || '',
|
|
249
|
+
teardown: plane.teardown || '',
|
|
250
|
+
worn: plane.worn || '',
|
|
251
|
+
narrow: scope === 'one flow' || scope === 'one artifact',
|
|
252
|
+
};
|
|
253
|
+
if (flavor === 'triage') {
|
|
254
|
+
const filled = new Set(filledOf(plane));
|
|
255
|
+
view.empty = FIELD_ORDER.filter((name) => !filled.has(name));
|
|
256
|
+
view.exam = examinePlane(plane, root).text;
|
|
257
|
+
}
|
|
258
|
+
return view;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function formatCardText(view) {
|
|
262
|
+
const rows = [
|
|
263
|
+
['Plane', view.plane],
|
|
264
|
+
['From', view.from],
|
|
265
|
+
['Digest', view.digest],
|
|
266
|
+
['Plate', view.plate],
|
|
267
|
+
['Entry', view.entry],
|
|
268
|
+
['Exit', view.exit],
|
|
269
|
+
['Files', view.files.join(', ')],
|
|
270
|
+
['Skills', view.skills],
|
|
271
|
+
['Setup', view.setup],
|
|
272
|
+
['Teardown', view.teardown],
|
|
273
|
+
['Worn', view.worn],
|
|
274
|
+
];
|
|
275
|
+
const shown = view.narrow
|
|
276
|
+
? rows.filter(([key]) => key === 'Plane' || key === 'Digest' || key === 'Files')
|
|
277
|
+
: rows;
|
|
278
|
+
let text = shown.map(([key, value]) => `${key}: ${value}`.trimEnd()).join('\n');
|
|
279
|
+
if (view.flavor === 'triage') {
|
|
280
|
+
const lines = [];
|
|
281
|
+
if (view.empty.length) lines.push(`Empty: ${view.empty.join(', ')}`);
|
|
282
|
+
lines.push(view.exam);
|
|
283
|
+
text = `${text}\n${lines.join('\n')}`;
|
|
284
|
+
}
|
|
285
|
+
return text;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function formatCardPane(view) {
|
|
289
|
+
const rows = [['Plane', view.plane]];
|
|
290
|
+
if (!view.narrow) rows.push(['From', view.from]);
|
|
291
|
+
rows.push(['Digest', view.digest]);
|
|
292
|
+
if (!view.narrow) {
|
|
293
|
+
rows.push(
|
|
294
|
+
['Plate', view.plate],
|
|
295
|
+
['Entry', view.entry],
|
|
296
|
+
['Exit', view.exit],
|
|
297
|
+
['Files', view.files.join(', ')],
|
|
298
|
+
['Skills', view.skills],
|
|
299
|
+
['Setup', view.setup],
|
|
300
|
+
['Teardown', view.teardown],
|
|
301
|
+
['Worn', view.worn],
|
|
302
|
+
);
|
|
303
|
+
} else {
|
|
304
|
+
rows.push(['Files', view.files.join(', ')]);
|
|
305
|
+
}
|
|
306
|
+
if (view.flavor === 'triage') {
|
|
307
|
+
if (Array.isArray(view.empty) && view.empty.length) rows.push(['Empty', view.empty.join(', ')]);
|
|
308
|
+
if (view.exam) rows.push(['', view.exam]);
|
|
309
|
+
}
|
|
310
|
+
const body = rows.map(([label, value]) => (label ? `${label.padEnd(8)} ${value}` : value).trimEnd());
|
|
311
|
+
const title = `${view.flavor} · ${view.plane}`;
|
|
312
|
+
const width = Math.max(title.length + 2, ...body.map((line) => line.length));
|
|
313
|
+
const top = `┌ ${title} ${'─'.repeat(Math.max(0, width - title.length - 1))}┐`;
|
|
314
|
+
const mid = body.map((line) => `│ ${line.padEnd(width)} │`);
|
|
315
|
+
const bot = `└${'─'.repeat(width + 2)}┘`;
|
|
316
|
+
return [top, ...mid, bot].join('\n');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function collectCards(flavor, lower) {
|
|
320
|
+
const named = cardPlanesNamed(lower);
|
|
321
|
+
const scopes = findScopes(lower.filter((word) => word !== flavor && !named.includes(word)));
|
|
322
|
+
if (named.length > 1 || scopes.length > 1) return null;
|
|
323
|
+
const scope = scopes[0] || '';
|
|
324
|
+
if (!named.length && (scope === 'part' || scope === 'one flow' || scope === 'one artifact')) return null;
|
|
325
|
+
const platesDir = findPlatesDir(HERE);
|
|
326
|
+
if (!platesDir) return null;
|
|
327
|
+
const ids = named.length ? named : CARD_PLANES;
|
|
328
|
+
const root = repoRootFrom(platesDir);
|
|
329
|
+
const cards = [];
|
|
330
|
+
for (const id of ids) {
|
|
331
|
+
const plane = assemblePlane(id, platesDir);
|
|
332
|
+
if (!plane) continue;
|
|
333
|
+
const view = cardView(plane, scope, flavor, root);
|
|
334
|
+
if (!view) return null;
|
|
335
|
+
cards.push(view);
|
|
336
|
+
}
|
|
337
|
+
return cards;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function findPlatesDir(start) {
|
|
341
|
+
let dir = start;
|
|
342
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
343
|
+
const candidate = join(dir, 'docs-site', 'docs', 'plates');
|
|
344
|
+
if (existsSync(join(candidate, 'index.md'))) return candidate;
|
|
345
|
+
const parent = dirname(dir);
|
|
346
|
+
if (parent === dir) break;
|
|
347
|
+
dir = parent;
|
|
348
|
+
}
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
function stripFrontmatter(raw) {
|
|
354
|
+
return String(raw).replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, '').trim();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
function boxTitles(line) {
|
|
359
|
+
const titles = [];
|
|
360
|
+
for (const part of String(line).split('│')) {
|
|
361
|
+
const title = part.replace(/\s+/g, ' ').trim();
|
|
362
|
+
if (!/[A-Za-z]/.test(title)) continue;
|
|
363
|
+
if (title.startsWith('·') || title.includes('LAYER')) continue;
|
|
364
|
+
titles.push(title);
|
|
365
|
+
}
|
|
366
|
+
return titles;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function doorsOf(body) {
|
|
370
|
+
let layer = '';
|
|
371
|
+
let want = false;
|
|
372
|
+
const found = { input: [], output: [] };
|
|
373
|
+
for (const line of String(body).split(/\r?\n/)) {
|
|
374
|
+
if (line.includes('INPUT LAYER')) { layer = 'input'; want = false; continue; }
|
|
375
|
+
if (line.includes('OUTPUT LAYER')) { layer = 'output'; want = false; continue; }
|
|
376
|
+
if (line.includes('PROCESSING LAYER')) { layer = ''; want = false; continue; }
|
|
377
|
+
if (layer !== 'input' && layer !== 'output') continue;
|
|
378
|
+
if (line.includes('┌')) { want = true; continue; }
|
|
379
|
+
if (!want) continue;
|
|
380
|
+
const titles = boxTitles(line);
|
|
381
|
+
if (!titles.length) continue;
|
|
382
|
+
found[layer].push(...titles);
|
|
383
|
+
want = false;
|
|
384
|
+
}
|
|
385
|
+
const join = (list) => (list.length ? list.join(' · ') : null);
|
|
386
|
+
return { entry: join(found.input), exit: join(found.output) };
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function takeOf(body) {
|
|
390
|
+
const lines = String(body).split(/\r?\n/);
|
|
391
|
+
const prose = [];
|
|
392
|
+
let pastHeading = false;
|
|
393
|
+
for (const line of lines) {
|
|
394
|
+
if (!pastHeading) {
|
|
395
|
+
if (/^#\s+/.test(line)) pastHeading = true;
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (line.startsWith('```')) break;
|
|
399
|
+
if (!line.trim()) {
|
|
400
|
+
if (prose.length) break;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
prose.push(line.trim());
|
|
404
|
+
}
|
|
405
|
+
const paragraph = prose.join(' ');
|
|
406
|
+
const sentence = paragraph.match(/^.*?[.!?](?:\s|$)/);
|
|
407
|
+
return (sentence ? sentence[0] : paragraph).trim();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
function overlayTable() {
|
|
412
|
+
const file = planesFile();
|
|
413
|
+
if (!existsSync(file)) return {};
|
|
414
|
+
return JSON.parse(readFileSync(file, 'utf8'));
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function present(value) {
|
|
418
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
419
|
+
return Boolean(value);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
export function filledOf(plane) {
|
|
423
|
+
const flags = {
|
|
424
|
+
plate: present(plane.plate),
|
|
425
|
+
entry: present(plane.entry),
|
|
426
|
+
exit: present(plane.exit),
|
|
427
|
+
files: present(plane.files) || present(plane.unpathed),
|
|
428
|
+
skills: present(plane.skills),
|
|
429
|
+
setup: present(plane.setup),
|
|
430
|
+
teardown: present(plane.teardown),
|
|
431
|
+
worn: present(plane.worn),
|
|
432
|
+
};
|
|
433
|
+
return FIELD_ORDER.filter((name) => flags[name]);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export function assemblePlane(id, platesDir) {
|
|
437
|
+
const extra = overlayTable()[id] || {};
|
|
438
|
+
let plate = null;
|
|
439
|
+
let digest = extra.digest || '';
|
|
440
|
+
let doors = { entry: null, exit: null };
|
|
441
|
+
if (id !== 'ground') {
|
|
442
|
+
const abs = join(platesDir, `${id}.md`);
|
|
443
|
+
if (!existsSync(abs)) return null;
|
|
444
|
+
const raw = readFileSync(abs, 'utf8');
|
|
445
|
+
plate = join('docs-site', 'docs', 'plates', `${id}.md`);
|
|
446
|
+
if (!digest) digest = takeOf(stripFrontmatter(raw));
|
|
447
|
+
doors = doorsOf(raw);
|
|
448
|
+
}
|
|
449
|
+
if (!digest) return null;
|
|
450
|
+
return {
|
|
451
|
+
id,
|
|
452
|
+
digest,
|
|
453
|
+
plate,
|
|
454
|
+
entry: extra.entry || doors.entry || null,
|
|
455
|
+
exit: extra.exit || doors.exit || null,
|
|
456
|
+
entryIsMark: Boolean(extra.entry),
|
|
457
|
+
exitIsMark: Boolean(extra.exit),
|
|
458
|
+
files: extra.files || null,
|
|
459
|
+
unpathed: extra.unpathed || null,
|
|
460
|
+
skills: extra.skills || null,
|
|
461
|
+
setup: extra.setup || null,
|
|
462
|
+
teardown: extra.teardown || null,
|
|
463
|
+
worn: extra.worn || null,
|
|
464
|
+
mark: extra.mark || null,
|
|
465
|
+
wornMark: extra.wornMark || null,
|
|
466
|
+
pick: extra.pick || null,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function repoRootFrom(platesDir) {
|
|
471
|
+
return dirname(dirname(dirname(platesDir)));
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function miss(text) {
|
|
475
|
+
return { ok: false, text };
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function ok(text) {
|
|
479
|
+
return { ok: true, text };
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function holds() {
|
|
483
|
+
return { kind: 'holds', text: 'Holds.' };
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function drift(text) {
|
|
487
|
+
return { kind: 'drift', text: `Drift: ${text}` };
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function drawing() {
|
|
491
|
+
return { kind: 'drawing', text: 'Drawing only.' };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function fileHas(root, rel, mark) {
|
|
495
|
+
if (!rel || !mark) return false;
|
|
496
|
+
const full = join(root, rel);
|
|
497
|
+
return existsSync(full) && readFileSync(full, 'utf8').includes(mark);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
function examinePlane(plane, root) {
|
|
502
|
+
const files = Array.isArray(plane.files) ? plane.files : [];
|
|
503
|
+
const checkable = files.length > 0 || plane.skills || plane.worn;
|
|
504
|
+
if (!checkable) return drawing();
|
|
505
|
+
for (const rel of files) {
|
|
506
|
+
if (!existsSync(join(root, rel))) return drift(`${rel} is not there`);
|
|
507
|
+
}
|
|
508
|
+
if (plane.mark && !fileHas(root, files[0], plane.mark)) {
|
|
509
|
+
return drift(`${plane.mark} is not in ${files[0]}`);
|
|
510
|
+
}
|
|
511
|
+
if (plane.worn && !fileHas(root, plane.worn, plane.wornMark || plane.mark)) {
|
|
512
|
+
return drift(`the worn build is not ${files[0] || plane.worn}`);
|
|
513
|
+
}
|
|
514
|
+
if (plane.skills && !existsSync(join(root, plane.skills))) {
|
|
515
|
+
return drift(`${plane.skills} is not there`);
|
|
516
|
+
}
|
|
517
|
+
if (plane.entryIsMark && plane.entry && files[0] && !fileHas(root, files[0], plane.entry)) {
|
|
518
|
+
return drift(`${plane.entry} is not in ${files[0]}`);
|
|
519
|
+
}
|
|
520
|
+
if (plane.exitIsMark && plane.exit && files[0] && !fileHas(root, files[0], plane.exit)) {
|
|
521
|
+
return drift(`${plane.exit} is not in ${files[0]}`);
|
|
522
|
+
}
|
|
523
|
+
return holds();
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
export function look(argv) {
|
|
528
|
+
return readGoggles(argv);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
function isGogglesWork(text) {
|
|
533
|
+
return /(?<![A-Za-z0-9-])goggles(?![A-Za-z0-9-])/i.test(String(text || ''));
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
export function cardStop(root, toolName, text, paths = []) {
|
|
538
|
+
const raw = [String(text || ''), ...(paths || [])].join('\n');
|
|
539
|
+
if (isGogglesWork(raw)) {
|
|
540
|
+
clearReading(root);
|
|
541
|
+
clearCardLine(root);
|
|
542
|
+
return null;
|
|
543
|
+
}
|
|
544
|
+
const held = loadReading(root);
|
|
545
|
+
if (!held) return null;
|
|
546
|
+
const drift = actualityLine();
|
|
547
|
+
if (drift) return organDeny(drift);
|
|
548
|
+
return organStop(held, { tool: toolName, text, paths });
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function stationFile(root) {
|
|
552
|
+
return join(root, '.xray', 'state', 'STATION.md');
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
function withoutCardLines(text) {
|
|
556
|
+
return String(text || '')
|
|
557
|
+
.split(/\r?\n/)
|
|
558
|
+
.filter((row) => !/^Card:\s/.test(row.trim()))
|
|
559
|
+
.join('\n')
|
|
560
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function clearCardLine(root) {
|
|
564
|
+
const dest = stationFile(root);
|
|
565
|
+
if (!existsSync(dest)) return;
|
|
566
|
+
const prev = readFileSync(dest, 'utf8');
|
|
567
|
+
const next = withoutCardLines(prev).replace(/\s*$/, '');
|
|
568
|
+
const body = next ? `${next}\n` : '';
|
|
569
|
+
if (body !== prev) writeFileSync(dest, body);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
function intentWords(text) {
|
|
574
|
+
return String(text || '').toLowerCase().split(/[^a-z0-9-]+/).filter(Boolean);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export function handCard(root, intent) {
|
|
578
|
+
try {
|
|
579
|
+
clearCardLine(root);
|
|
580
|
+
const text = String(intent || '');
|
|
581
|
+
if (isGogglesWork(text)) {
|
|
582
|
+
clearReading(root);
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
const words = intentWords(text);
|
|
586
|
+
const looked = readGoggles(words);
|
|
587
|
+
if (looked.text.startsWith('Actuality. Drift')) {
|
|
588
|
+
saveReading(root, { drift: looked.text });
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
const planes = acceptedPlanes().filter((name) => words.includes(name));
|
|
592
|
+
if (planes.length !== 1) {
|
|
593
|
+
clearReading(root);
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
const scopes = findScopes(words.filter((word) => word !== planes[0]));
|
|
597
|
+
if (scopes.length > 1) {
|
|
598
|
+
clearReading(root);
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
const next = { plane: planes[0], scope: scopes[0] || '' };
|
|
602
|
+
const prev = loadReading(root);
|
|
603
|
+
if (prev && prev.plane === next.plane && (prev.scope || '') === next.scope && !prev.drift) return null;
|
|
604
|
+
saveReading(root, next);
|
|
605
|
+
return null;
|
|
606
|
+
} catch {
|
|
607
|
+
return null;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
export function lensPath(root) {
|
|
613
|
+
return join(root, '.xray', 'state', 'LENS.md');
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
export function maintainLens(root) {
|
|
618
|
+
const text = actualityLine();
|
|
619
|
+
mkdirSync(dirname(lensPath(root)), { recursive: true });
|
|
620
|
+
writeFileSync(lensPath(root), `${text}\n`);
|
|
621
|
+
return ok(text);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
const isMain = Boolean(process.argv[1]) && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
626
|
+
if (isMain) {
|
|
627
|
+
const answered = gogglesAnswer(process.argv.slice(2));
|
|
628
|
+
const pane = process.stdout.isTTY && Array.isArray(answered.cards) && answered.cards.length > 0;
|
|
629
|
+
const text = pane ? answered.cards.map((card) => formatCardPane(card)).join('\n\n') : answered.text;
|
|
630
|
+
process.stdout.write(`${text}\n`);
|
|
631
|
+
process.exit(0);
|
|
632
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"actuality": "map vs worn",
|
|
3
|
+
"planes": ["dichotomy", "syncopate", "synthesis", "digest", "triage", "loop"],
|
|
4
|
+
"scope": ["ecosystem", "part", "one flow", "one artifact"],
|
|
5
|
+
"ground": {
|
|
6
|
+
"digest": "Home. The dev plane.",
|
|
7
|
+
"files": [
|
|
8
|
+
"src",
|
|
9
|
+
"grok-bot/OP-PROC.md",
|
|
10
|
+
"src/opencode/agents",
|
|
11
|
+
"Agents.md",
|
|
12
|
+
"src/integrations",
|
|
13
|
+
"package.json",
|
|
14
|
+
"scripts/foundry"
|
|
15
|
+
],
|
|
16
|
+
"skills": "SKILLS.md"
|
|
17
|
+
},
|
|
18
|
+
"routing": {
|
|
19
|
+
"files": ["src/nucleus/thin-dispatch.ts"],
|
|
20
|
+
"worn": "dist/nucleus/thin-dispatch.js",
|
|
21
|
+
"mark": "export function scoreAndRoute",
|
|
22
|
+
"wornMark": "function scoreAndRoute",
|
|
23
|
+
"pick": "resolveThinDispatch"
|
|
24
|
+
},
|
|
25
|
+
"house": {
|
|
26
|
+
"files": ["grok-bot/lib/seat-doctor.cjs"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -15,6 +15,11 @@ const PLATE_IDS = Object.freeze([
|
|
|
15
15
|
"reporting",
|
|
16
16
|
"memory-recall",
|
|
17
17
|
"house",
|
|
18
|
+
"goggles",
|
|
19
|
+
"suit",
|
|
20
|
+
"kits",
|
|
21
|
+
"host-pack",
|
|
22
|
+
"glossary",
|
|
18
23
|
]);
|
|
19
24
|
|
|
20
25
|
/** Id token, then extra phrases. Equal top scores recall nothing. */
|
|
@@ -68,6 +73,24 @@ const CUES = {
|
|
|
68
73
|
[/GROK_BOT_HOUSE/i, 4],
|
|
69
74
|
[/setup-house/i, 4],
|
|
70
75
|
],
|
|
76
|
+
goggles: [
|
|
77
|
+
[/\bgoggles\b/i, 6],
|
|
78
|
+
],
|
|
79
|
+
suit: [
|
|
80
|
+
[/suit plate/i, 6],
|
|
81
|
+
[/plates\/suit\b/i, 6],
|
|
82
|
+
],
|
|
83
|
+
kits: [
|
|
84
|
+
[/\bkits plate\b/i, 6],
|
|
85
|
+
[/\bkits\b/i, 5],
|
|
86
|
+
],
|
|
87
|
+
"host-pack": [
|
|
88
|
+
[/host\s*pack/i, 6],
|
|
89
|
+
[/host-pack/i, 6],
|
|
90
|
+
],
|
|
91
|
+
glossary: [
|
|
92
|
+
[/\bglossary\b/i, 6],
|
|
93
|
+
],
|
|
71
94
|
};
|
|
72
95
|
|
|
73
96
|
function platesDir() {
|