0xray 3.4.1 → 3.4.2

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 (56) hide show
  1. package/.xray/codex.json +598 -0
  2. package/.xray/config.json +25 -0
  3. package/.xray/features.json +146 -0
  4. package/.xray/features.schema.json +33 -0
  5. package/AGENTS-consumer.md +127 -10
  6. package/AGENTS.md +172 -56
  7. package/README.md +159 -82
  8. package/SKILLS.md +79 -53
  9. package/dist/AGENTS.md +172 -56
  10. package/dist/CHANGELOG.md +79 -52
  11. package/dist/README.md +159 -82
  12. package/dist/SKILLS.md +79 -53
  13. package/dist/core/features-config.js +5 -0
  14. package/dist/integrations/grok/hooks/grok-hook-activity.js +53 -0
  15. package/dist/integrations/grok/hooks/grok-hook-utils.js +261 -0
  16. package/dist/integrations/grok/hooks/pre-tool-use.js +85 -115
  17. package/dist/integrations/grok/hooks/session-start.js +52 -0
  18. package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +20 -3
  19. package/dist/mcps/config/server-config-registry.js +4 -3
  20. package/dist/mcps/orchestrator/handlers/complexity-handler.js +33 -3
  21. package/dist/mcps/orchestrator/server.js +1 -1
  22. package/dist/mcps/researcher.server.js +3 -0
  23. package/dist/nucleus/autonomy-kernel.js +176 -0
  24. package/dist/nucleus/index.js +1 -0
  25. package/dist/skills/boot-orchestrator/SKILL.md +1 -5
  26. package/dist/skills/orchestrator/SKILL.md +35 -12
  27. package/dist/skills/researcher/SKILL.md +17 -4
  28. package/dist/skills/strategist/SKILL.md +12 -0
  29. package/dist/skills/testing-strategy/SKILL.md +13 -2
  30. package/package.json +23 -8
  31. package/scripts/node/consumer-install-smoke.mjs +163 -0
  32. package/scripts/node/install-bridges.cjs +19 -6
  33. package/scripts/node/pre-publish-guard.js +107 -168
  34. package/scripts/node/reconcile-version.mjs +147 -0
  35. package/scripts/node/release-gate.mjs +66 -0
  36. package/scripts/node/release.js +5 -147
  37. package/scripts/node/release.mjs +106 -181
  38. package/scripts/node/setup.cjs +12 -22
  39. package/scripts/node/sync-versions.mjs +12 -134
  40. package/scripts/node/universal-version-manager.js +4 -0
  41. package/scripts/node/validate-release-docs.mjs +299 -0
  42. package/scripts/node/version-manager.mjs +225 -49
  43. package/src/integrations/grok/plugin/0xray/hooks/hooks.json +20 -3
  44. package/src/mcps/config/__tests__/server-config-registry.test.ts +9 -0
  45. package/src/mcps/config/server-config-registry.ts +5 -3
  46. package/src/mcps/orchestrator/handlers/complexity-handler.ts +54 -3
  47. package/src/mcps/orchestrator/server.ts +1 -1
  48. package/src/mcps/researcher.server.ts +4 -0
  49. package/src/skills/boot-orchestrator/SKILL.md +1 -5
  50. package/src/skills/orchestrator/SKILL.md +35 -12
  51. package/src/skills/researcher/SKILL.md +17 -4
  52. package/src/skills/strategist/SKILL.md +12 -0
  53. package/src/skills/testing-strategy/SKILL.md +13 -2
  54. package/xray/config.json +25 -0
  55. package/xray/features.json +146 -0
  56. package/xray/features.schema.json +33 -0
@@ -1,140 +1,18 @@
1
1
  #!/usr/bin/env node
2
-
3
2
  /**
4
- * Version Sync Script
5
- *
6
- * Syncs version strings across all config and doc files to match package.json.
7
- * Called automatically by the release script after `npm version patch`.
8
- *
9
- * Append-only for docs — never overwrites existing content, only replaces
10
- * version strings in known patterns.
11
- *
12
- * Usage:
13
- * node scripts/node/sync-versions.mjs # dry run (prints changes)
14
- * node scripts/node/sync-versions.mjs --apply # apply changes
3
+ * @deprecated Use: node scripts/node/version-manager.mjs --artifacts-only
4
+ * SSOT for version strings is package.json (see reconcile-version.mjs).
15
5
  */
