0xray 3.0.14 → 3.1.0

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 (95) hide show
  1. package/.opencode/hooks/post-commit +1 -1
  2. package/.opencode/init.sh +4 -4
  3. package/AGENTS.md +2 -2
  4. package/dist/AGENTS.md +2 -2
  5. package/dist/CHANGELOG.md +9 -0
  6. package/dist/benchmark/performance-benchmark.js +4 -2
  7. package/dist/cli/commands/hermes-install.js +4 -4
  8. package/dist/cli/commands/mcp-install.js +1 -1
  9. package/dist/cli/commands/openclaw-install.js +1 -1
  10. package/dist/cli/commands/plugin-commands.js +2 -2
  11. package/dist/cli/commands/publish-agent.js +5 -5
  12. package/dist/cli/commands/skill-install.js +1 -1
  13. package/dist/cli/commands/status.js +3 -3
  14. package/dist/cli/commands/storyteller.js +1 -1
  15. package/dist/cli/index.js +6 -6
  16. package/dist/cli/server.js +4 -4
  17. package/dist/core/boot-orchestrator.js +24 -24
  18. package/dist/core/bridge.mjs +22 -22
  19. package/dist/core/codex-formatter.js +2 -2
  20. package/dist/core/codex-injector.js +5 -5
  21. package/dist/core/config-loader.js +4 -2
  22. package/dist/core/config-paths.js +14 -14
  23. package/dist/core/context-loader.js +8 -5
  24. package/dist/core/index.js +1 -1
  25. package/dist/core/orchestrator.js +1 -1
  26. package/dist/core/system-prompt-generator.js +2 -2
  27. package/dist/core/xray-activation.js +42 -40
  28. package/dist/delegation/agent-delegator.js +2 -2
  29. package/dist/enforcement/enforcer-tools.js +2 -2
  30. package/dist/enforcement/loaders/codex-loader.js +2 -2
  31. package/dist/governance/llm-governance-provider.js +210 -0
  32. package/dist/index.js +8 -6
  33. package/dist/inference/deploy-verifier.js +1 -1
  34. package/dist/inference/inference-cycle.js +7 -7
  35. package/dist/integrations/hermes-agent/__init__.py +72 -72
  36. package/dist/integrations/hermes-agent/after-install.md +14 -14
  37. package/dist/integrations/hermes-agent/bridge.mjs +24 -24
  38. package/dist/integrations/hermes-agent/plugin.yaml +5 -5
  39. package/dist/integrations/hermes-agent/schemas.py +12 -12
  40. package/dist/integrations/hermes-agent/test_plugin.py +117 -117
  41. package/dist/integrations/hermes-agent/tools.py +25 -25
  42. package/dist/integrations/plugins/plugin-registry.js +2 -2
  43. package/dist/mcps/config/server-config-registry.js +10 -10
  44. package/dist/mcps/connection/mcp-connection.js +1 -1
  45. package/dist/mcps/framework-help.server.js +6 -6
  46. package/dist/mcps/knowledge-skills/code-review.server.js +12 -37
  47. package/dist/mcps/knowledge-skills/security-audit.server.js +12 -42
  48. package/dist/mcps/knowledge-skills/ui-ux-design.server.js +2 -2
  49. package/dist/mcps/lint.server.js +2 -2
  50. package/dist/mcps/mcp-client.js +5 -5
  51. package/dist/mcps/orchestrator/server.js +2 -2
  52. package/dist/mcps/researcher.server.js +12 -37
  53. package/dist/mcps/simulation/server-simulations.js +3 -3
  54. package/dist/orchestrator/enhanced-multi-agent-orchestrator.js +2 -2
  55. package/dist/orchestrator/intelligent-commit-batcher.js +3 -3
  56. package/dist/orchestrator/multi-agent-orchestration-coordinator.js +9 -9
  57. package/dist/orchestrator/orchestrator.js +10 -8
  58. package/dist/orchestrator/universal-registry-bridge.js +3 -3
  59. package/dist/plugin/xray-codex-injection.js +21 -21
  60. package/dist/postprocessor/PostProcessor.js +5 -5
  61. package/dist/postprocessor/services/RegressionAnalysisService.js +2 -2
  62. package/dist/postprocessor/triggers/GitHookTrigger.js +14 -14
  63. package/dist/processors/implementations/agents-md-validation-processor.js +2 -2
  64. package/dist/processors/implementations/inference-improvement-processor.js +1 -1
  65. package/dist/processors/implementations/log-protection-processor.js +2 -2
  66. package/dist/processors/implementations/publish-preflight-processor.js +3 -3
  67. package/dist/processors/implementations/regression-testing-processor.js +2 -2
  68. package/dist/processors/implementations/session-summary-processor.js +1 -1
  69. package/dist/processors/implementations/storytelling-trigger-processor.js +1 -1
  70. package/dist/reporting/report-formatter.js +1 -1
  71. package/dist/scripts/activate-kernel-pipeline.js +2 -2
  72. package/dist/services/inference-tuner.js +2 -2
  73. package/dist/skills/hermes-agent/SKILL.md +42 -42
  74. package/dist/skills/storyteller/SKILL.md +1 -1
  75. package/dist/state/index.js +2 -1
  76. package/dist/state/state-manager.js +3 -3
  77. package/dist/utils/token-manager.js +1 -1
  78. package/dist/validation/estimation-validator.js +1 -1
  79. package/package.json +1 -1
  80. package/scripts/node/pre-publish-guard.js +13 -9
  81. package/scripts/node/universal-version-manager.js +2 -2
  82. package/src/mcps/config/__tests__/server-config-registry.test.ts +12 -12
  83. package/src/mcps/config/server-config-registry.ts +10 -10
  84. package/src/mcps/connection/mcp-connection.ts +1 -1
  85. package/src/mcps/framework-help.server.ts +6 -6
  86. package/src/mcps/knowledge-skills/code-review.server.ts +19 -34
  87. package/src/mcps/knowledge-skills/security-audit.server.ts +19 -38
  88. package/src/mcps/knowledge-skills/ui-ux-design.server.ts +2 -2
  89. package/src/mcps/lint.server.ts +2 -2
  90. package/src/mcps/mcp-client.ts +5 -5
  91. package/src/mcps/orchestrator/server.ts +2 -2
  92. package/src/mcps/researcher.server.ts +19 -34
  93. package/src/mcps/simulation/server-simulations.ts +3 -3
  94. package/src/skills/hermes-agent/SKILL.md +42 -42
  95. package/src/skills/storyteller/SKILL.md +1 -1
