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.
- package/.opencode/hooks/post-commit +1 -1
- package/.opencode/init.sh +4 -4
- package/AGENTS.md +2 -2
- package/dist/AGENTS.md +2 -2
- package/dist/CHANGELOG.md +9 -0
- package/dist/benchmark/performance-benchmark.js +4 -2
- package/dist/cli/commands/hermes-install.js +4 -4
- package/dist/cli/commands/mcp-install.js +1 -1
- package/dist/cli/commands/openclaw-install.js +1 -1
- package/dist/cli/commands/plugin-commands.js +2 -2
- package/dist/cli/commands/publish-agent.js +5 -5
- package/dist/cli/commands/skill-install.js +1 -1
- package/dist/cli/commands/status.js +3 -3
- package/dist/cli/commands/storyteller.js +1 -1
- package/dist/cli/index.js +6 -6
- package/dist/cli/server.js +4 -4
- package/dist/core/boot-orchestrator.js +24 -24
- package/dist/core/bridge.mjs +22 -22
- package/dist/core/codex-formatter.js +2 -2
- package/dist/core/codex-injector.js +5 -5
- package/dist/core/config-loader.js +4 -2
- package/dist/core/config-paths.js +14 -14
- package/dist/core/context-loader.js +8 -5
- package/dist/core/index.js +1 -1
- package/dist/core/orchestrator.js +1 -1
- package/dist/core/system-prompt-generator.js +2 -2
- package/dist/core/xray-activation.js +42 -40
- package/dist/delegation/agent-delegator.js +2 -2
- package/dist/enforcement/enforcer-tools.js +2 -2
- package/dist/enforcement/loaders/codex-loader.js +2 -2
- package/dist/governance/llm-governance-provider.js +210 -0
- package/dist/index.js +8 -6
- package/dist/inference/deploy-verifier.js +1 -1
- package/dist/inference/inference-cycle.js +7 -7
- package/dist/integrations/hermes-agent/__init__.py +72 -72
- package/dist/integrations/hermes-agent/after-install.md +14 -14
- package/dist/integrations/hermes-agent/bridge.mjs +24 -24
- package/dist/integrations/hermes-agent/plugin.yaml +5 -5
- package/dist/integrations/hermes-agent/schemas.py +12 -12
- package/dist/integrations/hermes-agent/test_plugin.py +117 -117
- package/dist/integrations/hermes-agent/tools.py +25 -25
- package/dist/integrations/plugins/plugin-registry.js +2 -2
- package/dist/mcps/config/server-config-registry.js +10 -10
- package/dist/mcps/connection/mcp-connection.js +1 -1
- package/dist/mcps/framework-help.server.js +6 -6
- package/dist/mcps/knowledge-skills/code-review.server.js +12 -37
- package/dist/mcps/knowledge-skills/security-audit.server.js +12 -42
- package/dist/mcps/knowledge-skills/ui-ux-design.server.js +2 -2
- package/dist/mcps/lint.server.js +2 -2
- package/dist/mcps/mcp-client.js +5 -5
- package/dist/mcps/orchestrator/server.js +2 -2
- package/dist/mcps/researcher.server.js +12 -37
- package/dist/mcps/simulation/server-simulations.js +3 -3
- package/dist/orchestrator/enhanced-multi-agent-orchestrator.js +2 -2
- package/dist/orchestrator/intelligent-commit-batcher.js +3 -3
- package/dist/orchestrator/multi-agent-orchestration-coordinator.js +9 -9
- package/dist/orchestrator/orchestrator.js +10 -8
- package/dist/orchestrator/universal-registry-bridge.js +3 -3
- package/dist/plugin/xray-codex-injection.js +21 -21
- package/dist/postprocessor/PostProcessor.js +5 -5
- package/dist/postprocessor/services/RegressionAnalysisService.js +2 -2
- package/dist/postprocessor/triggers/GitHookTrigger.js +14 -14
- package/dist/processors/implementations/agents-md-validation-processor.js +2 -2
- package/dist/processors/implementations/inference-improvement-processor.js +1 -1
- package/dist/processors/implementations/log-protection-processor.js +2 -2
- package/dist/processors/implementations/publish-preflight-processor.js +3 -3
- package/dist/processors/implementations/regression-testing-processor.js +2 -2
- package/dist/processors/implementations/session-summary-processor.js +1 -1
- package/dist/processors/implementations/storytelling-trigger-processor.js +1 -1
- package/dist/reporting/report-formatter.js +1 -1
- package/dist/scripts/activate-kernel-pipeline.js +2 -2
- package/dist/services/inference-tuner.js +2 -2
- package/dist/skills/hermes-agent/SKILL.md +42 -42
- package/dist/skills/storyteller/SKILL.md +1 -1
- package/dist/state/index.js +2 -1
- package/dist/state/state-manager.js +3 -3
- package/dist/utils/token-manager.js +1 -1
- package/dist/validation/estimation-validator.js +1 -1
- package/package.json +1 -1
- package/scripts/node/pre-publish-guard.js +13 -9
- package/scripts/node/universal-version-manager.js +2 -2
- package/src/mcps/config/__tests__/server-config-registry.test.ts +12 -12
- package/src/mcps/config/server-config-registry.ts +10 -10
- package/src/mcps/connection/mcp-connection.ts +1 -1
- package/src/mcps/framework-help.server.ts +6 -6
- package/src/mcps/knowledge-skills/code-review.server.ts +19 -34
- package/src/mcps/knowledge-skills/security-audit.server.ts +19 -38
- package/src/mcps/knowledge-skills/ui-ux-design.server.ts +2 -2
- package/src/mcps/lint.server.ts +2 -2
- package/src/mcps/mcp-client.ts +5 -5
- package/src/mcps/orchestrator/server.ts +2 -2
- package/src/mcps/researcher.server.ts +19 -34
- package/src/mcps/simulation/server-simulations.ts +3 -3
- package/src/skills/hermes-agent/SKILL.md +42 -42
- package/src/skills/storyteller/SKILL.md +1 -1
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hermes-agent
|
|
3
|
-
description: Manage
|
|
3
|
+
description: Manage 0xRay framework from Hermes Agent via the native xray-hermes plugin. Covers the 4 plugin tools (validate, codex_check, health, hooks), lifecycle hooks, slash commands, bridge architecture, and CLI fallback.
|
|
4
4
|
version: 2.1.0
|
|
5
|
-
author:
|
|
5
|
+
author: 0xRay AI
|
|
6
6
|
metadata:
|
|
7
7
|
hermes:
|
|
8
|
-
tags: [
|
|
8
|
+
tags: [0xRay, Plugin, Validation, Codex, GitHooks, Bridge]
|
|
9
9
|
related_skills: []
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# 0xRay Hermes Plugin (xray-hermes)
|
|
13
13
|
|
|
14
|
-
Native Hermes plugin providing
|
|
14
|
+
Native Hermes plugin providing 0xRay framework integration — quality gates, codex enforcement, git hooks, and full pre/post processing pipeline. Runs via a Node.js bridge to compiled framework components.
|
|
15
15
|
|
|
16
16
|
## When to Use
|
|
17
17
|
|
|
18
|
-
- User asks about
|
|
18
|
+
- User asks about 0xRay health, validation, or codex checks
|
|
19
19
|
- User wants to install/manage git hooks for automated enforcement
|
|
20
20
|
- User asks about the plugin's tools, hooks, or slash commands
|
|
21
21
|
- User asks about bridge errors or framework not loading
|
|
@@ -24,11 +24,11 @@ Native Hermes plugin providing StringRay framework integration — quality gates
|
|
|
24
24
|
## Plugin Architecture
|
|
25
25
|
|
|
26
26
|
```
|
|
27
|
-
~/.hermes/plugins/
|
|
27
|
+
~/.hermes/plugins/xray-hermes/
|
|
28
28
|
├── __init__.py # Plugin registration, hooks, slash commands
|
|
29
29
|
├── tools.py # 4 tool handlers (validate, codex_check, health, hooks)
|
|
30
30
|
├── schemas.py # JSON schemas the LLM sees
|
|
31
|
-
├── bridge.mjs # Node.js bridge to compiled
|
|
31
|
+
├── bridge.mjs # Node.js bridge to compiled 0xRay framework
|
|
32
32
|
├── plugin.yaml # Plugin metadata (name, version, tools, hooks)
|
|
33
33
|
├── types.py # TypeScript-equivalent type definitions
|
|
34
34
|
├── after-install.md # Post-install instructions
|
|
@@ -43,17 +43,17 @@ Native Hermes plugin providing StringRay framework integration — quality gates
|
|
|
43
43
|
|
|
44
44
|
**Fallback:** When bridge is unavailable, tools fall back to `npx 0xray` CLI commands.
|
|
45
45
|
|
|
46
|
-
**Config path resolution:** `
|
|
46
|
+
**Config path resolution:** `XRAY_CONFIG_DIR/` > `.xray/` > `.opencode/xray/` > built-in defaults.
|
|
47
47
|
|
|
48
48
|
## 4 Tools
|
|
49
49
|
|
|
50
|
-
###
|
|
50
|
+
### xray_validate
|
|
51
51
|
|
|
52
52
|
Run pre-commit validation on files. Uses bridge quality gate + processor pipeline, falls back to CLI.
|
|
53
53
|
|
|
54
54
|
```
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
xray_validate(files=["src/my-module.ts"], operation="commit")
|
|
56
|
+
xray_validate(files=["src/auth.ts", "src/auth.test.ts"], operation="modify")
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
Parameters:
|
|
@@ -62,13 +62,13 @@ Parameters:
|
|
|
62
62
|
|
|
63
63
|
Returns: pass/fail with per-file results and violations.
|
|
64
64
|
|
|
65
|
-
###
|
|
65
|
+
### xray_codex_check
|
|
66
66
|
|
|
67
67
|
Validate code against the 60-term Universal Development Codex. Checks error-handling, type-safety, performance, security, architecture.
|
|
68
68
|
|
|
69
69
|
```
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
xray_codex_check(code="const x: any = foo()", operation="create")
|
|
71
|
+
xray_codex_check(code=snippet, operation="modify", focus_areas=["security", "error-handling"])
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
Parameters:
|
|
@@ -78,25 +78,25 @@ Parameters:
|
|
|
78
78
|
|
|
79
79
|
Returns: violations list with actionable remediation.
|
|
80
80
|
|
|
81
|
-
###
|
|
81
|
+
### xray_health
|
|
82
82
|
|
|
83
83
|
Framework health check. Returns version, loaded components, project root.
|
|
84
84
|
|
|
85
85
|
```
|
|
86
|
-
|
|
86
|
+
xray_health()
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
Returns: framework status, version, component availability, node version.
|
|
90
90
|
|
|
91
|
-
###
|
|
91
|
+
### xray_hooks
|
|
92
92
|
|
|
93
|
-
Manage
|
|
93
|
+
Manage 0xRay git hooks (install, uninstall, list, status).
|
|
94
94
|
|
|
95
95
|
```
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
xray_hooks(action="install")
|
|
97
|
+
xray_hooks(action="status")
|
|
98
|
+
xray_hooks(action="list")
|
|
99
|
+
xray_hooks(action="uninstall", hooks=["pre-commit"])
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
Parameters:
|
|
@@ -122,7 +122,7 @@ Fires before ANY tool executes:
|
|
|
122
122
|
1. Tracks session stats
|
|
123
123
|
2. Logs tool-start event to `logs/framework/plugin-tool-events.log`
|
|
124
124
|
3. For code-producing tools (write_file, patch, execute_code, write, edit): runs quality gate + pre-processors via bridge
|
|
125
|
-
4. For other tools: nudges when a
|
|
125
|
+
4. For other tools: nudges when a 0xRay MCP alternative exists (e.g., grep → search_codebase, eslint → xray_lint)
|
|
126
126
|
|
|
127
127
|
### post_tool_call
|
|
128
128
|
|
|
@@ -137,16 +137,16 @@ Fires when a new session starts. Resets stats and logs to disk. Registration is
|
|
|
137
137
|
## Slash Command
|
|
138
138
|
|
|
139
139
|
```
|
|
140
|
-
/
|
|
141
|
-
/
|
|
142
|
-
/
|
|
140
|
+
/xray status — Plugin and framework health (calls bridge)
|
|
141
|
+
/xray stats — Session pipeline statistics
|
|
142
|
+
/xray help — Show available commands
|
|
143
143
|
/sr status — Alias
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
## Session Stats (tracked automatically)
|
|
147
147
|
|
|
148
|
-
The plugin tracks per-session counters visible via `/
|
|
149
|
-
- total_tool_calls, code_operations,
|
|
148
|
+
The plugin tracks per-session counters visible via `/xray stats`:
|
|
149
|
+
- total_tool_calls, code_operations, xray_mcp_calls, native_tool_calls
|
|
150
150
|
- quality_gate_runs, quality_gate_blocks
|
|
151
151
|
- pre_processor_runs, post_processor_runs
|
|
152
152
|
- bridge_calls, bridge_errors
|
|
@@ -164,13 +164,13 @@ All logs go to `logs/framework/` in the project root:
|
|
|
164
164
|
|
|
165
165
|
| User Says | Tool / Command |
|
|
166
166
|
|----------|---------------|
|
|
167
|
-
| "Is
|
|
168
|
-
| "Check these files before I commit" | `
|
|
169
|
-
| "Is this code codex compliant?" | `
|
|
170
|
-
| "Set up git hooks" | `
|
|
171
|
-
| "What hooks are installed?" | `
|
|
172
|
-
| "Show session stats" | `/
|
|
173
|
-
| "Why is the bridge failing?" | Check `
|
|
167
|
+
| "Is 0xRay working?" | `xray_health()` or `/xray status` |
|
|
168
|
+
| "Check these files before I commit" | `xray_validate(files=[...], operation="commit")` |
|
|
169
|
+
| "Is this code codex compliant?" | `xray_codex_check(code=..., operation="create")` |
|
|
170
|
+
| "Set up git hooks" | `xray_hooks(action="install")` |
|
|
171
|
+
| "What hooks are installed?" | `xray_hooks(action="status")` |
|
|
172
|
+
| "Show session stats" | `/xray stats` |
|
|
173
|
+
| "Why is the bridge failing?" | Check `xray_health()` → if `framework: "not_loaded"`, verify `dist/` symlink |
|
|
174
174
|
|
|
175
175
|
## Bridge Commands (internal)
|
|
176
176
|
|
|
@@ -188,8 +188,8 @@ These are called by the Python tools via `bridge.mjs`, not directly by the LLM:
|
|
|
188
188
|
|
|
189
189
|
Bridge can be invoked directly for debugging:
|
|
190
190
|
```bash
|
|
191
|
-
echo '{"command":"health"}' | node ~/.hermes/plugins/
|
|
192
|
-
node ~/.hermes/plugins/
|
|
191
|
+
echo '{"command":"health"}' | node ~/.hermes/plugins/xray-hermes/bridge.mjs
|
|
192
|
+
node ~/.hermes/plugins/xray-hermes/bridge.mjs health --cwd /path/to/project
|
|
193
193
|
```
|
|
194
194
|
|
|
195
195
|
## Relationship to MCP Servers
|
|
@@ -198,15 +198,15 @@ The plugin and MCP servers are complementary:
|
|
|
198
198
|
- **Plugin tools** = offline-first, always available, lightweight (validate, codex check, health, hooks)
|
|
199
199
|
- **MCP servers** = deeper analysis requiring running Node.js (lint, security scan, architecture assessment, orchestration, codebase search)
|
|
200
200
|
|
|
201
|
-
The plugin's pre_tool_call hook nudges when an MCP alternative exists (e.g., "use
|
|
201
|
+
The plugin's pre_tool_call hook nudges when an MCP alternative exists (e.g., "use mcp_xray_lint_lint instead of raw eslint"). This is advisory, not blocking.
|
|
202
202
|
|
|
203
203
|
## Pitfalls
|
|
204
204
|
|
|
205
205
|
- Plugin requires restart after install/edit: Hermes loads plugins once at session start.
|
|
206
206
|
- Bridge needs `dist/` symlink: The bridge loads compiled `.js` from `dist/` → `node_modules/0xray/dist/`. If the symlink breaks, bridge returns `framework: "not_loaded"`.
|
|
207
|
-
- `
|
|
207
|
+
- `xray_codex_check` without `code` param returns health, not a codex check. Pass `code` for actual validation.
|
|
208
208
|
- CLI fallback requires `npx 0xray` in PATH. If bridge fails and CLI isn't available, tools return errors.
|
|
209
209
|
- Quality gate blocks are logged but NOT enforced (advisory). The tool returns violations; the agent decides what to do.
|
|
210
|
-
- Git hooks use symlinks from `.git/hooks/` → `hooks/`. If the `hooks/` directory doesn't exist in the project, `
|
|
211
|
-
- Project root detection walks up from CWD looking for `node_modules/0xray`, `.opencode/
|
|
210
|
+
- Git hooks use symlinks from `.git/hooks/` → `hooks/`. If the `hooks/` directory doesn't exist in the project, `xray_hooks(action="install")` skips those hooks.
|
|
211
|
+
- Project root detection walks up from CWD looking for `node_modules/0xray`, `.opencode/xray/features.json`, or `package.json`. Override with `XRAY_PROJECT_ROOT` env var.
|
|
212
212
|
- `logs/framework/` is created automatically. Never breaks the agent if permissions fail.
|
|
@@ -96,7 +96,7 @@ codex_terms: [5, 7, 32] # Related Codex term numbers
|
|
|
96
96
|
```markdown
|
|
97
97
|
## What Next?
|
|
98
98
|
|
|
99
|
-
- Related Codex terms: [codex.json](../../.opencode/
|
|
99
|
+
- Related Codex terms: [codex.json](../../.opencode/xray/codex.json)
|
|
100
100
|
- Next story to write: [suggestion]
|
|
101
101
|
```
|
|
102
102
|
|
package/dist/state/index.js
CHANGED
|
@@ -4,4 +4,5 @@ export * from "./state-manager.js";
|
|
|
4
4
|
export * from "./context-providers.js";
|
|
5
5
|
export * from "./state-types.js";
|
|
6
6
|
// Re-export commonly used state utilities
|
|
7
|
-
export {
|
|
7
|
+
export { XrayStateManager } from "./state-manager.js";
|
|
8
|
+
export { XrayStateManager as StringRayStateManager } from "./state-manager.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { frameworkLogger } from "../core/framework-logger.js";
|
|
2
2
|
import { resolveStateFilePath } from "../core/config-paths.js";
|
|
3
|
-
export class
|
|
3
|
+
export class XrayStateManager {
|
|
4
4
|
store = new Map();
|
|
5
5
|
persistencePath;
|
|
6
6
|
persistenceEnabled;
|
|
@@ -190,7 +190,7 @@ export class StringRayStateManager {
|
|
|
190
190
|
}
|
|
191
191
|
// Enterprise features for advanced state management
|
|
192
192
|
getStateVersion() {
|
|
193
|
-
return
|
|
193
|
+
return XrayStateManager.VERSION || "1.1.1";
|
|
194
194
|
}
|
|
195
195
|
getAuditLog() {
|
|
196
196
|
return []; // Simplified implementation for testing
|
|
@@ -205,4 +205,4 @@ export class StringRayStateManager {
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
// Export alias for scripts expecting StrRayStateManager (backward compatibility)
|
|
208
|
-
export {
|
|
208
|
+
export { XrayStateManager as StringRayStateManager };
|
|
@@ -3,7 +3,7 @@ import * as path from "path";
|
|
|
3
3
|
import { resolveConfigPath } from "../core/config-paths.js";
|
|
4
4
|
export class TokenManager {
|
|
5
5
|
config;
|
|
6
|
-
constructor(configPath = resolveConfigPath("config.json") || path.join(process.cwd(), ".
|
|
6
|
+
constructor(configPath = resolveConfigPath("config.json") || path.join(process.cwd(), ".xray", "config.json")) {
|
|
7
7
|
this.config = this.loadConfig(configPath);
|
|
8
8
|
}
|
|
9
9
|
loadConfig(configPath) {
|
|
@@ -12,7 +12,7 @@ import { frameworkLogger } from '../core/framework-logger.js';
|
|
|
12
12
|
export class EstimationValidator {
|
|
13
13
|
estimations = new Map();
|
|
14
14
|
calibrations = new Map();
|
|
15
|
-
STORAGE_KEY = '
|
|
15
|
+
STORAGE_KEY = 'xray-estimations';
|
|
16
16
|
constructor() {
|
|
17
17
|
this.loadFromStorage();
|
|
18
18
|
}
|
package/package.json
CHANGED
|
@@ -166,15 +166,19 @@ function checkVersionManagerRan() {
|
|
|
166
166
|
|
|
167
167
|
// Check that files have been updated (look for recent timestamps or version)
|
|
168
168
|
const { resolveConfigPath } = require('../helpers/resolve-config-path.cjs');
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
169
|
+
let features;
|
|
170
|
+
try {
|
|
171
|
+
const featuresPath = resolveConfigPath('features.json', rootDir);
|
|
172
|
+
features = JSON.parse(fs.readFileSync(featuresPath, 'utf-8'));
|
|
173
|
+
// Version manager should have updated version fields
|
|
174
|
+
if (!features.version && !features.xray_version) {
|
|
175
|
+
warnings.push('features.json may not have been synced by version manager');
|
|
176
|
+
log('features.json may need version sync', 'warn');
|
|
177
|
+
} else {
|
|
178
|
+
log('Version manager appears to have run', 'success');
|
|
179
|
+
}
|
|
180
|
+
} catch {
|
|
181
|
+
log('features.json not found — skipping version sync check', 'warn');
|
|
178
182
|
}
|
|
179
183
|
|
|
180
184
|
return true;
|
|
@@ -136,9 +136,9 @@ const CALCULATED_COUNTS = calculateCounts();
|
|
|
136
136
|
const OFFICIAL_VERSIONS = {
|
|
137
137
|
// Framework version
|
|
138
138
|
framework: {
|
|
139
|
-
version: "3.0
|
|
139
|
+
version: "3.1.0",
|
|
140
140
|
displayName: "xray: Self-Healing AI Governance OS",
|
|
141
|
-
lastUpdated: "2026-06-
|
|
141
|
+
lastUpdated: "2026-06-15",
|
|
142
142
|
// Counts (auto-calculated, but can be overridden)
|
|
143
143
|
...CALCULATED_COUNTS,
|
|
144
144
|
},
|
|
@@ -164,38 +164,38 @@ describe('ServerConfigRegistry', () => {
|
|
|
164
164
|
expect(config.timeout).toBe(30000);
|
|
165
165
|
});
|
|
166
166
|
|
|
167
|
-
it('should use
|
|
168
|
-
const originalEnv = process.env.
|
|
169
|
-
process.env.
|
|
167
|
+
it('should use XRAY_DEV_PATH env var in dynamic config', () => {
|
|
168
|
+
const originalEnv = process.env.XRAY_DEV_PATH;
|
|
169
|
+
process.env.XRAY_DEV_PATH = 'custom-dist';
|
|
170
170
|
|
|
171
171
|
const config = registry.createDynamicConfig('test-server');
|
|
172
172
|
expect(config.args[0]).toContain('custom-dist');
|
|
173
173
|
|
|
174
|
-
process.env.
|
|
174
|
+
process.env.XRAY_DEV_PATH = originalEnv;
|
|
175
175
|
});
|
|
176
176
|
});
|
|
177
177
|
|
|
178
178
|
describe('environment path handling', () => {
|
|
179
|
-
it('should use resolved framework path when
|
|
180
|
-
const originalEnv = process.env.
|
|
181
|
-
delete process.env.
|
|
179
|
+
it('should use resolved framework path when XRAY_DEV_PATH is not set', () => {
|
|
180
|
+
const originalEnv = process.env.XRAY_DEV_PATH;
|
|
181
|
+
delete process.env.XRAY_DEV_PATH;
|
|
182
182
|
|
|
183
183
|
const freshRegistry = new ServerConfigRegistry();
|
|
184
184
|
const config = freshRegistry.get('code-review');
|
|
185
185
|
expect(config?.args[0]).toContain('.server.js');
|
|
186
186
|
|
|
187
|
-
process.env.
|
|
187
|
+
process.env.XRAY_DEV_PATH = originalEnv;
|
|
188
188
|
});
|
|
189
189
|
|
|
190
|
-
it('should use
|
|
191
|
-
const originalEnv = process.env.
|
|
192
|
-
process.env.
|
|
190
|
+
it('should use XRAY_DEV_PATH when set', () => {
|
|
191
|
+
const originalEnv = process.env.XRAY_DEV_PATH;
|
|
192
|
+
process.env.XRAY_DEV_PATH = 'dist';
|
|
193
193
|
|
|
194
194
|
const freshRegistry = new ServerConfigRegistry();
|
|
195
195
|
const config = freshRegistry.get('code-review');
|
|
196
196
|
expect(config?.args[0]).toContain('dist/');
|
|
197
197
|
|
|
198
|
-
process.env.
|
|
198
|
+
process.env.XRAY_DEV_PATH = originalEnv;
|
|
199
199
|
});
|
|
200
200
|
});
|
|
201
201
|
|
|
@@ -20,21 +20,21 @@ import fs from 'fs';
|
|
|
20
20
|
/**
|
|
21
21
|
* Resolve the correct framework root and MCP servers path.
|
|
22
22
|
* Priority:
|
|
23
|
-
* 1.
|
|
24
|
-
* 2. The "
|
|
23
|
+
* 1. XRAY_DEV_PATH env var (explicit dev override)
|
|
24
|
+
* 2. The "xray" field in the nearest package.json that declares it (works in both source tree and installed package)
|
|
25
25
|
* 3. Safe fallback to node_modules/0xray/dist
|
|
26
26
|
*/
|
|
27
27
|
function resolveFrameworkPaths(): { frameworkRoot: string; mcpServersPath: string } {
|
|
28
28
|
// Highest priority: explicit environment override
|
|
29
|
-
if (process.env.
|
|
30
|
-
const devPath = process.env.
|
|
29
|
+
if (process.env.XRAY_DEV_PATH) {
|
|
30
|
+
const devPath = process.env.XRAY_DEV_PATH;
|
|
31
31
|
return {
|
|
32
32
|
frameworkRoot: devPath,
|
|
33
33
|
mcpServersPath: join(devPath, 'mcps'),
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// Walk upward from this module to find the package that owns the "
|
|
37
|
+
// Walk upward from this module to find the package that owns the "xray" config
|
|
38
38
|
let currentDir = dirname(fileURLToPath(import.meta.url));
|
|
39
39
|
|
|
40
40
|
// Safety limit to avoid walking the entire filesystem
|
|
@@ -44,10 +44,10 @@ function resolveFrameworkPaths(): { frameworkRoot: string; mcpServersPath: strin
|
|
|
44
44
|
if (fs.existsSync(pkgPath)) {
|
|
45
45
|
try {
|
|
46
46
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
47
|
-
if (pkg.name === '0xray' && pkg.
|
|
48
|
-
const
|
|
47
|
+
if (pkg.name === '0xray' && pkg.xray) {
|
|
48
|
+
const xrayCfg = pkg.xray as Record<string, string>;
|
|
49
49
|
const frameworkRoot = currentDir;
|
|
50
|
-
const declaredMcp =
|
|
50
|
+
const declaredMcp = xrayCfg.mcpServersPath || (xrayCfg.dist ? join(xrayCfg.dist, 'mcps') : 'dist/mcps');
|
|
51
51
|
return {
|
|
52
52
|
frameworkRoot,
|
|
53
53
|
mcpServersPath: join(frameworkRoot, declaredMcp),
|
|
@@ -65,7 +65,7 @@ function resolveFrameworkPaths(): { frameworkRoot: string; mcpServersPath: strin
|
|
|
65
65
|
// Final fallback (should almost never be reached)
|
|
66
66
|
const fallback = 'node_modules/0xray/dist';
|
|
67
67
|
frameworkLogger.log('server-config-registry', 'using-fallback-path', 'warning', {
|
|
68
|
-
reason: 'Could not locate
|
|
68
|
+
reason: 'Could not locate xray package.json with "xray" field',
|
|
69
69
|
fallback,
|
|
70
70
|
});
|
|
71
71
|
return {
|
|
@@ -367,7 +367,7 @@ export class ServerConfigRegistry {
|
|
|
367
367
|
/**
|
|
368
368
|
* Create a dynamic configuration for an unknown server
|
|
369
369
|
* Uses the knowledge-skills directory as default location.
|
|
370
|
-
* Now respects the "
|
|
370
|
+
* Now respects the "xray" field declared in package.json.
|
|
371
371
|
*/
|
|
372
372
|
createDynamicConfig(serverName: string): IServerConfig {
|
|
373
373
|
// Validate serverName against path traversal attacks
|
|
@@ -40,7 +40,7 @@ class FrameworkHelpServer {
|
|
|
40
40
|
return {
|
|
41
41
|
tools: [
|
|
42
42
|
{
|
|
43
|
-
name: "
|
|
43
|
+
name: "xray_get_capabilities",
|
|
44
44
|
description:
|
|
45
45
|
"Get comprehensive list of all 0xRay framework capabilities, commands, and available tools",
|
|
46
46
|
inputSchema: {
|
|
@@ -63,7 +63,7 @@ class FrameworkHelpServer {
|
|
|
63
63
|
},
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
name: "
|
|
66
|
+
name: "xray_get_commands",
|
|
67
67
|
description:
|
|
68
68
|
"Get list of available 0xRay commands and their usage",
|
|
69
69
|
inputSchema: {
|
|
@@ -84,7 +84,7 @@ class FrameworkHelpServer {
|
|
|
84
84
|
},
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
|
-
name: "
|
|
87
|
+
name: "xray_explain_capability",
|
|
88
88
|
description:
|
|
89
89
|
"Get detailed explanation of a specific 0xRay capability",
|
|
90
90
|
inputSchema: {
|
|
@@ -108,11 +108,11 @@ class FrameworkHelpServer {
|
|
|
108
108
|
|
|
109
109
|
try {
|
|
110
110
|
switch (name) {
|
|
111
|
-
case "
|
|
111
|
+
case "xray_get_capabilities":
|
|
112
112
|
return this.handleGetCapabilities(args);
|
|
113
|
-
case "
|
|
113
|
+
case "xray_get_commands":
|
|
114
114
|
return this.handleGetCommands(args);
|
|
115
|
-
case "
|
|
115
|
+
case "xray_explain_capability":
|
|
116
116
|
return this.handleExplainCapability(args);
|
|
117
117
|
default:
|
|
118
118
|
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import * as fs from "fs";
|
|
16
16
|
import * as path from "path";
|
|
17
17
|
import { createGracefulShutdown } from "../../utils/shutdown-handler.js";
|
|
18
|
+
import { tryLLMGovernance } from "../../governance/llm-governance-provider.js";
|
|
18
19
|
|
|
19
20
|
interface CodeReviewResult {
|
|
20
21
|
file: string;
|
|
@@ -465,47 +466,31 @@ class XrayCodeReviewServer {
|
|
|
465
466
|
*/
|
|
466
467
|
async analyzeProposal(args: AnalyzeProposalArgs) {
|
|
467
468
|
const { proposalTitle = "", proposalDescription = "", evidence = [], proposalType = "" } = args;
|
|
468
|
-
const text = `${proposalTitle} ${proposalDescription} ${evidence.join(" ")}`.toLowerCase();
|
|
469
|
-
|
|
470
|
-
let decision: "approve" | "reject" | "abstain" = "approve";
|
|
471
|
-
let confidence = 0.82;
|
|
472
|
-
let reasoning = "The proposal appears reasonable from a code quality and maintainability perspective.";
|
|
473
|
-
|
|
474
|
-
if (text.includes("aml") || text.includes("kyc") || text.includes("anti-money")) {
|
|
475
|
-
decision = "approve";
|
|
476
|
-
confidence = 0.88;
|
|
477
|
-
reasoning = "AML/KYC compliance code requires rigorous review: transaction monitoring must handle edge cases, avoid false positives from legitimate patterns, and maintain audit trails for regulatory inspection.";
|
|
478
|
-
} else if (text.includes("psd2") || text.includes("strong customer authentication") || text.includes("payment initiation")) {
|
|
479
|
-
decision = "approve";
|
|
480
|
-
confidence = 0.90;
|
|
481
|
-
reasoning = "PSD2 SCA implementation must balance security with user experience. Code should use well-audited MFA libraries, avoid rolling custom authentication, and include comprehensive test coverage for all authentication flows.";
|
|
482
|
-
} else if (text.includes("gdpr") || text.includes("right to erasure") || text.includes("data protection")) {
|
|
483
|
-
decision = "approve";
|
|
484
|
-
confidence = 0.92;
|
|
485
|
-
reasoning = "GDPR erasure pipelines require careful code review: cascading deletes must be transactional, audit logs must be preserved, and the 30-day SLA demands observability and monitoring integration.";
|
|
486
|
-
} else if (text.includes("extract method")) {
|
|
487
|
-
decision = "approve";
|
|
488
|
-
confidence = 0.93;
|
|
489
|
-
reasoning = "Extract Method is a well-established refactoring pattern that improves readability and reduces cognitive load when applied consistently.";
|
|
490
|
-
} else if (text.includes("test coverage")) {
|
|
491
|
-
decision = "approve";
|
|
492
|
-
confidence = 0.90;
|
|
493
|
-
reasoning = "Expanding automated test coverage generally improves long-term code health and reduces regression risk.";
|
|
494
|
-
} else if (text.includes("increase timeout") && text.includes("flaky")) {
|
|
495
|
-
decision = "reject";
|
|
496
|
-
confidence = 0.72;
|
|
497
|
-
reasoning = "Repeatedly increasing timeouts to mask flaky tests is an anti-pattern that hides underlying race conditions or timing issues.";
|
|
498
|
-
}
|
|
499
469
|
|
|
500
|
-
|
|
501
|
-
|
|
470
|
+
const vote = await tryLLMGovernance(
|
|
471
|
+
"code-review",
|
|
472
|
+
proposalTitle,
|
|
473
|
+
proposalDescription,
|
|
474
|
+
evidence,
|
|
475
|
+
proposalType,
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
if (!vote) {
|
|
479
|
+
return {
|
|
480
|
+
content: [
|
|
481
|
+
{
|
|
482
|
+
type: "text",
|
|
483
|
+
text: "DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: No LLM governance provider configured. Set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT, or install Hermes and run: hermes auth add xai-oauth --no-browser",
|
|
484
|
+
},
|
|
485
|
+
],
|
|
486
|
+
};
|
|
502
487
|
}
|
|
503
488
|
|
|
504
489
|
return {
|
|
505
490
|
content: [
|
|
506
491
|
{
|
|
507
492
|
type: "text",
|
|
508
|
-
text: `DECISION: ${decision}\nCONFIDENCE: ${confidence.toFixed(2)}\nREASONING: ${reasoning}`,
|
|
493
|
+
text: `DECISION: ${vote.decision}\nCONFIDENCE: ${vote.confidence.toFixed(2)}\nREASONING: ${vote.reasoning}`,
|
|
509
494
|
},
|
|
510
495
|
],
|
|
511
496
|
};
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import * as fs from "fs";
|
|
16
16
|
import * as path from "path";
|
|
17
17
|
import { createGracefulShutdown } from "../../utils/shutdown-handler.js";
|
|
18
|
+
import { tryLLMGovernance } from "../../governance/llm-governance-provider.js";
|
|
18
19
|
|
|
19
20
|
interface SecurityVulnerability {
|
|
20
21
|
id: string;
|
|
@@ -1122,51 +1123,31 @@ class XraySecurityAuditServer {
|
|
|
1122
1123
|
*/
|
|
1123
1124
|
async analyzeProposal(args: AnalyzeProposalArgs) {
|
|
1124
1125
|
const { proposalTitle = "", proposalDescription = "", evidence = [], proposalType = "" } = args;
|
|
1125
|
-
const text = `${proposalTitle} ${proposalDescription} ${evidence.join(" ")}`.toLowerCase();
|
|
1126
|
-
|
|
1127
|
-
let decision: "approve" | "reject" | "abstain" = "approve";
|
|
1128
|
-
let confidence = 0.82;
|
|
1129
|
-
let reasoning = "The proposal does not appear to introduce significant new security surface area.";
|
|
1130
|
-
|
|
1131
|
-
if (text.includes("aml") || text.includes("kyc") || text.includes("anti-money")) {
|
|
1132
|
-
decision = "approve";
|
|
1133
|
-
confidence = 0.91;
|
|
1134
|
-
reasoning = "AML/KYC compliance measures are critical for regulatory security posture. Automated transaction monitoring closes vulnerability gaps in financial crime detection and demonstrates due diligence for regulatory inspections.";
|
|
1135
|
-
} else if (text.includes("psd2") || text.includes("strong customer authentication") || text.includes("payment initiation")) {
|
|
1136
|
-
decision = "approve";
|
|
1137
|
-
confidence = 0.93;
|
|
1138
|
-
reasoning = "PSD2 SCA implementation is a mandatory security control for payment services. Multi-factor authentication with dynamic linking reduces unauthorized payment risk and satisfies EBA regulatory technical standards.";
|
|
1139
|
-
} else if (text.includes("gdpr") || text.includes("right to erasure") || text.includes("data protection")) {
|
|
1140
|
-
decision = "approve";
|
|
1141
|
-
confidence = 0.94;
|
|
1142
|
-
reasoning = "GDPR compliance controls are foundational to data security posture. Automated data erasure pipelines reduce data breach exposure windows and satisfy supervisory authority inspection requirements.";
|
|
1143
|
-
} else if (text.includes("beneficial ownership") || text.includes("ubo") || text.includes("pep screening")) {
|
|
1144
|
-
decision = "approve";
|
|
1145
|
-
confidence = 0.87;
|
|
1146
|
-
reasoning = "Beneficial ownership transparency and PEP screening are critical AML controls. Verifying ultimate beneficial owners reduces money laundering risk through corporate account structuring.";
|
|
1147
|
-
} else if (text.includes("extract method")) {
|
|
1148
|
-
decision = "approve";
|
|
1149
|
-
confidence = 0.88;
|
|
1150
|
-
reasoning = "Extract Method refactoring improves security posture by reducing attack surface in large monolithic files and enabling better isolation of sensitive logic.";
|
|
1151
|
-
} else if (text.includes("test coverage")) {
|
|
1152
|
-
decision = "approve";
|
|
1153
|
-
confidence = 0.91;
|
|
1154
|
-
reasoning = "Expanding test coverage is one of the highest-ROI security controls available — more tests surface regressions and boundary condition vulnerabilities earlier.";
|
|
1155
|
-
} else if (text.includes("increase timeout") && text.includes("flaky")) {
|
|
1156
|
-
decision = "reject";
|
|
1157
|
-
confidence = 0.75;
|
|
1158
|
-
reasoning = "Repeatedly increasing timeouts to hide flaky tests can mask timing attacks, race conditions, and resource exhaustion vulnerabilities. Root cause remediation is required.";
|
|
1159
|
-
}
|
|
1160
1126
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1127
|
+
const vote = await tryLLMGovernance(
|
|
1128
|
+
"security-audit",
|
|
1129
|
+
proposalTitle,
|
|
1130
|
+
proposalDescription,
|
|
1131
|
+
evidence,
|
|
1132
|
+
proposalType,
|
|
1133
|
+
);
|
|
1134
|
+
|
|
1135
|
+
if (!vote) {
|
|
1136
|
+
return {
|
|
1137
|
+
content: [
|
|
1138
|
+
{
|
|
1139
|
+
type: "text",
|
|
1140
|
+
text: "DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: No LLM governance provider configured. Set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT, or install Hermes and run: hermes auth add xai-oauth --no-browser",
|
|
1141
|
+
},
|
|
1142
|
+
],
|
|
1143
|
+
};
|
|
1163
1144
|
}
|
|
1164
1145
|
|
|
1165
1146
|
return {
|
|
1166
1147
|
content: [
|
|
1167
1148
|
{
|
|
1168
1149
|
type: "text",
|
|
1169
|
-
text: `DECISION: ${decision}\nCONFIDENCE: ${confidence.toFixed(2)}\nREASONING: ${reasoning}`,
|
|
1150
|
+
text: `DECISION: ${vote.decision}\nCONFIDENCE: ${vote.confidence.toFixed(2)}\nREASONING: ${vote.reasoning}`,
|
|
1170
1151
|
},
|
|
1171
1152
|
],
|
|
1172
1153
|
};
|
|
@@ -1985,7 +1985,7 @@ Available: ${Object.keys(system.components).length} component types
|
|
|
1985
1985
|
await this.server.connect(transport);
|
|
1986
1986
|
await frameworkLogger.log(
|
|
1987
1987
|
"ui-ux-design.server",
|
|
1988
|
-
"-
|
|
1988
|
+
"-xray-ui-ux-design-mcp-server-running-",
|
|
1989
1989
|
"info",
|
|
1990
1990
|
{ message: "xray UI/UX Design MCP Server running..." },
|
|
1991
1991
|
);
|
|
@@ -2011,7 +2011,7 @@ Available: ${Object.keys(system.components).length} component types
|
|
|
2011
2011
|
clearTimeout(timeout);
|
|
2012
2012
|
await frameworkLogger.log(
|
|
2013
2013
|
"ui-ux-design.server",
|
|
2014
|
-
"-
|
|
2014
|
+
"-xray-mcp-server-shut-down-gracefully-",
|
|
2015
2015
|
"info",
|
|
2016
2016
|
{ message: "xray MCP Server shut down gracefully" },
|
|
2017
2017
|
);
|