6
+ import { execSync } from "child_process";
7
+ import path from "path";
8
+ import { fileURLToPath } from "url";
16
9
 
17
- import { readFileSync, writeFileSync, existsSync } from "fs";
18
- import { join } from "path";
19
-
20
- const root = process.cwd();
21
- const apply = process.argv.includes("--apply");
22
-
23
- function readPkgVersion() {
24
- const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf-8"));
25
- return pkg.version;
26
- }
27
-
28
- function replaceVersionInFile(filePath, patterns, newVersion) {
29
- if (!existsSync(filePath)) {
30
- return { file: filePath, skipped: true, reason: "not found" };
31
- }
32
-
33
- let content = readFileSync(filePath, "utf-8");
34
- const oldContent = content;
35
- let changes = 0;
36
-
37
- for (const pattern of patterns) {
38
- const regex = pattern(newVersion);
39
- const matches = content.match(regex.regex);
40
- if (matches) {
41
- content = content.replace(regex.regex, regex.replacement);
42
- changes += matches.length;
43
- }
44
- }
45
-
46
- if (content !== oldContent && apply) {
47
- writeFileSync(filePath, content, "utf-8");
48
- }
49
-
50
- return { file: filePath, changes, applied: apply };
51
- }
52
-
53
- function replaceJsonVersion(filePath, newVersion) {
54
- return replaceVersionInFile(filePath, [
55
- (v) => ({
56
- regex: /"version"\s*:\s*"\d+\.\d+\.\d+"/g,
57
- replacement: `"version": "${v}"`,
58
- }),
59
- ], newVersion);
60
- }
61
-
62
- function replaceMdVersion(filePath, newVersion) {
63
- return replaceVersionInFile(filePath, [
64
- (v) => ({
65
- regex: /version-(\d+\.\d+\.\d+)/g,
66
- replacement: `version-${v}`,
67
- }),
68
- (v) => ({
69
- regex: /Version\*\*:\s*\d+\.\d+\.\d+/g,
70
- replacement: `Version**: ${v}`,
71
- }),
72
- (v) => ({
73
- regex: /v(\d+\.\d+\.\d+)/g,
74
- replacement: `v${v}`,
75
- }),
76
- (v) => ({
77
- regex: /\*\*Version\*\*:\s*\d+\.\d+\.\d+/g,
78
- replacement: `**Version**: ${v}`,
79
- }),
80
- (v) => ({
81
- regex: /"version":\s*"(\d+\.\d+\.\d+)"/g,
82
- replacement: `"version": "${v}"`,
83
- }),
84
- (v) => ({
85
- regex: /\d+\.\d+\.\d+(?=[^\d]*\.svg)/g,
86
- replacement: v,
87
- }),
88
- ], newVersion);
89
- }
90
-
91
- function main() {
92
- const newVersion = readPkgVersion();
93
- console.log(`\n=== Version Sync: ${newVersion} ===\n`);
94
- console.log(apply ? "Mode: APPLY" : "Mode: DRY RUN (use --apply to write)\n");
95
-
96
- const results = [];
97
-
98
- // Config JSON files (source of truth in src/opencode/)
99
- const configFiles = [
100
- "src/opencode/config.json",
101
- "src/opencode/features.json",
102
- "src/opencode/codex.codex",
103
- "src/opencode/integrations.json",
104
- ];
105
-
106
- for (const file of configFiles) {
107
- results.push(replaceJsonVersion(join(root, file), newVersion));
108
- }
109
-
110
- // Doc files
111
- const docFiles = [
112
- "AGENTS.md",
113
- "AGENTS-full.md",
114
- "docs/README.md",
115
- ];
116
-
117
- for (const file of docFiles) {
118
- results.push(replaceMdVersion(join(root, file), newVersion));
119
- }
120
-
121
- // Report
122
- let totalChanges = 0;
123
- for (const r of results) {
124
- if (r.skipped) {
125
- console.log(` SKIP ${r.file} (${r.reason})`);
126
- } else if (r.changes > 0) {
127
- totalChanges += r.changes;
128
- console.log(` ${r.applied ? "FIX" : "DRY"} ${r.file} (${r.changes} replacements)`);
129
- } else {
130
- console.log(` OK ${r.file}`);
131
- }
132
- }
10
+ const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
133
11
 
134
- console.log(`\nTotal: ${totalChanges} version strings ${apply ? "updated" : "would update"}`);
135
- if (!apply && totalChanges > 0) {
136
- console.log("Run with --apply to write changes.");
137
- }
138
- }
12
+ console.warn("\n⚠️ sync-versions.mjs is deprecated.");
13
+ console.warn(" Use: node scripts/node/version-manager.mjs --artifacts-only\n");
139
14
 
