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
|
@@ -21,7 +21,7 @@ BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
|
21
21
|
) &
|
|
22
22
|
|
|
23
23
|
# Load auto_reflection config from features.json
|
|
24
|
-
CONFIG_FILE="$PROJECT_ROOT/.opencode/
|
|
24
|
+
CONFIG_FILE="$PROJECT_ROOT/.opencode/xray/features.json"
|
|
25
25
|
MODE="minimal"
|
|
26
26
|
COMMIT_THRESHOLD=25
|
|
27
27
|
DAYS_THRESHOLD=14
|
package/.opencode/init.sh
CHANGED
|
@@ -30,7 +30,7 @@ fi
|
|
|
30
30
|
|
|
31
31
|
# 0xRay Framework Version - read from FRAMEWORK_ROOT (already resolved above)
|
|
32
32
|
# FRAMEWORK_ROOT correctly picks source in dev mode, node_modules in consumer mode
|
|
33
|
-
|
|
33
|
+
XRAY_VERSION=$(node -e "console.log(require('$FRAMEWORK_ROOT/package.json').version)" 2>/dev/null || echo "unknown")
|
|
34
34
|
|
|
35
35
|
# Dedup guard — prevent duplicate runs during startup
|
|
36
36
|
# Uses a TTL lockfile (10s window) since OpenCode may trigger config hook
|
|
@@ -90,10 +90,10 @@ if [ "$AGENTS_COUNT" -eq 0 ]; then
|
|
|
90
90
|
AGENTS_COUNT=$(ls -1 "$PROJECT_ROOT/node_modules/0xray/.opencode/agents/"*.yml 2>/dev/null | wc -l | tr -d ' ')
|
|
91
91
|
fi
|
|
92
92
|
|
|
93
|
-
# Skills - check .opencode/skills, then .
|
|
93
|
+
# Skills - check .opencode/skills, then .xray/skills (Hermes), then node_modules
|
|
94
94
|
SKILLS_COUNT=$(ls -1d "$PROJECT_ROOT/.opencode/skills/"* 2>/dev/null | wc -l | tr -d ' ')
|
|
95
95
|
if [ "$SKILLS_COUNT" -eq 0 ]; then
|
|
96
|
-
SKILLS_COUNT=$(ls -1d "$PROJECT_ROOT/.
|
|
96
|
+
SKILLS_COUNT=$(ls -1d "$PROJECT_ROOT/.xray/skills/"* 2>/dev/null | wc -l | tr -d ' ')
|
|
97
97
|
fi
|
|
98
98
|
if [ "$SKILLS_COUNT" -eq 0 ]; then
|
|
99
99
|
SKILLS_COUNT=$(ls -1d "$PROJECT_ROOT/node_modules/0xray/.opencode/skills/"* 2>/dev/null | wc -l | tr -d ' ')
|
|
@@ -124,7 +124,7 @@ if [ ! -f "$PROJECT_ROOT/.opencode/enforcer-config.json" ]; then
|
|
|
124
124
|
fi
|
|
125
125
|
|
|
126
126
|
echo ""
|
|
127
|
-
echo "⚡ 0xRay v$
|
|
127
|
+
echo "⚡ 0xRay v$XRAY_VERSION"
|
|
128
128
|
echo "🤖 Agents: $AGENTS_COUNT | ⚙️ MCPs: $MCPS_COUNT | 💡 Skills: $SKILLS_COUNT"
|
|
129
129
|
|
|
130
130
|
# BootOrchestrator check (check dev and consumer paths)
|
package/AGENTS.md
CHANGED
|
@@ -86,9 +86,9 @@ xray enforces the Universal Development Codex (60 terms) via Dynamo governance.
|
|
|
86
86
|
|
|
87
87
|
Pure v16 MCPs. Clean. Complete.
|
|
88
88
|
|
|
89
|
-
## Session: v3.0.
|
|
89
|
+
## Session: v3.0.14 Rename Polish
|
|
90
90
|
|
|
91
|
-
- Package: `0xray` (npm), `github.com/0xRayAI/xray`. Version `3.0.
|
|
91
|
+
- Package: `0xray` (npm), `github.com/0xRayAI/xray`. Version `3.0.14`.
|
|
92
92
|
- **All 182 test files pass**: 2527 tests, 0 failures, 36 skipped.
|
|
93
93
|
- **Build fix**: removed stale `.opencode/plugin/` copy; `package.json` → `dist/plugin/xray-codex-injection.js`.
|
|
94
94
|
- **default-plugins.ts**: monkey-patch `Server.prototype.setRequestHandler` to capture tool definitions from MCP Server instances; all registration functions async.
|
package/dist/AGENTS.md
CHANGED
|
@@ -86,9 +86,9 @@ xray enforces the Universal Development Codex (60 terms) via Dynamo governance.
|
|
|
86
86
|
|
|
87
87
|
Pure v16 MCPs. Clean. Complete.
|
|
88
88
|
|
|
89
|
-
## Session: v3.0.
|
|
89
|
+
## Session: v3.0.14 Rename Polish
|
|
90
90
|
|
|
91
|
-
- Package: `0xray` (npm), `github.com/0xRayAI/xray`. Version `3.0.
|
|
91
|
+
- Package: `0xray` (npm), `github.com/0xRayAI/xray`. Version `3.0.14`.
|
|
92
92
|
- **All 182 test files pass**: 2527 tests, 0 failures, 36 skipped.
|
|
93
93
|
- **Build fix**: removed stale `.opencode/plugin/` copy; `package.json` → `dist/plugin/xray-codex-injection.js`.
|
|
94
94
|
- **default-plugins.ts**: monkey-patch `Server.prototype.setRequestHandler` to capture tool definitions from MCP Server instances; all registration functions async.
|
package/dist/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Conventional Commits](https://www.conventionalcommits.org/).
|
|
6
6
|
|
|
7
|
+
## [3.1.0] - 2026-06-15
|
|
8
|
+
|
|
9
|
+
### 🔄 Changes
|
|
10
|
+
|
|
11
|
+
### 🐛 Bug Fixes
|
|
12
|
+
- fix: pre-publish-guard handles missing features.json (855e3cfdb)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
7
16
|
## [3.0.14] - 2026-06-14
|
|
8
17
|
|
|
9
18
|
### 🔄 Changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Consumer runtime compat shim from prior StringRay releases (1-line min per Scope Rule; primary xray paths + XRAY_||STRRAY_ env + .strray fallbacks)
|
|
2
2
|
import { frameworkLogger } from "../core/framework-logger.js";
|
|
3
3
|
import crypto from "crypto";
|
|
4
|
-
export class
|
|
4
|
+
export class XrayPerformanceBenchmark {
|
|
5
5
|
results = [];
|
|
6
6
|
activeBenchmarks = new Map();
|
|
7
7
|
/**
|
|
@@ -369,4 +369,6 @@ export class StringRayPerformanceBenchmark {
|
|
|
369
369
|
}
|
|
370
370
|
}
|
|
371
371
|
// Export singleton instance
|
|
372
|
-
export const performanceBenchmark = new
|
|
372
|
+
export const performanceBenchmark = new XrayPerformanceBenchmark();
|
|
373
|
+
// Backward compat alias
|
|
374
|
+
export { XrayPerformanceBenchmark as StringRayPerformanceBenchmark };
|
|
@@ -16,14 +16,14 @@ export function registerHermesCommands(hermesCmd) {
|
|
|
16
16
|
async function installForHermes(options = {}) {
|
|
17
17
|
frameworkLogger.log('hermes-integration', 'install-start', 'info', { options });
|
|
18
18
|
const home = homedir();
|
|
19
|
-
const targetPluginDir = path.join(home, '.hermes/plugins/
|
|
19
|
+
const targetPluginDir = path.join(home, '.hermes/plugins/xray-hermes');
|
|
20
20
|
const possibleSources = [
|
|
21
21
|
path.join(__dirname, '..', '..', '..', 'dist/integrations/hermes-agent'),
|
|
22
22
|
path.join(__dirname, '..', '..', '..', 'src/integrations/hermes-agent'),
|
|
23
23
|
];
|
|
24
24
|
let sourceDir = possibleSources.find(p => fs.existsSync(p));
|
|
25
25
|
if (!sourceDir) {
|
|
26
|
-
console.error('[Hermes] Could not locate the
|
|
26
|
+
console.error('[Hermes] Could not locate the xray-hermes plugin inside the package.');
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
if (options.dryRun) {
|
|
@@ -32,7 +32,7 @@ async function installForHermes(options = {}) {
|
|
|
32
32
|
}
|
|
33
33
|
try {
|
|
34
34
|
if (fs.existsSync(targetPluginDir) && !options.force) {
|
|
35
|
-
console.log('[Hermes]
|
|
35
|
+
console.log('[Hermes] xray-hermes plugin is already installed.');
|
|
36
36
|
console.log('Use --force to reinstall.');
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
@@ -56,7 +56,7 @@ async function installForHermes(options = {}) {
|
|
|
56
56
|
}
|
|
57
57
|
console.log('\n✅ 0xRay is now installed as a Hermes Agent plugin!');
|
|
58
58
|
console.log('Restart Hermes to load the plugin and its tools.');
|
|
59
|
-
console.log(' Run: /
|
|
59
|
+
console.log(' Run: /xray status (to verify)');
|
|
60
60
|
}
|
|
61
61
|
catch (err) {
|
|
62
62
|
frameworkLogger.log('hermes-integration', 'install-error', 'error', { error: err.message });
|
|
@@ -3,7 +3,7 @@ import { join, dirname } from "path";
|
|
|
3
3
|
import { execSync } from "child_process";
|
|
4
4
|
import { getConfigDir } from "../../core/config-paths.js";
|
|
5
5
|
function getMCPConfigPath() {
|
|
6
|
-
return join(process.cwd(), ".opencode", "
|
|
6
|
+
return join(process.cwd(), ".opencode", "xray", "mcp-registry.json");
|
|
7
7
|
}
|
|
8
8
|
function getBundledMCPRegistry() {
|
|
9
9
|
const paths = [
|
|
@@ -14,7 +14,7 @@ export function registerOpenClawCommands(openclawCmd) {
|
|
|
14
14
|
}
|
|
15
15
|
async function installForOpenClaw(options = {}) {
|
|
16
16
|
frameworkLogger.log('openclaw-integration', 'install-start', 'info', { options });
|
|
17
|
-
const configPath = path.join(process.cwd(), '.
|
|
17
|
+
const configPath = path.join(process.cwd(), '.xray', 'config', 'openclaw.json');
|
|
18
18
|
if (options.dryRun) {
|
|
19
19
|
console.log(`[OpenClaw] Dry run: Would create config at ${configPath}`);
|
|
20
20
|
return;
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
import * as fs from "fs";
|
|
15
15
|
import * as path from "path";
|
|
16
16
|
import { spawnSync } from "child_process";
|
|
17
|
-
const PLUGINS_DIR = ".
|
|
18
|
-
const CONFIG_PATH = ".
|
|
17
|
+
const PLUGINS_DIR = ".xray/plugins";
|
|
18
|
+
const CONFIG_PATH = ".xray/config/plugin-config.json";
|
|
19
19
|
export async function pluginListCommand() {
|
|
20
20
|
console.log("\n📦 0xRay Plugins\n");
|
|
21
21
|
console.log("═".repeat(60));
|
|
@@ -69,10 +69,10 @@ function getPackageVersion(cwd) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
catch { /* ignore */ }
|
|
72
|
-
const
|
|
72
|
+
const xrayPkgPath = join(cwd, ".opencode", "package.json");
|
|
73
73
|
try {
|
|
74
|
-
if (existsSync(
|
|
75
|
-
const pkg = JSON.parse(readFileSync(
|
|
74
|
+
if (existsSync(xrayPkgPath)) {
|
|
75
|
+
const pkg = JSON.parse(readFileSync(xrayPkgPath, "utf-8"));
|
|
76
76
|
if (pkg.version)
|
|
77
77
|
return pkg.version;
|
|
78
78
|
}
|
|
@@ -89,7 +89,7 @@ function createAgentManifest(agentName, configPath, version, cwd) {
|
|
|
89
89
|
author: extractYamlField(content, "author") || extractYamlField(content, "maintainer") || "0xRay User",
|
|
90
90
|
license: extractYamlField(content, "license") || "MIT",
|
|
91
91
|
source: extractYamlField(content, "source") || "custom",
|
|
92
|
-
framework: "
|
|
92
|
+
framework: "0xray",
|
|
93
93
|
frameworkVersion: getPackageVersion(cwd),
|
|
94
94
|
publishedAt: new Date().toISOString(),
|
|
95
95
|
skills: [],
|
|
@@ -98,7 +98,7 @@ function createAgentManifest(agentName, configPath, version, cwd) {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
function packageAgent(agentName, configPath, version, cwd) {
|
|
101
|
-
const outputDir = join(cwd, ".
|
|
101
|
+
const outputDir = join(cwd, ".xray", "publish", agentName);
|
|
102
102
|
mkdirSync(outputDir, { recursive: true });
|
|
103
103
|
const manifest = createAgentManifest(agentName, configPath, version, cwd);
|
|
104
104
|
writeFileSync(join(outputDir, "agent.json"), JSON.stringify(manifest, null, 2));
|
|
@@ -2,7 +2,7 @@ import { existsSync, readdirSync, readFileSync, mkdirSync, writeFileSync, cpSync
|
|
|
2
2
|
import { join, basename, dirname } from "path";
|
|
3
3
|
import { execSync } from "child_process";
|
|
4
4
|
function getLocalRegistryPath() {
|
|
5
|
-
return join(process.cwd(), ".opencode", "
|
|
5
|
+
return join(process.cwd(), ".opencode", "xray", "skill-registry.json");
|
|
6
6
|
}
|
|
7
7
|
function getBundledRegistry() {
|
|
8
8
|
const paths = [
|
|
@@ -41,7 +41,7 @@ function getAgentsList(cwd) {
|
|
|
41
41
|
];
|
|
42
42
|
const configuredAgents = [];
|
|
43
43
|
const configDir = getConfigDir(cwd);
|
|
44
|
-
const agentsConfigPath = join(configDir, "
|
|
44
|
+
const agentsConfigPath = join(configDir, "xray", "agents.json");
|
|
45
45
|
if (existsSync(agentsConfigPath)) {
|
|
46
46
|
try {
|
|
47
47
|
const config = JSON.parse(readFileSync(agentsConfigPath, "utf-8"));
|
|
@@ -51,7 +51,7 @@ function getAgentsList(cwd) {
|
|
|
51
51
|
}
|
|
52
52
|
catch { /* ignore */ }
|
|
53
53
|
}
|
|
54
|
-
const featuresPath = join(configDir, "
|
|
54
|
+
const featuresPath = join(configDir, "xray", "features.json");
|
|
55
55
|
if (existsSync(featuresPath)) {
|
|
56
56
|
try {
|
|
57
57
|
const features = JSON.parse(readFileSync(featuresPath, "utf-8"));
|
|
@@ -93,7 +93,7 @@ function getInferenceStatus(cwd) {
|
|
|
93
93
|
let outcomesCount = 0;
|
|
94
94
|
let patternsCount = 0;
|
|
95
95
|
try {
|
|
96
|
-
const inferenceDir = join(getConfigDir(cwd), "
|
|
96
|
+
const inferenceDir = join(getConfigDir(cwd), "xray", "inference");
|
|
97
97
|
const tunerStatusPath = join(inferenceDir, "tuner-status.json");
|
|
98
98
|
if (existsSync(tunerStatusPath)) {
|
|
99
99
|
const status = JSON.parse(readFileSync(tunerStatusPath, "utf-8"));
|
|
@@ -17,7 +17,7 @@ const STORY_TYPES = ["reflection", "saga", "journey", "narrative"];
|
|
|
17
17
|
function loadConfig(cwd) {
|
|
18
18
|
const candidates = [
|
|
19
19
|
join(cwd, ".opencode", "strray", "features.json"),
|
|
20
|
-
join(cwd, ".
|
|
20
|
+
join(cwd, ".xray", "features.json"),
|
|
21
21
|
];
|
|
22
22
|
for (const path of candidates) {
|
|
23
23
|
if (existsSync(path)) {
|
package/dist/cli/index.js
CHANGED
|
@@ -385,7 +385,7 @@ program
|
|
|
385
385
|
const path = await import("path");
|
|
386
386
|
let defaultLimit = 500;
|
|
387
387
|
try {
|
|
388
|
-
const featuresPath = path.join(process.cwd(), ".opencode", "plugins", "features.json"); // plain xray primary (min compat .
|
|
388
|
+
const featuresPath = path.join(process.cwd(), ".opencode", "plugins", "features.json"); // plain xray primary (min compat .xray/ handled in getConfigDir per Scope Rule)
|
|
389
389
|
if (fs.existsSync(featuresPath)) {
|
|
390
390
|
const features = JSON.parse(fs.readFileSync(featuresPath, "utf-8"));
|
|
391
391
|
defaultLimit = features.analytics?.default_limit || 500;
|
|
@@ -450,16 +450,16 @@ program
|
|
|
450
450
|
else {
|
|
451
451
|
console.log("✅ xray package installed");
|
|
452
452
|
}
|
|
453
|
-
// Check configuration - check for opencode.json or .
|
|
453
|
+
// Check configuration - check for opencode.json or .xray/ (min compat .xray/ fallback for prior 0xRay consumer runtime per Scope Rule; plain xray primary)
|
|
454
454
|
const cwd = process.cwd();
|
|
455
455
|
const opencodeConfigPath = path.join(cwd, "opencode.json");
|
|
456
456
|
const strrayDir = getConfigDir(cwd);
|
|
457
457
|
const opencodeExists = fs.existsSync(opencodeConfigPath);
|
|
458
|
-
const
|
|
458
|
+
const configDirExists = fs.existsSync(strrayDir);
|
|
459
459
|
if (opencodeExists) {
|
|
460
460
|
console.log("✅ opencode configuration found");
|
|
461
461
|
}
|
|
462
|
-
else if (
|
|
462
|
+
else if (configDirExists) {
|
|
463
463
|
console.log(`✅ Configuration directory found: ${strrayDir}`);
|
|
464
464
|
}
|
|
465
465
|
else {
|
|
@@ -684,13 +684,13 @@ program
|
|
|
684
684
|
}
|
|
685
685
|
else {
|
|
686
686
|
console.log('Inference feature is disabled in features.json.');
|
|
687
|
-
console.log('Enable it by setting inference.enabled = true in .opencode/plugins/features.json (min compat .
|
|
687
|
+
console.log('Enable it by setting inference.enabled = true in .opencode/plugins/features.json (min compat .xray/ fallback for prior 0xRay consumer runtime per Scope Rule)');
|
|
688
688
|
}
|
|
689
689
|
return;
|
|
690
690
|
}
|
|
691
691
|
const projectRoot = process.cwd();
|
|
692
692
|
const inferenceDir = `${projectRoot}/docs/inference`;
|
|
693
|
-
const stateDir = `${projectRoot}/.
|
|
693
|
+
const stateDir = `${projectRoot}/.xray/inference`;
|
|
694
694
|
const stateFile = `${stateDir}/inference-cycle-state.json`;
|
|
695
695
|
if (!options.json) {
|
|
696
696
|
console.log('xray Inference Cycle');
|
package/dist/cli/server.js
CHANGED
|
@@ -15,7 +15,7 @@ const packageJsonPath = join(ROOT_DIR, "package.json");
|
|
|
15
15
|
const { version } = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
16
16
|
const app = express();
|
|
17
17
|
const PORT = 3000;
|
|
18
|
-
const API_KEY = process.env.
|
|
18
|
+
const API_KEY = process.env.XRAY_API_KEY || undefined;
|
|
19
19
|
function timingSafeCompare(a, b) {
|
|
20
20
|
const aBuf = Buffer.from(a, "utf-8");
|
|
21
21
|
const bBuf = Buffer.from(b, "utf-8");
|
|
@@ -26,13 +26,13 @@ function timingSafeCompare(a, b) {
|
|
|
26
26
|
function requireAuth(req, res, next) {
|
|
27
27
|
if (!API_KEY) {
|
|
28
28
|
frameworkLogger.log("cli-server", "auth-skipped", "warning", {
|
|
29
|
-
message: "No
|
|
29
|
+
message: "No XRAY_API_KEY set — API is unauthenticated. Set XRAY_API_KEY in production.",
|
|
30
30
|
});
|
|
31
31
|
return next();
|
|
32
32
|
}
|
|
33
33
|
const providedKey = req.headers["x-api-key"];
|
|
34
34
|
if (typeof providedKey !== "string") {
|
|
35
|
-
return res.status(401).json({ error: "API key required. Set
|
|
35
|
+
return res.status(401).json({ error: "API key required. Set XRAY_API_KEY environment variable." });
|
|
36
36
|
}
|
|
37
37
|
if (!timingSafeCompare(providedKey, API_KEY)) {
|
|
38
38
|
return res.status(403).json({ error: "Invalid API key" });
|
|
@@ -112,7 +112,7 @@ app.get("/", (req, res) => {
|
|
|
112
112
|
});
|
|
113
113
|
// Add route for refactoring logs
|
|
114
114
|
app.get("/logs", requireAuth, async (req, res) => {
|
|
115
|
-
const logPath = resolveConfigPath("REFACTORING_LOG.md") || join(__dirname, "..", ".
|
|
115
|
+
const logPath = resolveConfigPath("REFACTORING_LOG.md") || join(__dirname, "..", ".xray", "REFACTORING_LOG.md");
|
|
116
116
|
// Server debug logging - remove for production
|
|
117
117
|
try {
|
|
118
118
|
if (fs.existsSync(logPath)) {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Boot Orchestrator (min documented consumer runtime compat shim from prior
|
|
2
|
+
* Boot Orchestrator (min documented consumer runtime compat shim from prior 0xRay releases; primary Xray* paths + XRAY_||STRRAY_ env + .xray fallbacks only; 1-line per Scope Rule).
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { XrayContextLoader } from "./context-loader.js";
|
|
5
|
+
import { XrayStateManager } from "../state/state-manager.js";
|
|
6
6
|
import { ProcessorManager } from "../processors/processor-manager.js";
|
|
7
7
|
import { pathResolver } from "../utils/path-resolver.js";
|
|
8
8
|
import * as fs from "fs";
|
|
9
9
|
import * as path from "path";
|
|
10
10
|
const { existsSync, readFileSync } = fs;
|
|
11
11
|
// Path configuration - can be overridden by environment or use path resolver
|
|
12
|
-
const AGENTS_BASE_PATH = process.env.STRRAY_AGENTS_PATH || "../agents";
|
|
12
|
+
const AGENTS_BASE_PATH = process.env.XRAY_AGENTS_PATH || process.env.STRRAY_AGENTS_PATH || "../agents";
|
|
13
13
|
import { createAgentDelegator, createSessionCoordinator, } from "../delegation/index.js";
|
|
14
14
|
import { createSessionCleanupManager } from "../session/session-cleanup-manager.js";
|
|
15
15
|
import { createSessionMonitor } from "../session/session-monitor.js";
|
|
@@ -30,10 +30,10 @@ import { initializeGovernanceIntegration } from "../integrations/governance/inde
|
|
|
30
30
|
*/
|
|
31
31
|
function setupGracefulShutdown() {
|
|
32
32
|
// Prevent duplicate listeners
|
|
33
|
-
if (process.
|
|
33
|
+
if (process._xrayShutdownSetup) {
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
process.
|
|
36
|
+
process._xrayShutdownSetup = true;
|
|
37
37
|
let isShuttingDown = false;
|
|
38
38
|
process.on("SIGINT", async () => {
|
|
39
39
|
if (isShuttingDown) {
|
|
@@ -98,8 +98,8 @@ export class BootOrchestrator {
|
|
|
98
98
|
shutdownInitialized = false;
|
|
99
99
|
constructor(config = {}, stateManager) {
|
|
100
100
|
// Initialize components first for state management
|
|
101
|
-
this.contextLoader =
|
|
102
|
-
this.stateManager = stateManager || new
|
|
101
|
+
this.contextLoader = XrayContextLoader.getInstance();
|
|
102
|
+
this.stateManager = stateManager || new XrayStateManager();
|
|
103
103
|
this.processorManager = new ProcessorManager(this.stateManager);
|
|
104
104
|
this.config = {
|
|
105
105
|
enableEnforcement: true,
|
|
@@ -131,8 +131,8 @@ export class BootOrchestrator {
|
|
|
131
131
|
loadProcessorsConfig() {
|
|
132
132
|
try {
|
|
133
133
|
const configPaths = [
|
|
134
|
-
path.join(process.cwd(), ".
|
|
135
|
-
path.join(process.cwd(), ".opencode", "
|
|
134
|
+
path.join(process.cwd(), ".xray", "features.json"),
|
|
135
|
+
path.join(process.cwd(), ".opencode", "xray", "features.json"),
|
|
136
136
|
];
|
|
137
137
|
for (const configPath of configPaths) {
|
|
138
138
|
if (existsSync(configPath)) {
|
|
@@ -152,7 +152,7 @@ export class BootOrchestrator {
|
|
|
152
152
|
async initializePluginSystem(jobId) {
|
|
153
153
|
try {
|
|
154
154
|
frameworkLogger.log("boot-orchestrator", "initializing plugin system", "info", { jobId });
|
|
155
|
-
const pluginsDir = path.join(process.cwd(), ".
|
|
155
|
+
const pluginsDir = path.join(process.cwd(), ".xray", "plugins");
|
|
156
156
|
this.pluginRegistry = new PluginRegistry({
|
|
157
157
|
pluginsDir,
|
|
158
158
|
autoStart: true,
|
|
@@ -596,8 +596,8 @@ export class BootOrchestrator {
|
|
|
596
596
|
};
|
|
597
597
|
try {
|
|
598
598
|
frameworkLogger.log("boot-orchestrator", "loading xray configuration", "info", { jobId });
|
|
599
|
-
// Consumer runtime compat shim from prior
|
|
600
|
-
await this.
|
|
599
|
+
// Consumer runtime compat shim from prior 0xRay releases (1-line min per Scope Rule; primary xray paths + XRAY_||STRRAY_ env + .xray fallbacks)
|
|
600
|
+
await this.loadXrayConfiguration(jobId);
|
|
601
601
|
frameworkLogger.log("boot-orchestrator", "xray configuration loaded", "success", { jobId });
|
|
602
602
|
// Phase 1: Initialize core systems
|
|
603
603
|
frameworkLogger.log("boot-orchestrator", "initializing core systems", "info", { jobId });
|
|
@@ -727,11 +727,11 @@ export class BootOrchestrator {
|
|
|
727
727
|
this.stateManager.set("boot:errors", result.errors);
|
|
728
728
|
return result;
|
|
729
729
|
}
|
|
730
|
-
// Consumer runtime compat shim from prior
|
|
731
|
-
async
|
|
730
|
+
// Consumer runtime compat shim from prior 0xRay releases (1-line min per Scope Rule; primary xray paths + XRAY_||STRRAY_ env + .xray fallbacks)
|
|
731
|
+
async loadXrayConfiguration(jobId) {
|
|
732
732
|
try {
|
|
733
|
-
// Consumer runtime compat shim from prior
|
|
734
|
-
const
|
|
733
|
+
// Consumer runtime compat shim from prior 0xRay releases (1-line min per Scope Rule; primary xray paths + XRAY_||STRRAY_ env + .xray fallbacks)
|
|
734
|
+
const xrayConfig = {
|
|
735
735
|
version: "1.22.67",
|
|
736
736
|
codex_enabled: true,
|
|
737
737
|
codex_version: "v1.7.5",
|
|
@@ -793,13 +793,13 @@ export class BootOrchestrator {
|
|
|
793
793
|
},
|
|
794
794
|
};
|
|
795
795
|
// Store configuration in state manager for use by other components
|
|
796
|
-
this.stateManager.set("
|
|
797
|
-
this.stateManager.set("
|
|
798
|
-
this.stateManager.set("
|
|
799
|
-
this.stateManager.set("
|
|
800
|
-
this.stateManager.set("
|
|
801
|
-
this.stateManager.set("
|
|
802
|
-
this.stateManager.set("
|
|
796
|
+
this.stateManager.set("xray:config", xrayConfig);
|
|
797
|
+
this.stateManager.set("xray:version", xrayConfig.version);
|
|
798
|
+
this.stateManager.set("xray:codex_enabled", xrayConfig.codex_enabled);
|
|
799
|
+
this.stateManager.set("xray:codex_terms", xrayConfig.codex_terms);
|
|
800
|
+
this.stateManager.set("xray:monitoring_metrics", xrayConfig.monitoring_metrics);
|
|
801
|
+
this.stateManager.set("xray:monitoring_alerts", xrayConfig.monitoring_alerts);
|
|
802
|
+
this.stateManager.set("xray:agent_capabilities", xrayConfig.agent_capabilities);
|
|
803
803
|
await frameworkLogger.log("boot-orchestrator", "configuration-loaded", "success", { jobId });
|
|
804
804
|
}
|
|
805
805
|
catch (error) {
|
package/dist/core/bridge.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* 0xRay Universal Bridge
|
|
5
5
|
*
|
|
6
|
-
* Standalone bridge that provides
|
|
6
|
+
* Standalone bridge that provides 0xRay framework capabilities
|
|
7
7
|
* to ANY consumer — no OpenCode dependency.
|
|
8
8
|
*
|
|
9
9
|
* Supports three transport modes:
|
|
@@ -74,7 +74,7 @@ function findProjectRoot() {
|
|
|
74
74
|
|
|
75
75
|
const candidates = [
|
|
76
76
|
process.cwd(),
|
|
77
|
-
join(homedir(), "dev", "
|
|
77
|
+
join(homedir(), "dev", "xray"),
|
|
78
78
|
join(dirname(__dirname), "..", ".."), // core/ -> project root
|
|
79
79
|
join(dirname(__dirname), "..", "..", ".."), // integrations/ -> project root
|
|
80
80
|
];
|
|
@@ -84,7 +84,7 @@ function findProjectRoot() {
|
|
|
84
84
|
const pkgPath = join(dir, "package.json");
|
|
85
85
|
if (existsSync(pkgPath)) {
|
|
86
86
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
87
|
-
if (pkg.name === "
|
|
87
|
+
if (pkg.name === "0xray" || pkg.dependencies?.["0xray"]) {
|
|
88
88
|
return dir;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -222,8 +222,8 @@ function getCodexCandidates(projectRoot) {
|
|
|
222
222
|
const envDir = process.env.STRRAY_CONFIG_DIR;
|
|
223
223
|
const candidates = [];
|
|
224
224
|
if (envDir) candidates.push(join(projectRoot, envDir, "codex.json"));
|
|
225
|
-
candidates.push(join(projectRoot, ".
|
|
226
|
-
candidates.push(join(projectRoot, ".opencode", "
|
|
225
|
+
candidates.push(join(projectRoot, ".xray", "codex.json"));
|
|
226
|
+
candidates.push(join(projectRoot, ".opencode", "xray", "codex.json"));
|
|
227
227
|
candidates.push(join(projectRoot, "codex.json"));
|
|
228
228
|
return candidates;
|
|
229
229
|
}
|
|
@@ -281,7 +281,7 @@ async function handleGetCodexPrompt(input, projectRoot, logDir) {
|
|
|
281
281
|
terms.sort((a, b) => (severityOrder[a.severity] || 3) - (severityOrder[b.severity] || 3));
|
|
282
282
|
if (maxTerms) terms = terms.slice(0, maxTerms);
|
|
283
283
|
|
|
284
|
-
const lines = [`##
|
|
284
|
+
const lines = [`## 0xRay Universal Development Codex v${termsSource.version}`];
|
|
285
285
|
const emojis = { blocking: "🔴", high: "🟡", medium: "🟢" };
|
|
286
286
|
const labels = { blocking: "BLOCKING", high: "HIGH PRIORITY", medium: "MEDIUM" };
|
|
287
287
|
|
|
@@ -348,8 +348,8 @@ async function handleGetConfig(input, projectRoot, logDir) {
|
|
|
348
348
|
// Load features.json
|
|
349
349
|
const featurePaths = [];
|
|
350
350
|
if (envDir) featurePaths.push(join(projectRoot, envDir, "features.json"));
|
|
351
|
-
featurePaths.push(join(projectRoot, ".
|
|
352
|
-
featurePaths.push(join(projectRoot, ".opencode", "
|
|
351
|
+
featurePaths.push(join(projectRoot, ".xray", "features.json"));
|
|
352
|
+
featurePaths.push(join(projectRoot, ".opencode", "xray", "features.json"));
|
|
353
353
|
|
|
354
354
|
let featurePath = null;
|
|
355
355
|
for (const p of featurePaths) {
|
|
@@ -604,7 +604,7 @@ function handleHooks(input, projectRoot) {
|
|
|
604
604
|
const { action, hooks } = input;
|
|
605
605
|
const hookTypes = hooks || ["pre-commit", "post-commit", "pre-push", "post-push"];
|
|
606
606
|
const gitHooksDir = join(projectRoot, ".git", "hooks");
|
|
607
|
-
const
|
|
607
|
+
const xrayHooksDir = join(projectRoot, "hooks");
|
|
608
608
|
|
|
609
609
|
if (!existsSync(gitHooksDir)) {
|
|
610
610
|
return { error: "Not a git repository — no .git/hooks directory" };
|
|
@@ -616,14 +616,14 @@ function handleHooks(input, projectRoot) {
|
|
|
616
616
|
if (action === "list" || action === "status") {
|
|
617
617
|
for (const hookName of hookTypes) {
|
|
618
618
|
const gitHook = join(gitHooksDir, hookName);
|
|
619
|
-
const
|
|
619
|
+
const xrayHook = join(xrayHooksDir, hookName);
|
|
620
620
|
|
|
621
621
|
if (!existsSync(gitHook)) {
|
|
622
622
|
result.missing.push(hookName);
|
|
623
623
|
} else {
|
|
624
624
|
try {
|
|
625
625
|
const content = readFileSync(gitHook, "utf-8");
|
|
626
|
-
if (content.includes("
|
|
626
|
+
if (content.includes("0xRay") || content.includes("xray") || content.includes("run-hook.js")) {
|
|
627
627
|
result.managed.push(hookName);
|
|
628
628
|
} else {
|
|
629
629
|
result.external.push(hookName);
|
|
@@ -633,8 +633,8 @@ function handleHooks(input, projectRoot) {
|
|
|
633
633
|
}
|
|
634
634
|
}
|
|
635
635
|
|
|
636
|
-
// Check if
|
|
637
|
-
if (!existsSync(
|
|
636
|
+
// Check if xray source hook exists
|
|
637
|
+
if (!existsSync(xrayHook)) {
|
|
638
638
|
result.stale.push(hookName);
|
|
639
639
|
}
|
|
640
640
|
}
|
|
@@ -644,7 +644,7 @@ function handleHooks(input, projectRoot) {
|
|
|
644
644
|
action,
|
|
645
645
|
hooks: result,
|
|
646
646
|
gitHooksDir,
|
|
647
|
-
|
|
647
|
+
xrayHooksDir,
|
|
648
648
|
};
|
|
649
649
|
}
|
|
650
650
|
|
|
@@ -655,7 +655,7 @@ function handleHooks(input, projectRoot) {
|
|
|
655
655
|
const errors = [];
|
|
656
656
|
|
|
657
657
|
for (const hookName of hookTypes) {
|
|
658
|
-
const src = join(
|
|
658
|
+
const src = join(xrayHooksDir, hookName);
|
|
659
659
|
const dst = join(gitHooksDir, hookName);
|
|
660
660
|
|
|
661
661
|
if (!existsSync(src)) {
|
|
@@ -664,11 +664,11 @@ function handleHooks(input, projectRoot) {
|
|
|
664
664
|
}
|
|
665
665
|
|
|
666
666
|
try {
|
|
667
|
-
// Backup existing non-
|
|
667
|
+
// Backup existing non-xray hooks
|
|
668
668
|
if (existsSync(dst)) {
|
|
669
669
|
const content = readFileSync(dst, "utf-8");
|
|
670
|
-
if (!content.includes("
|
|
671
|
-
renameSync(dst, `${dst}.
|
|
670
|
+
if (!content.includes("0xRay") && !content.includes("xray") && !content.includes("run-hook.js")) {
|
|
671
|
+
renameSync(dst, `${dst}.xray-backup`);
|
|
672
672
|
} else {
|
|
673
673
|
unlinkSync(dst);
|
|
674
674
|
}
|
|
@@ -699,15 +699,15 @@ function handleHooks(input, projectRoot) {
|
|
|
699
699
|
|
|
700
700
|
for (const hookName of hookTypes) {
|
|
701
701
|
const dst = join(gitHooksDir, hookName);
|
|
702
|
-
const backup = `${dst}.
|
|
702
|
+
const backup = `${dst}.xray-backup`;
|
|
703
703
|
|
|
704
704
|
if (!existsSync(dst)) continue;
|
|
705
705
|
|
|
706
706
|
try {
|
|
707
707
|
const content = readFileSync(dst, "utf-8");
|
|
708
|
-
const
|
|
708
|
+
const isXray = content.includes("0xRay") || content.includes("xray") || content.includes("run-hook.js");
|
|
709
709
|
|
|
710
|
-
if (
|
|
710
|
+
if (isXray || lstatSync(dst).isSymbolicLink()) {
|
|
711
711
|
unlinkSync(dst);
|
|
712
712
|
|
|
713
713
|
// Restore backup if exists
|
|
@@ -89,8 +89,8 @@ export function findCodexPath(projectRoot) {
|
|
|
89
89
|
if (envDir) {
|
|
90
90
|
candidates.push(resolve(root, envDir, "codex.json"));
|
|
91
91
|
}
|
|
92
|
-
candidates.push(join(root, ".
|
|
93
|
-
candidates.push(join(root, ".opencode", "
|
|
92
|
+
candidates.push(join(root, ".xray", "codex.json"));
|
|
93
|
+
candidates.push(join(root, ".opencode", "xray", "codex.json"));
|
|
94
94
|
// Additional fallback locations (for standalone usage)
|
|
95
95
|
candidates.push(join(root, "codex.json"));
|
|
96
96
|
candidates.push(join(root, "src", "codex.json"));
|