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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Compact ingest — persist matched signals back into the organ (project-local copy).
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
|
|
8
|
+
const root = process.argv[2];
|
|
9
|
+
const sessionId = process.argv[3] || 'station';
|
|
10
|
+
const hookEvent = process.argv[4] || 'post_compact';
|
|
11
|
+
let signals = [];
|
|
12
|
+
try {
|
|
13
|
+
signals = JSON.parse(process.argv[5] || '[]');
|
|
14
|
+
} catch {
|
|
15
|
+
signals = [];
|
|
16
|
+
}
|
|
17
|
+
if (!root || !Array.isArray(signals) || signals.length === 0) {
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let routing = { enabled: false, provider: 'null' };
|
|
22
|
+
const featuresPath = join(root, '.xray', 'features.json');
|
|
23
|
+
if (existsSync(featuresPath)) {
|
|
24
|
+
try {
|
|
25
|
+
routing = JSON.parse(readFileSync(featuresPath, 'utf8')).memory_routing || routing;
|
|
26
|
+
} catch {
|
|
27
|
+
/* leftover */
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const { loadMemoryRoutingProvider } = await import('../../memory-routing/index.js');
|
|
32
|
+
const provider = await loadMemoryRoutingProvider(routing, root);
|
|
33
|
+
if (!provider || typeof provider.ingestFeedback !== 'function') process.exit(0);
|
|
34
|
+
|
|
35
|
+
provider.ingestFeedback({
|
|
36
|
+
timestamp: new Date().toISOString(),
|
|
37
|
+
sessionId,
|
|
38
|
+
taskId: `station-${hookEvent}`,
|
|
39
|
+
assignedAgent: 'station',
|
|
40
|
+
memorySignals: signals,
|
|
41
|
+
complexity: 0,
|
|
42
|
+
success: true,
|
|
43
|
+
durationMs: 0,
|
|
44
|
+
});
|
|
45
|
+
process.exit(0);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Sync helper for station-hook-runtime.cjs — match Repertoire signals for an intent.
|
|
4
|
+
* Prints a JSON string array. Used on every floor's station heat, not only Grok.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
|
|
9
|
+
const root = process.argv[2];
|
|
10
|
+
const intent = process.argv[3] || '';
|
|
11
|
+
if (!root || !intent) {
|
|
12
|
+
process.stdout.write('[]\n');
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let routing = { enabled: false, provider: 'null' };
|
|
17
|
+
const featuresPath = join(root, '.xray', 'features.json');
|
|
18
|
+
if (existsSync(featuresPath)) {
|
|
19
|
+
try {
|
|
20
|
+
routing = JSON.parse(readFileSync(featuresPath, 'utf8')).memory_routing || routing;
|
|
21
|
+
} catch {
|
|
22
|
+
/* leftover */
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { loadMemoryRoutingProvider } = await import('../../memory-routing/index.js');
|
|
27
|
+
const provider = await loadMemoryRoutingProvider(routing, root);
|
|
28
|
+
if (!provider || provider.id === 'null' || typeof provider.getTaskConfidence !== 'function') {
|
|
29
|
+
process.stdout.write('[]\n');
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const conf = provider.getTaskConfidence({
|
|
34
|
+
id: 'station',
|
|
35
|
+
description: String(intent),
|
|
36
|
+
type: 'station',
|
|
37
|
+
});
|
|
38
|
+
const names = Array.isArray(conf.matchedSignals) ? conf.matchedSignals : [];
|
|
39
|
+
const safe = [];
|
|
40
|
+
for (const signalName of names) {
|
|
41
|
+
const name = String(signalName || '').trim();
|
|
42
|
+
if (!name || name.toLowerCase().startsWith('bedrock-')) continue;
|
|
43
|
+
safe.push(name);
|
|
44
|
+
if (safe.length >= 4) break;
|
|
45
|
+
}
|
|
46
|
+
process.stdout.write(`${JSON.stringify(safe)}\n`);
|
|
47
|
+
process.exit(0);
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenClaw WebSocket Client
|
|
3
3
|
*
|
|
4
|
-
* Implements OpenClaw Gateway Protocol v3 with proper request/response handling,
|
|
4
|
+
* Implements OpenClaw Gateway Protocol v3–v4 with proper request/response handling,
|
|
5
5
|
* reconnection logic, and event management.
|
|
6
6
|
*
|
|
7
7
|
* @since 2026-03-14
|
|
8
8
|
*/
|
|
9
9
|
import { OpenClawClientConfig, OpenClawClientState, ClientStatistics } from './types.js';
|
|
10
|
+
export declare function isUsableOpenClawDeviceIdentity(deviceId: string | undefined, keyPair: {
|
|
11
|
+
publicKey?: string;
|
|
12
|
+
privateKey?: string;
|
|
13
|
+
} | undefined): boolean;
|
|
10
14
|
/**
|
|
11
15
|
* OpenClaw WebSocket Client
|
|
12
16
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenClaw WebSocket Client
|
|
3
3
|
*
|
|
4
|
-
* Implements OpenClaw Gateway Protocol v3 with proper request/response handling,
|
|
4
|
+
* Implements OpenClaw Gateway Protocol v3–v4 with proper request/response handling,
|
|
5
5
|
* reconnection logic, and event management.
|
|
6
6
|
*
|
|
7
7
|
* @since 2026-03-14
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
import { WebSocket } from 'ws';
|
|
10
10
|
import * as crypto from 'crypto';
|
|
11
11
|
import { isOpenClawResponse, isOpenClawEvent, OpenClawTimeoutError, OpenClawConnectionError, } from './types.js';
|
|
12
|
+
export function isUsableOpenClawDeviceIdentity(deviceId, keyPair) {
|
|
13
|
+
if (!deviceId || deviceId === 'your-device-id') {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return Boolean(keyPair?.publicKey && keyPair?.privateKey);
|
|
17
|
+
}
|
|
12
18
|
/**
|
|
13
19
|
* OpenClaw WebSocket Client
|
|
14
20
|
*/
|
|
@@ -249,9 +255,9 @@ export class OpenClawClient {
|
|
|
249
255
|
sendHandshake() {
|
|
250
256
|
const params = {
|
|
251
257
|
minProtocol: 3,
|
|
252
|
-
maxProtocol:
|
|
258
|
+
maxProtocol: 4,
|
|
253
259
|
client: {
|
|
254
|
-
id: '
|
|
260
|
+
id: 'gateway-client',
|
|
255
261
|
version: '1.0.0',
|
|
256
262
|
platform: process.platform,
|
|
257
263
|
mode: 'cli',
|
|
@@ -260,18 +266,20 @@ export class OpenClawClient {
|
|
|
260
266
|
scopes: ['operator.read', 'operator.write', 'operator.admin'],
|
|
261
267
|
caps: [],
|
|
262
268
|
commands: [],
|
|
263
|
-
userAgent: `OpenClaw-TUI/2026.
|
|
269
|
+
userAgent: `OpenClaw-TUI/2026.7.1`,
|
|
264
270
|
};
|
|
265
271
|
// Add auth if provided
|
|
266
272
|
if (this.config.authToken) {
|
|
267
273
|
params.auth = { token: this.config.authToken };
|
|
268
274
|
}
|
|
269
|
-
//
|
|
270
|
-
|
|
275
|
+
// Never send a placeholder device — gateway treats stub identity as NOT_PAIRED.
|
|
276
|
+
const deviceId = this.config.deviceId;
|
|
277
|
+
const keyPair = this.config.deviceKeyPair;
|
|
278
|
+
if (isUsableOpenClawDeviceIdentity(deviceId, keyPair) && deviceId && keyPair) {
|
|
271
279
|
params.device = {
|
|
272
|
-
id:
|
|
273
|
-
publicKey:
|
|
274
|
-
signature: this.signDeviceChallenge(
|
|
280
|
+
id: deviceId,
|
|
281
|
+
publicKey: keyPair.publicKey,
|
|
282
|
+
signature: this.signDeviceChallenge(deviceId),
|
|
275
283
|
signedAt: Date.now(),
|
|
276
284
|
nonce: this.generateNonce(),
|
|
277
285
|
};
|
|
@@ -308,7 +308,6 @@ export class OpenClawConfigLoader {
|
|
|
308
308
|
// SECURITY WARNING: authToken MUST be configured before use.
|
|
309
309
|
// Leaving this empty will prevent authenticated connections.
|
|
310
310
|
authToken: process.env.OPENCLAW_AUTH_TOKEN || '',
|
|
311
|
-
deviceId: process.env.OPENCLAW_DEVICE_ID || 'your-device-id',
|
|
312
311
|
autoReconnect: true,
|
|
313
312
|
maxReconnectAttempts: 5,
|
|
314
313
|
reconnectDelay: 1000,
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw host PreToolUse runtime — stdin JSON → stdout { action: block|allow }.
|
|
4
|
+
* Installed to ~/.openclaw/hooks/xray-pre-tool.mjs by `0xray openclaw install`.
|
|
5
|
+
*/
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import { stdin } from 'node:process';
|
|
11
|
+
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
|
|
15
|
+
function resolveGate() {
|
|
16
|
+
const envRoot = process.env.XRAY_AI_PATH || process.env.XRAY_ROOT || '';
|
|
17
|
+
const candidates = [
|
|
18
|
+
envRoot ? join(envRoot, 'dist/nucleus/delegation-gate.js') : '',
|
|
19
|
+
join(__dirname, '../../../nucleus/delegation-gate.js'),
|
|
20
|
+
join(__dirname, '../../../../dist/nucleus/delegation-gate.js'),
|
|
21
|
+
join(process.cwd(), 'node_modules/0xray/dist/nucleus/delegation-gate.js'),
|
|
22
|
+
join(process.cwd(), 'dist/nucleus/delegation-gate.js'),
|
|
23
|
+
].filter(Boolean);
|
|
24
|
+
const found = candidates.find((p) => existsSync(p));
|
|
25
|
+
if (!found) {
|
|
26
|
+
throw new Error('delegation-gate.js missing — build 0xray or npm install 0xray');
|
|
27
|
+
}
|
|
28
|
+
return require(found);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readStdin() {
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
const chunks = [];
|
|
34
|
+
stdin.setEncoding('utf8');
|
|
35
|
+
stdin.on('data', (c) => chunks.push(c));
|
|
36
|
+
stdin.on('end', () => {
|
|
37
|
+
const raw = chunks.join('').trim();
|
|
38
|
+
if (!raw) {
|
|
39
|
+
resolve({});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
resolve(JSON.parse(raw));
|
|
44
|
+
} catch (err) {
|
|
45
|
+
reject(err);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
stdin.on('error', reject);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function decide(event, gate) {
|
|
53
|
+
const projectRoot =
|
|
54
|
+
event.cwd || event.workspaceRoot || event.projectRoot || process.cwd();
|
|
55
|
+
const sessionId = event.sessionId || event.session_id || 'openclaw';
|
|
56
|
+
const toolName = event.tool || event.toolName || event.name || 'unknown';
|
|
57
|
+
const args = event.args || event.toolInput || event.input || {};
|
|
58
|
+
const features = gate.loadDelegationGateFeatures(projectRoot, 'openclaw');
|
|
59
|
+
const outcome = gate.evaluatePreToolGate(toolName, args, {
|
|
60
|
+
projectRoot,
|
|
61
|
+
sessionId,
|
|
62
|
+
features,
|
|
63
|
+
host: 'openclaw',
|
|
64
|
+
});
|
|
65
|
+
if (!outcome.allow) {
|
|
66
|
+
return {
|
|
67
|
+
action: 'block',
|
|
68
|
+
allow: false,
|
|
69
|
+
reason: outcome.reason,
|
|
70
|
+
gate: outcome.gate,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
action: 'allow',
|
|
75
|
+
allow: true,
|
|
76
|
+
reason: outcome.reason,
|
|
77
|
+
gate: outcome.gate,
|
|
78
|
+
warn: Boolean(outcome.reason),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function main() {
|
|
83
|
+
try {
|
|
84
|
+
const event = await readStdin();
|
|
85
|
+
const gate = resolveGate();
|
|
86
|
+
const decision = decide(event, gate);
|
|
87
|
+
console.log(JSON.stringify(decision));
|
|
88
|
+
process.exit(decision.action === 'block' ? 2 : 0);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
console.log(
|
|
91
|
+
JSON.stringify({
|
|
92
|
+
action: 'block',
|
|
93
|
+
allow: false,
|
|
94
|
+
gate: 'openclaw-pre-tool-error',
|
|
95
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
98
|
+
process.exit(2);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
main();
|
|
@@ -11,7 +11,9 @@ import { OpenClawClient } from './client.js';
|
|
|
11
11
|
import { XrayAPIServer } from './api-server.js';
|
|
12
12
|
import { initializeGovernanceIntegration } from '../governance/index.js';
|
|
13
13
|
import { featuresConfigLoader } from '../../core/features-config.js';
|
|
14
|
+
import { writeSuitSessionBoot } from '../../nucleus/suit-temperament.js';
|
|
14
15
|
import { OpenClawHooksManager } from './hooks/xray-hooks.js';
|
|
16
|
+
import { evaluateOpenClawHostPreTool } from './pre-tool-gate.js';
|
|
15
17
|
import { mcpClientManager } from '../../mcps/mcp-client.js';
|
|
16
18
|
/**
|
|
17
19
|
* Main OpenClaw Integration class
|
|
@@ -52,6 +54,12 @@ export class OpenClawIntegration extends BaseIntegration {
|
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
54
56
|
await this.log('info', 'Initializing...');
|
|
57
|
+
try {
|
|
58
|
+
writeSuitSessionBoot(process.cwd(), 'openclaw', { source: '0xray/openclaw-init' });
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
await this.log('warning', 'Failed to write suit session-boot');
|
|
62
|
+
}
|
|
55
63
|
// Initialize API server if enabled
|
|
56
64
|
if (config.apiServer?.enabled) {
|
|
57
65
|
await this.log('info', 'Starting API server...');
|
|
@@ -123,6 +131,14 @@ export class OpenClawIntegration extends BaseIntegration {
|
|
|
123
131
|
this.mcpToolBeforeUnsubscribe = await mcpClientManager.onToolEvent('tool.before', async (event) => {
|
|
124
132
|
const toolEvent = event;
|
|
125
133
|
try {
|
|
134
|
+
const gate = evaluateOpenClawHostPreTool(toolEvent.toolName, (toolEvent.args ?? {}), {
|
|
135
|
+
projectRoot: process.cwd(),
|
|
136
|
+
sessionId: String(toolEvent.sessionId ?? 'openclaw'),
|
|
137
|
+
});
|
|
138
|
+
if (!gate.allow) {
|
|
139
|
+
await this.log('error', `OpenClaw PreToolUse blocked ${toolEvent.toolName}: ${gate.reason}`);
|
|
140
|
+
throw new Error(`xray-openclaw-pre-tool:${gate.gate}:${gate.reason}`);
|
|
141
|
+
}
|
|
126
142
|
await this.hooksManager.onToolBefore({
|
|
127
143
|
toolName: toolEvent.toolName,
|
|
128
144
|
toolId: `${toolEvent.serverName}:${toolEvent.toolName}`,
|
|
@@ -134,6 +150,7 @@ export class OpenClawIntegration extends BaseIntegration {
|
|
|
134
150
|
}
|
|
135
151
|
catch (error) {
|
|
136
152
|
await this.log('error', `Error in tool.before handler: ${error}`);
|
|
153
|
+
throw error;
|
|
137
154
|
}
|
|
138
155
|
});
|
|
139
156
|
// Subscribe to tool.after events and store unsubscribe function
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { definePluginEntry } from 'openclaw/plugin-sdk/plugin-entry';
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const pluginDir = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
function hasGate(root) {
|
|
12
|
+
return Boolean(root) && existsSync(join(root, 'dist/nucleus/delegation-gate.js'));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function resolveXrayRoot() {
|
|
16
|
+
if (hasGate(process.env.XRAY_AI_PATH || '')) {
|
|
17
|
+
return process.env.XRAY_AI_PATH;
|
|
18
|
+
}
|
|
19
|
+
const marker = join(homedir(), '.openclaw', 'xray-consumer-root.txt');
|
|
20
|
+
const marked = existsSync(marker) ? readFileSync(marker, 'utf8').trim() : '';
|
|
21
|
+
const candidates = [
|
|
22
|
+
marked,
|
|
23
|
+
marked ? join(marked, 'node_modules', '0xray') : '',
|
|
24
|
+
marked ? join(marked, '..', 'xray') : '',
|
|
25
|
+
// Linked plugin lives at src/integrations/openclaw/plugin/xray-pre-tool
|
|
26
|
+
join(pluginDir, '..', '..', '..', '..', '..'),
|
|
27
|
+
].filter(Boolean);
|
|
28
|
+
for (const candidate of candidates) {
|
|
29
|
+
if (hasGate(candidate)) {
|
|
30
|
+
return candidate;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default definePluginEntry({
|
|
37
|
+
id: 'xray-pre-tool',
|
|
38
|
+
name: '0xRay PreToolUse',
|
|
39
|
+
register(api) {
|
|
40
|
+
api.on(
|
|
41
|
+
'before_tool_call',
|
|
42
|
+
(event, ctx) => {
|
|
43
|
+
try {
|
|
44
|
+
const xrayRoot = resolveXrayRoot();
|
|
45
|
+
if (!xrayRoot) {
|
|
46
|
+
return { block: true, blockReason: '0xRay dist missing — set XRAY_AI_PATH' };
|
|
47
|
+
}
|
|
48
|
+
const gate = require(join(xrayRoot, 'dist/nucleus/delegation-gate.js'));
|
|
49
|
+
const projectRoot =
|
|
50
|
+
process.env.XRAY_ROOT ||
|
|
51
|
+
ctx?.workspaceDir ||
|
|
52
|
+
ctx?.cwd ||
|
|
53
|
+
process.cwd();
|
|
54
|
+
const features = gate.loadDelegationGateFeatures(projectRoot, 'openclaw');
|
|
55
|
+
const outcome = gate.evaluatePreToolGate(event.toolName, event.params || {}, {
|
|
56
|
+
projectRoot,
|
|
57
|
+
sessionId: ctx?.sessionId || ctx?.sessionKey || 'openclaw',
|
|
58
|
+
features,
|
|
59
|
+
host: 'openclaw',
|
|
60
|
+
});
|
|
61
|
+
if (!outcome.allow) {
|
|
62
|
+
return { block: true, blockReason: outcome.reason || '0xRay constitution' };
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
} catch (err) {
|
|
66
|
+
return {
|
|
67
|
+
block: true,
|
|
68
|
+
blockReason: err instanceof Error ? err.message : String(err),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{ priority: 80 },
|
|
73
|
+
);
|
|
74
|
+
},
|
|
75
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "xray-pre-tool",
|
|
3
|
+
"name": "0xRay PreToolUse",
|
|
4
|
+
"description": "Constitution and temperament gate for OpenClaw tool calls (Codex 11/29/69, spawn plan).",
|
|
5
|
+
"configSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw host-agent PreToolUse adapter.
|
|
3
|
+
* Platform still lacks a native consumer tool-block API; this SSOT is what
|
|
4
|
+
* install writes to ~/.openclaw/hooks and what the integration uses on tool.before.
|
|
5
|
+
*/
|
|
6
|
+
import { type ToolGateInput } from '../../nucleus/delegation-gate.js';
|
|
7
|
+
export interface OpenClawPreToolContext {
|
|
8
|
+
projectRoot: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
}
|
|
11
|
+
export interface OpenClawPreToolDecision {
|
|
12
|
+
action: 'block' | 'allow';
|
|
13
|
+
allow: boolean;
|
|
14
|
+
reason?: string;
|
|
15
|
+
gate?: string;
|
|
16
|
+
hint?: unknown;
|
|
17
|
+
warn?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function evaluateOpenClawHostPreTool(toolName: string, args: ToolGateInput, ctx: OpenClawPreToolContext): OpenClawPreToolDecision;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw host-agent PreToolUse adapter.
|
|
3
|
+
* Platform still lacks a native consumer tool-block API; this SSOT is what
|
|
4
|
+
* install writes to ~/.openclaw/hooks and what the integration uses on tool.before.
|
|
5
|
+
*/
|
|
6
|
+
import { evaluatePreToolGate, loadDelegationGateFeatures, } from '../../nucleus/delegation-gate.js';
|
|
7
|
+
export function evaluateOpenClawHostPreTool(toolName, args, ctx) {
|
|
8
|
+
const features = loadDelegationGateFeatures(ctx.projectRoot, 'openclaw');
|
|
9
|
+
const outcome = evaluatePreToolGate(toolName, args, {
|
|
10
|
+
projectRoot: ctx.projectRoot,
|
|
11
|
+
sessionId: ctx.sessionId,
|
|
12
|
+
features,
|
|
13
|
+
host: 'openclaw',
|
|
14
|
+
});
|
|
15
|
+
if (!outcome.allow) {
|
|
16
|
+
const blocked = {
|
|
17
|
+
action: 'block',
|
|
18
|
+
allow: false,
|
|
19
|
+
reason: outcome.reason,
|
|
20
|
+
gate: outcome.gate,
|
|
21
|
+
};
|
|
22
|
+
if ('hint' in outcome && outcome.hint)
|
|
23
|
+
blocked.hint = outcome.hint;
|
|
24
|
+
return blocked;
|
|
25
|
+
}
|
|
26
|
+
const allowed = {
|
|
27
|
+
action: 'allow',
|
|
28
|
+
allow: true,
|
|
29
|
+
};
|
|
30
|
+
if (outcome.reason) {
|
|
31
|
+
allowed.reason = outcome.reason;
|
|
32
|
+
allowed.warn = true;
|
|
33
|
+
}
|
|
34
|
+
if (outcome.gate)
|
|
35
|
+
allowed.gate = outcome.gate;
|
|
36
|
+
if ('hint' in outcome && outcome.hint)
|
|
37
|
+
allowed.hint = outcome.hint;
|
|
38
|
+
return allowed;
|
|
39
|
+
}
|
|
@@ -70,11 +70,11 @@ export class ComplexityHandler {
|
|
|
70
70
|
isUserAsidesEnabled(projectRoot);
|
|
71
71
|
let userAsideReport = '';
|
|
72
72
|
let leadDevPlan = synthesisCheckpoint
|
|
73
|
-
? buildSynthesisCheckpointPlan(args.synthesisDueReason ?? null)
|
|
73
|
+
? buildSynthesisCheckpointPlan(args.synthesisDueReason ?? null, projectRoot)
|
|
74
74
|
: userAsideIntake
|
|
75
75
|
? null
|
|
76
76
|
: isLeadDevModeActive() && (primaryDescription || planTaskInputs.length > 0)
|
|
77
|
-
? buildLeadDevPlan(primaryDescription, taskTypes.length ? taskTypes : ['implement'], planTaskInputs, analysis.overallComplexity)
|
|
77
|
+
? buildLeadDevPlan(primaryDescription, taskTypes.length ? taskTypes : ['implement'], planTaskInputs, analysis.overallComplexity, projectRoot)
|
|
78
78
|
: null;
|
|
79
79
|
let planPersisted = synthesisCheckpoint
|
|
80
80
|
? leadDevPlan !== null
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { MemoryRoutingProvider, MemoryRoutingContext, MemoryInheritedContext, MemoryAgentCapability, MemoryOrchestrationTask, MemoryThinDispatchResult, MemoryRoutingConfig, OrchestratorFeedbackEntry, } from './types.js';
|
|
2
2
|
export { getMemoryRoutingProvider, getMemoryRoutingProviderSync, getMemoryRoutingConfig, resetMemoryRoutingProvider, initializeMemoryRouting, } from './provider-registry.js';
|
|
3
3
|
export { NullMemoryRoutingProvider, createMemoryRoutingProvider } from './null-provider.js';
|
|
4
|
-
export { loadMemoryRoutingProvider } from './provider-loader.js';
|
|
4
|
+
export { loadMemoryRoutingProvider, isLeftoverMemoryRoutingOff, isExplicitMemoryRoutingOptOut, resolveLeftoverEnabledConfig, } from './provider-loader.js';
|
|
5
5
|
export { validateMemoryRoutingConfig } from './validate-config.js';
|
|
6
6
|
export type { MemoryRoutingValidation } from './validate-config.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { getMemoryRoutingProvider, getMemoryRoutingProviderSync, getMemoryRoutingConfig, resetMemoryRoutingProvider, initializeMemoryRouting, } from './provider-registry.js';
|
|
2
2
|
export { NullMemoryRoutingProvider, createMemoryRoutingProvider } from './null-provider.js';
|
|
3
|
-
export { loadMemoryRoutingProvider } from './provider-loader.js';
|
|
3
|
+
export { loadMemoryRoutingProvider, isLeftoverMemoryRoutingOff, isExplicitMemoryRoutingOptOut, resolveLeftoverEnabledConfig, } from './provider-loader.js';
|
|
4
4
|
export { validateMemoryRoutingConfig } from './validate-config.js';
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import type { MemoryRoutingConfig, MemoryRoutingProvider } from './types.js';
|
|
2
|
+
export declare function isExplicitMemoryRoutingOptOut(config: MemoryRoutingConfig): boolean;
|
|
3
|
+
/** Leftover shipped default: enabled false + provider null. Not an explicit opt-out. */
|
|
4
|
+
export declare function isLeftoverMemoryRoutingOff(config: MemoryRoutingConfig): boolean;
|
|
5
|
+
export declare function resolveLeftoverEnabledConfig(config: MemoryRoutingConfig, cwd: string): MemoryRoutingConfig | null;
|
|
2
6
|
export declare function loadMemoryRoutingProvider(config: MemoryRoutingConfig, cwd?: string): Promise<MemoryRoutingProvider>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
|
-
import { resolve, dirname } from 'node:path';
|
|
2
|
+
import { resolve, dirname, join } from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import { frameworkLogger } from '../core/framework-logger.js';
|
|
5
5
|
import { createMemoryRoutingProvider as createNullProvider } from './null-provider.js';
|
|
@@ -20,6 +20,8 @@ function resolveUnavailableReason(provider) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
const REPERTOIRE_CANDIDATE_PATHS = [
|
|
23
|
+
'node_modules/@0xray/repertoire/dist/provider/memory-routing-provider.js',
|
|
24
|
+
'vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js',
|
|
23
25
|
'../repertoire/dist/provider/memory-routing-provider.js',
|
|
24
26
|
'../../repertoire/dist/provider/memory-routing-provider.js',
|
|
25
27
|
'../../../repertoire/dist/provider/memory-routing-provider.js',
|
|
@@ -50,15 +52,55 @@ function defaultPathForProvider(provider, cwd) {
|
|
|
50
52
|
if (existsSync(abs))
|
|
51
53
|
return abs;
|
|
52
54
|
}
|
|
55
|
+
const nm = join(cwd, 'node_modules', '@0xray', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js');
|
|
56
|
+
return existsSync(nm) ? nm : null;
|
|
57
|
+
}
|
|
58
|
+
export function isExplicitMemoryRoutingOptOut(config) {
|
|
59
|
+
return config.enabled === false && config.provider === 'repertoire';
|
|
60
|
+
}
|
|
61
|
+
/** Leftover shipped default: enabled false + provider null. Not an explicit opt-out. */
|
|
62
|
+
export function isLeftoverMemoryRoutingOff(config) {
|
|
63
|
+
if (config.enabled === true)
|
|
64
|
+
return false;
|
|
65
|
+
if (isExplicitMemoryRoutingOptOut(config))
|
|
66
|
+
return false;
|
|
67
|
+
return config.provider === 'null' || !config.provider;
|
|
68
|
+
}
|
|
69
|
+
function leftoverRepertoireModulePath(cwd) {
|
|
70
|
+
const nm = join(cwd, 'node_modules', '@0xray', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js');
|
|
71
|
+
if (existsSync(nm))
|
|
72
|
+
return nm;
|
|
73
|
+
const vendor = join(cwd, 'vendor', '@0xray', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js');
|
|
74
|
+
if (existsSync(vendor))
|
|
75
|
+
return vendor;
|
|
76
|
+
const sibling = resolve(cwd, '../repertoire/dist/provider/memory-routing-provider.js');
|
|
77
|
+
if (existsSync(sibling))
|
|
78
|
+
return sibling;
|
|
53
79
|
return null;
|
|
54
80
|
}
|
|
81
|
+
export function resolveLeftoverEnabledConfig(config, cwd) {
|
|
82
|
+
if (!isLeftoverMemoryRoutingOff(config))
|
|
83
|
+
return null;
|
|
84
|
+
const modulePath = resolveModulePath(config.module_path, cwd) ?? leftoverRepertoireModulePath(cwd);
|
|
85
|
+
if (!modulePath)
|
|
86
|
+
return null;
|
|
87
|
+
const enabled = {
|
|
88
|
+
enabled: true,
|
|
89
|
+
provider: 'repertoire',
|
|
90
|
+
module_path: modulePath,
|
|
91
|
+
};
|
|
92
|
+
if (config.config)
|
|
93
|
+
enabled.config = config.config;
|
|
94
|
+
return enabled;
|
|
95
|
+
}
|
|
55
96
|
export async function loadMemoryRoutingProvider(config, cwd = process.cwd()) {
|
|
56
97
|
const validation = validateMemoryRoutingConfig(config);
|
|
57
98
|
if (!validation.valid) {
|
|
58
99
|
await frameworkLogger.log('memory-routing', 'config-invalid', 'error', { errors: validation.errors, provider: config.provider });
|
|
59
100
|
return createNullProvider();
|
|
60
101
|
}
|
|
61
|
-
const
|
|
102
|
+
const leftover = resolveLeftoverEnabledConfig(validation.normalized, cwd);
|
|
103
|
+
const effective = leftover ?? validation.normalized;
|
|
62
104
|
if (!effective.enabled || effective.provider === 'null') {
|
|
63
105
|
return createNullProvider();
|
|
64
106
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { featuresConfigLoader } from '../core/features-config.js';
|
|
2
2
|
import { NullMemoryRoutingProvider } from './null-provider.js';
|
|
3
|
-
import { loadMemoryRoutingProvider } from './provider-loader.js';
|
|
3
|
+
import { loadMemoryRoutingProvider, resolveLeftoverEnabledConfig } from './provider-loader.js';
|
|
4
4
|
import { validateMemoryRoutingConfig } from './validate-config.js';
|
|
5
5
|
let cachedProvider = null;
|
|
6
6
|
let loadPromise = null;
|
|
@@ -8,7 +8,8 @@ const nullProviderSingleton = new NullMemoryRoutingProvider();
|
|
|
8
8
|
export function getMemoryRoutingConfig() {
|
|
9
9
|
const raw = featuresConfigLoader.loadConfig().memory_routing;
|
|
10
10
|
const validation = validateMemoryRoutingConfig(raw ?? { enabled: false, provider: 'null' });
|
|
11
|
-
return validation.normalized
|
|
11
|
+
return (resolveLeftoverEnabledConfig(validation.normalized, process.cwd()) ??
|
|
12
|
+
validation.normalized);
|
|
12
13
|
}
|
|
13
14
|
export async function getMemoryRoutingProvider(forceReload = false) {
|
|
14
15
|
if (!forceReload && cachedProvider)
|
|
@@ -43,8 +43,8 @@ export declare function isLeadDevModeActive(): boolean;
|
|
|
43
43
|
export declare function routeSubagent(taskType: string): SubagentRoute;
|
|
44
44
|
export declare function shouldFlagFullTestSuite(command: string): boolean;
|
|
45
45
|
/** Mandatory-consult plan for synthesis checkpoint realignment (no implementation phase). */
|
|
46
|
-
export declare function buildSynthesisCheckpointPlan(dueReason: string | null): LeadDevPlan | null;
|
|
47
|
-
export declare function buildLeadDevPlan(description: string, taskTypes?: string[], taskInputs?: LeadDevPlanTaskInput[], mcpOverallComplexity?: number): LeadDevPlan | null;
|
|
46
|
+
export declare function buildSynthesisCheckpointPlan(dueReason: string | null, projectRoot?: string): LeadDevPlan | null;
|
|
47
|
+
export declare function buildLeadDevPlan(description: string, taskTypes?: string[], taskInputs?: LeadDevPlanTaskInput[], mcpOverallComplexity?: number, projectRoot?: string): LeadDevPlan | null;
|
|
48
48
|
export declare function buildSessionBootContext(): Record<string, unknown>;
|
|
49
49
|
/** Persist plan for PreToolUse spawn_subagent gate */
|
|
50
50
|
export declare function persistLeadDevPlan(plan: LeadDevPlan, projectRoot?: string): string;
|