140
- main();
15
+ execSync("node scripts/node/version-manager.mjs --artifacts-only", {
16
+ cwd: rootDir,
17
+ stdio: "inherit",
18
+ });
@@ -651,6 +651,10 @@ const UPDATE_PATTERNS = [
651
651
  }
652
652
 
653
653
  async function standardizeVersions() {
654
+ console.warn("\n⚠️ universal-version-manager.js is DEPRECATED for releases.");
655
+ console.warn(" Use: npm run release:patch or npm run version:sync");
656
+ console.warn(" (version-manager.mjs --artifacts-only). Mass JSON version replace is disabled.\n");
657
+ return;
654
658
  console.log("🔧 Starting Universal Version Standardization");
655
659
  console.log(`📋 Framework: ${OFFICIAL_VERSIONS.framework.displayName}`);
656
660
  console.log(
@@ -0,0 +1,299 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * validate-release-docs.mjs — Blocking guard for release doc freshness.
4
+ *
5
+ * Ensures README, AGENTS, SKILLS, CHANGELOG, Docusaurus headers, and required
6
+ * guides match package.json version and live framework counts before tag/publish.
7
+ *
8
+ * Usage:
9
+ * node scripts/node/validate-release-docs.mjs
10
+ * node scripts/node/validate-release-docs.mjs --json
11
+ */
12
+
13
+ import fs from 'fs';
14
+ import path from 'path';
15
+ import { fileURLToPath } from 'url';
16
+ import {
17
+ buildDocsHeader,
18
+ DOCS_SITE_HEADER_FILES,
19
+ getFrameworkCounts,
20
+ getReleaseArtifactPaths,
21
+ } from './version-manager.mjs';
22
+
23
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
24
+ const defaultRoot = path.resolve(__dirname, '../..');
25
+
26
+ const STANDARD_HEADER_RE =
27
+ /^\*{0,2}v[\d.]+\*{0,2}\s*—\s*\d+ agents · \d+ skills · \d+ MCP servers? · \d+ codex terms(?: · [\d,]+ tests)?/m;
28
+
29
+ /** Guides that must exist and reference the current release (body or header). */
30
+ const REQUIRED_GUIDES = [
31
+ 'docs-site/docs/guides/features-since-3.1.md',
32
+ 'docs-site/docs/guides/features-json.md',
33
+ 'docs-site/docs/guides/memory-routing.md',
34
+ 'docs-site/docs/guides/aside-context.md',
35
+ 'docs-site/docs/guides/repertoire.md',
36
+ 'docs-site/docs/guides/integrations.md',
37
+ 'docs-site/docs/guides/consumer-migration.md',
38
+ 'docs-site/docs/mcp/README.md',
39
+ 'docs-site/docs/agents/README.md',
40
+ ];
41
+
42
+ const ROOT_DOC_CHECKS = [
43
+ {
44
+ rel: 'README.md',
45
+ validate: (content, version, counts, header) => {
46
+ const errors = [];
47
+ if (!content.includes(header)) {
48
+ errors.push(`missing or stale standard header (expected: ${header})`);
49
+ }
50
+ if (!content.includes('SKILLS.md')) {
51
+ errors.push('missing SKILLS.md reference in postinstall/docs section');
52
+ }
53
+ if (!content.includes('install-bridges') && !content.includes('installAllBridges')) {
54
+ errors.push('missing install-bridges / installAllBridges reference');
55
+ }
56
+ return errors;
57
+ },
58
+ },
59
+ {
60
+ rel: 'AGENTS.md',
61
+ validate: (content, version, counts) => {
62
+ const errors = [];
63
+ if (!content.includes(`**v${version}**`)) {
64
+ errors.push(`missing version marker **v${version}**`);
65
+ }
66
+ if (!content.includes(`${counts.agents} agents`)) {
67
+ errors.push(`expected ${counts.agents} agents in header`);
68
+ }
69
+ if (!content.includes(`${counts.skills} skills`)) {
70
+ errors.push(`expected ${counts.skills} skills in header`);
71
+ }
72
+ if (!content.includes('68 codex terms')) {
73
+ errors.push('expected 68 codex terms in header');
74
+ }
75
+ if (!content.includes('aside-context.md') && !content.includes('AsideContext')) {
76
+ errors.push('missing AsideContext documentation reference');
77
+ }
78
+ if (!content.includes('SKILLS.md')) {
79
+ errors.push('missing SKILLS.md link');
80
+ }
81
+ return errors;
82
+ },
83
+ },
84
+ {
85
+ rel: 'AGENTS-consumer.md',
86
+ validate: (content, version, counts) => {
87
+ const errors = [];
88
+ const expected = `**v${version}** — ${counts.mcps} MCP servers · ${counts.skills} skills · 68 codex terms`;
89
+ if (!content.includes(expected)) {
90
+ errors.push(`consumer header stale (expected substring: ${expected})`);
91
+ }
92
+ if (!content.includes('SKILLS.md')) {
93
+ errors.push('missing SKILLS.md in postinstall section');
94
+ }
95
+ if (!content.includes('AsideContext')) {
96
+ errors.push('missing AsideContext section');
97
+ }
98
+ return errors;
99
+ },
100
+ },
101
+ {
102
+ rel: 'SKILLS.md',
103
+ validate: (content, version, counts) => {
104
+ const errors = [];
105
+ const expected = `**v${version}** — **${counts.skills} skills**`;
106
+ if (!content.includes(expected)) {
107
+ errors.push(`header stale (expected: ${expected})`);
108
+ }
109
+ return errors;
110
+ },
111
+ },
112
+ ];
113
+
114
+ function readFile(rootDir, rel) {
115
+ const full = path.join(rootDir, rel);
116
+ if (!fs.existsSync(full)) return null;
117
+ return fs.readFileSync(full, 'utf-8');
118
+ }
119
+
120
+ function getPackageVersion(rootDir) {
121
+ const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8'));
122
+ return pkg.version;
123
+ }
124
+
125
+ function getCodexTermCount(rootDir) {
126
+ const codexPath = path.join(rootDir, '.xray/codex.json');
127
+ if (!fs.existsSync(codexPath)) return null;
128
+ const codex = JSON.parse(fs.readFileSync(codexPath, 'utf-8'));
129
+ return Object.keys(codex.terms || {}).length;
130
+ }
131
+
132
+ function validateChangelog(content, version) {
133
+ const errors = [];
134
+ const first = content.match(/^## \[([^\]]+)\]/m);
135
+ if (!first) {
136
+ errors.push('no version sections found');
137
+ return errors;
138
+ }
139
+ if (first[1] !== version) {
140
+ errors.push(`top CHANGELOG entry is [${first[1]}], expected [${version}]`);
141
+ }
142
+ if (!content.includes(`## [${version}]`)) {
143
+ errors.push(`missing ## [${version}] section`);
144
+ }
145
+ return errors;
146
+ }
147
+
148
+ function validateStandardHeader(content, expectedHeader, label) {
149
+ const match = content.match(STANDARD_HEADER_RE);
150
+ if (!match) {
151
+ return [`${label}: no standard docs header line found`];
152
+ }
153
+ if (match[0] !== expectedHeader) {
154
+ return [`${label}: header is "${match[0]}", expected "${expectedHeader}"`];
155
+ }
156
+ return [];
157
+ }
158
+
159
+ function validateDocusaurusTagline(content, counts) {
160
+ const errors = [];
161
+ const expectedParts = [
162
+ `${counts.agents} agents`,
163
+ `${counts.skills} skills`,
164
+ `${counts.mcps} MCP servers`,
165
+ '68 codex terms',
166
+ ];
167
+ for (const part of expectedParts) {
168
+ if (!content.includes(part)) {
169
+ errors.push(`docusaurus.config.ts tagline missing "${part}"`);
170
+ }
171
+ }
172
+ return errors;
173
+ }
174
+
175
+ /**
176
+ * @param {string} [rootDir]
177
+ * @returns {{ ok: boolean; version: string; counts: object; errors: string[]; warnings: string[] }}
178
+ */
179
+ export function validateReleaseDocs(rootDir = defaultRoot) {
180
+ const errors = [];
181
+ const warnings = [];
182
+ const version = getPackageVersion(rootDir);
183
+ const counts = getFrameworkCounts(rootDir);
184
+ const expectedHeader = buildDocsHeader(counts, version);
185
+ const codexTerms = getCodexTermCount(rootDir);
186
+
187
+ if (codexTerms !== null && codexTerms !== 68) {
188
+ warnings.push(`codex.json has ${codexTerms} terms (docs reference 68)`);
189
+ }
190
+
191
+ const changelog = readFile(rootDir, 'CHANGELOG.md');
192
+ if (!changelog) {
193
+ errors.push('CHANGELOG.md missing');
194
+ } else {
195
+ errors.push(...validateChangelog(changelog, version).map((e) => `CHANGELOG.md: ${e}`));
196
+ }
197
+
198
+ for (const check of ROOT_DOC_CHECKS) {
199
+ const content = readFile(rootDir, check.rel);
200
+ if (!content) {
201
+ errors.push(`${check.rel}: file missing`);
202
+ continue;
203
+ }
204
+ const relErrors = check.validate(content, version, counts, expectedHeader);
205
+ for (const e of relErrors) {
206
+ errors.push(`${check.rel}: ${e}`);
207
+ }
208
+ }
209
+
210
+ for (const rel of DOCS_SITE_HEADER_FILES) {
211
+ const content = readFile(rootDir, rel);
212
+ if (!content) {
213
+ errors.push(`${rel}: file missing`);
214
+ continue;
215
+ }
216
+ errors.push(...validateStandardHeader(content, expectedHeader, rel));
217
+ }
218
+
219
+ for (const rel of REQUIRED_GUIDES) {
220
+ const content = readFile(rootDir, rel);
221
+ if (!content) {
222
+ errors.push(`${rel}: required guide missing`);
223
+ continue;
224
+ }
225
+ if (content.trim().length < 200) {
226
+ errors.push(`${rel}: guide too short — likely stub`);
227
+ }
228
+ if (rel.includes('features-since-3.1') && !content.includes(version)) {
229
+ errors.push(`${rel}: must reference current version ${version}`);
230
+ }
231
+ }
232
+
233
+ const docusaurus = readFile(rootDir, 'docs-site/docusaurus.config.ts');
234
+ if (!docusaurus) {
235
+ errors.push('docs-site/docusaurus.config.ts: missing');
236
+ } else {
237
+ errors.push(...validateDocusaurusTagline(docusaurus, counts));
238
+ }
239
+
240
+ for (const rel of getReleaseArtifactPaths()) {
241
+ if (!fs.existsSync(path.join(rootDir, rel))) {
242
+ errors.push(`release artifact path missing: ${rel}`);
243
+ }
244
+ }
245
+
246
+ return {
247
+ ok: errors.length === 0,
248
+ version,
249
+ counts,
250
+ errors,
251
+ warnings,
252
+ };
253
+ }
254
+
255
+ function main() {
256
+ const jsonOut = process.argv.includes('--json');
257
+ const result = validateReleaseDocs();
258
+
259
+ if (!jsonOut) {
260
+ console.log('\n╔════════════════════════════════════════════════════════╗');
261
+ console.log('║ 📚 Release Docs Validation ║');
262
+ console.log('╚════════════════════════════════════════════════════════╝');
263
+ console.log(`\n📌 package.json version: v${result.version}`);
264
+ console.log(
265
+ `📊 counts: ${result.counts.agents} agents · ${result.counts.skills} skills · ${result.counts.mcps} MCP servers\n`,
266
+ );
267
+ }
268
+
269
+ if (result.warnings.length > 0 && !jsonOut) {
270
+ console.log('⚠️ Warnings:');
271
+ for (const w of result.warnings) console.log(` - ${w}`);
272
+ console.log();
273
+ }
274
+
275
+ if (!result.ok) {
276
+ if (jsonOut) {
277
+ console.log(JSON.stringify(result, null, 2));
278
+ } else {
279
+ console.error('❌ Release docs validation FAILED:\n');
280
+ for (const e of result.errors) console.error(` • ${e}`);
281
+ console.error('\nFix docs then run: npm run version:sync');
282
+ console.error('Or: node scripts/node/validate-release-docs.mjs\n');
283
+ }
284
+ process.exit(1);
285
+ }
286
+
287
+ if (jsonOut) {
288
+ console.log(JSON.stringify(result, null, 2));
289
+ } else {
290
+ console.log('✅ Release docs validation passed\n');
291
+ }
292
+ }
293
+
294
+ const isMain =
295
+ process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
296
+
297
+ if (isMain) {
298
+ main();
299
+ }