0xray 3.1.0 → 3.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 (274) hide show
  1. package/.gitignore.default +59 -0
  2. package/.mcp.json +35 -0
  3. package/.opencode/codex.codex +1 -1
  4. package/.opencode/commands/dependency-audit.md +3 -3
  5. package/.opencode/commands/summary-logger.md +4 -4
  6. package/.opencode/enforcer-config.json +2 -2
  7. package/.opencode/hooks/post-commit +1 -1
  8. package/.opencode/init.sh +6 -0
  9. package/.plugin/plugin.json +11 -0
  10. package/AGENTS-consumer.md +46 -0
  11. package/AGENTS.md +8 -8
  12. package/LICENSE +1 -1
  13. package/README.md +8 -8
  14. package/SKILLS.md +140 -0
  15. package/dist/.gitignore.default +59 -0
  16. package/dist/AGENTS.md +8 -8
  17. package/dist/CHANGELOG.md +25 -0
  18. package/dist/LICENSE +1 -1
  19. package/dist/README.md +8 -8
  20. package/dist/SKILLS.md +140 -0
  21. package/dist/agents/index.js +3 -1
  22. package/dist/agents/registry.js +13 -0
  23. package/dist/analytics/routing-refiner.js +1 -1
  24. package/dist/architect/architectural-integrity.js +3 -3
  25. package/dist/benchmark/performance-benchmark.js +1 -2
  26. package/dist/cli/commands/antigravity-status.js +23 -23
  27. package/dist/cli/commands/credible-init.js +1 -1
  28. package/dist/cli/commands/hermes-install.js +8 -0
  29. package/dist/cli/commands/mcp-install.js +1 -1
  30. package/dist/cli/commands/openclaw-install.js +9 -0
  31. package/dist/cli/commands/opencode-install.js +22 -0
  32. package/dist/cli/commands/skill-install.js +39 -2
  33. package/dist/cli/commands/status.js +5 -0
  34. package/dist/cli/commands/storyteller.js +1 -1
  35. package/dist/cli/index.js +12 -6
  36. package/dist/core/activity-logger.js +4 -4
  37. package/dist/core/agent-spawn-gate.js +1 -1
  38. package/dist/core/boot-orchestrator.js +12 -13
  39. package/dist/core/bridge.mjs +4 -4
  40. package/dist/core/codex-formatter.js +1 -2
  41. package/dist/core/codex-injector.js +3 -3
  42. package/dist/core/config-loader.js +1 -2
  43. package/dist/core/config-paths.js +30 -23
  44. package/dist/core/context-loader.js +0 -3
  45. package/dist/core/features-config.js +1 -1
  46. package/dist/core/index.js +2 -2
  47. package/dist/core/logging-config.js +7 -7
  48. package/dist/core/orchestrator.js +1 -1
  49. package/dist/core/xray-activation.js +3 -4
  50. package/dist/delegation/agent-delegator.js +2 -2
  51. package/dist/enforcement/enforcer-tools.js +2 -2
  52. package/dist/enforcement/loaders/codex-loader.js +2 -2
  53. package/dist/execution/opencode-cli-invoker.js +1 -1
  54. package/dist/governance/governance-service.js +1 -1
  55. package/dist/governance/llm-governance-provider.js +14 -1
  56. package/dist/index.js +3 -5
  57. package/dist/inference/inference-cycle.js +11 -11
  58. package/dist/integrations/base/README.md +1 -1
  59. package/dist/integrations/enforcement-gate.js +2 -2
  60. package/dist/integrations/governance/index.js +1 -1
  61. package/dist/integrations/grok/grok-cli.js +20 -6
  62. package/dist/integrations/grok/hooks/pre-tool-use.js +3 -3
  63. package/dist/integrations/grok/plugin/0xray/.mcp.json +16 -4
  64. package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +2 -2
  65. package/dist/integrations/hermes-agent/__init__.py +25 -14
  66. package/dist/integrations/hermes-agent/bridge.mjs +39 -4
  67. package/dist/integrations/hermes-agent/schemas.py +49 -0
  68. package/dist/integrations/hermes-agent/test_plugin.py +7 -7
  69. package/dist/integrations/hermes-agent/tools.py +107 -3
  70. package/dist/integrations/openclaw/README.md +6 -6
  71. package/dist/integrations/openclaw/config.js +1 -1
  72. package/dist/integrations/openclaw/index.js +2 -2
  73. package/dist/integrations/openclaw/types.js +3 -3
  74. package/dist/integrations/plugins/plugin-integration.js +1 -1
  75. package/dist/integrations/plugins/plugin-registry.js +1 -1
  76. package/dist/mcps/architect-tools.server.js +3 -2
  77. package/dist/mcps/auto-format.server.js +2 -2
  78. package/dist/mcps/boot-orchestrator.server.js +2 -2
  79. package/dist/mcps/config/config-loader.js +40 -9
  80. package/dist/mcps/enforcer-tools.server.js +2 -2
  81. package/dist/mcps/estimation.server.js +3 -2
  82. package/dist/mcps/framework-compliance-audit.server.js +2 -2
  83. package/dist/mcps/framework-help.server.js +3 -2
  84. package/dist/mcps/governance.server.js +8 -4
  85. package/dist/mcps/knowledge-skills/api-design.server.js +3 -2
  86. package/dist/mcps/knowledge-skills/architecture-patterns.server.js +3 -2
  87. package/dist/mcps/knowledge-skills/bug-triage-specialist.server.js +3 -3
  88. package/dist/mcps/knowledge-skills/code-analyzer.server.js +2 -2
  89. package/dist/mcps/knowledge-skills/code-review.server.js +2 -2
  90. package/dist/mcps/knowledge-skills/content-creator.server.js +3 -3
  91. package/dist/mcps/knowledge-skills/database-design.server.js +2 -2
  92. package/dist/mcps/knowledge-skills/devops-deployment.server.js +3 -2
  93. package/dist/mcps/knowledge-skills/git-workflow.server.js +3 -2
  94. package/dist/mcps/knowledge-skills/growth-strategist.server.js +3 -3
  95. package/dist/mcps/knowledge-skills/log-monitor.server.js +3 -3
  96. package/dist/mcps/knowledge-skills/mobile-development.server.js +3 -3
  97. package/dist/mcps/knowledge-skills/multimodal-looker.server.js +3 -3
  98. package/dist/mcps/knowledge-skills/performance-optimization.server.js +2 -2
  99. package/dist/mcps/knowledge-skills/project-analysis.server.js +2 -2
  100. package/dist/mcps/knowledge-skills/refactoring-strategies.server.js +3 -2
  101. package/dist/mcps/knowledge-skills/security-audit.server.js +2 -2
  102. package/dist/mcps/knowledge-skills/seo-consultant.server.js +3 -2
  103. package/dist/mcps/knowledge-skills/session-management.server.js +3 -2
  104. package/dist/mcps/knowledge-skills/skill-invocation.server.js +105 -3
  105. package/dist/mcps/knowledge-skills/strategist.server.js +3 -3
  106. package/dist/mcps/knowledge-skills/tech-writer.server.js +3 -3
  107. package/dist/mcps/knowledge-skills/testing-best-practices.server.js +3 -2
  108. package/dist/mcps/knowledge-skills/testing-strategy.server.js +2 -2
  109. package/dist/mcps/knowledge-skills/ui-ux-design.server.js +3 -2
  110. package/dist/mcps/lint.server.js +2 -2
  111. package/dist/mcps/model-health-check.server.js +3 -2
  112. package/dist/mcps/orchestrator/server.js +2 -1
  113. package/dist/mcps/orchestrator.server.js +2 -1
  114. package/dist/mcps/performance-analysis.server.js +2 -2
  115. package/dist/mcps/processor-pipeline.server.js +3 -2
  116. package/dist/mcps/registry.json +1 -1
  117. package/dist/mcps/researcher.server.js +2 -2
  118. package/dist/mcps/security-scan.server.js +2 -2
  119. package/dist/mcps/state-manager.server.js +5 -5
  120. package/dist/metrics/agent-metrics.js +1 -1
  121. package/dist/orchestrator/enhanced-multi-agent-orchestrator.js +2 -2
  122. package/dist/orchestrator/intelligent-commit-batcher.js +0 -1
  123. package/dist/orchestrator/multi-agent-orchestration-coordinator.js +1 -1
  124. package/dist/orchestrator/orchestrator.js +1 -2
  125. package/dist/orchestrator/universal-registry-bridge.js +1 -1
  126. package/dist/postprocessor/PostProcessor.js +5 -5
  127. package/dist/postprocessor/services/RegressionAnalysisService.js +2 -2
  128. package/dist/postprocessor/triggers/GitHookTrigger.js +4 -4
  129. package/dist/processors/implementations/inference-improvement-processor.js +0 -1
  130. package/dist/processors/implementations/publish-preflight-processor.js +0 -1
  131. package/dist/processors/implementations/session-summary-processor.js +2 -2
  132. package/dist/processors/implementations/storytelling-trigger-processor.js +0 -1
  133. package/dist/public/about.html +6 -6
  134. package/dist/public/enterprise.html +1 -1
  135. package/dist/public/features.html +2 -2
  136. package/dist/public/index.html +4 -4
  137. package/dist/reporting/report-formatter.js +1 -1
  138. package/dist/scripts/activate-kernel-pipeline.js +2 -2
  139. package/dist/scripts/pre-command +1 -1
  140. package/dist/services/inference-tuner.js +1 -1
  141. package/dist/skills/api-design/SKILL.md +1 -1
  142. package/dist/skills/architect-tools/SKILL.md +1 -1
  143. package/dist/skills/architecture-patterns/SKILL.md +1 -1
  144. package/dist/skills/auto-format/SKILL.md +1 -1
  145. package/dist/skills/boot-orchestrator/SKILL.md +1 -1
  146. package/dist/skills/bug-triage/SKILL.md +1 -1
  147. package/dist/skills/code-analyzer/SKILL.md +1 -1
  148. package/dist/skills/code-review/SKILL.md +1 -1
  149. package/dist/skills/enforcer/SKILL.md +1 -1
  150. package/dist/skills/framework-compliance-audit/SKILL.md +1 -1
  151. package/dist/skills/git-workflow/SKILL.md +1 -1
  152. package/dist/skills/hermes-agent/SKILL.md +2 -2
  153. package/dist/skills/inference-improve/SKILL.md +1 -1
  154. package/dist/skills/lint/SKILL.md +1 -1
  155. package/dist/skills/log-monitor/SKILL.md +1 -1
  156. package/dist/skills/model-health-check/SKILL.md +1 -1
  157. package/dist/skills/multimodal-looker/SKILL.md +1 -1
  158. package/dist/skills/orchestrator/SKILL.md +1 -1
  159. package/dist/skills/performance-analysis/SKILL.md +1 -1
  160. package/dist/skills/performance-optimization/SKILL.md +1 -1
  161. package/dist/skills/processor-pipeline/SKILL.md +1 -1
  162. package/dist/skills/project-analysis/SKILL.md +1 -1
  163. package/dist/skills/refactoring-strategies/SKILL.md +1 -1
  164. package/dist/skills/registry.json +1 -1
  165. package/dist/skills/researcher/SKILL.md +1 -1
  166. package/dist/skills/security-audit/SKILL.md +1 -1
  167. package/dist/skills/security-scan/SKILL.md +1 -1
  168. package/dist/skills/session-management/SKILL.md +1 -1
  169. package/dist/skills/state-manager/SKILL.md +1 -1
  170. package/dist/skills/storyteller/SKILL.md +1 -1
  171. package/dist/skills/testing-best-practices/SKILL.md +1 -1
  172. package/dist/skills/testing-strategy/SKILL.md +1 -1
  173. package/dist/skills/ui-ux-design/SKILL.md +1 -1
  174. package/dist/state/index.js +0 -1
  175. package/dist/state/state-manager.js +1 -2
  176. package/dist/utils/import-resolver.js +1 -1
  177. package/dist/utils/path-resolver.js +2 -2
  178. package/package.json +10 -3
  179. package/scripts/hooks/pre-command +1 -1
  180. package/scripts/hooks/run-hook.js +2 -2
  181. package/scripts/node/auto-reflection-generator.mjs +30 -36
  182. package/scripts/node/govern-reflection.mjs +1 -1
  183. package/scripts/node/postinstall.cjs +37 -2
  184. package/scripts/node/setup-xai-oauth.mjs +244 -0
  185. package/scripts/node/universal-version-manager.js +8 -8
  186. package/scripts/node/version-manager.mjs +1 -1
  187. package/src/integrations/grok/plugin/0xray/.mcp.json +16 -4
  188. package/src/integrations/grok/plugin/0xray/hooks/hooks.json +2 -2
  189. package/src/mcps/architect-tools.server.ts +2 -2
  190. package/src/mcps/auto-format.server.ts +2 -2
  191. package/src/mcps/boot-orchestrator.server.ts +2 -2
  192. package/src/mcps/config/__tests__/config-loader.test.ts +29 -33
  193. package/src/mcps/config/config-loader.ts +50 -11
  194. package/src/mcps/enforcer-tools.server.ts +2 -2
  195. package/src/mcps/estimation.server.ts +3 -2
  196. package/src/mcps/framework-compliance-audit.server.ts +2 -2
  197. package/src/mcps/framework-help.server.ts +3 -2
  198. package/src/mcps/governance.server.ts +8 -3
  199. package/src/mcps/knowledge-skills/api-design.server.ts +3 -2
  200. package/src/mcps/knowledge-skills/architecture-patterns.server.ts +2 -2
  201. package/src/mcps/knowledge-skills/bug-triage-specialist.server.ts +2 -2
  202. package/src/mcps/knowledge-skills/code-analyzer.server.ts +2 -2
  203. package/src/mcps/knowledge-skills/code-review.server.ts +2 -2
  204. package/src/mcps/knowledge-skills/content-creator.server.ts +3 -3
  205. package/src/mcps/knowledge-skills/database-design.server.ts +2 -2
  206. package/src/mcps/knowledge-skills/devops-deployment.server.ts +3 -2
  207. package/src/mcps/knowledge-skills/git-workflow.server.ts +3 -2
  208. package/src/mcps/knowledge-skills/growth-strategist.server.ts +3 -3
  209. package/src/mcps/knowledge-skills/log-monitor.server.ts +3 -3
  210. package/src/mcps/knowledge-skills/mobile-development.server.ts +3 -3
  211. package/src/mcps/knowledge-skills/multimodal-looker.server.ts +3 -3
  212. package/src/mcps/knowledge-skills/performance-optimization.server.ts +2 -2
  213. package/src/mcps/knowledge-skills/project-analysis.server.ts +2 -2
  214. package/src/mcps/knowledge-skills/refactoring-strategies.server.ts +3 -2
  215. package/src/mcps/knowledge-skills/security-audit.server.ts +2 -2
  216. package/src/mcps/knowledge-skills/seo-consultant.server.ts +3 -2
  217. package/src/mcps/knowledge-skills/session-management.server.ts +3 -2
  218. package/src/mcps/knowledge-skills/skill-invocation.server.ts +113 -3
  219. package/src/mcps/knowledge-skills/strategist.server.ts +3 -3
  220. package/src/mcps/knowledge-skills/tech-writer.server.ts +3 -3
  221. package/src/mcps/knowledge-skills/testing-best-practices.server.ts +3 -2
  222. package/src/mcps/knowledge-skills/testing-strategy.server.ts +2 -2
  223. package/src/mcps/knowledge-skills/ui-ux-design.server.ts +3 -2
  224. package/src/mcps/lint.server.ts +2 -2
  225. package/src/mcps/model-health-check.server.ts +2 -2
  226. package/src/mcps/orchestrator/server.ts +2 -1
  227. package/src/mcps/orchestrator.server.ts +2 -1
  228. package/src/mcps/performance-analysis.server.ts +2 -2
  229. package/src/mcps/processor-pipeline.server.ts +3 -2
  230. package/src/mcps/registry.json +1 -1
  231. package/src/mcps/researcher.server.ts +2 -2
  232. package/src/mcps/security-scan.server.ts +2 -2
  233. package/src/mcps/state-manager.server.ts +5 -5
  234. package/src/opencode/codex.codex +1 -1
  235. package/src/opencode/commands/dependency-audit.md +3 -3
  236. package/src/opencode/commands/summary-logger.md +4 -4
  237. package/src/opencode/enforcer-config.json +2 -2
  238. package/src/skills/api-design/SKILL.md +1 -1
  239. package/src/skills/architect-tools/SKILL.md +1 -1
  240. package/src/skills/architecture-patterns/SKILL.md +1 -1
  241. package/src/skills/auto-format/SKILL.md +1 -1
  242. package/src/skills/boot-orchestrator/SKILL.md +1 -1
  243. package/src/skills/bug-triage/SKILL.md +1 -1
  244. package/src/skills/code-analyzer/SKILL.md +1 -1
  245. package/src/skills/code-review/SKILL.md +1 -1
  246. package/src/skills/enforcer/SKILL.md +1 -1
  247. package/src/skills/framework-compliance-audit/SKILL.md +1 -1
  248. package/src/skills/git-workflow/SKILL.md +1 -1
  249. package/src/skills/hermes-agent/SKILL.md +2 -2
  250. package/src/skills/inference-improve/SKILL.md +1 -1
  251. package/src/skills/lint/SKILL.md +1 -1
  252. package/src/skills/log-monitor/SKILL.md +1 -1
  253. package/src/skills/model-health-check/SKILL.md +1 -1
  254. package/src/skills/multimodal-looker/SKILL.md +1 -1
  255. package/src/skills/orchestrator/SKILL.md +1 -1
  256. package/src/skills/performance-analysis/SKILL.md +1 -1
  257. package/src/skills/performance-optimization/SKILL.md +1 -1
  258. package/src/skills/processor-pipeline/SKILL.md +1 -1
  259. package/src/skills/project-analysis/SKILL.md +1 -1
  260. package/src/skills/refactoring-strategies/SKILL.md +1 -1
  261. package/src/skills/registry.json +1 -1
  262. package/src/skills/researcher/SKILL.md +1 -1
  263. package/src/skills/security-audit/SKILL.md +1 -1
  264. package/src/skills/security-scan/SKILL.md +1 -1
  265. package/src/skills/session-management/SKILL.md +1 -1
  266. package/src/skills/state-manager/SKILL.md +1 -1
  267. package/src/skills/storyteller/SKILL.md +1 -1
  268. package/src/skills/testing-best-practices/SKILL.md +1 -1
  269. package/src/skills/testing-strategy/SKILL.md +1 -1
  270. package/src/skills/ui-ux-design/SKILL.md +1 -1
  271. package/xray/agents_template.md +46 -0
  272. package/xray/codex.json +598 -0
  273. package/dist/plugin/xray-codex-injection.js +0 -857
  274. /package/dist/integrations/openclaw/hooks/{strray-hooks.js → xray-hooks.js} +0 -0
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * xAI OAuth PKCE setup — saves verifier to temp file so it survives aborts.
4
+ *
5
+ * Usage:
6
+ * node setup-xai-oauth.mjs # prints URL, waits for callback
7
+ * node setup-xai-oauth.mjs <code> # exchange previously gotten code
8
+ * node setup-xai-oauth.mjs daemon # non-blocking: prints URL & exits,
9
+ * # child server handles callback + deploy
10
+ */
11
+
12
+ import { randomBytes, createHash } from "node:crypto";
13
+ import { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from "node:fs";
14
+ import { join } from "node:path";
15
+ import { homedir, tmpdir } from "node:os";
16
+ import { fork } from "node:child_process";
17
+ import http from "node:http";
18
+
19
+ const PORT = 56121;
20
+ const HERMES_AUTH_PATH = join(homedir(), ".hermes", "auth.json");
21
+ const VERIFIER_PATH = join(tmpdir(), "xray-xai-oauth-verifier.txt");
22
+ const XAI_AUTH_URL = "https://auth.x.ai/oauth2/authorize";
23
+ const XAI_TOKEN_URL = "https://auth.x.ai/oauth2/token";
24
+ const XAI_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
25
+ const REDIRECT_URI = `http://127.0.0.1:${PORT}/callback`;
26
+
27
+ function generateVerifier() {
28
+ return randomBytes(32).toString("base64")
29
+ .replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
30
+ }
31
+
32
+ function challenge(verifier) {
33
+ return createHash("sha256").update(verifier).digest()
34
+ .toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
35
+ }
36
+
37
+ function printUrl(verifier) {
38
+ const codeChallenge = challenge(verifier);
39
+ const state = randomBytes(16).toString("hex");
40
+ const nonce = randomBytes(16).toString("hex");
41
+
42
+ const params = new URLSearchParams({
43
+ response_type: "code",
44
+ client_id: XAI_CLIENT_ID,
45
+ redirect_uri: REDIRECT_URI,
46
+ scope: "openid profile email offline_access grok-cli:access api:access",
47
+ code_challenge: codeChallenge,
48
+ code_challenge_method: "S256",
49
+ state, nonce,
50
+ plan: "generic",
51
+ referrer: "hermes-agent",
52
+ }).toString();
53
+
54
+ console.log("\n========================================");
55
+ console.log(" xAI OAuth Setup");
56
+ console.log("========================================");
57
+ console.log("\nOpen this URL in your browser:\n");
58
+ console.log(` ${XAI_AUTH_URL}?${params}\n`);
59
+ console.log("Authorize → callback handled → token saved → Railway deployed.");
60
+ console.log("You can close the browser tab when it says ✅ Authorized.\n");
61
+ }
62
+
63
+ async function startServer(verifier) {
64
+ return new Promise((resolve, reject) => {
65
+ const server = http.createServer((req, res) => {
66
+ const url = new URL(req.url, `http://127.0.0.1:${PORT}`);
67
+
68
+ if (url.pathname === "/callback" && url.searchParams.has("code")) {
69
+ const code = url.searchParams.get("code");
70
+ res.writeHead(200, { "Content-Type": "text/html" });
71
+ res.end(wrapHtml("<h1>✅ Authorized!</h1><p>Token saved. Railway deploying. You can close this window.</p>"));
72
+ try { unlinkSync(VERIFIER_PATH); } catch {}
73
+ // Give response a moment to send, then close
74
+ setTimeout(() => { server.close(); resolve(code); }, 100);
75
+ return;
76
+ }
77
+
78
+ if (url.pathname === "/callback") {
79
+ res.writeHead(400);
80
+ res.end("Missing code parameter");
81
+ return;
82
+ }
83
+
84
+ res.writeHead(404, { "Content-Type": "text/html" });
85
+ res.end(wrapHtml("<h1>404</h1><p>This server only handles xAI OAuth callbacks.</p>"));
86
+ });
87
+
88
+ server.listen(PORT, "127.0.0.1", () => {
89
+ // Persist verifier so it survives script abort
90
+ writeFileSync(VERIFIER_PATH, verifier, "utf-8");
91
+ });
92
+
93
+ server.on("error", (err) => {
94
+ if (err.code === "EADDRINUSE") {
95
+ console.error(`Port ${PORT} is already in use.`);
96
+ }
97
+ reject(err);
98
+ });
99
+ });
100
+ }
101
+
102
+ function wrapHtml(body) {
103
+ return `<html><head><style>body{font-family:sans-serif;display:flex;justify-content:center;align-items:center;height:100vh;background:#0f172a;color:#e2e8f0;text-align:center}</style></head><body>${body}</body></html>`;
104
+ }
105
+
106
+ async function exchangeCode(code, verifier) {
107
+ const body = new URLSearchParams({
108
+ grant_type: "authorization_code",
109
+ code,
110
+ redirect_uri: REDIRECT_URI,
111
+ code_verifier: verifier,
112
+ client_id: XAI_CLIENT_ID,
113
+ });
114
+
115
+ const response = await fetch(XAI_TOKEN_URL, {
116
+ method: "POST",
117
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
118
+ body: body.toString(),
119
+ });
120
+
121
+ if (!response.ok) {
122
+ const text = await response.text();
123
+ throw new Error(`Token exchange failed (${response.status}): ${text}`);
124
+ }
125
+
126
+ return response.json();
127
+ }
128
+
129
+ function saveToken(tokens) {
130
+ const authData = {
131
+ "xai-oauth": {
132
+ access_token: tokens.access_token,
133
+ refresh_token: tokens.refresh_token,
134
+ expires_at: Math.floor(Date.now() / 1000) + (tokens.expires_in || 86400),
135
+ token_type: tokens.token_type || "Bearer",
136
+ scope: tokens.scope || "openid profile email offline_access grok-cli:access api:access",
137
+ },
138
+ };
139
+
140
+ mkdirSync(join(homedir(), ".hermes"), { recursive: true });
141
+ writeFileSync(HERMES_AUTH_PATH, JSON.stringify(authData, null, 2));
142
+
143
+ console.log(`\n✅ Token saved to ${HERMES_AUTH_PATH}`);
144
+ console.log(` Expires: ${new Date(Date.now() + (tokens.expires_in || 86400) * 1000).toISOString()}\n`);
145
+ return authData;
146
+ }
147
+
148
+ async function deployToRailway() {
149
+ const { execSync } = await import("node:child_process");
150
+ const authContent = readFileSync(HERMES_AUTH_PATH, "utf-8");
151
+ const base64 = Buffer.from(authContent).toString("base64");
152
+
153
+ console.log("Setting Railway env var XRAY_HERMES_AUTH...");
154
+
155
+ // Use Railway API to set the variable
156
+ const projectId = execSync("railway project --json 2>/dev/null || echo ''", { encoding: "utf-8" }).trim();
157
+ console.log("Project info:", projectId || "(no project info)");
158
+
159
+ // We need to set the var via Railway env edit API or similar
160
+ // For now, fall back to railway run with the var
161
+ try {
162
+ execSync(`railway env edit --json -v XRAY_HERMES_AUTH="${base64}" 2>/dev/null`, {
163
+ stdio: "inherit",
164
+ timeout: 15000,
165
+ });
166
+ } catch {
167
+ // env edit might not support --json; try railway up instead
168
+ console.log("Attempting deploy with implicit env...");
169
+ }
170
+
171
+ console.log("Deploying to Railway...");
172
+ try {
173
+ execSync("railway up --service governance", { stdio: "inherit", timeout: 120000 });
174
+ console.log("\n✅ Deployed to Railway!");
175
+ } catch (err) {
176
+ console.error("\n⚠️ Deploy failed:", err.message);
177
+ console.log("Token was saved locally. Deploy manually: railway up --service governance");
178
+ }
179
+ }
180
+
181
+ // ── Daemon mode (non-blocking) ──────────────────────────────
182
+ async function daemonMain() {
183
+ const verifier = generateVerifier();
184
+ printUrl(verifier);
185
+
186
+ try {
187
+ const code = await startServer(verifier);
188
+ try { unlinkSync(VERIFIER_PATH); } catch {}
189
+
190
+ console.log("Exchanging code for tokens...");
191
+ const tokens = await exchangeCode(code, verifier);
192
+ saveToken(tokens);
193
+ await deployToRailway();
194
+ } catch (err) {
195
+ console.error("\n❌ Failed:", err.message);
196
+ try { unlinkSync(VERIFIER_PATH); } catch {}
197
+ process.exit(1);
198
+ }
199
+ }
200
+
201
+ // ── Interactive mode (blocking for code exchange) ────────────
202
+ async function interactiveMain() {
203
+ const existingCode = process.argv[2];
204
+
205
+ let verifier;
206
+ if (existingCode) {
207
+ verifier = readFileSync(VERIFIER_PATH, "utf-8").trim();
208
+ console.log("Using saved verifier from", VERIFIER_PATH);
209
+ } else {
210
+ verifier = generateVerifier();
211
+ }
212
+
213
+ try {
214
+ const code = existingCode || await startServer(verifier);
215
+ try { unlinkSync(VERIFIER_PATH); } catch {}
216
+
217
+ console.log("Exchanging code for tokens...");
218
+ const tokens = await exchangeCode(code, verifier);
219
+ saveToken(tokens);
220
+ } catch (err) {
221
+ console.error("\n❌ Setup failed:", err.message);
222
+ process.exit(1);
223
+ }
224
+ }
225
+
226
+ // ── Entry ────────────────────────────────────────────────────
227
+ const isDaemon = process.argv[2] === "daemon";
228
+
229
+ if (isDaemon) {
230
+ // Fork a child process that runs the daemon so the parent can exit immediately
231
+ const child = fork(process.argv[1], ["_daemon"], {
232
+ stdio: ["ignore", "pipe", "pipe", "ipc"],
233
+ detached: true,
234
+ });
235
+ child.stdout.on("data", (d) => process.stdout.write(d));
236
+ child.stderr.on("data", (d) => process.stderr.write(d));
237
+ child.unref();
238
+ // Give child a moment to start and print the URL
239
+ setTimeout(() => process.exit(0), 500);
240
+ } else if (process.argv[2] === "_daemon") {
241
+ daemonMain();
242
+ } else {
243
+ interactiveMain();
244
+ }
@@ -136,9 +136,9 @@ const CALCULATED_COUNTS = calculateCounts();
136
136
  const OFFICIAL_VERSIONS = {
137
137
  // Framework version
138
138
  framework: {
139
- version: "3.1.0",
139
+ version: "3.1.1",
140
140
  displayName: "xray: Self-Healing AI Governance OS",
141
- lastUpdated: "2026-06-15",
141
+ lastUpdated: "2026-06-16",
142
142
  // Counts (auto-calculated, but can be overridden)
143
143
  ...CALCULATED_COUNTS,
144
144
  },
@@ -327,29 +327,29 @@ const UPDATE_PATTERNS = [
327
327
  },
328
328
 
329
329
  // === BADGE AND COUNT PATTERNS ===
330
- // Test count in docs badge (e.g., tests-2527-brightgreen)
330
+ // Test count in docs badge (e.g., tests-2500-brightgreen)
331
331
  {
332
332
  pattern: /tests-[0-9]+(?=-brightgreen)/g,
333
333
  replacement: `tests-${OFFICIAL_VERSIONS.framework.tests}`,
334
334
  },
335
- // Test count in npm badge (e.g., tests-2527%20passed-brightgreen)
335
+ // Test count in npm badge (e.g., tests-2500%20passed-brightgreen)
336
336
  {
337
337
  pattern: /tests-[0-9,]+%20passed/g,
338
338
  replacement: `tests-${OFFICIAL_VERSIONS.framework.tests}%20passed`,
339
339
  },
340
- // Test count in prose (e.g., "2,2527 Tests" or "2527 Tests" but NOT in badge URLs)
340
+ // Test count in prose (e.g., "2,2500 Tests" or "2500 Tests" but NOT in badge URLs)
341
341
  {
342
342
  pattern: /(\*\s*✅\s*)([0-9]{1,3},?[0-9]{3})(\s*Tests)/g,
343
343
  replacement: (match, p1, p2, p3) => {
344
344
  return `${p1}${OFFICIAL_VERSIONS.framework.tests}${p3}`;
345
345
  },
346
346
  },
347
- // Test count in feature bullets (e.g., "✅ 2527 Tests")
347
+ // Test count in feature bullets (e.g., "✅ 2500 Tests")
348
348
  {
349
349
  pattern: /[0-9]+ Tests/g,
350
350
  replacement: `${OFFICIAL_VERSIONS.framework.tests} Tests`,
351
351
  },
352
- // Test count in config tree (e.g., "2527 tests")
352
+ // Test count in config tree (e.g., "2500 tests")
353
353
  {
354
354
  pattern: /[0-9]+ tests/g,
355
355
  replacement: `${OFFICIAL_VERSIONS.framework.tests} tests`,
@@ -384,7 +384,7 @@ const UPDATE_PATTERNS = [
384
384
  pattern: /xray AI v[0-9]+\.[0-9]+\.[0-9]+/g,
385
385
  replacement: `xray AI v${OFFICIAL_VERSIONS.framework.version}`,
386
386
  },
387
- // Footer bare version (e.g., "**Version**: 1.22.67")
387
+ // Footer bare version (e.g., "**Version**: 3.1.0")
388
388
  {
389
389
  pattern: /\*\*Version\*\*:\s*[0-9]+\.[0-9]+\.[0-9]+/g,
390
390
  replacement: `**Version**: ${OFFICIAL_VERSIONS.framework.version}`,
@@ -308,7 +308,7 @@ function updateAgentsMd(counts) {
308
308
 
309
309
  // Legacy header count update (min compat for old consumer AGENTS.md files only; xray v2 YML SSOT primary)
310
310
  agentsMd = agentsMd.replace(
311
- /0xRay\s*2\.0\s*-\s*\d+\s+Agents|StringRay\s*-\s*\d+\s+Agents/,
311
+ /0xRay\s*2\.0\s*-\s*\d+\s+Agents|0xRay\s*-\s*\d+\s+Agents/,
312
312
  `xray v2 - ${counts.agents} Agents`
313
313
  );
314
314
 
@@ -1,23 +1,35 @@
1
1
  {
2
2
  "mcpServers": {
3
- "0xray-governance": {
3
+ "xray-governance": {
4
4
  "command": "npx",
5
5
  "args": ["-y", "0xray", "mcp", "governance"],
6
6
  "env": {
7
7
  "XRAY_FORCE_MCP_GOVERNANCE": "true"
8
8
  }
9
9
  },
10
- "0xray-skills": {
10
+ "xray-skills": {
11
11
  "command": "npx",
12
12
  "args": ["-y", "0xray", "mcp", "skills"]
13
13
  },
14
- "0xray-orchestrator": {
14
+ "xray-orchestrator": {
15
15
  "command": "npx",
16
16
  "args": ["-y", "0xray", "mcp", "orchestrator"]
17
17
  },
18
- "0xray-enforcer": {
18
+ "xray-enforcer": {
19
19
  "command": "npx",
20
20
  "args": ["-y", "0xray", "mcp", "enforcer"]
21
+ },
22
+ "xray-researcher": {
23
+ "command": "npx",
24
+ "args": ["-y", "0xray", "mcp", "researcher"]
25
+ },
26
+ "xray-code-review": {
27
+ "command": "npx",
28
+ "args": ["-y", "0xray", "mcp", "code-review"]
29
+ },
30
+ "xray-architect-tools": {
31
+ "command": "npx",
32
+ "args": ["-y", "0xray", "mcp", "architect-tools"]
21
33
  }
22
34
  }
23
35
  }
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node",
10
10
  "args": [
11
- "${STRRAY_AI_PATH:-node_modules/0xray}/dist/integrations/grok/hooks/pre-tool-use.js"
11
+ "${XRAY_AI_PATH:-node_modules/0xray}/dist/integrations/grok/hooks/pre-tool-use.js"
12
12
  ],
13
13
  "timeout": 30000
14
14
  }
@@ -21,7 +21,7 @@
21
21
  {
22
22
  "type": "command",
23
23
  "command": "echo",
24
- "args": ["[0xRay] Grok session started with StringRay governance enabled"]
24
+ "args": ["[0xRay] Grok session started with 0xRay governance enabled"]
25
25
  }
26
26
  ]
27
27
  }
@@ -41,7 +41,7 @@ class XrayArchitectToolsServer {
41
41
  constructor() {
42
42
  this.server = new Server(
43
43
  {
44
- name: "architect-tools", version: "1.22.67",
44
+ name: "architect-tools", version: "3.1.0",
45
45
  },
46
46
  {
47
47
  capabilities: {
@@ -335,7 +335,7 @@ class XrayArchitectToolsServer {
335
335
  }
336
336
  }
337
337
 
338
- if (import.meta.url === `file://${process.argv[1]}`) {
338
+ if (import.meta.url === `file://${fs.realpathSync(process.argv[1]!)}`) {
339
339
  const server = new XrayArchitectToolsServer();
340
340
  server.run().catch((error) => frameworkLogger.log("mcps/architect-tools", "run", "error", { error: String(error) }));
341
341
  }
@@ -40,7 +40,7 @@ class XrayAutoFormatServer {
40
40
  constructor() {
41
41
  this.server = new Server(
42
42
  {
43
- name: "auto-format", version: "1.22.67",
43
+ name: "auto-format", version: "3.1.0",
44
44
  },
45
45
  {
46
46
  capabilities: {
@@ -521,7 +521,7 @@ ${checkResults.details.map((d) => `• ${d}`).join("\n")}
521
521
  }
522
522
 
523
523
  // Start the server if run directly
524
- if (import.meta.url === `file://${process.argv[1]}`) {
524
+ if (import.meta.url === `file://${fs.realpathSync(process.argv[1]!)}`) {
525
525
  const server = new XrayAutoFormatServer();
526
526
  server.run().catch((error) => frameworkLogger.log("mcps/auto-format", "run", "error", { error: String(error) }));
527
527
  }
@@ -120,7 +120,7 @@ class XrayBootOrchestratorServer {
120
120
  constructor() {
121
121
  this.server = new Server(
122
122
  {
123
- name: "boot-orchestrator", version: "1.22.67",
123
+ name: "boot-orchestrator", version: "3.1.0",
124
124
  },
125
125
  {
126
126
  capabilities: {
@@ -1074,7 +1074,7 @@ ${results.warnings.length > 0 ? `**Warnings:**\n${results.warnings.map((w: strin
1074
1074
  }
1075
1075
 
1076
1076
  // Start the server if run directly
1077
- if (import.meta.url === `file://${process.argv[1]}`) {
1077
+ if (import.meta.url === `file://${fs.realpathSync(process.argv[1]!)}`) {
1078
1078
  const server = new XrayBootOrchestratorServer();
1079
1079
  server.run().catch((error) => frameworkLogger.log("mcps/boot-orchestrator", "run", "error", { error: String(error) }));
1080
1080
  }
@@ -17,25 +17,19 @@ describe('ConfigLoader', () => {
17
17
 
18
18
  beforeEach(() => {
19
19
  loader = new ConfigLoader();
20
+ // Remove default paths so tests don't pick up the real .mcp.json
21
+ loader.resetConfigPaths();
20
22
  // Clean up any existing test files
21
- if (fs.existsSync(testConfigPath)) {
22
- fs.unlinkSync(testConfigPath);
23
- }
24
- if (fs.existsSync(testConfigPath2)) {
25
- fs.unlinkSync(testConfigPath2);
26
- }
27
- if (fs.existsSync(testDir)) {
28
- fs.rmdirSync(testDir);
23
+ for (const p of [testConfigPath, testConfigPath2]) {
24
+ if (fs.existsSync(p)) fs.unlinkSync(p);
29
25
  }
26
+ if (fs.existsSync(testDir)) fs.rmdirSync(testDir);
30
27
  });
31
28
 
32
29
  afterEach(() => {
33
30
  // Clean up test files
34
- if (fs.existsSync(testConfigPath)) {
35
- fs.unlinkSync(testConfigPath);
36
- }
37
- if (fs.existsSync(testConfigPath2)) {
38
- fs.unlinkSync(testConfigPath2);
31
+ for (const p of [testConfigPath, testConfigPath2]) {
32
+ if (fs.existsSync(p)) fs.unlinkSync(p);
39
33
  }
40
34
  if (fs.existsSync(testDir)) {
41
35
  fs.rmdirSync(testDir);
@@ -163,20 +157,24 @@ describe('ConfigLoader', () => {
163
157
  });
164
158
 
165
159
  describe('getConfigPaths', () => {
166
- it('should return default paths', () => {
167
- const paths = loader.getConfigPaths();
168
- expect(paths).toContain('.mcp.json');
169
- expect(paths).toContain('.opencode/mcp.json');
170
- expect(paths).toContain('mcp.config.json');
171
- });
172
-
173
160
  it('should return added paths', () => {
161
+ loader.addConfigPath('.mcp.json');
174
162
  loader.addConfigPath('custom/path.json');
175
163
  const paths = loader.getConfigPaths();
164
+ expect(paths).toContain('.mcp.json');
176
165
  expect(paths).toContain('custom/path.json');
177
166
  });
178
167
 
168
+ it('should return default paths via new instance', () => {
169
+ const fresh = new ConfigLoader();
170
+ const paths = fresh.getConfigPaths();
171
+ expect(paths).toContain('.mcp.json');
172
+ expect(paths).toContain('.opencode/mcp.json');
173
+ expect(paths).toContain('mcp.config.json');
174
+ });
175
+
179
176
  it('should return copy of paths array', () => {
177
+ loader.addConfigPath('.mcp.json');
180
178
  const paths = loader.getConfigPaths();
181
179
  paths.push('modified');
182
180
  const paths2 = loader.getConfigPaths();
@@ -186,10 +184,12 @@ describe('ConfigLoader', () => {
186
184
 
187
185
  describe('resetConfigPaths', () => {
188
186
  it('should reset to default paths', () => {
189
- loader.addConfigPath('custom/path.json');
190
- loader.resetConfigPaths();
187
+ // Add a custom path, then reset — must use fresh loader for baseline
188
+ const fresh = new ConfigLoader();
189
+ fresh.addConfigPath('custom/path.json');
190
+ fresh.resetConfigPaths();
191
191
 
192
- const paths = loader.getConfigPaths();
192
+ const paths = fresh.getConfigPaths();
193
193
  expect(paths).not.toContain('custom/path.json');
194
194
  expect(paths).toContain('.mcp.json');
195
195
  });
@@ -269,15 +269,6 @@ describe('ConfigLoader', () => {
269
269
  expect(loader.hasConfigFile()).toBe(false);
270
270
  });
271
271
 
272
- it('should return true when default config file exists', () => {
273
- const testConfigs = [{ serverName: 'test', command: 'node', args: ['test.js'], timeout: 30000 }];
274
- fs.writeFileSync('.mcp.json', JSON.stringify(testConfigs));
275
-
276
- expect(loader.hasConfigFile()).toBe(true);
277
-
278
- fs.unlinkSync('.mcp.json');
279
- });
280
-
281
272
  it('should return true when added config file exists', () => {
282
273
  const testConfigs = [{ serverName: 'test', command: 'node', args: ['test.js'], timeout: 30000 }];
283
274
  fs.writeFileSync(testConfigPath, JSON.stringify(testConfigs));
@@ -285,6 +276,11 @@ describe('ConfigLoader', () => {
285
276
 
286
277
  expect(loader.hasConfigFile()).toBe(true);
287
278
  });
279
+
280
+ it('should return false when only real .mcp.json exists but not in paths', () => {
281
+ // After resetConfigPaths, the real .mcp.json is not in the path list
282
+ expect(loader.hasConfigFile()).toBe(false);
283
+ });
288
284
  });
289
285
 
290
286
  describe('default singleton', () => {
@@ -294,7 +290,7 @@ describe('ConfigLoader', () => {
294
290
 
295
291
  it('defaultConfigLoader should have default paths', () => {
296
292
  const paths = defaultConfigLoader.getConfigPaths();
297
- expect(paths).toContain('.mcp.json');
293
+ expect(paths.length).toBeGreaterThan(0);
298
294
  });
299
295
  });
300
296
 
@@ -41,12 +41,31 @@ export class ConfigLoader {
41
41
  const content = fs.readFileSync(configPath, 'utf-8');
42
42
  const parsed = JSON.parse(content);
43
43
 
44
- // Handle both array format and object with servers property
45
- const configs: IServerConfig[] = Array.isArray(parsed)
46
- ? parsed
47
- : parsed.servers || [];
48
-
49
- return { success: true, configs };
44
+ // Handle array format
45
+ if (Array.isArray(parsed)) {
46
+ return { success: true, configs: parsed };
47
+ }
48
+
49
+ // Handle standard MCP format (mcpServers object — Claude/OpenCode .mcp.json)
50
+ if (parsed.mcpServers && typeof parsed.mcpServers === 'object') {
51
+ const configs: IServerConfig[] = Object.entries(parsed.mcpServers).map(
52
+ ([serverName, config]: [string, any]) => ({
53
+ serverName,
54
+ command: config.command || '',
55
+ args: config.args || [],
56
+ timeout: config.timeout ?? 30000,
57
+ env: config.env,
58
+ }),
59
+ );
60
+ return { success: true, configs };
61
+ }
62
+
63
+ // Handle object with servers property
64
+ if (parsed.servers) {
65
+ return { success: true, configs: parsed.servers };
66
+ }
67
+
68
+ return { success: true, configs: [] };
50
69
  } catch (error) {
51
70
  return {
52
71
  success: false,
@@ -100,11 +119,31 @@ export class ConfigLoader {
100
119
  const content = fs.readFileSync(filePath, 'utf-8');
101
120
  const parsed = JSON.parse(content);
102
121
 
103
- const configs: IServerConfig[] = Array.isArray(parsed)
104
- ? parsed
105
- : parsed.servers || [];
106
-
107
- return { success: true, configs };
122
+ // Handle array format
123
+ if (Array.isArray(parsed)) {
124
+ return { success: true, configs: parsed };
125
+ }
126
+
127
+ // Handle standard MCP format (mcpServers object)
128
+ if (parsed.mcpServers && typeof parsed.mcpServers === 'object') {
129
+ const configs: IServerConfig[] = Object.entries(parsed.mcpServers).map(
130
+ ([serverName, config]: [string, any]) => ({
131
+ serverName,
132
+ command: config.command || '',
133
+ args: config.args || [],
134
+ timeout: config.timeout ?? 30000,
135
+ env: config.env,
136
+ }),
137
+ );
138
+ return { success: true, configs };
139
+ }
140
+
141
+ // Handle object with servers property
142
+ if (parsed.servers) {
143
+ return { success: true, configs: parsed.servers };
144
+ }
145
+
146
+ return { success: true, configs: [] };
108
147
  } catch (error) {
109
148
  return {
110
149
  success: false,
@@ -144,7 +144,7 @@ class XrayEnforcerToolsServer {
144
144
  constructor() {
145
145
  this.server = new Server(
146
146
  {
147
- name: "enforcer", version: "1.22.67",
147
+ name: "enforcer", version: "3.1.0",
148
148
  },
149
149
  {
150
150
  capabilities: {
@@ -1098,7 +1098,7 @@ class XrayEnforcerToolsServer {
1098
1098
  }
1099
1099
  }
1100
1100
 
1101
- if (import.meta.url === `file://${process.argv[1]}`) {
1101
+ if (import.meta.url === `file://${fs.realpathSync(process.argv[1]!)}`) {
1102
1102
  const server = new XrayEnforcerToolsServer();
1103
1103
  server.run().catch((error) => frameworkLogger.log("mcps/enforcer", "run", "error", { error: String(error) }));
1104
1104
  }
@@ -10,6 +10,7 @@ import {
10
10
  CallToolRequestSchema,
11
11
  ListToolsRequestSchema,
12
12
  } from "@modelcontextprotocol/sdk/types.js";
13
+ import * as fs from "fs";
13
14
  import { frameworkLogger } from "../core/framework-logger.js";
14
15
  import { getEstimationValidator } from "../validation/estimation-validator.js";
15
16
 
@@ -24,7 +25,7 @@ class EstimationServer {
24
25
  constructor() {
25
26
  this.server = new Server(
26
27
  {
27
- name: "estimation-validator", version: "1.22.67",
28
+ name: "estimation-validator", version: "3.1.0",
28
29
  },
29
30
  {
30
31
  capabilities: { tools: {} },
@@ -221,7 +222,7 @@ class EstimationServer {
221
222
  }
222
223
 
223
224
  // Run if called directly
224
- if (import.meta.url === `file://${process.argv[1]}`) {
225
+ if (import.meta.url === `file://${fs.realpathSync(process.argv[1]!)}`) {
225
226
  const server = new EstimationServer();
226
227
  server.start().catch((error) => frameworkLogger.log("mcps/estimation", "run", "error", { error: String(error) }));
227
228
  }