@@ -13,7 +13,7 @@ import { frameworkLogger } from "../core/framework-logger.js";
13
13
  import { resolveCodexPath } from "./config-paths.js";
14
14
  // Dynamic imports for cross-environment compatibility
15
15
  let extractCodexMetadata;
16
- let StringRayContextLoader;
16
+ let XrayContextLoaderClass;
17
17
  let importsInitialized = false;
18
18
  async function initializeImports() {
19
19
  if (importsInitialized)
@@ -22,13 +22,13 @@ async function initializeImports() {
22
22
  const codexParser = await import("../utils/codex-parser.js");
23
23
  const contextLoaderModule = await import("./context-loader.js");
24
24
  extractCodexMetadata = codexParser.extractCodexMetadata;
25
- StringRayContextLoader = contextLoaderModule.StringRayContextLoader;
25
+ XrayContextLoaderClass = contextLoaderModule.XrayContextLoader;
26
26
  }
27
27
  catch {
28
28
  const codexParser = await import("../utils/codex-parser");
29
29
  const contextLoaderModule = await import("./context-loader");
30
30
  extractCodexMetadata = codexParser.extractCodexMetadata;
31
- StringRayContextLoader = contextLoaderModule.StringRayContextLoader;
31
+ XrayContextLoaderClass = contextLoaderModule.XrayContextLoader;
32
32
  }
33
33
  importsInitialized = true;
34
34
  }
