0xray 3.5.4 → 4.0.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/.mcp.json +51 -7
- 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 +32 -6
- package/.xray/features.schema.json +87 -0
- package/AGENTS-consumer.md +16 -6
- package/AGENTS.md +21 -3
- package/README.md +13 -10
- package/SKILLS.md +1 -1
- package/dist/AGENTS.md +21 -3
- package/dist/CHANGELOG.md +98 -0
- package/dist/README.md +13 -10
- package/dist/SKILLS.md +1 -1
- package/dist/cli/commands/hermes-install.js +6 -1
- package/dist/cli/commands/openclaw-install.js +14 -0
- package/dist/cli/index.js +0 -0
- package/dist/core/features-config.d.ts +30 -2
- package/dist/governance/governance-service.d.ts +1 -0
- package/dist/governance/governance-service.js +81 -6
- package/dist/infrastructure/schemas/cloud-schemas.d.ts +1 -1
- package/dist/integrations/enforcement-gate.js +15 -5
- package/dist/integrations/grok/grok-cli.d.ts +3 -0
- package/dist/integrations/grok/grok-cli.js +92 -13
- package/dist/integrations/grok/hooks/grok-hook-utils.js +99 -9
- package/dist/integrations/grok/hooks/post-tool-use.js +68 -25
- package/dist/integrations/grok/hooks/pre-tool-use.js +17 -14
- package/dist/integrations/grok/hooks/session-start.js +114 -4
- package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +31 -24
- package/dist/integrations/hermes-agent/__init__.py +11 -1
- package/dist/integrations/hermes-agent/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/integrations/hermes-agent/__pycache__/schemas.cpython-313.pyc +0 -0
- package/dist/integrations/hermes-agent/__pycache__/tools.cpython-313.pyc +0 -0
- package/dist/integrations/hermes-agent/bridge.mjs +92 -11
- package/dist/integrations/hooks/confer-hook-runtime.mjs +49 -0
- package/dist/integrations/hooks/delegation-gate-runtime.mjs +32 -3
- package/dist/integrations/hooks/pipeline-hook-runtime.mjs +211 -0
- package/dist/integrations/hooks/plan-hook-runtime.mjs +68 -0
- 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/hooks/user-aside-hook-runtime.mjs +49 -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 +10 -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/architect-tools.server.js +6 -1
- package/dist/mcps/orchestrator/handlers/complexity-handler.d.ts +7 -0
- package/dist/mcps/orchestrator/handlers/complexity-handler.js +107 -8
- package/dist/mcps/orchestrator/handlers/task-handler.d.ts +6 -0
- package/dist/mcps/orchestrator/handlers/task-handler.js +75 -0
- package/dist/mcps/orchestrator/server.js +54 -5
- 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 +74 -4
- package/dist/memory-routing/provider-registry.js +3 -2
- package/dist/nucleus/aside-worktree.d.ts +41 -0
- package/dist/nucleus/aside-worktree.js +164 -0
- package/dist/nucleus/autonomy-kernel.d.ts +2 -2
- package/dist/nucleus/autonomy-kernel.js +17 -6
- package/dist/nucleus/confer.d.ts +57 -0
- package/dist/nucleus/confer.js +322 -0
- package/dist/nucleus/delegation-gate.d.ts +18 -8
- package/dist/nucleus/delegation-gate.js +234 -20
- package/dist/nucleus/lead-dev-plan-persistence.d.ts +27 -3
- package/dist/nucleus/lead-dev-plan-persistence.js +201 -19
- package/dist/nucleus/spawn-plan-resolution.d.ts +20 -0
- package/dist/nucleus/spawn-plan-resolution.js +42 -0
- package/dist/nucleus/suit-temperament.d.ts +40 -0
- package/dist/nucleus/suit-temperament.js +157 -0
- package/dist/nucleus/synthesis-consult-receipt.js +18 -2
- package/dist/nucleus/synthesis-context.js +1 -1
- package/dist/nucleus/user-aside.d.ts +70 -0
- package/dist/nucleus/user-aside.js +393 -0
- package/dist/plugin/xray-codex-injection.js +14 -3
- package/dist/postprocessor/PostProcessor.d.ts +1 -0
- package/dist/postprocessor/PostProcessor.js +11 -0
- package/dist/postprocessor/triggers/GitHookTrigger.js +11 -5
- package/dist/processors/implementations/session-summary-processor.d.ts +1 -1
- package/dist/processors/implementations/session-summary-processor.js +9 -6
- package/opencode.json +88 -0
- package/package.json +25 -6
- package/scripts/hooks/install-hooks.cjs +21 -6
- package/scripts/hooks/run-hook.js +237 -88
- package/scripts/mjs/run-repertoire-mcp.mjs +39 -0
- package/scripts/mjs/verify-confer-core.mjs +103 -0
- package/scripts/mjs/verify-delegation-gate-core.mjs +76 -3
- package/scripts/mjs/verify-four-floor-compact.mjs +524 -0
- package/scripts/mjs/verify-hermes-session-start.mjs +137 -0
- package/scripts/mjs/verify-pipeline-facets.mjs +215 -0
- package/scripts/mjs/verify-pre-push-diff-core.mjs +87 -0
- package/scripts/mjs/verify-temperament-live.mjs +261 -0
- package/scripts/mjs/verify-user-aside-core.mjs +137 -0
- package/scripts/node/bridge-mcp-wiring.cjs +287 -29
- package/scripts/node/install-bridges.cjs +198 -44
- package/scripts/node/load-reflection-config.mjs +2 -2
- package/scripts/node/postinstall.cjs +50 -27
- package/scripts/node/release-gate.mjs +8 -4
- package/scripts/node/release.mjs +2 -2
- package/scripts/node/validate-release-docs.mjs +20 -33
- package/scripts/node/version-manager.mjs +25 -10
- 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 +10 -0
- package/src/mcps/architect-tools.server.ts +6 -1
- package/src/mcps/orchestrator/handlers/complexity-handler.ts +180 -21
- package/src/mcps/orchestrator/handlers/task-handler.ts +99 -0
- package/src/mcps/orchestrator/server.ts +56 -5
- 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 +32 -6
- package/xray/features.schema.json +87 -0
|
@@ -13,23 +13,19 @@ const {
|
|
|
13
13
|
wireOpencodeBridge,
|
|
14
14
|
wireOpenClawBridge,
|
|
15
15
|
deployPortableProjectMcpJson,
|
|
16
|
+
copyHermesFindProjectRootHelper,
|
|
17
|
+
copyHermesHookRuntimes,
|
|
18
|
+
installOpenClawHostWear,
|
|
19
|
+
maybeWriteOpenClawCliBackend,
|
|
20
|
+
isEphemeralInstallRoot,
|
|
21
|
+
enableMemoryRoutingIfResolves,
|
|
22
|
+
XRAY_MCP_SERVERS,
|
|
16
23
|
} = require("./bridge-mcp-wiring.cjs");
|
|
17
24
|
|
|
18
25
|
const SKIP_DIRS = new Set(["node_modules", "logs"]);
|
|
19
26
|
const MERGE_FILES = new Set(["enforcer-config.json"]);
|
|
20
27
|
const KEEP_IF_EXISTS = new Set([".yml", ".yaml", ".md"]);
|
|
21
28
|
|
|
22
|
-
/** Canonical 7-server MCP surface — matches package .mcp.json and Grok plugin */
|
|
23
|
-
const XRAY_MCP_SERVERS = [
|
|
24
|
-
{ name: "xray-governance", mcpCmd: "governance", env: { XRAY_FORCE_MCP_GOVERNANCE: "true" } },
|
|
25
|
-
{ name: "xray-skills", mcpCmd: "skills", env: {} },
|
|
26
|
-
{ name: "xray-orchestrator", mcpCmd: "orchestrator", env: {} },
|
|
27
|
-
{ name: "xray-enforcer", mcpCmd: "enforcer", env: {} },
|
|
28
|
-
{ name: "xray-researcher", mcpCmd: "researcher", env: {} },
|
|
29
|
-
{ name: "xray-code-review", mcpCmd: "code-review", env: {} },
|
|
30
|
-
{ name: "xray-architect-tools", mcpCmd: "architect-tools", env: {} },
|
|
31
|
-
];
|
|
32
|
-
|
|
33
29
|
function resolveConsumerTargetDir(packageRoot, fallbackDir) {
|
|
34
30
|
const resolved = path.resolve(packageRoot);
|
|
35
31
|
const inNodeModules =
|
|
@@ -128,8 +124,21 @@ function copyTree(src, dest, relPath = "") {
|
|
|
128
124
|
|
|
129
125
|
function copyPluginDir(src, dest) {
|
|
130
126
|
if (!fs.existsSync(src)) return false;
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
try {
|
|
128
|
+
if (fs.existsSync(dest)) {
|
|
129
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
130
|
+
}
|
|
131
|
+
fs.cpSync(src, dest, { recursive: true, force: true });
|
|
132
|
+
return true;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
try {
|
|
135
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
136
|
+
fs.cpSync(src, dest, { recursive: true, force: true });
|
|
137
|
+
return true;
|
|
138
|
+
} catch {
|
|
139
|
+
throw e;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
function writePluginMcpJson(pluginDir, targetDir, log, label) {
|
|
@@ -168,30 +177,96 @@ function mergeOpencodeJson(targetDir, packageRoot, log) {
|
|
|
168
177
|
}
|
|
169
178
|
}
|
|
170
179
|
|
|
180
|
+
function grokHookShellCommand(packageRoot, scriptName, extraArgs) {
|
|
181
|
+
const script = path.join(packageRoot, "dist", "integrations", "grok", "hooks", scriptName);
|
|
182
|
+
const extra = extraArgs ? ` ${extraArgs}` : "";
|
|
183
|
+
// JSON.stringify quotes so spaces/$ in install paths still exec (Grok fail-opens on crash).
|
|
184
|
+
return `XRAY_AI_PATH=${JSON.stringify(packageRoot)} node ${JSON.stringify(script)}${extra}`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function patchGrokHookEntry(hook, packageRoot, targetDir, scriptName, extraArgs) {
|
|
188
|
+
if (!hook) return;
|
|
189
|
+
hook.type = "command";
|
|
190
|
+
hook.command = grokHookShellCommand(packageRoot, scriptName, extraArgs);
|
|
191
|
+
hook.timeout = 30;
|
|
192
|
+
delete hook.args;
|
|
193
|
+
hook.env = {
|
|
194
|
+
...(hook.env || {}),
|
|
195
|
+
XRAY_ROOT: targetDir,
|
|
196
|
+
XRAY_AI_PATH: packageRoot,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function ensureGrokHookEvent(hooks, eventName) {
|
|
201
|
+
if (!hooks.hooks) hooks.hooks = {};
|
|
202
|
+
if (!Array.isArray(hooks.hooks[eventName]) || !hooks.hooks[eventName][0]) {
|
|
203
|
+
hooks.hooks[eventName] = [{ hooks: [{}] }];
|
|
204
|
+
}
|
|
205
|
+
if (!Array.isArray(hooks.hooks[eventName][0].hooks) || !hooks.hooks[eventName][0].hooks[0]) {
|
|
206
|
+
hooks.hooks[eventName][0].hooks = [{}];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
171
210
|
function patchGrokHooks(pluginDir, packageRoot, targetDir, log, label) {
|
|
172
|
-
const
|
|
211
|
+
const hooksDir = path.join(pluginDir, "hooks");
|
|
212
|
+
const hooksPath = path.join(hooksDir, "hooks.json");
|
|
173
213
|
const hookScript = path.join(packageRoot, "dist", "integrations", "grok", "hooks", "pre-tool-use.js");
|
|
174
|
-
if (!fs.existsSync(hooksPath))
|
|
214
|
+
if (!fs.existsSync(hooksPath)) {
|
|
215
|
+
if (!fs.existsSync(hooksDir)) fs.mkdirSync(hooksDir, { recursive: true });
|
|
216
|
+
if (!fs.existsSync(hooksPath)) return;
|
|
217
|
+
}
|
|
175
218
|
|
|
176
219
|
try {
|
|
177
220
|
const hooks = JSON.parse(fs.readFileSync(hooksPath, "utf8"));
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
221
|
+
if (!fs.existsSync(hookScript)) return;
|
|
222
|
+
patchGrokHookEntry(hooks.hooks?.PreToolUse?.[0]?.hooks?.[0], packageRoot, targetDir, "pre-tool-use.js");
|
|
223
|
+
patchGrokHookEntry(hooks.hooks?.SessionStart?.[0]?.hooks?.[0], packageRoot, targetDir, "session-start.js");
|
|
224
|
+
patchGrokHookEntry(
|
|
225
|
+
hooks.hooks?.UserPromptSubmit?.[0]?.hooks?.[0],
|
|
226
|
+
packageRoot,
|
|
227
|
+
targetDir,
|
|
228
|
+
"session-start.js",
|
|
229
|
+
"--hook-event=user_prompt_submit",
|
|
230
|
+
);
|
|
231
|
+
patchGrokHookEntry(hooks.hooks?.PostToolUse?.[0]?.hooks?.[0], packageRoot, targetDir, "post-tool-use.js");
|
|
232
|
+
ensureGrokHookEvent(hooks, "PreCompact");
|
|
233
|
+
ensureGrokHookEvent(hooks, "PostCompact");
|
|
234
|
+
patchGrokHookEntry(
|
|
235
|
+
hooks.hooks?.PreCompact?.[0]?.hooks?.[0],
|
|
236
|
+
packageRoot,
|
|
237
|
+
targetDir,
|
|
238
|
+
"session-start.js",
|
|
239
|
+
"--hook-event=pre_compact",
|
|
240
|
+
);
|
|
241
|
+
patchGrokHookEntry(
|
|
242
|
+
hooks.hooks?.PostCompact?.[0]?.hooks?.[0],
|
|
243
|
+
packageRoot,
|
|
244
|
+
targetDir,
|
|
245
|
+
"session-start.js",
|
|
246
|
+
"--hook-event=post_compact",
|
|
247
|
+
);
|
|
248
|
+
fs.writeFileSync(hooksPath, JSON.stringify(hooks, null, 2) + "\n");
|
|
249
|
+
writeGrokDiscoveredHooks(targetDir, hooksPath, log, label);
|
|
250
|
+
log(label, "hooks.json patched → Grok command-string enforcement gate", "info");
|
|
190
251
|
} catch (e) {
|
|
191
252
|
log(label, "hooks.json patch failed", "warn", { error: e.message });
|
|
192
253
|
}
|
|
193
254
|
}
|
|
194
255
|
|
|
256
|
+
/** Grok TUI loads `<project>/.grok/hooks/*.json`, not `plugins/0xray/hooks`. */
|
|
257
|
+
function writeGrokDiscoveredHooks(targetDir, hooksPath, log, label) {
|
|
258
|
+
if (!targetDir || !fs.existsSync(hooksPath)) return;
|
|
259
|
+
try {
|
|
260
|
+
const destDir = path.join(targetDir, ".grok", "hooks");
|
|
261
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
262
|
+
const dest = path.join(destDir, "0xray.json");
|
|
263
|
+
fs.copyFileSync(hooksPath, dest);
|
|
264
|
+
log(label, "Grok discovered hooks → .grok/hooks/0xray.json", "info", { dest });
|
|
265
|
+
} catch (e) {
|
|
266
|
+
log(label, "Grok discovered hooks copy failed", "warn", { error: e.message });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
195
270
|
function installOpencodeBridge(targetDir, packageRoot, log) {
|
|
196
271
|
const opencodeSource = path.join(packageRoot, ".opencode");
|
|
197
272
|
const opencodeDest = path.join(targetDir, ".opencode");
|
|
@@ -287,10 +362,13 @@ function installGrokBridge(targetDir, packageRoot, log) {
|
|
|
287
362
|
}
|
|
288
363
|
|
|
289
364
|
const home = os.homedir();
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
365
|
+
const ephemeral = isEphemeralInstallRoot(targetDir);
|
|
366
|
+
const targets = [path.join(targetDir, ".grok", "plugins", "0xray")];
|
|
367
|
+
if (!ephemeral) {
|
|
368
|
+
targets.push(path.join(home, ".grok", "plugins", "0xray"));
|
|
369
|
+
} else {
|
|
370
|
+
log("grok-bridge", "skip machine ~/.grok plugin — ephemeral consumer", "info");
|
|
371
|
+
}
|
|
294
372
|
|
|
295
373
|
for (const dest of targets) {
|
|
296
374
|
if (copyPluginDir(sourceDir, dest)) {
|
|
@@ -303,14 +381,14 @@ function installGrokBridge(targetDir, packageRoot, log) {
|
|
|
303
381
|
}
|
|
304
382
|
}
|
|
305
383
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
384
|
+
if (!ephemeral) {
|
|
385
|
+
const grokGlobalSkills = path.join(home, ".grok", "skills");
|
|
386
|
+
const globalCopied = syncBuiltinSkills(grokGlobalSkills, packageRoot);
|
|
387
|
+
if (globalCopied > 0) {
|
|
388
|
+
log("grok-bridge", `global skills synced (${globalCopied})`, "info", { path: "~/.grok/skills/" });
|
|
389
|
+
}
|
|
390
|
+
registerGrokMcpServers(targetDir, log);
|
|
311
391
|
}
|
|
312
|
-
|
|
313
|
-
registerGrokMcpServers(targetDir, log);
|
|
314
392
|
}
|
|
315
393
|
|
|
316
394
|
function installHermesBridge(targetDir, packageRoot, log) {
|
|
@@ -335,6 +413,10 @@ function installHermesBridge(targetDir, packageRoot, log) {
|
|
|
335
413
|
fs.copyFileSync(src, dst);
|
|
336
414
|
}
|
|
337
415
|
}
|
|
416
|
+
copyHermesFindProjectRootHelper(packageRoot, targetPluginDir);
|
|
417
|
+
if (copyHermesHookRuntimes(packageRoot)) {
|
|
418
|
+
log("hermes-bridge", "hook runtimes copied", "info", { path: "~/.hermes/plugins/hooks" });
|
|
419
|
+
}
|
|
338
420
|
log("hermes-bridge", "plugin copied", "info", { path: "~/.hermes/plugins/xray-hermes" });
|
|
339
421
|
|
|
340
422
|
writePluginMcpJson(targetPluginDir, targetDir, log, "hermes-bridge");
|
|
@@ -342,10 +424,13 @@ function installHermesBridge(targetDir, packageRoot, log) {
|
|
|
342
424
|
const copied = syncBuiltinSkills(path.join(targetPluginDir, "skills"), packageRoot);
|
|
343
425
|
if (copied > 0) log("hermes-bridge", `skills synced (${copied})`, "info");
|
|
344
426
|
|
|
345
|
-
// Marker so bridge.mjs resolves the consumer project on hook invocation
|
|
346
427
|
const rootMarker = path.join(targetPluginDir, "xray-consumer-root.txt");
|
|
347
|
-
|
|
348
|
-
|
|
428
|
+
if (!isEphemeralInstallRoot(targetDir)) {
|
|
429
|
+
fs.writeFileSync(rootMarker, targetDir + "\n");
|
|
430
|
+
log("hermes-bridge", "consumer root marker written", "info");
|
|
431
|
+
} else {
|
|
432
|
+
log("hermes-bridge", "skip machine consumer marker — ephemeral consumer", "info");
|
|
433
|
+
}
|
|
349
434
|
|
|
350
435
|
try {
|
|
351
436
|
const result = wireHermesBridge(targetDir);
|
|
@@ -399,6 +484,16 @@ function installOpenclawBridge(targetDir, packageRoot, log) {
|
|
|
399
484
|
} catch (e) {
|
|
400
485
|
log("openclaw-bridge", "openclaw.json mcp wire failed", "warn", { error: e.message });
|
|
401
486
|
}
|
|
487
|
+
|
|
488
|
+
if (!isEphemeralInstallRoot(targetDir)) {
|
|
489
|
+
const hook = installOpenClawHostWear(packageRoot);
|
|
490
|
+
if (hook) log("openclaw-bridge", "PreToolUse hook installed", "info", { path: hook });
|
|
491
|
+
if (maybeWriteOpenClawCliBackend()) {
|
|
492
|
+
log("openclaw-bridge", "opencode-cli backend written", "info");
|
|
493
|
+
}
|
|
494
|
+
} else {
|
|
495
|
+
log("openclaw-bridge", "skip machine PreToolUse wear — ephemeral consumer", "info");
|
|
496
|
+
}
|
|
402
497
|
}
|
|
403
498
|
|
|
404
499
|
const XRAY_CONFIG_FILES = ["codex.json", "features.json", "features.schema.json", "config.json"];
|
|
@@ -419,9 +514,20 @@ function writeJsonFile(filePath, data) {
|
|
|
419
514
|
fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`);
|
|
420
515
|
}
|
|
421
516
|
|
|
422
|
-
function
|
|
517
|
+
function applyResolvedMemoryRouting(dst, targetDir) {
|
|
518
|
+
try {
|
|
519
|
+
const features = JSON.parse(fs.readFileSync(dst, "utf8"));
|
|
520
|
+
const next = enableMemoryRoutingIfResolves(features, targetDir);
|
|
521
|
+
if (next.changed) writeJsonFile(dst, next.features);
|
|
522
|
+
} catch {
|
|
523
|
+
/* leftover default stays off when features.json is unreadable */
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
function deployXrayConfigFile(file, src, dst, packageRoot, targetDir) {
|
|
423
528
|
if (!fs.existsSync(dst)) {
|
|
424
529
|
fs.copyFileSync(src, dst);
|
|
530
|
+
if (file === "features.json") applyResolvedMemoryRouting(dst, targetDir);
|
|
425
531
|
return true;
|
|
426
532
|
}
|
|
427
533
|
|
|
@@ -442,12 +548,28 @@ function deployXrayConfigFile(file, src, dst, packageRoot) {
|
|
|
442
548
|
const pkgVersion = readPackageVersion(packageRoot);
|
|
443
549
|
if (pkgVersion) merged.version = pkgVersion;
|
|
444
550
|
else if (shipped.version) merged.version = shipped.version;
|
|
551
|
+
// v3: existing consumers without suit_temperament stay guided on upgrade.
|
|
552
|
+
// Fresh copy (dst missing) already returned above with shipped auto.
|
|
553
|
+
const hadTemperament =
|
|
554
|
+
consumer.suit_temperament &&
|
|
555
|
+
typeof consumer.suit_temperament === "object" &&
|
|
556
|
+
consumer.suit_temperament.profile;
|
|
557
|
+
if (!hadTemperament) {
|
|
558
|
+
merged.suit_temperament = {
|
|
559
|
+
...(merged.suit_temperament || {}),
|
|
560
|
+
profile: "guided",
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
writeJsonFile(dst, merged);
|
|
564
|
+
applyResolvedMemoryRouting(dst, targetDir);
|
|
565
|
+
return true;
|
|
445
566
|
}
|
|
446
567
|
writeJsonFile(dst, merged);
|
|
447
568
|
return true;
|
|
448
569
|
} catch {
|
|
449
570
|
if (fs.statSync(src).mtime > fs.statSync(dst).mtime) {
|
|
450
571
|
fs.copyFileSync(src, dst);
|
|
572
|
+
if (file === "features.json") applyResolvedMemoryRouting(dst, targetDir);
|
|
451
573
|
return true;
|
|
452
574
|
}
|
|
453
575
|
return false;
|
|
@@ -481,7 +603,7 @@ function deployXrayConfig(targetDir, packageRoot, log) {
|
|
|
481
603
|
const src = resolveXrayConfigSource(packageRoot, file);
|
|
482
604
|
const dst = path.join(xrayTargetDir, file);
|
|
483
605
|
if (!src) continue;
|
|
484
|
-
if (deployXrayConfigFile(file, src, dst, packageRoot)) {
|
|
606
|
+
if (deployXrayConfigFile(file, src, dst, packageRoot, targetDir)) {
|
|
485
607
|
copied++;
|
|
486
608
|
}
|
|
487
609
|
}
|
|
@@ -500,6 +622,29 @@ function installGitHooks(packageRoot, log) {
|
|
|
500
622
|
}
|
|
501
623
|
}
|
|
502
624
|
|
|
625
|
+
/**
|
|
626
|
+
* Framework dogfood: do not deploy consumer copies over the package,
|
|
627
|
+
* but keep Grok discovery hooks hot and enable Repertoire when it resolves.
|
|
628
|
+
*/
|
|
629
|
+
function installFrameworkDogfoodWear(packageRoot, log) {
|
|
630
|
+
const featuresPath = path.join(packageRoot, ".xray", "features.json");
|
|
631
|
+
if (fs.existsSync(featuresPath)) {
|
|
632
|
+
applyResolvedMemoryRouting(featuresPath, packageRoot);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
const sourceDir = findGrokPluginSource(packageRoot);
|
|
636
|
+
const pluginDest = path.join(packageRoot, ".grok", "plugins", "0xray");
|
|
637
|
+
if (!sourceDir) {
|
|
638
|
+
log("grok-dogfood", "skipped", "warn", { reason: "grok plugin source missing" });
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const hooksJson = path.join(pluginDest, "hooks", "hooks.json");
|
|
642
|
+
if (!fs.existsSync(hooksJson)) {
|
|
643
|
+
copyPluginDir(sourceDir, pluginDest);
|
|
644
|
+
}
|
|
645
|
+
patchGrokHooks(pluginDest, packageRoot, packageRoot, log, "grok-dogfood");
|
|
646
|
+
}
|
|
647
|
+
|
|
503
648
|
/**
|
|
504
649
|
* Install all 4 platform bridges for a consumer project.
|
|
505
650
|
* @param {{ targetDir: string, packageRoot: string, log?: Function }} opts
|
|
@@ -513,7 +658,11 @@ function installAllBridges(opts) {
|
|
|
513
658
|
/* noop */
|
|
514
659
|
});
|
|
515
660
|
|
|
516
|
-
if (!isConsumerInstall(packageRoot, targetDir))
|
|
661
|
+
if (!isConsumerInstall(packageRoot, targetDir)) {
|
|
662
|
+
log("install-bridges", "framework dogfood wear", "info");
|
|
663
|
+
installFrameworkDogfoodWear(packageRoot, log);
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
517
666
|
|
|
518
667
|
log("install-bridges", "starting 4-platform install", "info");
|
|
519
668
|
|
|
@@ -539,4 +688,9 @@ module.exports = {
|
|
|
539
688
|
resolveXrayConfigSource,
|
|
540
689
|
XRAY_CONFIG_FILES,
|
|
541
690
|
MERGE_CONFIG_FILES,
|
|
691
|
+
patchGrokHooks,
|
|
692
|
+
grokHookShellCommand,
|
|
693
|
+
writeGrokDiscoveredHooks,
|
|
694
|
+
isEphemeralInstallRoot,
|
|
695
|
+
installFrameworkDogfoodWear,
|
|
542
696
|
};
|
|
@@ -16,9 +16,9 @@ const root = process.env.PROJECT_ROOT || process.cwd();
|
|
|
16
16
|
const configPath = join(root, '.xray', 'features.json');
|
|
17
17
|
|
|
18
18
|
let mode = 'minimal';
|
|
19
|
-
let commitThreshold =
|
|
19
|
+
let commitThreshold = 50;
|
|
20
20
|
let daysThreshold = 14;
|
|
21
|
-
let autoGenerate =
|
|
21
|
+
let autoGenerate = false;
|
|
22
22
|
let promptUser = true;
|
|
23
23
|
|
|
24
24
|
if (existsSync(configPath)) {
|
|
@@ -15,17 +15,12 @@ function structuredLog(component, action, status, details) {
|
|
|
15
15
|
console.log(`${ts} [${component}] ${action} - ${String(status).toUpperCase()}${detailsPart}`);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const packageRoot = path.join(__dirname, "..", "..");
|
|
19
|
-
const targetDir = resolveConsumerTargetDir(packageRoot, process.env.PWD || process.cwd());
|
|
20
|
-
const resolvedPackage = path.resolve(packageRoot);
|
|
21
|
-
const resolvedTarget = path.resolve(targetDir);
|
|
22
|
-
|
|
23
18
|
const XRAY_MANAGED_AGENTS_MARKER = "<!-- 0xray-managed -->";
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
const agentsConsumer = path.join(packageRoot, "AGENTS-consumer.md");
|
|
27
|
-
const agentsDest = path.join(targetDir, "AGENTS.md");
|
|
28
|
-
if (fs.existsSync(agentsConsumer)
|
|
20
|
+
function deployManagedAgents(packageRoot, targetDir, log) {
|
|
21
|
+
const agentsConsumer = path.join(packageRoot, "AGENTS-consumer.md");
|
|
22
|
+
const agentsDest = path.join(targetDir, "AGENTS.md");
|
|
23
|
+
if (!fs.existsSync(agentsConsumer)) return;
|
|
29
24
|
const shouldDeployAgents =
|
|
30
25
|
!fs.existsSync(agentsDest) ||
|
|
31
26
|
fs.readFileSync(agentsDest, "utf8").includes(XRAY_MANAGED_AGENTS_MARKER);
|
|
@@ -36,37 +31,65 @@ if (fs.existsSync(agentsConsumer) && isConsumerInstall(resolvedPackage, resolved
|
|
|
36
31
|
}
|
|
37
32
|
fs.writeFileSync(agentsDest, content);
|
|
38
33
|
} else {
|
|
39
|
-
|
|
34
|
+
log("postinstall", "Skipped AGENTS.md (consumer-customized)", "info");
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
if (isConsumerInstall(resolvedPackage, resolvedTarget)) {
|
|
38
|
+
function deployConsumerGitignore(packageRoot, targetDir, log) {
|
|
45
39
|
const gitignoreResult = applyConsumerGitignore(targetDir, packageRoot);
|
|
46
40
|
if (gitignoreResult === "created") {
|
|
47
|
-
|
|
41
|
+
log("postinstall", "Created .gitignore from template", "info");
|
|
48
42
|
} else if (gitignoreResult === "merged") {
|
|
49
|
-
|
|
43
|
+
log("postinstall", "Merged 0xray suit entries into .gitignore", "info");
|
|
50
44
|
}
|
|
51
45
|
}
|
|
52
46
|
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Wear bridges for consumers (full 4-platform) and the framework repo (dogfood).
|
|
49
|
+
* installAllBridges already decides which path.
|
|
50
|
+
*/
|
|
51
|
+
function runPostinstall(packageRoot, targetDir, log) {
|
|
52
|
+
const logFn = log || structuredLog;
|
|
53
|
+
const resolvedPackage = path.resolve(packageRoot);
|
|
54
|
+
const resolvedTarget = path.resolve(targetDir);
|
|
55
|
+
const consumer = isConsumerInstall(resolvedPackage, resolvedTarget);
|
|
56
|
+
|
|
57
|
+
if (consumer) {
|
|
58
|
+
deployManagedAgents(resolvedPackage, resolvedTarget, logFn);
|
|
59
|
+
deployConsumerGitignore(resolvedPackage, resolvedTarget, logFn);
|
|
60
|
+
}
|
|
61
|
+
|
|
55
62
|
try {
|
|
56
63
|
installAllBridges({
|
|
57
|
-
targetDir,
|
|
58
|
-
packageRoot,
|
|
59
|
-
log:
|
|
64
|
+
targetDir: resolvedTarget,
|
|
65
|
+
packageRoot: resolvedPackage,
|
|
66
|
+
log: logFn,
|
|
60
67
|
});
|
|
61
68
|
} catch (e) {
|
|
62
|
-
|
|
69
|
+
logFn("postinstall", "Bridge install failed", "error", { error: e.message });
|
|
70
|
+
throw e;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (consumer) {
|
|
74
|
+
logFn(
|
|
75
|
+
"postinstall",
|
|
76
|
+
"0xRay framework installed (4 bridges). Run `npx 0xray setup` for symlinks/Hermes skill extras.",
|
|
77
|
+
"success",
|
|
78
|
+
);
|
|
79
|
+
} else {
|
|
80
|
+
logFn("postinstall", "framework dogfood wear complete", "success");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = { runPostinstall };
|
|
85
|
+
|
|
86
|
+
if (require.main === module) {
|
|
87
|
+
const packageRoot = path.join(__dirname, "..", "..");
|
|
88
|
+
const targetDir = resolveConsumerTargetDir(packageRoot, process.env.PWD || process.cwd());
|
|
89
|
+
try {
|
|
90
|
+
runPostinstall(packageRoot, targetDir);
|
|
91
|
+
} catch {
|
|
63
92
|
console.error("\n❌ 0xRay postinstall failed — bridge wiring did not complete.\n");
|
|
64
93
|
process.exit(1);
|
|
65
94
|
}
|
|
66
|
-
|
|
67
|
-
structuredLog(
|
|
68
|
-
"postinstall",
|
|
69
|
-
"0xRay framework installed (4 bridges). Run `npx 0xray setup` for symlinks/Hermes skill extras.",
|
|
70
|
-
"success"
|
|
71
|
-
);
|
|
72
|
-
}
|
|
95
|
+
}
|
|
@@ -48,14 +48,18 @@ function main() {
|
|
|
48
48
|
step("4/5 Consumer install smoke", "node scripts/node/consumer-install-smoke.mjs");
|
|
49
49
|
}
|
|
50
50
|
} else {
|
|
51
|
-
step("1/
|
|
52
|
-
step("2/
|
|
51
|
+
step("1/6 Build", "npm run build");
|
|
52
|
+
step("2/6 Tests", "npm test");
|
|
53
53
|
step(
|
|
54
|
-
"3/
|
|
54
|
+
"3/6 Consumer hook verifiers",
|
|
55
|
+
"npm run verify:pre-commit-diff && npm run verify:pre-push-diff && node scripts/mjs/verify-delegation-gate-core.mjs --host=grok && node scripts/mjs/verify-delegation-gate-core.mjs --host=hermes && node scripts/mjs/verify-delegation-gate-core.mjs --host=opencode && node scripts/mjs/verify-hermes-session-start.mjs && node scripts/mjs/verify-confer-core.mjs && npm run verify:user-aside && npm run build && node scripts/mjs/verify-pipeline-facets.mjs --package-only",
|
|
56
|
+
);
|
|
57
|
+
step(
|
|
58
|
+
"4/6 Plugin infrastructure",
|
|
55
59
|
"node scripts/test/validate-plugins-e2e.cjs --structural-only",
|
|
56
60
|
);
|
|
57
61
|
if (!skipSmoke) {
|
|
58
|
-
step("
|
|
62
|
+
step("5/6 Consumer install smoke (fresh + upgrade)", "node scripts/node/consumer-install-smoke.mjs");
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
|
package/scripts/node/release.mjs
CHANGED
|
@@ -24,7 +24,7 @@ import { getReleaseArtifactPaths } from "./version-manager.mjs";
|
|
|
24
24
|
const rootDir = process.cwd();
|
|
25
25
|
const args = process.argv.slice(2);
|
|
26
26
|
const dryRun = args.includes("--dry-run");
|
|
27
|
-
const releaseType = args.find((a) => ["major", "minor", "patch"].includes(a))
|
|
27
|
+
const releaseType = args.find((a) => ["major", "minor", "patch"].includes(a));
|
|
28
28
|
|
|
29
29
|
function run(cmd, label) {
|
|
30
30
|
console.log(`\n> ${cmd}`);
|
|
@@ -70,7 +70,7 @@ function publishIdempotent(version) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
async function main() {
|
|
73
|
-
if (!["major", "minor", "patch"].includes(releaseType)) {
|
|
73
|
+
if (!releaseType || !["major", "minor", "patch"].includes(releaseType)) {
|
|
74
74
|
console.error("Usage: node scripts/node/release.mjs [patch|minor|major] [--dry-run]");
|
|
75
75
|
process.exit(1);
|
|
76
76
|
}
|
|
@@ -24,7 +24,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
24
24
|
const defaultRoot = path.resolve(__dirname, '../..');
|
|
25
25
|
|
|
26
26
|
const STANDARD_HEADER_RE =
|
|
27
|
-
/^\*{0,2}v[\d.]+\*{0,2}\s*—\s
|
|
27
|
+
/^\*{0,2}v[\d.]+\*{0,2}\s*—\s*a suit that survives the context window/m;
|
|
28
28
|
|
|
29
29
|
/** Guides that must exist and reference the current release (body or header). */
|
|
30
30
|
const REQUIRED_GUIDES = [
|
|
@@ -45,7 +45,10 @@ const ROOT_DOC_CHECKS = [
|
|
|
45
45
|
validate: (content, version, counts, header) => {
|
|
46
46
|
const errors = [];
|
|
47
47
|
if (!content.includes(header)) {
|
|
48
|
-
errors.push(`missing
|
|
48
|
+
errors.push(`missing kernel header (expected substring: ${header})`);
|
|
49
|
+
}
|
|
50
|
+
if (!content.includes('survive the context window') && !content.includes('survives the context window')) {
|
|
51
|
+
errors.push('missing context-window / exo kernel copy');
|
|
49
52
|
}
|
|
50
53
|
if (!content.includes('SKILLS.md')) {
|
|
51
54
|
errors.push('missing SKILLS.md reference in postinstall/docs section');
|
|
@@ -63,14 +66,8 @@ const ROOT_DOC_CHECKS = [
|
|
|
63
66
|
if (!content.includes(`**v${version}**`)) {
|
|
64
67
|
errors.push(`missing version marker **v${version}**`);
|
|
65
68
|
}
|
|
66
|
-
if (!content.includes(
|
|
67
|
-
errors.push(
|
|
68
|
-
}
|
|
69
|
-
if (!content.includes(`${counts.skills} skills`)) {
|
|
70
|
-
errors.push(`expected ${counts.skills} skills in header`);
|
|
71
|
-
}
|
|
72
|
-
if (!content.includes('68 codex terms')) {
|
|
73
|
-
errors.push('expected 68 codex terms in header');
|
|
69
|
+
if (!content.includes('survive the context window') && !content.includes('survives the context window') && !content.includes('Exo, not catalog')) {
|
|
70
|
+
errors.push('missing exo / context-window kernel copy');
|
|
74
71
|
}
|
|
75
72
|
if (!content.includes('aside-context.md') && !content.includes('AsideContext')) {
|
|
76
73
|
errors.push('missing AsideContext documentation reference');
|
|
@@ -85,9 +82,11 @@ const ROOT_DOC_CHECKS = [
|
|
|
85
82
|
rel: 'AGENTS-consumer.md',
|
|
86
83
|
validate: (content, version, counts) => {
|
|
87
84
|
const errors = [];
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
if (!content.includes(`**v${version}**`)) {
|
|
86
|
+
errors.push(`missing version marker **v${version}**`);
|
|
87
|
+
}
|
|
88
|
+
if (!content.includes('survive the context window') && !content.includes('survives the context window')) {
|
|
89
|
+
errors.push('consumer header missing context-window kernel copy');
|
|
91
90
|
}
|
|
92
91
|
if (!content.includes('SKILLS.md')) {
|
|
93
92
|
errors.push('missing SKILLS.md in postinstall section');
|
|
@@ -146,28 +145,16 @@ function validateChangelog(content, version) {
|
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
function validateStandardHeader(content, expectedHeader, label) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return [`${label}: no standard docs header line found`];
|
|
152
|
-
}
|
|
153
|
-
if (match[0] !== expectedHeader) {
|
|
154
|
-
return [`${label}: header is "${match[0]}", expected "${expectedHeader}"`];
|
|
148
|
+
if (!content.includes(expectedHeader) && !STANDARD_HEADER_RE.test(content)) {
|
|
149
|
+
return [`${label}: missing kernel header (expected substring: ${expectedHeader})`];
|
|
155
150
|
}
|
|
156
151
|
return [];
|
|
157
152
|
}
|
|
158
153
|
|
|
159
|
-
function validateDocusaurusTagline(content
|
|
154
|
+
function validateDocusaurusTagline(content) {
|
|
160
155
|
const errors = [];
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
`${counts.skills} skills`,
|
|
164
|
-
`${counts.mcps} MCP servers`,
|
|
165
|
-
'68 codex terms',
|
|
166
|
-
];
|
|
167
|
-
for (const part of expectedParts) {
|
|
168
|
-
if (!content.includes(part)) {
|
|
169
|
-
errors.push(`docusaurus.config.ts tagline missing "${part}"`);
|
|
170
|
-
}
|
|
156
|
+
if (!content.includes('survive the context window') && !content.includes('survives the context window')) {
|
|
157
|
+
errors.push('docusaurus.config.ts tagline missing context-window kernel copy');
|
|
171
158
|
}
|
|
172
159
|
return errors;
|
|
173
160
|
}
|
|
@@ -184,8 +171,8 @@ export function validateReleaseDocs(rootDir = defaultRoot) {
|
|
|
184
171
|
const expectedHeader = buildDocsHeader(counts, version);
|
|
185
172
|
const codexTerms = getCodexTermCount(rootDir);
|
|
186
173
|
|
|
187
|
-
if (codexTerms !== null && codexTerms !==
|
|
188
|
-
warnings.push(`codex.json has ${codexTerms} terms (
|
|
174
|
+
if (codexTerms !== null && counts.codexTerms && codexTerms !== counts.codexTerms) {
|
|
175
|
+
warnings.push(`codex.json has ${codexTerms} terms (counts.codexTerms is ${counts.codexTerms})`);
|
|
189
176
|
}
|
|
190
177
|
|
|
191
178
|
const changelog = readFile(rootDir, 'CHANGELOG.md');
|
|
@@ -234,7 +221,7 @@ export function validateReleaseDocs(rootDir = defaultRoot) {
|
|
|
234
221
|
if (!docusaurus) {
|
|
235
222
|
errors.push('docs-site/docusaurus.config.ts: missing');
|
|
236
223
|
} else {
|
|
237
|
-
errors.push(...validateDocusaurusTagline(docusaurus
|
|
224
|
+
errors.push(...validateDocusaurusTagline(docusaurus));
|
|
238
225
|
}
|
|
239
226
|
|
|
240
227
|
for (const rel of getReleaseArtifactPaths()) {
|