0xray 3.3.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 (70) hide show
  1. package/.opencode/enforcer-config.json +1 -4
  2. package/.xray/codex.json +598 -0
  3. package/.xray/config.json +25 -0
  4. package/.xray/features.json +146 -0
  5. package/.xray/features.schema.json +33 -0
  6. package/AGENTS-consumer.md +127 -10
  7. package/AGENTS.md +172 -56
  8. package/README.md +159 -82
  9. package/SKILLS.md +79 -53
  10. package/dist/AGENTS.md +172 -56
  11. package/dist/CHANGELOG.md +90 -51
  12. package/dist/README.md +159 -82
  13. package/dist/SKILLS.md +79 -53
  14. package/dist/analytics/routing-refiner.js +0 -2
  15. package/dist/core/boot-orchestrator.js +9 -1
  16. package/dist/core/features-config.js +5 -1
  17. package/dist/integrations/grok/grok-cli.js +47 -25
  18. package/dist/integrations/grok/hooks/grok-hook-activity.js +53 -0
  19. package/dist/integrations/grok/hooks/grok-hook-utils.js +261 -0
  20. package/dist/integrations/grok/hooks/pre-tool-use.js +85 -115
  21. package/dist/integrations/grok/hooks/session-start.js +52 -0
  22. package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +20 -3
  23. package/dist/integrations/hermes-agent/bridge.mjs +11 -1
  24. package/dist/mcps/config/server-config-registry.js +4 -3
  25. package/dist/mcps/orchestrator/handlers/complexity-handler.js +33 -3
  26. package/dist/mcps/orchestrator/server.js +1 -1
  27. package/dist/mcps/registry.json +0 -1
  28. package/dist/mcps/researcher.server.js +3 -0
  29. package/dist/nucleus/autonomy-kernel.js +176 -0
  30. package/dist/nucleus/index.js +1 -0
  31. package/dist/orchestrator/universal-registry-bridge.js +1 -1
  32. package/dist/skills/boot-orchestrator/SKILL.md +1 -5
  33. package/dist/skills/orchestrator/SKILL.md +35 -12
  34. package/dist/skills/registry.json +0 -1
  35. package/dist/skills/researcher/SKILL.md +17 -4
  36. package/dist/skills/strategist/SKILL.md +12 -0
  37. package/dist/skills/testing-strategy/SKILL.md +13 -2
  38. package/package.json +23 -8
  39. package/scripts/node/consumer-install-smoke.mjs +163 -0
  40. package/scripts/node/enforce-agents-md.mjs +0 -26
  41. package/scripts/node/enforce-version-compliance.sh +0 -1
  42. package/scripts/node/enforce-version-compliance.ts +0 -10
  43. package/scripts/node/install-bridges.cjs +154 -39
  44. package/scripts/node/pre-publish-guard.js +108 -165
  45. package/scripts/node/reconcile-version.mjs +147 -0
  46. package/scripts/node/release-gate.mjs +66 -0
  47. package/scripts/node/release.js +5 -147
  48. package/scripts/node/release.mjs +106 -181
  49. package/scripts/node/setup.cjs +21 -26
  50. package/scripts/node/sync-versions.mjs +12 -134
  51. package/scripts/node/universal-version-manager.js +22 -4
  52. package/scripts/node/validate-release-docs.mjs +299 -0
  53. package/scripts/node/version-manager.mjs +225 -49
  54. package/src/integrations/grok/plugin/0xray/hooks/hooks.json +20 -3
  55. package/src/mcps/config/__tests__/server-config-registry.test.ts +9 -0
  56. package/src/mcps/config/server-config-registry.ts +5 -3
  57. package/src/mcps/orchestrator/handlers/complexity-handler.ts +54 -3
  58. package/src/mcps/orchestrator/server.ts +1 -1
  59. package/src/mcps/registry.json +0 -1
  60. package/src/mcps/researcher.server.ts +4 -0
  61. package/src/opencode/enforcer-config.json +1 -4
  62. package/src/skills/boot-orchestrator/SKILL.md +1 -5
  63. package/src/skills/orchestrator/SKILL.md +35 -12
  64. package/src/skills/registry.json +0 -1
  65. package/src/skills/researcher/SKILL.md +17 -4
  66. package/src/skills/strategist/SKILL.md +12 -0
  67. package/src/skills/testing-strategy/SKILL.md +13 -2
  68. package/xray/config.json +25 -0
  69. package/xray/features.json +146 -0
  70. 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
+ });
@@ -17,7 +17,6 @@
17
17
  * - Historical docs (docs/reflections, docs/archive)
18
18
  * - Test files with assertions
19
19
  *
20
- * @version 2.0.0
21
20
  * @since 2026-01-15
22
21
  * @updated 2026-03-09 - Enhanced with documentation management, validation, and backup
23
22
  */
@@ -28,6 +27,19 @@ const require = createRequire(import.meta.url);
28
27
  import fs from "fs";
29
28
  import path from "path";
30
29
  import { execSync } from "child_process";
30
+ import { fileURLToPath } from "url";
31
+
32
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
33
+ const rootDir = path.resolve(__dirname, "../..");
34
+
35
+ function readPackageVersion() {
36
+ try {
37
+ const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf-8"));
38
+ return pkg.version;
39
+ } catch {
40
+ return "0.0.0";
41
+ }
42
+ }
31
43
 
32
44
  /**
33
45
  * Auto-calculate framework counts from filesystem
@@ -133,12 +145,14 @@ const CALCULATED_COUNTS = calculateCounts();
133
145
  * Framework version information - SINGLE SOURCE OF TRUTH
134
146
  * Version manager updates this, then propagates to all files
135
147
  */
148
+ const PACKAGE_VERSION = readPackageVersion();
149
+
136
150
  const OFFICIAL_VERSIONS = {
137
- // Framework version
151
+ // Framework version — SSOT: package.json
138
152
  framework: {
139
- version: "3.3.0",
153
+ version: PACKAGE_VERSION,
140
154
  displayName: "xray: Self-Healing AI Governance OS",
141
- lastUpdated: "2026-06-18",
155
+ lastUpdated: "2026-06-17",
142
156
  // Counts (auto-calculated, but can be overridden)
143
157
  ...CALCULATED_COUNTS,
144
158
  },
@@ -637,6 +651,10 @@ const UPDATE_PATTERNS = [
637
651
  }
638
652
 
639
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;
640
658
  console.log("🔧 Starting Universal Version Standardization");
641
659
  console.log(`📋 Framework: ${OFFICIAL_VERSIONS.framework.displayName}`);
642
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
+ }