@@ -38,7 +38,7 @@ async function initializeImports() {
38
38
  const codexCache = new Map();
39
39
  /**
40
40
  * Codex file locations resolved through the standard priority chain.
41
- * Uses config-paths.ts resolver so STRRAY_CONFIG_DIR and .strray/ work.
41
+ * Uses config-paths.ts resolver so STRRAY_CONFIG_DIR and .xray/ work.
42
42
  */
43
43
  function getCodexFileLocations(projectRoot) {
44
44
  const root = projectRoot || process.cwd();
@@ -193,7 +193,7 @@ export function createXrayCodexInjectorHook() {
193
193
  await frameworkLogger.log("codex-injector", "codex context loaded for validation", "success", { jobId, contextCount: codexContexts.length });
194
194
  // Use the initialized context loader
195
195
  await initializeImports();
196
- const ContextLoaderClass = StringRayContextLoader;
196
+ const ContextLoaderClass = XrayContextLoaderClass;
197
197
  const contextLoader = new ContextLoaderClass();
198
198
  const loadResult = await contextLoader.loadCodexContext(sessionId);
199
199
  if (!loadResult.success || !loadResult.context) {
@@ -10,7 +10,7 @@ import * as fs from "fs";
10
10
  import * as path from "path";
11
11
  import { frameworkLogger } from "./framework-logger.js";
12
12
  import { getConfigDir, resolveConfigPath } from "./config-paths.js";
13
- export class StringRayConfigLoader {
13
+ export class XrayConfigLoader {
14
14
  configPath;
15
15
  cachedConfig = null;
16
16
  cacheExpiry = 30000; // 30 seconds
@@ -145,4 +145,6 @@ export class StringRayConfigLoader {
145
145
  }
146
146
  }
147
147
  // Export singleton instance
148
- export const strRayConfigLoader = new StringRayConfigLoader();
148
+ export const xrayConfigLoader = new XrayConfigLoader();
149
+ export { XrayConfigLoader as StringRayConfigLoader };
150
+ export { xrayConfigLoader as strRayConfigLoader };
@@ -7,15 +7,15 @@
7
7
  *
8
8
  * Resolution order (per file type):
9
9
  * 1. STRRAY_CONFIG_DIR/<relative_path> (if env var set)
10
- * 2. .strray/<relative_path> (preferred lightweight root)
11
- * 3. .opencode/strray/<relative_path> (legacy OpenCode root)
10
+ * 2. .xray/<relative_path> (preferred lightweight root)
11
+ * 3. .opencode/xray/<relative_path> (legacy OpenCode root)
12
12
  * 4. null (callers fall back to built-in defaults)
13
13
  *
14
14
  * For state/data directories, uses:
15
15
  * 1. STRRAY_CONFIG_DIR/state (if env var set)
16
- * 2. .strray/state
16
+ * 2. .xray/state
17
17
  * 3. .opencode/state (legacy)
18
- * 4. .strray/state (default — always writable)
18
+ * 4. .xray/state (default — always writable)
19
19
  */
20
20
  import { existsSync } from "fs";
21
21
  import { join, resolve } from "path";
@@ -40,8 +40,8 @@ export function getConfigDir(projectRoot) {
40
40
  const resolved = resolve(root, envDir);
41
41
  candidates.push({ dir: resolved, source: "env" });
42
42
  }
43
- candidates.push({ dir: join(root, ".strray"), source: "dot-strray" });
44
- candidates.push({ dir: join(root, ".opencode", "strray"), source: "dot-opencode" });
43
+ candidates.push({ dir: join(root, ".xray"), source: "dot-xray" });
44
+ candidates.push({ dir: join(root, ".opencode", "xray"), source: "dot-opencode" });
45
45
  // Return the first that exists, or the highest-priority default
46
46
  for (const c of candidates) {
47
47
  if (existsSync(c.dir)) {
@@ -49,7 +49,7 @@ export function getConfigDir(projectRoot) {
49
49
  return c.dir;
50
50
  }
51
51
  }
52
- // Nothing exists — use highest priority default (env > .strray > .opencode)
52
+ // Nothing exists — use highest priority default (env > .xray > .opencode)
53
53
  const defaultDir = candidates[0];
54
54
  _resolvedConfigDirs.set(root, defaultDir.dir);
55
55
  return defaultDir.dir;
@@ -68,8 +68,8 @@ export function resolveConfigPath(relativePath, projectRoot) {
68
68
  if (envDir) {
69
69
  candidates.push(resolve(root, envDir, relativePath));
70
70
  }
71
- candidates.push(join(root, ".strray", relativePath));
72
- candidates.push(join(root, ".opencode", "strray", relativePath));
71
+ candidates.push(join(root, ".xray", relativePath));
72
+ candidates.push(join(root, ".opencode", "xray", relativePath));
73
73
  for (const candidate of candidates) {
74
74
  if (existsSync(candidate)) {
75
75
  return candidate;
@@ -90,7 +90,7 @@ export function resolveStateDir(projectRoot) {
90
90
  if (envDir) {
91
91
  candidates.push(join(root, envDir, "state"));
92
92
  }
93
- candidates.push(join(root, ".strray", "state"));
93
+ candidates.push(join(root, ".xray", "state"));
94
94
  candidates.push(join(root, ".opencode", "state"));
95
95
  for (const candidate of candidates) {
96
96
  if (existsSync(candidate)) {
@@ -117,8 +117,8 @@ export function resolveProfilesDir(projectRoot) {
117
117
  if (envDir) {
118
118
  candidates.push(join(root, envDir, "profiles"));
119
119
  }
120
- candidates.push(join(root, ".strray", "profiles"));
121
- candidates.push(join(root, ".opencode", "strray", "profiles"));
120
+ candidates.push(join(root, ".xray", "profiles"));
121
+ candidates.push(join(root, ".opencode", "xray", "profiles"));
122
122
  for (const candidate of candidates) {
123
123
  if (existsSync(candidate)) {
124
124
  return candidate;
@@ -137,9 +137,9 @@ export function resolveCodexPath(projectRoot) {
137
137
  if (envDir) {
138
138
  candidates.push(join(root, envDir, "codex.json"));
139
139
  }
140
- candidates.push(join(root, ".strray", "codex.json"));
140
+ candidates.push(join(root, ".xray", "codex.json"));
141
141
  candidates.push(join(root, "xray", "codex.json"));
142
- candidates.push(join(root, ".opencode", "strray", "codex.json"));
142
+ candidates.push(join(root, ".opencode", "xray", "codex.json"));
143
143
  // Additional fallback locations (for standalone usage)
144
144
  candidates.push(join(root, "codex.json"));
145
145
  candidates.push(join(root, "src", "codex.json"));
@@ -22,7 +22,7 @@ function isValidMatch(match, index) {
22
22
  *
23
23
  * Loads and parses the Universal Development Codex v1.2.0 from codex.json
24
24
  */
25
- export class StringRayContextLoader {
25
+ export class XrayContextLoader {
26
26
  static instance;
27
27
  cachedContext = null;
28
28
  codexFilePaths = [];
@@ -33,10 +33,10 @@ export class StringRayContextLoader {
33
33
  * Get singleton instance
34
34
  */
35
35
  static getInstance() {
36
- if (!StringRayContextLoader.instance) {
37
- StringRayContextLoader.instance = new StringRayContextLoader();
36
+ if (!XrayContextLoader.instance) {
37
+ XrayContextLoader.instance = new XrayContextLoader();
38
38
  }
39
- return StringRayContextLoader.instance;
39
+ return XrayContextLoader.instance;
40
40
  }
41
41
  /**
42
42
  * Load codex context
@@ -266,4 +266,7 @@ export class StringRayContextLoader {
266
266
  /**
267
267
  * Export singleton instance
268
268
  */
269
- export const strRayContextLoader = StringRayContextLoader.getInstance();
269
+ export const xrayContextLoader = XrayContextLoader.getInstance();
270
+ // Backward compat aliases
271
+ export { XrayContextLoader as StringRayContextLoader };
272
+ export { xrayContextLoader as strRayContextLoader };
@@ -1,5 +1,5 @@
1
1
  export { KernelOrchestrator } from "./orchestrator.js";
2
- export { defaultStringRayConfig } from "./xray-activation.js"; // consumer runtime compat from prior StringRay releases (1-line min per Scope Rule)
2
+ export { defaultXrayConfig, defaultXrayConfig as defaultStringRayConfig } from "./xray-activation.js"; // consumer runtime compat
3
3
  // Decoupled config path resolution (Layer 1)
4
4
  export { getConfigDir, resolveConfigPath, resolveStateDir, resolveProfilesDir, resolveCodexPath, resolveLogDir, resetConfigDirCache, STRRAY_CONFIG_DIR_ENV, } from "./config-paths.js";
5
5
  // Standalone codex formatter (Layer 2)
@@ -267,7 +267,7 @@ export class KernelOrchestrator {
267
267
  `B) Use a single orchestrator for all dependent tasks\n` +
268
268
  `C) Remove the dependency if it's not needed\n\n` +
269
269
  `Example of correct usage:\n` +
270
- ` const orch = new StringRayOrchestrator();\n` +
270
+ ` const orch = new XrayOrchestrator();\n` +
271
271
  ` await orch.executeComplexTask("test", [\n` +
272
272
  ` { id: "task-1" },\n` +
273
273
  ` { id: "task-2", dependencies: ["task-1"] } // ✅ Same orchestrator\n` +
@@ -7,7 +7,7 @@
7
7
  * @version 1.0.0
8
8
  * @since 2026-03-03
9
9
  */
10
- import { StringRayContextLoader } from "./context-loader.js";
10
+ import { XrayContextLoader } from "./context-loader.js";
11
11
  import { validateContext, preventSystemPromptBloat } from "./context-validator.js";
12
12
  import fs from "fs";
13
13
  import path from "path";
@@ -140,7 +140,7 @@ export async function generateLeanSystemPrompt(config = {}) {
140
140
  let finalPrompt = systemPrompt;
141
141
  if (showCodexContext && enableTokenOptimization) {
142
142
  try {
143
- const contextLoader = StringRayContextLoader.getInstance();
143
+ const contextLoader = XrayContextLoader.getInstance();
144
144
  const loadResult = await contextLoader.loadCodexContext(process.cwd());
145
145
  if (loadResult.success && loadResult.context) {
146
146
  const codexSummary = generateCodexSummary(loadResult.context, maxTokenBudget);
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Consumer runtime compat shim from prior StringRay releases (1-line min per Scope Rule; primary xray paths + XRAY_||STRRAY_ env + .strray fallbacks).
2
+ * Consumer runtime compat shim from prior 0xRay releases (1-line min per Scope Rule; primary xray paths + XRAY_||STRRAY_ env + .xray fallbacks).
3
3
  */
4
4
  import { frameworkLogger } from "../core/framework-logger.js";
5
5
  import { ensureCriticalComponents } from "../architect/architectural-integrity.js";
6
6
  import { validateRegistryConsistency } from "../agents/registry.js";
7
- export const defaultStringRayConfig = {
7
+ export const defaultXrayConfig = {
8
8
  enableOrchestrator: true,
9
9
  enableBootOrchestrator: true,
10
10
  enableStateManagement: true,
@@ -13,15 +13,15 @@ export const defaultStringRayConfig = {
13
13
  enableProcessors: true,
14
14
  enablePostProcessor: true,
15
15
  };
16
- export async function activateStringRayFramework(config = {}) {
16
+ export async function activateXrayFramework(config = {}) {
17
17
  const jobId = `activation-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
18
- const activationConfig = { ...defaultStringRayConfig, ...config };
18
+ const activationConfig = { ...defaultXrayConfig, ...config };
19
19
  // Banner display moved to init.sh execution in plugin
20
20
  // Framework activation proceeds quietly
21
- frameworkLogger.log("stringray-activation", "beginning xray framework activation", "info", { jobId, ...activationConfig });
21
+ frameworkLogger.log("xray-activation", "beginning xray framework activation", "info", { jobId, ...activationConfig });
22
22
  const registryValidation = validateRegistryConsistency();
23
23
  if (!registryValidation.valid) {
24
- frameworkLogger.log("stringray-activation", "registry-validation-failed", "warning", { errors: registryValidation.errors });
24
+ frameworkLogger.log("xray-activation", "registry-validation-failed", "warning", { errors: registryValidation.errors });
25
25
  }
26
26
  try {
27
27
  if (activationConfig.enableCodexInjection) {
@@ -48,87 +48,89 @@ export async function activateStringRayFramework(config = {}) {
48
48
  // Ensure architectural integrity - critical components must always be active
49
49
  await ensureCriticalComponents();
50
50
  // Loading display moved to init.sh for dramatic line-by-line presentation
51
- frameworkLogger.log("stringray-activation", "xray framework activation completed successfully", "success", { jobId });
51
+ frameworkLogger.log("xray-activation", "xray framework activation completed successfully", "success", { jobId });
52
52
  }
53
53
  catch (error) {
54
- await frameworkLogger.log("stringray-activation", "framework-activation-failed", "error", { jobId, error: String(error) });
54
+ await frameworkLogger.log("xray-activation", "framework-activation-failed", "error", { jobId, error: String(error) });
55
55
  throw error;
56
56
  }
57
57
  }
58
58
  async function activateCodexInjection(jobId) {
59
- frameworkLogger.log("stringray-activation", "activating codex injection", "info", { jobId });
59
+ frameworkLogger.log("xray-activation", "activating codex injection", "info", { jobId });
60
60
  const { createXrayCodexInjectorHook } = await import("./codex-injector.js");
61
61
  const hook = createXrayCodexInjectorHook();
62
- globalThis.strRayHooks = globalThis.strRayHooks || [];
63
- globalThis.strRayHooks.push(hook);
64
- frameworkLogger.log("stringray-activation", "codex injection activated", "success", { jobId, hookName: hook.name });
62
+ globalThis.xrayHooks = globalThis.xrayHooks || [];
63
+ globalThis.xrayHooks.push(hook);
64
+ frameworkLogger.log("xray-activation", "codex injection activated", "success", { jobId, hookName: hook.name });
65
65
  }
66
66
  async function activateHooks(jobId) {
67
67
  try {
68
- frameworkLogger.log("stringray-activation", "activating xray hooks", "info", { jobId });
68
+ frameworkLogger.log("xray-activation", "activating xray hooks", "info", { jobId });
69
69
  // Create and register the Codex injector hook
70
70
  const { createXrayCodexInjectorHook } = await import("./codex-injector");
71
71
  const hook = createXrayCodexInjectorHook();
72
72
  // Store hook globally for OpenCode to pick up
73
- globalThis.strRayHooks = globalThis.strRayHooks || [];
74
- globalThis.strRayHooks.push(hook);
75
- frameworkLogger.log("stringray-activation", "xray hooks activated", "success", {
73
+ globalThis.xrayHooks = globalThis.xrayHooks || [];
74
+ globalThis.xrayHooks.push(hook);
75
+ frameworkLogger.log("xray-activation", "xray hooks activated", "success", {
76
76
  jobId,
77
77
  hookName: hook.name,
78
- hooksRegistered: globalThis.strRayHooks.length
78
+ hooksRegistered: globalThis.xrayHooks.length
79
79
  });
80
80
  }
81
81
  catch (error) {
82
- await frameworkLogger.log("stringray-activation", "hooks activation failed", "error", { jobId, error: String(error) });
82
+ await frameworkLogger.log("xray-activation", "hooks activation failed", "error", { jobId, error: String(error) });
83
83
  }
84
84
  }
85
85
  async function activateBootOrchestrator(jobId) {
86
- frameworkLogger.log("stringray-activation", "activating boot orchestrator", "info", { jobId });
86
+ frameworkLogger.log("xray-activation", "activating boot orchestrator", "info", { jobId });
87
87
  const { bootOrchestrator } = await import("./boot-orchestrator");
88
88
  await bootOrchestrator.executeBootSequence();
89
- frameworkLogger.log("stringray-activation", "boot orchestrator activated", "success", { jobId });
89
+ frameworkLogger.log("xray-activation", "boot orchestrator activated", "success", { jobId });
90
90
  }
91
91
  async function activateStateManagement(jobId) {
92
- frameworkLogger.log("stringray-activation", "activating state management", "info", { jobId });
93
- const { StringRayStateManager } = await import("../state/state-manager");
94
- const stateManager = new StringRayStateManager();
92
+ frameworkLogger.log("xray-activation", "activating state management", "info", { jobId });
93
+ const { XrayStateManager } = await import("../state/state-manager");
94
+ const stateManager = new XrayStateManager();
95
95
  // Store the state manager instance globally for framework use
96
- globalThis.strRayStateManager = stateManager;
97
- frameworkLogger.log("stringray-activation", "state management activated", "success", { jobId });
96
+ globalThis.xrayStateManager = stateManager;
97
+ frameworkLogger.log("xray-activation", "state management activated", "success", { jobId });
98
98
  }
99
99
  async function activateOrchestrator(jobId) {
100
- frameworkLogger.log("stringray-activation", "activating xray orchestrator", "info", { jobId });
100
+ frameworkLogger.log("xray-activation", "activating xray orchestrator", "info", { jobId });
101
101
  const { strRayOrchestrator } = await import("./orchestrator");
102
102
  // Also activate the multi-agent orchestration coordinator
103
103
  const { multiAgentOrchestrationCoordinator } = await import("../orchestrator/multi-agent-orchestration-coordinator");
104
- frameworkLogger.log("stringray-activation", "xray orchestrator and multi-agent coordination activated", "success", { jobId });
104
+ frameworkLogger.log("xray-activation", "xray orchestrator and multi-agent coordination activated", "success", { jobId });
105
105
  }
106
106
  async function activateProcessors(jobId) {
107
- frameworkLogger.log("stringray-activation", "activating processor pipeline", "info", { jobId });
107
+ frameworkLogger.log("xray-activation", "activating processor pipeline", "info", { jobId });
108
108
  const { ProcessorManager } = await import("../processors/processor-manager");
109
- const { StringRayStateManager } = await import("../state/state-manager");
110
- const stateManager = new StringRayStateManager();
109
+ const { XrayStateManager } = await import("../state/state-manager");
110
+ const stateManager = new XrayStateManager();
111
111
  const processorManager = new ProcessorManager(stateManager);
112
112
  // Store the processor manager instance globally for framework use
113
- globalThis.strRayProcessorManager = processorManager;
114
- frameworkLogger.log("stringray-activation", "processor pipeline activated", "success", { jobId });
113
+ globalThis.xrayProcessorManager = processorManager;
114
+ frameworkLogger.log("xray-activation", "processor pipeline activated", "success", { jobId });
115
115
  }
116
116
  async function activatePostProcessor(jobId) {
117
- frameworkLogger.log("stringray-activation", "activating post-processor system", "info", { jobId });
117
+ frameworkLogger.log("xray-activation", "activating post-processor system", "info", { jobId });
118
118
  const { PostProcessor } = await import("../postprocessor/PostProcessor");
119
119
  // Get existing state manager (should be initialized by boot orchestrator)
120
- const stateManager = globalThis.strRayStateManager;
120
+ const stateManager = globalThis.xrayStateManager;
121
121
  if (!stateManager) {
122
122
  throw new Error("State manager not initialized - boot orchestrator must run first");
123
123
  }
124
124
  const postProcessor = new PostProcessor(stateManager, null, {});
125
- globalThis.strRayPostProcessor = postProcessor;
126
- frameworkLogger.log("stringray-activation", "post-processor system activated", "success", { jobId });
125
+ globalThis.xrayPostProcessor = postProcessor;
126
+ frameworkLogger.log("xray-activation", "post-processor system activated", "success", { jobId });
127
127
  const { pathResolver } = await import("../utils/path-resolver.js");
128
- globalThis.strRayPathResolver = pathResolver;
129
- frameworkLogger.log("stringray-activation", "path resolver activated", "success", { jobId });
128
+ globalThis.xrayPathResolver = pathResolver;
129
+ frameworkLogger.log("xray-activation", "path resolver activated", "success", { jobId });
130
130
  const { CodexInjector } = await import("./codex-injector.js");
131
131
  const codexInjector = new CodexInjector();
132
- globalThis.strRayCodexInjector = codexInjector;
133
- frameworkLogger.log("stringray-activation", "codex injector activated", "success", { jobId });
132
+ globalThis.xrayCodexInjector = codexInjector;
133
+ frameworkLogger.log("xray-activation", "codex injector activated", "success", { jobId });
134
134
  }
135
+ export { defaultXrayConfig as defaultStringRayConfig };
136
+ export { activateXrayFramework as activateStringRayFramework };
@@ -45,9 +45,9 @@ export class AgentDelegator {
45
45
  */
46
46
  loadRoutingMappings() {
47
47
  const candidates = [
48
- path.resolve(process.cwd(), ".strray/routing-mappings.json"),
48
+ path.resolve(process.cwd(), ".xray/routing-mappings.json"),
49
49
  path.resolve(process.cwd(), "xray/routing-mappings.json"),
50
- path.resolve(process.cwd(), ".opencode/strray/routing-mappings.json"),
50
+ path.resolve(process.cwd(), ".opencode/xray/routing-mappings.json"),
51
51
  path.resolve(process.cwd(), "routing-mappings.json"),
52
52
  ];
53
53
  for (const p of candidates) {
@@ -5,7 +5,7 @@
5
5
  import { ruleEnforcer, } from "./rule-enforcer.js";
6
6
  import { frameworkLogger } from "../core/framework-logger.js";
7
7
  import { AgentDelegator } from "../delegation/agent-delegator.js";
8
- import { StringRayStateManager } from "../state/state-manager.js";
8
+ import { XrayStateManager } from "../state/state-manager.js";
9
9
  import { strRayConfigLoader } from "../core/config-loader.js";
10
10
  import * as fs from "fs";
11
11
  import * as path from "path";
@@ -325,7 +325,7 @@ async function executeReleaseWorkflow(operation, context, jobId, routing) {
325
325
  async function delegateToAgent(agentName, operation, context, jobId) {
326
326
  try {
327
327
  // Create a minimal state manager and config loader for the delegator
328
- const stateManager = new StringRayStateManager();
328
+ const stateManager = new XrayStateManager();
329
329
  // Create the delegator
330
330
  const delegator = new AgentDelegator(stateManager, strRayConfigLoader);
331
331
  // Build task description for the delegated agent
@@ -30,13 +30,13 @@ export class CodexLoader extends BaseLoader {
30
30
  name = "codex";
31
31
  /**
32
32
  * Path to the codex.json file.
33
- * Uses the standard config-paths resolver which checks .strray/, .opencode/strray/, etc.
33
+ * Uses the standard config-paths resolver which checks .xray/, .opencode/xray/, etc.
34
34
  */
35
35
  get codexPath() {
36
36
  const candidates = resolveCodexPath();
37
37
  const found = candidates.find((p) => existsSync(p));
38
38
  // Fallback to primary path even if not found yet
39
- return found ?? candidates[0] ?? this.resolvePath(".opencode/strray/codex.json");
39
+ return found ?? candidates[0] ?? this.resolvePath(".opencode/xray/codex.json");
40
40
  }
41
41
  /**
42
42
  * Check if codex.json exists.
@@ -0,0 +1,210 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { frameworkLogger } from "../core/framework-logger.js";
5
+ const XAI_ENDPOINT = "https://api.x.ai/v1/chat/completions";
6
+ const XAI_MODEL = "grok-4.3";
7
+ const ROLE_PROMPTS = {
8
+ "code-review": `You are a senior code reviewer on a governance committee for a software project. Analyze the following proposal from a code quality, maintainability, readability, and engineering best practices perspective.
9
+
10
+ Consider:
11
+ - Does the proposal improve or degrade code quality?
12
+ - Does it follow established design patterns?
13
+ - Does it introduce technical debt?
14
+ - Are there potential regressions or edge cases?
15
+
16
+ Respond with a structured vote in exactly this format:
17
+ DECISION: approve|reject|abstain
18
+ CONFIDENCE: <0.0-1.0>
19
+ REASONING: <2-4 sentence analysis of the proposal's code quality implications>`,
20
+ "security-audit": `You are a senior security engineer on a governance committee for a software project. Analyze the following proposal from a security, threat modeling, and compliance perspective.
21
+
22
+ Consider:
23
+ - Does the proposal introduce new attack surface?
24
+ - Does it handle authentication, authorization, and data protection properly?
25
+ - Are there compliance implications (GDPR, SOC2, PCI-DSS, etc.)?
26
+ - Does it follow security best practices (input validation, least privilege, defense in depth)?
27
+
28
+ Respond with a structured vote in exactly this format:
29
+ DECISION: approve|reject|abstain
30
+ CONFIDENCE: <0.0-1.0>
31
+ REASONING: <2-4 sentence analysis of the proposal's security implications>`,
32
+ "researcher": `You are a senior architect and researcher on a governance committee for a software project. Analyze the following proposal from a codebase-wide architectural and historical perspective.
33
+
34
+ Consider:
35
+ - Does the proposal align with the project's observed architecture patterns?
36
+ - Does it integrate well with existing systems and data flows?
37
+ - Does it address recurring problems observed in the project history?
38
+ - What is the broader impact on the codebase ecosystem?
39
+
40
+ Respond with a structured vote in exactly this format:
41
+ DECISION: approve|reject|abstain
42
+ CONFIDENCE: <0.0-1.0>
43
+ REASONING: <2-4 sentence analysis of the proposal's broader project impact>`,
44
+ };
45
+ function readHermesOAuthToken() {
46
+ try {
47
+ const authPath = join(homedir(), ".hermes", "auth.json");
48
+ if (!existsSync(authPath))
49
+ return null;
50
+ const raw = readFileSync(authPath, "utf-8");
51
+ const data = JSON.parse(raw);
52
+ let entry;
53
+ if (data && typeof data === "object" && !Array.isArray(data)) {
54
+ entry = data["xai-oauth"];
55
+ if (!entry?.access_token && data.access_token) {
56
+ entry = data;
57
+ }
58
+ }
59
+ if (!entry?.access_token && Array.isArray(data)) {
60
+ entry = data.find((e) => e.provider === "xai-oauth" || !!e.access_token);
61
+ }
62
+ if (!entry?.access_token)
63
+ return null;
64
+ if (entry.expires_at && Date.now() / 1000 > entry.expires_at) {
65
+ frameworkLogger.log("llm-governance", "hermes-token-expired", "warning", { expiresAt: entry.expires_at });
66
+ return null;
67
+ }
68
+ return entry.access_token;
69
+ }
70
+ catch (err) {
71
+ frameworkLogger.log("llm-governance", "hermes-auth-read-error", "warning", { error: String(err) });
72
+ return null;
73
+ }
74
+ }
75
+ function getConfig() {
76
+ const directEndpoint = process.env.XRAY_LLM_ENDPOINT ||
77
+ process.env.XRAY_GOVERNANCE_LLM_ENDPOINT ||
78
+ "";
79
+ const directApiKey = process.env.XRAY_LLM_API_KEY ||
80
+ process.env.XRAY_GOVERNANCE_LLM_API_KEY ||
81
+ "";
82
+ const directModel = process.env.XRAY_LLM_MODEL ||
83
+ process.env.XRAY_GOVERNANCE_LLM_MODEL ||
84
+ "gpt-4o";
85
+ const directEnabled = process.env.XRAY_GOVERNANCE_LLM_ENABLED === "true" ||
86
+ process.env.XRAY_LLM_ENABLED === "true";
87
+ if (directEnabled && directEndpoint && directApiKey) {
88
+ return { endpoint: directEndpoint, apiKey: directApiKey, model: directModel };
89
+ }
90
+ const hermesToken = readHermesOAuthToken();
91
+ if (hermesToken) {
92
+ frameworkLogger.log("llm-governance", "using-hermes-oauth", "info", { provider: "xai-oauth", endpoint: XAI_ENDPOINT, model: XAI_MODEL });
93
+ return { endpoint: XAI_ENDPOINT, apiKey: hermesToken, model: XAI_MODEL };
94
+ }
95
+ return null;
96
+ }
97
+ function parseVote(text) {
98
+ const decisionMatch = text.match(/DECISION:\s*(approve|reject|abstain)/i);
99
+ const confidenceMatch = text.match(/CONFIDENCE:\s*([0-9.]+)/i);
100
+ const reasoningMatch = text.match(/REASONING:\s*(.+)/is);
101
+ if (!decisionMatch || !decisionMatch[1])
102
+ return null;
103
+ const rawConfidence = confidenceMatch?.[1];
104
+ const confidence = rawConfidence ? parseFloat(rawConfidence) : 0.5;
105
+ return {
106
+ decision: decisionMatch[1].toLowerCase(),
107
+ confidence: isNaN(confidence) ? 0.5 : Math.min(1, Math.max(0, confidence)),
108
+ reasoning: reasoningMatch?.[1]?.trim() || "No reasoning provided",
109
+ };
110
+ }
111
+ export async function tryLLMGovernance(role, proposalTitle, proposalDescription, evidence, proposalType) {
112
+ const config = getConfig();
113
+ if (!config) {
114
+ return null;
115
+ }
116
+ const systemPrompt = ROLE_PROMPTS[role];
117
+ const userMessage = `## Proposal
118
+
119
+ **Title:** ${proposalTitle}
120
+
121
+ **Description:** ${proposalDescription}
122
+
123
+ **Type:** ${proposalType}
124
+
125
+ ${evidence.length > 0 ? `**Supporting Evidence:**\n${evidence.map((e, i) => `${i + 1}. ${e}`).join("\n")}` : ""}
126
+
127
+ ---
128
+
129
+ Please provide your structured vote.`;
130
+ try {
131
+ const response = await fetch(config.endpoint, {
132
+ method: "POST",
133
+ headers: {
134
+ "Content-Type": "application/json",
135
+ Authorization: `Bearer ${config.apiKey}`,
136
+ },
137
+ body: JSON.stringify({
138
+ model: config.model,
139
+ messages: [
140
+ { role: "system", content: systemPrompt },
141
+ { role: "user", content: userMessage },
142
+ ],
143
+ temperature: 0.3,
144
+ max_tokens: 500,
145
+ }),
146
+ });
147
+ if (!response.ok) {
148
+ frameworkLogger.log("llm-governance", "api-call", "error", {
149
+ status: response.status,
150
+ statusText: response.statusText,
151
+ role,
152
+ });
153
+ return null;
154
+ }
155
+ const data = (await response.json());
156
+ const choices = data?.choices;
157
+ const message = choices?.[0]?.message;
158
+ const content = message?.content;
159
+ if (!content) {
160
+ frameworkLogger.log("llm-governance", "parse", "warning", {
161
+ issue: "missing content in response",
162
+ role,
163
+ });
164
+ return null;
165
+ }
166
+ const vote = parseVote(content);
167
+ if (!vote) {
168
+ frameworkLogger.log("llm-governance", "parse", "warning", {
169
+ issue: "unparseable response",
170
+ snippet: content.slice(0, 200),
171
+ role,
172
+ });
173
+ return null;
174
+ }
175
+ frameworkLogger.log("llm-governance", "vote", "success", {
176
+ role,
177
+ decision: vote.decision,
178
+ confidence: vote.confidence,
179
+ });
180
+ return vote;
181
+ }
182
+ catch (error) {
183
+ frameworkLogger.log("llm-governance", "error", "error", {
184
+ error: String(error),
185
+ role,
186
+ });
187
+ return null;
188
+ }
189
+ }
190
+ export function checkHermesOAuthStatus() {
191
+ const config = getConfig();
192
+ if (!config) {
193
+ const hermesPath = join(homedir(), ".hermes", "auth.json");
194
+ if (existsSync(hermesPath)) {
195
+ return {
196
+ configured: false,
197
+ error: "Hermes auth file found but no valid xai-oauth token. Run: hermes auth add xai-oauth --no-browser",
198
+ };
199
+ }
200
+ return {
201
+ configured: false,
202
+ error: "No Hermes auth file found (~/.hermes/auth.json). Install Hermes and run: hermes auth add xai-oauth --no-browser",
203
+ };
204
+ }
205
+ return {
206
+ configured: true,
207
+ endpoint: XAI_ENDPOINT,
208
+ model: XAI_MODEL,
209
+ };
210
+ }