0xray 3.5.5 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mcp.json +18 -14
- package/.opencode/skills/api-design/SKILL.md +1 -1
- package/.opencode/skills/architect-tools/SKILL.md +1 -1
- package/.opencode/skills/architecture-patterns/SKILL.md +1 -1
- package/.opencode/skills/auto-format/SKILL.md +1 -1
- package/.opencode/skills/boot-orchestrator/SKILL.md +2 -6
- package/.opencode/skills/bug-triage/SKILL.md +1 -1
- package/.opencode/skills/code-analyzer/SKILL.md +1 -1
- package/.opencode/skills/code-review/SKILL.md +1 -1
- package/.opencode/skills/enforcer/SKILL.md +1 -1
- package/.opencode/skills/framework-compliance-audit/SKILL.md +1 -1
- package/.opencode/skills/git-workflow/SKILL.md +1 -1
- package/.opencode/skills/hermes-agent/SKILL.md +36 -36
- package/.opencode/skills/inference-improve/SKILL.md +1 -1
- package/.opencode/skills/lint/SKILL.md +1 -1
- package/.opencode/skills/log-monitor/SKILL.md +1 -1
- package/.opencode/skills/model-health-check/SKILL.md +1 -1
- package/.opencode/skills/multimodal-looker/SKILL.md +1 -1
- package/.opencode/skills/orchestrator/SKILL.md +38 -14
- package/.opencode/skills/performance-analysis/SKILL.md +1 -1
- package/.opencode/skills/performance-optimization/SKILL.md +1 -1
- package/.opencode/skills/processor-pipeline/SKILL.md +1 -1
- package/.opencode/skills/project-analysis/SKILL.md +1 -1
- package/.opencode/skills/refactoring-strategies/SKILL.md +1 -1
- package/.opencode/skills/registry.json +65 -0
- package/.opencode/skills/researcher/SKILL.md +18 -5
- package/.opencode/skills/security-audit/SKILL.md +1 -1
- package/.opencode/skills/security-scan/SKILL.md +1 -1
- package/.opencode/skills/session-management/SKILL.md +1 -1
- package/.opencode/skills/state-manager/SKILL.md +1 -1
- package/.opencode/skills/storyteller/SKILL.md +1 -1
- package/.opencode/skills/strategist/SKILL.md +12 -0
- package/.opencode/skills/testing-best-practices/SKILL.md +37 -0
- package/.opencode/skills/testing-strategy/SKILL.md +14 -3
- package/.opencode/skills/ui-ux-design/SKILL.md +1 -1
- package/.opencode/skills/xray-orchestrator/index.ts +267 -0
- package/.xray/codex.json +12 -3
- package/.xray/features.json +28 -6
- package/.xray/features.schema.json +31 -0
- package/AGENTS-consumer.md +17 -7
- package/AGENTS.md +18 -10
- package/README.md +30 -27
- package/SKILLS.md +2 -2
- package/dist/AGENTS.md +18 -10
- package/dist/CHANGELOG.md +81 -11
- package/dist/README.md +30 -27
- package/dist/SKILLS.md +2 -2
- package/dist/cli/commands/hermes-install.js +3 -0
- package/dist/cli/commands/openclaw-install.js +14 -0
- package/dist/cli/index.js +10 -1
- package/dist/core/features-config.d.ts +15 -2
- package/dist/infrastructure/schemas/cloud-schemas.d.ts +1 -1
- package/dist/integrations/grok/grok-cli.d.ts +3 -0
- package/dist/integrations/grok/grok-cli.js +92 -4
- package/dist/integrations/grok/hooks/grok-hook-utils.js +53 -7
- package/dist/integrations/grok/hooks/post-tool-use.js +68 -46
- package/dist/integrations/grok/hooks/pre-tool-use.js +14 -31
- package/dist/integrations/grok/hooks/session-start.js +86 -4
- package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +31 -24
- package/dist/integrations/hermes-agent/bridge.mjs +26 -1
- package/dist/integrations/hooks/delegation-gate-runtime.mjs +32 -3
- package/dist/integrations/hooks/pipeline-hook-runtime.mjs +1 -1
- package/dist/integrations/hooks/station-hook-runtime.cjs +421 -0
- package/dist/integrations/hooks/station-hook-runtime.mjs +24 -0
- package/dist/integrations/hooks/station-memory-ingest.mjs +45 -0
- package/dist/integrations/hooks/station-memory-match.mjs +47 -0
- package/dist/integrations/openclaw/client.d.ts +5 -1
- package/dist/integrations/openclaw/client.js +17 -9
- package/dist/integrations/openclaw/config.js +0 -1
- package/dist/integrations/openclaw/hooks/pre-tool-gate-runtime.mjs +102 -0
- package/dist/integrations/openclaw/index.js +17 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/index.js +75 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/openclaw.plugin.json +10 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +12 -0
- package/dist/integrations/openclaw/pre-tool-gate.d.ts +19 -0
- package/dist/integrations/openclaw/pre-tool-gate.js +39 -0
- package/dist/mcps/orchestrator/handlers/complexity-handler.js +2 -2
- package/dist/memory-routing/index.d.ts +1 -1
- package/dist/memory-routing/index.js +1 -1
- package/dist/memory-routing/provider-loader.d.ts +4 -0
- package/dist/memory-routing/provider-loader.js +44 -2
- package/dist/memory-routing/provider-registry.js +3 -2
- package/dist/nucleus/autonomy-kernel.d.ts +2 -2
- package/dist/nucleus/autonomy-kernel.js +17 -6
- package/dist/nucleus/confer.js +17 -3
- package/dist/nucleus/delegation-gate.d.ts +14 -8
- package/dist/nucleus/delegation-gate.js +151 -16
- package/dist/nucleus/suit-temperament.d.ts +40 -0
- package/dist/nucleus/suit-temperament.js +157 -0
- package/dist/nucleus/user-aside.js +1 -1
- package/dist/plugin/xray-codex-injection.js +14 -3
- package/dist/postprocessor/triggers/GitHookTrigger.js +11 -5
- package/opencode.json +80 -0
- package/package.json +15 -5
- package/scripts/hooks/install-hooks.cjs +18 -3
- package/scripts/hooks/run-hook.js +67 -3
- package/scripts/mjs/run-repertoire-mcp.mjs +39 -0
- package/scripts/mjs/verify-confer-core.mjs +1 -1
- package/scripts/mjs/verify-delegation-gate-core.mjs +29 -2
- package/scripts/mjs/verify-four-floor-compact.mjs +524 -0
- package/scripts/mjs/verify-pipeline-facets.mjs +215 -0
- package/scripts/mjs/verify-temperament-live.mjs +261 -0
- package/scripts/node/bridge-mcp-wiring.cjs +277 -29
- package/scripts/node/consumer-install-smoke.mjs +55 -2
- package/scripts/node/install-bridges.cjs +195 -33
- package/scripts/node/postinstall.cjs +50 -27
- package/scripts/node/reconcile-version.mjs +0 -4
- package/scripts/node/release-gate.mjs +1 -1
- package/scripts/node/release.mjs +2 -2
- package/scripts/node/universal-version-manager.js +1 -1
- package/scripts/node/validate-release-docs.mjs +20 -33
- package/scripts/node/version-manager.mjs +63 -18
- package/src/integrations/grok/plugin/0xray/hooks/hooks.json +31 -24
- package/src/integrations/openclaw/README.md +134 -0
- package/src/integrations/openclaw/plugin/xray-pre-tool/index.js +75 -0
- package/src/integrations/openclaw/plugin/xray-pre-tool/openclaw.plugin.json +10 -0
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +12 -0
- package/src/mcps/orchestrator/handlers/complexity-handler.ts +2 -1
- package/vendor/@0xray/repertoire/AGENTS.md +163 -0
- package/vendor/@0xray/repertoire/LICENSE +21 -0
- package/vendor/@0xray/repertoire/README.md +120 -0
- package/vendor/@0xray/repertoire/data/curated_signals.json +208 -0
- package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts +78 -0
- package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/RepertoireService.js +153 -0
- package/vendor/@0xray/repertoire/dist/RepertoireService.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.d.ts +39 -0
- package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.js +60 -0
- package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/index.d.ts +14 -0
- package/vendor/@0xray/repertoire/dist/index.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/index.js +14 -0
- package/vendor/@0xray/repertoire/dist/index.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.d.ts +26 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.js +109 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.d.ts +18 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.js +94 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.d.ts +7 -0
- package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.js +18 -0
- package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.d.ts +31 -0
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js +83 -0
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/mcp/server.d.ts +6 -0
- package/vendor/@0xray/repertoire/dist/mcp/server.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/mcp/server.js +173 -0
- package/vendor/@0xray/repertoire/dist/mcp/server.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.d.ts +27 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.js +107 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.d.ts +11 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.js +32 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.d.ts +9 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js +72 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.d.ts +5 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.js +18 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.d.ts +31 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js +218 -0
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/paths.d.ts +24 -0
- package/vendor/@0xray/repertoire/dist/paths.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/paths.js +74 -0
- package/vendor/@0xray/repertoire/dist/paths.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.d.ts +141 -0
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js +210 -0
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts +48 -0
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js +221 -0
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.d.ts +11 -0
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.js +43 -0
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/registry/signal-prune.d.ts +15 -0
- package/vendor/@0xray/repertoire/dist/registry/signal-prune.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/registry/signal-prune.js +35 -0
- package/vendor/@0xray/repertoire/dist/registry/signal-prune.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.d.ts +3 -0
- package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.js +24 -0
- package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.d.ts +24 -0
- package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.js +148 -0
- package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.d.ts +4 -0
- package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.js +44 -0
- package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.d.ts +22 -0
- package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.js +66 -0
- package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/types.d.ts +210 -0
- package/vendor/@0xray/repertoire/dist/types.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/types.js +2 -0
- package/vendor/@0xray/repertoire/dist/types.js.map +1 -0
- package/vendor/@0xray/repertoire/docs/MEMORY-ROUTING-PROVIDER.md +54 -0
- package/vendor/@0xray/repertoire/hermes-mcp.example.json +20 -0
- package/vendor/@0xray/repertoire/mcp-config.example.json +11 -0
- package/vendor/@0xray/repertoire/package.json +124 -0
- package/vendor/@0xray/repertoire/schemas/curated-signal.schema.json +68 -0
- package/vendor/@0xray/repertoire/schemas/inference-log.schema.json +82 -0
- package/vendor/@0xray/repertoire/scripts/confirm-suit-all.mjs +253 -0
- package/vendor/@0xray/repertoire/scripts/confirm-suit-harness.mjs +220 -0
- package/vendor/@0xray/repertoire/scripts/run-live-synthesis-checkpoint.mjs +215 -0
- package/vendor/@0xray/repertoire/scripts/suit-bridge-shared.mjs +139 -0
- package/vendor/@0xray/repertoire/scripts/verify-grok-suit.mjs +304 -0
- package/vendor/@0xray/repertoire/scripts/verify-hermes-suit.mjs +163 -0
- package/vendor/@0xray/repertoire/scripts/verify-openclaw-suit.mjs +125 -0
- package/vendor/@0xray/repertoire/scripts/verify-opencode-suit.mjs +127 -0
- package/vendor/@0xray/repertoire/scripts/verify-synthesis-dogfood.mjs +207 -0
- package/vendor/@0xray/repertoire/skills/repertoire-trap-handling/SKILL.md +206 -0
- package/xray/codex.json +12 -3
- package/xray/features.json +28 -6
- package/xray/features.schema.json +31 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const os = require("os");
|
|
9
|
-
const { execSync } = require("child_process");
|
|
9
|
+
const { execFileSync, execSync } = require("child_process");
|
|
10
10
|
|
|
11
11
|
/** Canonical 7-server MCP surface */
|
|
12
12
|
const XRAY_MCP_SERVERS = [
|
|
@@ -24,31 +24,118 @@ const HERMES_PLUGIN_DIR = path.join(os.homedir(), ".hermes", "plugins", "xray-he
|
|
|
24
24
|
const OPENCLAW_CONFIG_PATH = path.join(os.homedir(), ".openclaw", "openclaw.json");
|
|
25
25
|
const OPENCLAW_STATE_DIR = path.join(os.homedir(), ".openclaw");
|
|
26
26
|
|
|
27
|
+
function isRepertoirePackageRoot(dir) {
|
|
28
|
+
try {
|
|
29
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
30
|
+
return pkg.name === "@0xray/repertoire" || pkg.name === "repertoire";
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function resolveRepertoireMcp(targetDir) {
|
|
37
|
+
const selfRoot = targetDir;
|
|
38
|
+
const siblingRoot = path.join(targetDir, "..", "repertoire");
|
|
39
|
+
const candidates = [
|
|
40
|
+
path.join(targetDir, "node_modules", "@0xray", "repertoire", "dist", "mcp", "server.js"),
|
|
41
|
+
path.join(targetDir, "vendor", "@0xray", "repertoire", "dist", "mcp", "server.js"),
|
|
42
|
+
isRepertoirePackageRoot(selfRoot) ? path.join(selfRoot, "dist", "mcp", "server.js") : null,
|
|
43
|
+
isRepertoirePackageRoot(siblingRoot) ? path.join(siblingRoot, "dist", "mcp", "server.js") : null,
|
|
44
|
+
];
|
|
45
|
+
return candidates.find((p) => p && fs.existsSync(p)) || null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function resolveRepertoireProvider(targetDir) {
|
|
49
|
+
const siblingRoot = path.join(targetDir, "..", "repertoire");
|
|
50
|
+
const siblingProvider = path.join(siblingRoot, "dist", "provider", "memory-routing-provider.js");
|
|
51
|
+
const nmProvider = path.join(
|
|
52
|
+
targetDir,
|
|
53
|
+
"node_modules",
|
|
54
|
+
"@0xray",
|
|
55
|
+
"repertoire",
|
|
56
|
+
"dist",
|
|
57
|
+
"provider",
|
|
58
|
+
"memory-routing-provider.js",
|
|
59
|
+
);
|
|
60
|
+
const vendorProvider = path.join(
|
|
61
|
+
targetDir,
|
|
62
|
+
"vendor",
|
|
63
|
+
"@0xray",
|
|
64
|
+
"repertoire",
|
|
65
|
+
"dist",
|
|
66
|
+
"provider",
|
|
67
|
+
"memory-routing-provider.js",
|
|
68
|
+
);
|
|
69
|
+
if (fs.existsSync(nmProvider)) return nmProvider;
|
|
70
|
+
if (fs.existsSync(vendorProvider)) return vendorProvider;
|
|
71
|
+
if (isRepertoirePackageRoot(siblingRoot) && fs.existsSync(siblingProvider)) return siblingProvider;
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function isDefaultMemoryRoutingOff(mr) {
|
|
76
|
+
if (!mr || typeof mr !== "object") return true;
|
|
77
|
+
if (mr.enabled === true) return false;
|
|
78
|
+
const provider = mr.provider == null || mr.provider === "" ? "null" : mr.provider;
|
|
79
|
+
return provider === "null";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function enableMemoryRoutingIfResolves(features, targetDir) {
|
|
83
|
+
const modulePath = resolveRepertoireProvider(targetDir);
|
|
84
|
+
if (!modulePath) return { features, changed: false };
|
|
85
|
+
const mr = (features && features.memory_routing) || {};
|
|
86
|
+
if (!isDefaultMemoryRoutingOff(mr)) return { features, changed: false };
|
|
87
|
+
|
|
88
|
+
const siblingRel = "../repertoire/dist/provider/memory-routing-provider.js";
|
|
89
|
+
const siblingAbs = path.join(targetDir, "..", "repertoire", "dist", "provider", "memory-routing-provider.js");
|
|
90
|
+
const useSibling = path.resolve(modulePath) === path.resolve(siblingAbs);
|
|
91
|
+
const repertoireRoot = path.resolve(modulePath, "..", "..", "..");
|
|
92
|
+
const signalsAbs = path.join(repertoireRoot, "data", "curated_signals.json");
|
|
93
|
+
const config = { ...(mr.config || {}) };
|
|
94
|
+
if (!config.signalsPath && fs.existsSync(signalsAbs)) {
|
|
95
|
+
config.signalsPath = useSibling ? "../repertoire/data/curated_signals.json" : signalsAbs;
|
|
96
|
+
}
|
|
97
|
+
if (!config.statePath) {
|
|
98
|
+
config.statePath = ".xray/state/repertoire/inference-state.json";
|
|
99
|
+
}
|
|
100
|
+
if (!config.feedbackDir) {
|
|
101
|
+
config.feedbackDir = ".xray/state/repertoire/feedback";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
features: {
|
|
106
|
+
...features,
|
|
107
|
+
memory_routing: {
|
|
108
|
+
...mr,
|
|
109
|
+
enabled: true,
|
|
110
|
+
provider: "repertoire",
|
|
111
|
+
module_path: useSibling ? siblingRel : modulePath,
|
|
112
|
+
config,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
changed: true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
27
119
|
function detectConsumerExtraMcpServers(targetDir) {
|
|
28
120
|
const extras = { hermes: {}, opencode: {}, openclaw: {} };
|
|
29
121
|
try {
|
|
30
|
-
const
|
|
31
|
-
if (!
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
command: "node",
|
|
48
|
-
args: [localRepertoireMcp],
|
|
49
|
-
env: { XRAY_ROOT: targetDir },
|
|
50
|
-
};
|
|
51
|
-
}
|
|
122
|
+
const repertoireMcp = resolveRepertoireMcp(targetDir);
|
|
123
|
+
if (!repertoireMcp) return extras;
|
|
124
|
+
extras.hermes.repertoire = {
|
|
125
|
+
command: "node",
|
|
126
|
+
args: [repertoireMcp],
|
|
127
|
+
env: { XRAY_ROOT: targetDir },
|
|
128
|
+
};
|
|
129
|
+
extras.opencode.repertoire = {
|
|
130
|
+
type: "local",
|
|
131
|
+
command: ["node", repertoireMcp],
|
|
132
|
+
enabled: true,
|
|
133
|
+
};
|
|
134
|
+
extras.openclaw.repertoire = {
|
|
135
|
+
command: "node",
|
|
136
|
+
args: [repertoireMcp],
|
|
137
|
+
env: { XRAY_ROOT: targetDir },
|
|
138
|
+
};
|
|
52
139
|
} catch {
|
|
53
140
|
// best-effort
|
|
54
141
|
}
|
|
@@ -130,13 +217,31 @@ function copyHermesFindProjectRootHelper(packageRoot, targetPluginDir) {
|
|
|
130
217
|
return true;
|
|
131
218
|
}
|
|
132
219
|
|
|
220
|
+
function isEphemeralInstallRoot(targetDir) {
|
|
221
|
+
const normalized = String(targetDir || "").replace(/\\/g, "/");
|
|
222
|
+
return /\/T\/|\/tmp\/|\/var\/folders\/|\/Temp\//i.test(normalized);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function copyHermesHookRuntimes(packageRoot) {
|
|
226
|
+
const hooksSrc = [
|
|
227
|
+
path.join(packageRoot, "dist", "integrations", "hooks"),
|
|
228
|
+
path.join(packageRoot, "src", "integrations", "hooks"),
|
|
229
|
+
].find((p) => fs.existsSync(p));
|
|
230
|
+
if (!hooksSrc) return false;
|
|
231
|
+
const hooksDst = path.join(os.homedir(), ".hermes", "plugins", "hooks");
|
|
232
|
+
fs.mkdirSync(hooksDst, { recursive: true });
|
|
233
|
+
fs.cpSync(hooksSrc, hooksDst, { recursive: true, force: true });
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
|
|
133
237
|
function writeHermesPluginArtifacts(targetDir) {
|
|
134
238
|
if (!fs.existsSync(HERMES_PLUGIN_DIR)) return false;
|
|
135
|
-
fs.writeFileSync(path.join(HERMES_PLUGIN_DIR, "xray-consumer-root.txt"), `${targetDir}\n`);
|
|
136
239
|
fs.writeFileSync(
|
|
137
240
|
path.join(HERMES_PLUGIN_DIR, ".mcp.json"),
|
|
138
241
|
`${JSON.stringify(buildPluginMcpJson(targetDir), null, 2)}\n`
|
|
139
242
|
);
|
|
243
|
+
if (isEphemeralInstallRoot(targetDir)) return true;
|
|
244
|
+
fs.writeFileSync(path.join(HERMES_PLUGIN_DIR, "xray-consumer-root.txt"), `${targetDir}\n`);
|
|
140
245
|
return true;
|
|
141
246
|
}
|
|
142
247
|
|
|
@@ -192,11 +297,13 @@ function deployPortableProjectMcpJson(targetDir) {
|
|
|
192
297
|
existing = { mcpServers: {} };
|
|
193
298
|
}
|
|
194
299
|
}
|
|
300
|
+
const extras = detectConsumerExtraMcpServers(targetDir);
|
|
195
301
|
const merged = {
|
|
196
302
|
...existing,
|
|
197
303
|
mcpServers: {
|
|
198
304
|
...(existing.mcpServers || {}),
|
|
199
305
|
...portable.mcpServers,
|
|
306
|
+
...(extras.openclaw || {}),
|
|
200
307
|
},
|
|
201
308
|
};
|
|
202
309
|
fs.writeFileSync(destPath, `${JSON.stringify(merged, null, 2)}\n`);
|
|
@@ -204,10 +311,20 @@ function deployPortableProjectMcpJson(targetDir) {
|
|
|
204
311
|
|
|
205
312
|
function enableHermesPluginBestEffort() {
|
|
206
313
|
try {
|
|
207
|
-
execSync("hermes plugins enable
|
|
314
|
+
execSync("hermes plugins enable xray-hermes", { stdio: "pipe", encoding: "utf8" });
|
|
315
|
+
try {
|
|
316
|
+
execSync("hermes plugins disable 0xray-hermes", { stdio: "pipe", encoding: "utf8" });
|
|
317
|
+
} catch {
|
|
318
|
+
/* stale id may be absent */
|
|
319
|
+
}
|
|
208
320
|
return true;
|
|
209
321
|
} catch {
|
|
210
|
-
|
|
322
|
+
try {
|
|
323
|
+
execSync("hermes plugins enable 0xray-hermes", { stdio: "pipe", encoding: "utf8" });
|
|
324
|
+
return true;
|
|
325
|
+
} catch {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
211
328
|
}
|
|
212
329
|
}
|
|
213
330
|
|
|
@@ -269,10 +386,12 @@ function syncOpenClawMcpRegistry(targetDir) {
|
|
|
269
386
|
}
|
|
270
387
|
|
|
271
388
|
function writeOpenClawConsumerArtifacts(targetDir) {
|
|
272
|
-
if (!
|
|
273
|
-
fs.
|
|
389
|
+
if (!isEphemeralInstallRoot(targetDir)) {
|
|
390
|
+
if (!fs.existsSync(OPENCLAW_STATE_DIR)) {
|
|
391
|
+
fs.mkdirSync(OPENCLAW_STATE_DIR, { recursive: true });
|
|
392
|
+
}
|
|
393
|
+
fs.writeFileSync(path.join(OPENCLAW_STATE_DIR, "xray-consumer-root.txt"), `${targetDir}\n`);
|
|
274
394
|
}
|
|
275
|
-
fs.writeFileSync(path.join(OPENCLAW_STATE_DIR, "xray-consumer-root.txt"), `${targetDir}\n`);
|
|
276
395
|
|
|
277
396
|
const consumerConfigPath = path.join(targetDir, ".xray", "config", "openclaw.json");
|
|
278
397
|
if (fs.existsSync(consumerConfigPath)) {
|
|
@@ -287,6 +406,124 @@ function writeOpenClawConsumerArtifacts(targetDir) {
|
|
|
287
406
|
return true;
|
|
288
407
|
}
|
|
289
408
|
|
|
409
|
+
function resolveOpenClawPreToolHookSource(packageRoot) {
|
|
410
|
+
return [
|
|
411
|
+
path.join(packageRoot, "dist", "integrations", "openclaw", "hooks", "pre-tool-gate-runtime.mjs"),
|
|
412
|
+
path.join(packageRoot, "src", "integrations", "openclaw", "hooks", "pre-tool-gate-runtime.mjs"),
|
|
413
|
+
].find((p) => fs.existsSync(p)) || null;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function resolveOpenClawPluginDir(packageRoot) {
|
|
417
|
+
return [
|
|
418
|
+
path.join(packageRoot, "dist", "integrations", "openclaw", "plugin", "xray-pre-tool"),
|
|
419
|
+
path.join(packageRoot, "src", "integrations", "openclaw", "plugin", "xray-pre-tool"),
|
|
420
|
+
].find((p) => fs.existsSync(path.join(p, "index.js"))) || null;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function installOpenClawHostWear(packageRoot) {
|
|
424
|
+
const source = resolveOpenClawPreToolHookSource(packageRoot);
|
|
425
|
+
if (!source) return null;
|
|
426
|
+
|
|
427
|
+
const hookDir = path.join(os.homedir(), ".openclaw", "hooks");
|
|
428
|
+
fs.mkdirSync(hookDir, { recursive: true });
|
|
429
|
+
const dest = path.join(hookDir, "xray-pre-tool.mjs");
|
|
430
|
+
fs.copyFileSync(source, dest);
|
|
431
|
+
fs.writeFileSync(
|
|
432
|
+
path.join(hookDir, "xray-pre-tool.json"),
|
|
433
|
+
`${JSON.stringify(
|
|
434
|
+
{
|
|
435
|
+
name: "xray-pre-tool",
|
|
436
|
+
command: "node",
|
|
437
|
+
args: [dest],
|
|
438
|
+
stdin: "json",
|
|
439
|
+
blockExitCode: 2,
|
|
440
|
+
env: { XRAY_AI_PATH: packageRoot },
|
|
441
|
+
},
|
|
442
|
+
null,
|
|
443
|
+
2,
|
|
444
|
+
)}\n`,
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
const pluginSrc = resolveOpenClawPluginDir(packageRoot);
|
|
448
|
+
if (pluginSrc) {
|
|
449
|
+
try {
|
|
450
|
+
execFileSync("openclaw", ["plugins", "install", "-l", pluginSrc], {
|
|
451
|
+
stdio: "pipe",
|
|
452
|
+
encoding: "utf8",
|
|
453
|
+
timeout: 60000,
|
|
454
|
+
});
|
|
455
|
+
} catch {
|
|
456
|
+
/* link is best-effort — stdin runtime is still installed */
|
|
457
|
+
}
|
|
458
|
+
try {
|
|
459
|
+
execFileSync("openclaw", ["config", "set", "plugins.entries.xray-pre-tool.enabled", "true"], {
|
|
460
|
+
stdio: "pipe",
|
|
461
|
+
encoding: "utf8",
|
|
462
|
+
timeout: 20000,
|
|
463
|
+
});
|
|
464
|
+
} catch {
|
|
465
|
+
/* enable is best-effort */
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return dest;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function resolveOpencodeBin() {
|
|
472
|
+
try {
|
|
473
|
+
const found = execSync("command -v opencode", { encoding: "utf8" }).trim();
|
|
474
|
+
return found || null;
|
|
475
|
+
} catch {
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function maybeWriteOpenClawCliBackend() {
|
|
481
|
+
const bin = resolveOpencodeBin();
|
|
482
|
+
if (!bin) return false;
|
|
483
|
+
const configPath = resolveOpenClawConfigPath();
|
|
484
|
+
if (!fs.existsSync(configPath)) return false;
|
|
485
|
+
let config;
|
|
486
|
+
try {
|
|
487
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
488
|
+
} catch {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
if (!config.agents || typeof config.agents !== "object") config.agents = {};
|
|
492
|
+
if (!config.agents.defaults || typeof config.agents.defaults !== "object") {
|
|
493
|
+
config.agents.defaults = {};
|
|
494
|
+
}
|
|
495
|
+
const defaults = config.agents.defaults;
|
|
496
|
+
if (!defaults.cliBackends || typeof defaults.cliBackends !== "object") {
|
|
497
|
+
defaults.cliBackends = {};
|
|
498
|
+
}
|
|
499
|
+
defaults.cliBackends["opencode-cli"] = {
|
|
500
|
+
command: bin,
|
|
501
|
+
args: ["run", "--pure"],
|
|
502
|
+
output: "text",
|
|
503
|
+
input: "arg",
|
|
504
|
+
modelArg: "--model",
|
|
505
|
+
modelAliases: { "big-pickle": "opencode/big-pickle" },
|
|
506
|
+
sessionMode: "none",
|
|
507
|
+
};
|
|
508
|
+
if (!defaults.models || typeof defaults.models !== "object") defaults.models = {};
|
|
509
|
+
defaults.models["opencode-cli/big-pickle"] = {};
|
|
510
|
+
const model = defaults.model && typeof defaults.model === "object" ? defaults.model : {};
|
|
511
|
+
const primary = model.primary;
|
|
512
|
+
if (!primary || primary === "opencode/big-pickle") {
|
|
513
|
+
const fallbacks = Array.isArray(model.fallbacks) ? model.fallbacks.slice() : [];
|
|
514
|
+
if (primary === "opencode/big-pickle" && !fallbacks.includes("opencode/big-pickle")) {
|
|
515
|
+
fallbacks.unshift("opencode/big-pickle");
|
|
516
|
+
}
|
|
517
|
+
defaults.model = {
|
|
518
|
+
...model,
|
|
519
|
+
primary: "opencode-cli/big-pickle",
|
|
520
|
+
fallbacks,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
526
|
+
|
|
290
527
|
function wireOpenClawBridge(targetDir) {
|
|
291
528
|
writeOpenClawConsumerArtifacts(targetDir);
|
|
292
529
|
return syncOpenClawMcpRegistry(targetDir);
|
|
@@ -317,4 +554,15 @@ module.exports = {
|
|
|
317
554
|
writeOpenClawConsumerArtifacts,
|
|
318
555
|
resolveOpenClawConfigPath,
|
|
319
556
|
detectConsumerExtraMcpServers,
|
|
557
|
+
isRepertoirePackageRoot,
|
|
558
|
+
resolveRepertoireMcp,
|
|
559
|
+
resolveRepertoireProvider,
|
|
560
|
+
isDefaultMemoryRoutingOff,
|
|
561
|
+
enableMemoryRoutingIfResolves,
|
|
562
|
+
isEphemeralInstallRoot,
|
|
563
|
+
copyHermesHookRuntimes,
|
|
564
|
+
resolveOpenClawPreToolHookSource,
|
|
565
|
+
resolveOpenClawPluginDir,
|
|
566
|
+
installOpenClawHostWear,
|
|
567
|
+
maybeWriteOpenClawCliBackend,
|
|
320
568
|
};
|
|
@@ -48,9 +48,14 @@ function assertFreshInstallDefaults(tmpRoot, version) {
|
|
|
48
48
|
if (!features.memory_routing) {
|
|
49
49
|
throw new Error("Deployed features.json missing memory_routing block");
|
|
50
50
|
}
|
|
51
|
-
if (features.memory_routing.enabled !==
|
|
51
|
+
if (features.memory_routing.enabled !== true) {
|
|
52
52
|
throw new Error(
|
|
53
|
-
`Fresh install must
|
|
53
|
+
`Fresh 4.0 install must ship memory_routing.enabled=true with the vendored organ (got ${features.memory_routing.enabled})`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
if (features.memory_routing.provider !== "repertoire") {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`Fresh install memory_routing.provider must be repertoire (got ${features.memory_routing.provider})`,
|
|
54
59
|
);
|
|
55
60
|
}
|
|
56
61
|
if (!features.inference_governance) {
|
|
@@ -59,6 +64,33 @@ function assertFreshInstallDefaults(tmpRoot, version) {
|
|
|
59
64
|
if (features.inference_governance.enabled !== false) {
|
|
60
65
|
throw new Error("Fresh install must default inference_governance.enabled=false");
|
|
61
66
|
}
|
|
67
|
+
const organHoisted = path.join(tmpRoot, "node_modules", "@0xray", "repertoire", "package.json");
|
|
68
|
+
const organNested = path.join(
|
|
69
|
+
tmpRoot,
|
|
70
|
+
"node_modules",
|
|
71
|
+
"0xray",
|
|
72
|
+
"node_modules",
|
|
73
|
+
"@0xray",
|
|
74
|
+
"repertoire",
|
|
75
|
+
"package.json",
|
|
76
|
+
);
|
|
77
|
+
const organVendor = path.join(
|
|
78
|
+
tmpRoot,
|
|
79
|
+
"node_modules",
|
|
80
|
+
"0xray",
|
|
81
|
+
"vendor",
|
|
82
|
+
"@0xray",
|
|
83
|
+
"repertoire",
|
|
84
|
+
"package.json",
|
|
85
|
+
);
|
|
86
|
+
const organPkg = [organNested, organHoisted, organVendor].find((p) => fs.existsSync(p));
|
|
87
|
+
if (!organPkg) {
|
|
88
|
+
throw new Error("vendored @0xray/repertoire missing from fresh tarball install");
|
|
89
|
+
}
|
|
90
|
+
const organ = JSON.parse(fs.readFileSync(organPkg, "utf-8"));
|
|
91
|
+
if (organ.version !== "0.2.0") {
|
|
92
|
+
throw new Error(`expected organ 0.2.0, got ${organ.version}`);
|
|
93
|
+
}
|
|
62
94
|
console.log(" ✅ .xray/features.json fresh-install defaults (opt-in off)");
|
|
63
95
|
return { consumerFeaturesPath, features };
|
|
64
96
|
}
|
|
@@ -114,6 +146,27 @@ function runUpgradeMergeSmoke(tmpRoot, nmRoot, version) {
|
|
|
114
146
|
if (shippedMarker && !merged[shippedMarker]) {
|
|
115
147
|
throw new Error(`Upgrade merge missing shipped template key: ${shippedMarker}`);
|
|
116
148
|
}
|
|
149
|
+
fs.writeFileSync(
|
|
150
|
+
consumerFeaturesPath,
|
|
151
|
+
`${JSON.stringify(
|
|
152
|
+
{
|
|
153
|
+
version: "3.5.5",
|
|
154
|
+
memory_routing: { enabled: false, provider: "repertoire" },
|
|
155
|
+
},
|
|
156
|
+
null,
|
|
157
|
+
2,
|
|
158
|
+
)}\n`,
|
|
159
|
+
);
|
|
160
|
+
deployXrayConfig(tmpRoot, nmRoot, () => {});
|
|
161
|
+
const optedOut = JSON.parse(fs.readFileSync(consumerFeaturesPath, "utf-8"));
|
|
162
|
+
if (optedOut.memory_routing?.enabled !== false) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Upgrade merge must keep explicit memory_routing opt-out (got ${optedOut.memory_routing?.enabled})`,
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
if (optedOut.memory_routing?.provider !== "repertoire") {
|
|
168
|
+
throw new Error("Upgrade merge dropped memory_routing.provider on opt-out");
|
|
169
|
+
}
|
|
117
170
|
|
|
118
171
|
console.log(" ✅ upgrade merge preserves opt-ins + bumps features.version");
|
|
119
172
|
}
|