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.
Files changed (266) hide show
  1. package/.mcp.json +51 -7
  2. package/.opencode/skills/api-design/SKILL.md +1 -1
  3. package/.opencode/skills/architect-tools/SKILL.md +1 -1
  4. package/.opencode/skills/architecture-patterns/SKILL.md +1 -1
  5. package/.opencode/skills/auto-format/SKILL.md +1 -1
  6. package/.opencode/skills/boot-orchestrator/SKILL.md +2 -6
  7. package/.opencode/skills/bug-triage/SKILL.md +1 -1
  8. package/.opencode/skills/code-analyzer/SKILL.md +1 -1
  9. package/.opencode/skills/code-review/SKILL.md +1 -1
  10. package/.opencode/skills/enforcer/SKILL.md +1 -1
  11. package/.opencode/skills/framework-compliance-audit/SKILL.md +1 -1
  12. package/.opencode/skills/git-workflow/SKILL.md +1 -1
  13. package/.opencode/skills/hermes-agent/SKILL.md +36 -36
  14. package/.opencode/skills/inference-improve/SKILL.md +1 -1
  15. package/.opencode/skills/lint/SKILL.md +1 -1
  16. package/.opencode/skills/log-monitor/SKILL.md +1 -1
  17. package/.opencode/skills/model-health-check/SKILL.md +1 -1
  18. package/.opencode/skills/multimodal-looker/SKILL.md +1 -1
  19. package/.opencode/skills/orchestrator/SKILL.md +38 -14
  20. package/.opencode/skills/performance-analysis/SKILL.md +1 -1
  21. package/.opencode/skills/performance-optimization/SKILL.md +1 -1
  22. package/.opencode/skills/processor-pipeline/SKILL.md +1 -1
  23. package/.opencode/skills/project-analysis/SKILL.md +1 -1
  24. package/.opencode/skills/refactoring-strategies/SKILL.md +1 -1
  25. package/.opencode/skills/registry.json +65 -0
  26. package/.opencode/skills/researcher/SKILL.md +18 -5
  27. package/.opencode/skills/security-audit/SKILL.md +1 -1
  28. package/.opencode/skills/security-scan/SKILL.md +1 -1
  29. package/.opencode/skills/session-management/SKILL.md +1 -1
  30. package/.opencode/skills/state-manager/SKILL.md +1 -1
  31. package/.opencode/skills/storyteller/SKILL.md +1 -1
  32. package/.opencode/skills/strategist/SKILL.md +12 -0
  33. package/.opencode/skills/testing-best-practices/SKILL.md +37 -0
  34. package/.opencode/skills/testing-strategy/SKILL.md +14 -3
  35. package/.opencode/skills/ui-ux-design/SKILL.md +1 -1
  36. package/.opencode/skills/xray-orchestrator/index.ts +267 -0
  37. package/.xray/codex.json +12 -3
  38. package/.xray/features.json +32 -6
  39. package/.xray/features.schema.json +87 -0
  40. package/AGENTS-consumer.md +16 -6
  41. package/AGENTS.md +21 -3
  42. package/README.md +13 -10
  43. package/SKILLS.md +1 -1
  44. package/dist/AGENTS.md +21 -3
  45. package/dist/CHANGELOG.md +98 -0
  46. package/dist/README.md +13 -10
  47. package/dist/SKILLS.md +1 -1
  48. package/dist/cli/commands/hermes-install.js +6 -1
  49. package/dist/cli/commands/openclaw-install.js +14 -0
  50. package/dist/cli/index.js +0 -0
  51. package/dist/core/features-config.d.ts +30 -2
  52. package/dist/governance/governance-service.d.ts +1 -0
  53. package/dist/governance/governance-service.js +81 -6
  54. package/dist/infrastructure/schemas/cloud-schemas.d.ts +1 -1
  55. package/dist/integrations/enforcement-gate.js +15 -5
  56. package/dist/integrations/grok/grok-cli.d.ts +3 -0
  57. package/dist/integrations/grok/grok-cli.js +92 -13
  58. package/dist/integrations/grok/hooks/grok-hook-utils.js +99 -9
  59. package/dist/integrations/grok/hooks/post-tool-use.js +68 -25
  60. package/dist/integrations/grok/hooks/pre-tool-use.js +17 -14
  61. package/dist/integrations/grok/hooks/session-start.js +114 -4
  62. package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +31 -24
  63. package/dist/integrations/hermes-agent/__init__.py +11 -1
  64. package/dist/integrations/hermes-agent/__pycache__/__init__.cpython-313.pyc +0 -0
  65. package/dist/integrations/hermes-agent/__pycache__/schemas.cpython-313.pyc +0 -0
  66. package/dist/integrations/hermes-agent/__pycache__/tools.cpython-313.pyc +0 -0
  67. package/dist/integrations/hermes-agent/bridge.mjs +92 -11
  68. package/dist/integrations/hooks/confer-hook-runtime.mjs +49 -0
  69. package/dist/integrations/hooks/delegation-gate-runtime.mjs +32 -3
  70. package/dist/integrations/hooks/pipeline-hook-runtime.mjs +211 -0
  71. package/dist/integrations/hooks/plan-hook-runtime.mjs +68 -0
  72. package/dist/integrations/hooks/station-hook-runtime.cjs +421 -0
  73. package/dist/integrations/hooks/station-hook-runtime.mjs +24 -0
  74. package/dist/integrations/hooks/station-memory-ingest.mjs +45 -0
  75. package/dist/integrations/hooks/station-memory-match.mjs +47 -0
  76. package/dist/integrations/hooks/user-aside-hook-runtime.mjs +49 -0
  77. package/dist/integrations/openclaw/client.d.ts +5 -1
  78. package/dist/integrations/openclaw/client.js +17 -9
  79. package/dist/integrations/openclaw/config.js +0 -1
  80. package/dist/integrations/openclaw/hooks/pre-tool-gate-runtime.mjs +102 -0
  81. package/dist/integrations/openclaw/index.js +17 -0
  82. package/dist/integrations/openclaw/plugin/xray-pre-tool/index.js +75 -0
  83. package/dist/integrations/openclaw/plugin/xray-pre-tool/openclaw.plugin.json +10 -0
  84. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +10 -0
  85. package/dist/integrations/openclaw/pre-tool-gate.d.ts +19 -0
  86. package/dist/integrations/openclaw/pre-tool-gate.js +39 -0
  87. package/dist/mcps/architect-tools.server.js +6 -1
  88. package/dist/mcps/orchestrator/handlers/complexity-handler.d.ts +7 -0
  89. package/dist/mcps/orchestrator/handlers/complexity-handler.js +107 -8
  90. package/dist/mcps/orchestrator/handlers/task-handler.d.ts +6 -0
  91. package/dist/mcps/orchestrator/handlers/task-handler.js +75 -0
  92. package/dist/mcps/orchestrator/server.js +54 -5
  93. package/dist/memory-routing/index.d.ts +1 -1
  94. package/dist/memory-routing/index.js +1 -1
  95. package/dist/memory-routing/provider-loader.d.ts +4 -0
  96. package/dist/memory-routing/provider-loader.js +74 -4
  97. package/dist/memory-routing/provider-registry.js +3 -2
  98. package/dist/nucleus/aside-worktree.d.ts +41 -0
  99. package/dist/nucleus/aside-worktree.js +164 -0
  100. package/dist/nucleus/autonomy-kernel.d.ts +2 -2
  101. package/dist/nucleus/autonomy-kernel.js +17 -6
  102. package/dist/nucleus/confer.d.ts +57 -0
  103. package/dist/nucleus/confer.js +322 -0
  104. package/dist/nucleus/delegation-gate.d.ts +18 -8
  105. package/dist/nucleus/delegation-gate.js +234 -20
  106. package/dist/nucleus/lead-dev-plan-persistence.d.ts +27 -3
  107. package/dist/nucleus/lead-dev-plan-persistence.js +201 -19
  108. package/dist/nucleus/spawn-plan-resolution.d.ts +20 -0
  109. package/dist/nucleus/spawn-plan-resolution.js +42 -0
  110. package/dist/nucleus/suit-temperament.d.ts +40 -0
  111. package/dist/nucleus/suit-temperament.js +157 -0
  112. package/dist/nucleus/synthesis-consult-receipt.js +18 -2
  113. package/dist/nucleus/synthesis-context.js +1 -1
  114. package/dist/nucleus/user-aside.d.ts +70 -0
  115. package/dist/nucleus/user-aside.js +393 -0
  116. package/dist/plugin/xray-codex-injection.js +14 -3
  117. package/dist/postprocessor/PostProcessor.d.ts +1 -0
  118. package/dist/postprocessor/PostProcessor.js +11 -0
  119. package/dist/postprocessor/triggers/GitHookTrigger.js +11 -5
  120. package/dist/processors/implementations/session-summary-processor.d.ts +1 -1
  121. package/dist/processors/implementations/session-summary-processor.js +9 -6
  122. package/opencode.json +88 -0
  123. package/package.json +25 -6
  124. package/scripts/hooks/install-hooks.cjs +21 -6
  125. package/scripts/hooks/run-hook.js +237 -88
  126. package/scripts/mjs/run-repertoire-mcp.mjs +39 -0
  127. package/scripts/mjs/verify-confer-core.mjs +103 -0
  128. package/scripts/mjs/verify-delegation-gate-core.mjs +76 -3
  129. package/scripts/mjs/verify-four-floor-compact.mjs +524 -0
  130. package/scripts/mjs/verify-hermes-session-start.mjs +137 -0
  131. package/scripts/mjs/verify-pipeline-facets.mjs +215 -0
  132. package/scripts/mjs/verify-pre-push-diff-core.mjs +87 -0
  133. package/scripts/mjs/verify-temperament-live.mjs +261 -0
  134. package/scripts/mjs/verify-user-aside-core.mjs +137 -0
  135. package/scripts/node/bridge-mcp-wiring.cjs +287 -29
  136. package/scripts/node/install-bridges.cjs +198 -44
  137. package/scripts/node/load-reflection-config.mjs +2 -2
  138. package/scripts/node/postinstall.cjs +50 -27
  139. package/scripts/node/release-gate.mjs +8 -4
  140. package/scripts/node/release.mjs +2 -2
  141. package/scripts/node/validate-release-docs.mjs +20 -33
  142. package/scripts/node/version-manager.mjs +25 -10
  143. package/src/integrations/grok/plugin/0xray/hooks/hooks.json +31 -24
  144. package/src/integrations/openclaw/README.md +134 -0
  145. package/src/integrations/openclaw/plugin/xray-pre-tool/index.js +75 -0
  146. package/src/integrations/openclaw/plugin/xray-pre-tool/openclaw.plugin.json +10 -0
  147. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +10 -0
  148. package/src/mcps/architect-tools.server.ts +6 -1
  149. package/src/mcps/orchestrator/handlers/complexity-handler.ts +180 -21
  150. package/src/mcps/orchestrator/handlers/task-handler.ts +99 -0
  151. package/src/mcps/orchestrator/server.ts +56 -5
  152. package/vendor/@0xray/repertoire/AGENTS.md +163 -0
  153. package/vendor/@0xray/repertoire/LICENSE +21 -0
  154. package/vendor/@0xray/repertoire/README.md +120 -0
  155. package/vendor/@0xray/repertoire/data/curated_signals.json +208 -0
  156. package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts +78 -0
  157. package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts.map +1 -0
  158. package/vendor/@0xray/repertoire/dist/RepertoireService.js +153 -0
  159. package/vendor/@0xray/repertoire/dist/RepertoireService.js.map +1 -0
  160. package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.d.ts +39 -0
  161. package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.d.ts.map +1 -0
  162. package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.js +60 -0
  163. package/vendor/@0xray/repertoire/dist/governance/ontological-trap-enforcer.js.map +1 -0
  164. package/vendor/@0xray/repertoire/dist/index.d.ts +14 -0
  165. package/vendor/@0xray/repertoire/dist/index.d.ts.map +1 -0
  166. package/vendor/@0xray/repertoire/dist/index.js +14 -0
  167. package/vendor/@0xray/repertoire/dist/index.js.map +1 -0
  168. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.d.ts +26 -0
  169. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.d.ts.map +1 -0
  170. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.js +109 -0
  171. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.js.map +1 -0
  172. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.d.ts +18 -0
  173. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.d.ts.map +1 -0
  174. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.js +94 -0
  175. package/vendor/@0xray/repertoire/dist/ingestion/groover-log-parser.js.map +1 -0
  176. package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.d.ts +7 -0
  177. package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.d.ts.map +1 -0
  178. package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.js +18 -0
  179. package/vendor/@0xray/repertoire/dist/ingestion/orchestrator-feedback-ingester.js.map +1 -0
  180. package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.d.ts +31 -0
  181. package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.d.ts.map +1 -0
  182. package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js +83 -0
  183. package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js.map +1 -0
  184. package/vendor/@0xray/repertoire/dist/mcp/server.d.ts +6 -0
  185. package/vendor/@0xray/repertoire/dist/mcp/server.d.ts.map +1 -0
  186. package/vendor/@0xray/repertoire/dist/mcp/server.js +173 -0
  187. package/vendor/@0xray/repertoire/dist/mcp/server.js.map +1 -0
  188. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.d.ts +27 -0
  189. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.d.ts.map +1 -0
  190. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.js +107 -0
  191. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/RepertoireOrchestratorBridge.js.map +1 -0
  192. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.d.ts +11 -0
  193. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.d.ts.map +1 -0
  194. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.js +32 -0
  195. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/capability-enhancer.js.map +1 -0
  196. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.d.ts +9 -0
  197. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.d.ts.map +1 -0
  198. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js +72 -0
  199. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js.map +1 -0
  200. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.d.ts +5 -0
  201. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.d.ts.map +1 -0
  202. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.js +18 -0
  203. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-agent-affinity.js.map +1 -0
  204. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.d.ts +31 -0
  205. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.d.ts.map +1 -0
  206. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js +218 -0
  207. package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js.map +1 -0
  208. package/vendor/@0xray/repertoire/dist/paths.d.ts +24 -0
  209. package/vendor/@0xray/repertoire/dist/paths.d.ts.map +1 -0
  210. package/vendor/@0xray/repertoire/dist/paths.js +74 -0
  211. package/vendor/@0xray/repertoire/dist/paths.js.map +1 -0
  212. package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.d.ts +141 -0
  213. package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.d.ts.map +1 -0
  214. package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js +210 -0
  215. package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js.map +1 -0
  216. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts +48 -0
  217. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts.map +1 -0
  218. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js +221 -0
  219. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js.map +1 -0
  220. package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.d.ts +11 -0
  221. package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.d.ts.map +1 -0
  222. package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.js +43 -0
  223. package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.js.map +1 -0
  224. package/vendor/@0xray/repertoire/dist/registry/signal-prune.d.ts +15 -0
  225. package/vendor/@0xray/repertoire/dist/registry/signal-prune.d.ts.map +1 -0
  226. package/vendor/@0xray/repertoire/dist/registry/signal-prune.js +35 -0
  227. package/vendor/@0xray/repertoire/dist/registry/signal-prune.js.map +1 -0
  228. package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.d.ts +3 -0
  229. package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.d.ts.map +1 -0
  230. package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.js +24 -0
  231. package/vendor/@0xray/repertoire/dist/synthesis/concrete-sections.js.map +1 -0
  232. package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.d.ts +24 -0
  233. package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.d.ts.map +1 -0
  234. package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.js +148 -0
  235. package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.js.map +1 -0
  236. package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.d.ts +4 -0
  237. package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.d.ts.map +1 -0
  238. package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.js +44 -0
  239. package/vendor/@0xray/repertoire/dist/synthesis/primitive-confidence-aggregator.js.map +1 -0
  240. package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.d.ts +22 -0
  241. package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.d.ts.map +1 -0
  242. package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.js +66 -0
  243. package/vendor/@0xray/repertoire/dist/synthesis/synthesis-prompt-builder.js.map +1 -0
  244. package/vendor/@0xray/repertoire/dist/types.d.ts +210 -0
  245. package/vendor/@0xray/repertoire/dist/types.d.ts.map +1 -0
  246. package/vendor/@0xray/repertoire/dist/types.js +2 -0
  247. package/vendor/@0xray/repertoire/dist/types.js.map +1 -0
  248. package/vendor/@0xray/repertoire/docs/MEMORY-ROUTING-PROVIDER.md +54 -0
  249. package/vendor/@0xray/repertoire/hermes-mcp.example.json +20 -0
  250. package/vendor/@0xray/repertoire/mcp-config.example.json +11 -0
  251. package/vendor/@0xray/repertoire/package.json +124 -0
  252. package/vendor/@0xray/repertoire/schemas/curated-signal.schema.json +68 -0
  253. package/vendor/@0xray/repertoire/schemas/inference-log.schema.json +82 -0
  254. package/vendor/@0xray/repertoire/scripts/confirm-suit-all.mjs +253 -0
  255. package/vendor/@0xray/repertoire/scripts/confirm-suit-harness.mjs +220 -0
  256. package/vendor/@0xray/repertoire/scripts/run-live-synthesis-checkpoint.mjs +215 -0
  257. package/vendor/@0xray/repertoire/scripts/suit-bridge-shared.mjs +139 -0
  258. package/vendor/@0xray/repertoire/scripts/verify-grok-suit.mjs +304 -0
  259. package/vendor/@0xray/repertoire/scripts/verify-hermes-suit.mjs +163 -0
  260. package/vendor/@0xray/repertoire/scripts/verify-openclaw-suit.mjs +125 -0
  261. package/vendor/@0xray/repertoire/scripts/verify-opencode-suit.mjs +127 -0
  262. package/vendor/@0xray/repertoire/scripts/verify-synthesis-dogfood.mjs +207 -0
  263. package/vendor/@0xray/repertoire/skills/repertoire-trap-handling/SKILL.md +206 -0
  264. package/xray/codex.json +12 -3
  265. package/xray/features.json +32 -6
  266. package/xray/features.schema.json +87 -0
@@ -0,0 +1,393 @@
1
+ /**
2
+ * User aside — parallel work tracks (worktree-like) declared by the user.
3
+ * SSOT: `.xray/state/asides/{id}.json` + `_active.json`.
4
+ * Todo ids: `{asideId}.a.{phase}.{todo}` — globally unique per aside.
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import { buildLeadDevPlan, isLeadDevModeActive, } from './autonomy-kernel.js';
9
+ import { allPlanTodos, getNextRequiredTodo, getOutstandingTodos, } from './lead-dev-plan-persistence.js';
10
+ export const USER_ASIDE_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/;
11
+ /** Namespaced aside todo: `suit-nft.a.1.1` */
12
+ export const USER_ASIDE_TODO_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}\.a\.\d+\.\d+$/;
13
+ export const USER_ASIDE_STATE_VERSION = 1;
14
+ export class UserAsideValidationError extends Error {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = 'UserAsideValidationError';
18
+ }
19
+ }
20
+ export function assertSafeAsideId(asideId) {
21
+ const trimmed = asideId.trim();
22
+ if (!trimmed || !USER_ASIDE_ID_PATTERN.test(trimmed)) {
23
+ throw new UserAsideValidationError(`Invalid aside id "${asideId}" — use [a-zA-Z0-9][a-zA-Z0-9._-]{0,63}`);
24
+ }
25
+ if (trimmed.includes('..') || trimmed.includes('/') || trimmed.includes('\\')) {
26
+ throw new UserAsideValidationError(`Invalid aside id "${asideId}" — path characters forbidden`);
27
+ }
28
+ return trimmed;
29
+ }
30
+ export function asideTodoId(asideId, phaseIndex, todoIndex) {
31
+ return `${assertSafeAsideId(asideId)}.a.${phaseIndex + 1}.${todoIndex + 1}`;
32
+ }
33
+ export function isUserAsideTodoId(todoId) {
34
+ return USER_ASIDE_TODO_PATTERN.test(todoId);
35
+ }
36
+ export function parseAsideIdFromTodoId(todoId) {
37
+ if (!isUserAsideTodoId(todoId))
38
+ return null;
39
+ const dotA = todoId.indexOf('.a.');
40
+ if (dotA <= 0)
41
+ return null;
42
+ const asideId = todoId.slice(0, dotA);
43
+ try {
44
+ return assertSafeAsideId(asideId);
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ export function userAsidesDir(projectRoot = process.cwd()) {
51
+ return path.join(projectRoot, '.xray', 'state', 'asides');
52
+ }
53
+ export function userAsidePath(asideId, projectRoot = process.cwd()) {
54
+ const safe = assertSafeAsideId(asideId);
55
+ const resolved = path.resolve(userAsidesDir(projectRoot), `${safe}.json`);
56
+ const base = path.resolve(userAsidesDir(projectRoot));
57
+ if (!resolved.startsWith(base + path.sep) && resolved !== base) {
58
+ throw new UserAsideValidationError(`Aside path escapes asides directory: ${asideId}`);
59
+ }
60
+ return resolved;
61
+ }
62
+ export function activeAsidePointerPath(projectRoot = process.cwd()) {
63
+ return path.join(userAsidesDir(projectRoot), '_active.json');
64
+ }
65
+ export function isUserAsidesEnabled(projectRoot = process.cwd()) {
66
+ const featuresPath = path.join(projectRoot, '.xray', 'features.json');
67
+ if (!fs.existsSync(featuresPath))
68
+ return isLeadDevModeActive();
69
+ try {
70
+ const data = JSON.parse(fs.readFileSync(featuresPath, 'utf8'));
71
+ const raw = data.multi_agent_orchestration?.user_asides;
72
+ if (raw?.enabled === false)
73
+ return false;
74
+ return isLeadDevModeActive();
75
+ }
76
+ catch {
77
+ return isLeadDevModeActive();
78
+ }
79
+ }
80
+ function validateLoadedAside(parsed, expectedId) {
81
+ if (!parsed || typeof parsed !== 'object')
82
+ return null;
83
+ const row = parsed;
84
+ if (row.version !== USER_ASIDE_STATE_VERSION)
85
+ return null;
86
+ if (!row.id || !row.title || !row.description || !row.plan)
87
+ return null;
88
+ if (!Array.isArray(row.plan.phases))
89
+ return null;
90
+ try {
91
+ assertSafeAsideId(row.id);
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ if (expectedId && row.id !== expectedId)
97
+ return null;
98
+ for (const phase of row.plan.phases) {
99
+ if (!phase?.todos || !Array.isArray(phase.todos))
100
+ return null;
101
+ }
102
+ return row;
103
+ }
104
+ function remapPhasesToAsidePrefix(asideId, phases) {
105
+ const safeId = assertSafeAsideId(asideId);
106
+ return phases.map((phase, phaseIndex) => ({
107
+ ...phase,
108
+ id: phase.id.startsWith('phase-') ? `aside-phase-${phaseIndex + 1}` : phase.id,
109
+ todos: phase.todos.map((todo, todoIndex) => ({
110
+ ...todo,
111
+ id: asideTodoId(safeId, phaseIndex, todoIndex),
112
+ status: todo.status ?? 'pending',
113
+ })),
114
+ }));
115
+ }
116
+ /** Build a phased aside plan from task intake (mirrors lead-dev plan, namespaced todo ids). */
117
+ export function buildUserAsidePlan(asideId, title, description, taskInputs = [], mcpOverallComplexity, projectRoot = process.cwd()) {
118
+ if (!isUserAsidesEnabled(projectRoot))
119
+ return null;
120
+ const safeId = assertSafeAsideId(asideId);
121
+ const taskTypes = taskInputs.map((t) => t.type ?? 'implement');
122
+ const basePlan = buildLeadDevPlan(description, taskTypes, taskInputs, mcpOverallComplexity, projectRoot);
123
+ if (!basePlan)
124
+ return null;
125
+ return {
126
+ version: USER_ASIDE_STATE_VERSION,
127
+ id: safeId,
128
+ title,
129
+ status: 'active',
130
+ description,
131
+ persistedAt: new Date().toISOString(),
132
+ plan: {
133
+ ...basePlan,
134
+ description: `[Aside ${safeId}] ${description}`,
135
+ phases: remapPhasesToAsidePrefix(safeId, basePlan.phases),
136
+ },
137
+ };
138
+ }
139
+ /** Merge new task intake into an existing aside (re-intake). */
140
+ export function mergeUserAsideIntake(existing, description, taskInputs, mcpOverallComplexity, projectRoot = process.cwd()) {
141
+ const fresh = buildUserAsidePlan(existing.id, existing.title, description || existing.description, taskInputs.length > 0 ? taskInputs : [{ description: existing.description, type: 'implement' }], mcpOverallComplexity, projectRoot);
142
+ if (!fresh)
143
+ return existing;
144
+ const mergedPhases = [...existing.plan.phases];
145
+ for (const phase of fresh.plan.phases) {
146
+ const match = mergedPhases.find((p) => p.id === phase.id);
147
+ if (match) {
148
+ const existingIds = new Set(match.todos.map((t) => t.id));
149
+ for (const todo of phase.todos) {
150
+ if (!existingIds.has(todo.id))
151
+ match.todos.push(todo);
152
+ }
153
+ }
154
+ else {
155
+ mergedPhases.push(phase);
156
+ }
157
+ }
158
+ return {
159
+ ...existing,
160
+ description: description || existing.description,
161
+ status: existing.status === 'completed' ? 'active' : existing.status,
162
+ plan: { ...existing.plan, phases: mergedPhases },
163
+ };
164
+ }
165
+ export function loadUserAside(asideId, projectRoot = process.cwd()) {
166
+ try {
167
+ const filePath = userAsidePath(asideId, projectRoot);
168
+ if (!fs.existsSync(filePath))
169
+ return null;
170
+ const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
171
+ return validateLoadedAside(parsed, assertSafeAsideId(asideId));
172
+ }
173
+ catch {
174
+ return null;
175
+ }
176
+ }
177
+ export function saveUserAside(aside, projectRoot = process.cwd()) {
178
+ assertSafeAsideId(aside.id);
179
+ const dir = userAsidesDir(projectRoot);
180
+ fs.mkdirSync(dir, { recursive: true });
181
+ const filePath = userAsidePath(aside.id, projectRoot);
182
+ const payload = {
183
+ ...aside,
184
+ version: USER_ASIDE_STATE_VERSION,
185
+ persistedAt: new Date().toISOString(),
186
+ };
187
+ fs.writeFileSync(filePath, JSON.stringify(payload, null, 2));
188
+ return filePath;
189
+ }
190
+ export function listUserAsideIds(projectRoot = process.cwd()) {
191
+ const dir = userAsidesDir(projectRoot);
192
+ if (!fs.existsSync(dir))
193
+ return [];
194
+ return fs
195
+ .readdirSync(dir)
196
+ .filter((f) => f.endsWith('.json') && f !== '_active.json')
197
+ .map((f) => f.replace(/\.json$/, ''))
198
+ .filter((id) => USER_ASIDE_ID_PATTERN.test(id));
199
+ }
200
+ export function loadActiveAsidePointer(projectRoot = process.cwd()) {
201
+ const pointerPath = activeAsidePointerPath(projectRoot);
202
+ if (!fs.existsSync(pointerPath))
203
+ return null;
204
+ try {
205
+ const parsed = JSON.parse(fs.readFileSync(pointerPath, 'utf8'));
206
+ if (!parsed?.asideId)
207
+ return null;
208
+ assertSafeAsideId(parsed.asideId);
209
+ return parsed;
210
+ }
211
+ catch {
212
+ return null;
213
+ }
214
+ }
215
+ export function getActiveAsideId(projectRoot = process.cwd(), sessionId) {
216
+ if (!isUserAsidesEnabled(projectRoot))
217
+ return null;
218
+ const pointer = loadActiveAsidePointer(projectRoot);
219
+ if (!pointer)
220
+ return null;
221
+ if (pointer.sessionId) {
222
+ if (!sessionId || pointer.sessionId !== sessionId)
223
+ return null;
224
+ }
225
+ const aside = loadUserAside(pointer.asideId, projectRoot);
226
+ if (!aside || aside.status !== 'active')
227
+ return null;
228
+ return pointer.asideId;
229
+ }
230
+ export function setActiveAsideId(asideId, projectRoot = process.cwd(), sessionId) {
231
+ const safeId = assertSafeAsideId(asideId);
232
+ const aside = loadUserAside(safeId, projectRoot);
233
+ if (!aside) {
234
+ throw new UserAsideValidationError(`Cannot activate aside "${safeId}" — file not found at .xray/state/asides/${safeId}.json`);
235
+ }
236
+ if (aside.status !== 'active' && aside.status !== 'paused') {
237
+ throw new UserAsideValidationError(`Cannot activate aside "${safeId}" — status is ${aside.status}`);
238
+ }
239
+ if (aside.status === 'paused') {
240
+ aside.status = 'active';
241
+ saveUserAside(aside, projectRoot);
242
+ }
243
+ const dir = userAsidesDir(projectRoot);
244
+ fs.mkdirSync(dir, { recursive: true });
245
+ const pointer = {
246
+ asideId: safeId,
247
+ activatedAt: new Date().toISOString(),
248
+ ...(sessionId ? { sessionId } : {}),
249
+ };
250
+ fs.writeFileSync(activeAsidePointerPath(projectRoot), JSON.stringify(pointer, null, 2));
251
+ return pointer;
252
+ }
253
+ export function clearActiveAside(projectRoot = process.cwd()) {
254
+ const pointerPath = activeAsidePointerPath(projectRoot);
255
+ if (!fs.existsSync(pointerPath))
256
+ return false;
257
+ fs.unlinkSync(pointerPath);
258
+ return true;
259
+ }
260
+ export function loadActiveUserAside(projectRoot = process.cwd(), sessionId) {
261
+ const id = getActiveAsideId(projectRoot, sessionId);
262
+ if (!id) {
263
+ const pointer = loadActiveAsidePointer(projectRoot);
264
+ if (pointer) {
265
+ const aside = loadUserAside(pointer.asideId, projectRoot);
266
+ if (aside && aside.status !== 'active')
267
+ clearActiveAside(projectRoot);
268
+ }
269
+ return null;
270
+ }
271
+ const aside = loadUserAside(id, projectRoot);
272
+ if (!aside || aside.status !== 'active') {
273
+ clearActiveAside(projectRoot);
274
+ return null;
275
+ }
276
+ return aside;
277
+ }
278
+ /** PersistedLeadDevPlan view of an aside for spawn-gate reuse. */
279
+ export function asideToSpawnPlan(aside) {
280
+ const plan = { ...aside.plan };
281
+ if (aside.persistedAt)
282
+ plan.persistedAt = aside.persistedAt;
283
+ if (aside.sessionId)
284
+ plan.sessionId = aside.sessionId;
285
+ return plan;
286
+ }
287
+ /** Aside routable when active for session, or pointer is unscoped (accepted exception). */
288
+ export function isAsideActiveForSession(asideId, projectRoot = process.cwd(), sessionId) {
289
+ const activeId = getActiveAsideId(projectRoot, sessionId);
290
+ if (activeId === asideId)
291
+ return true;
292
+ const pointer = loadActiveAsidePointer(projectRoot);
293
+ if (!pointer || pointer.asideId !== asideId)
294
+ return false;
295
+ if (!pointer.sessionId)
296
+ return true;
297
+ return Boolean(sessionId && pointer.sessionId === sessionId);
298
+ }
299
+ export function findAsideContainingTodo(todoId, projectRoot = process.cwd(), preferredAsideId) {
300
+ if (!isUserAsideTodoId(todoId))
301
+ return null;
302
+ if (preferredAsideId) {
303
+ const direct = loadUserAside(preferredAsideId, projectRoot);
304
+ if (direct) {
305
+ const hit = allPlanTodos(asideToSpawnPlan(direct)).some((t) => t.id === todoId);
306
+ if (hit)
307
+ return direct;
308
+ }
309
+ }
310
+ const parsedId = parseAsideIdFromTodoId(todoId);
311
+ if (parsedId) {
312
+ const aside = loadUserAside(parsedId, projectRoot);
313
+ if (aside) {
314
+ const hit = allPlanTodos(asideToSpawnPlan(aside)).some((t) => t.id === todoId);
315
+ if (hit)
316
+ return aside;
317
+ }
318
+ }
319
+ return null;
320
+ }
321
+ export function updateUserAsideTodoStatus(todoId, status, projectRoot = process.cwd(), sessionId) {
322
+ const parsedId = parseAsideIdFromTodoId(todoId);
323
+ let aside = parsedId
324
+ ? findAsideContainingTodo(todoId, projectRoot, parsedId)
325
+ : null;
326
+ if (aside && parsedId && !isAsideActiveForSession(parsedId, projectRoot, sessionId)) {
327
+ aside = null;
328
+ }
329
+ if (!aside)
330
+ aside = loadActiveUserAside(projectRoot, sessionId);
331
+ if (!aside)
332
+ return false;
333
+ let updated = false;
334
+ for (const phase of aside.plan.phases) {
335
+ for (const todo of phase.todos) {
336
+ if (todo.id === todoId) {
337
+ todo.status = status;
338
+ updated = true;
339
+ }
340
+ }
341
+ }
342
+ if (!updated)
343
+ return false;
344
+ const outstanding = getOutstandingTodos(asideToSpawnPlan(aside));
345
+ if (outstanding.length === 0) {
346
+ aside.status = 'completed';
347
+ clearActiveAside(projectRoot);
348
+ }
349
+ saveUserAside(aside, projectRoot);
350
+ return true;
351
+ }
352
+ export function getNextAsideTodo(aside) {
353
+ return getNextRequiredTodo(asideToSpawnPlan(aside));
354
+ }
355
+ export function formatUserAsideSummary(aside) {
356
+ const todos = allPlanTodos(asideToSpawnPlan(aside));
357
+ const done = todos.filter((t) => t.status === 'completed').length;
358
+ const lines = [
359
+ `**Aside \`${aside.id}\`** — ${aside.title}`,
360
+ `Status: ${aside.status} | Todos: ${done}/${todos.length}`,
361
+ aside.worktree ? `Worktree: \`${aside.worktree}\`` : null,
362
+ aside.branch ? `Branch: \`${aside.branch}\`` : null,
363
+ '',
364
+ ...todos.map((t) => `- [${t.status === 'completed' ? 'x' : ' '}] ${t.id} (${t.subagent}): ${t.task}`),
365
+ ].filter(Boolean);
366
+ return lines.join('\n');
367
+ }
368
+ export function getUserAsideBootHints(projectRoot = process.cwd(), sessionId) {
369
+ if (!isUserAsidesEnabled(projectRoot))
370
+ return null;
371
+ const aside = loadActiveUserAside(projectRoot, sessionId);
372
+ if (!aside)
373
+ return null;
374
+ const hints = {
375
+ activeAside: aside.id,
376
+ asideTitle: aside.title,
377
+ asideStatus: aside.status,
378
+ asideTodoPrefix: `${aside.id}.a.*`,
379
+ asideHint: 'Spawns route to active aside todos; orchestrate-task clearActiveAside to resume main',
380
+ };
381
+ if (aside.worktree)
382
+ hints.asideWorktree = aside.worktree;
383
+ if (aside.branch)
384
+ hints.asideBranch = aside.branch;
385
+ if (aside.governance?.trapSignals?.length) {
386
+ hints.asideTrapSignals = aside.governance.trapSignals;
387
+ }
388
+ if (aside.governance?.conferOnPhaseStart) {
389
+ hints.asideConferRecommended = true;
390
+ hints.asideConferTrigger = 'orchestrate-task { confer: true } or synthesis analyze-complexity';
391
+ }
392
+ return hints;
393
+ }
@@ -7,7 +7,7 @@ import { getOrCreateLogger } from "./plugin-logger.js";
7
7
  import { resolveStateDir, importSystemPromptGenerator, loadXrayComponents, getProcessorManager, getXrayStateManager, getFeaturesConfigLoader, getDetectTaskType, getSystemPromptGenerator, } from "./plugin-modules.js";
8
8
  import { getFrameworkIdentity, classifyTaskType, isWriteEditOperation, isPublishOperation, resolveAgentName, registerAllProcessors, registerAfterPostProcessors, logPreProcessorResults, logPostProcessorResults, logTestAutoCreationResult, spawnPromise, } from "./plugin-helpers.js";
9
9
  import { runEnforcerQualityGate } from "./plugin-quality-gate.js";
10
- import { evaluatePostToolSpawn, evaluatePreToolGate, isSubagentTool, loadDelegationGateFeatures, } from "../nucleus/delegation-gate.js";
10
+ import { evaluatePostToolSpawn, evaluatePreToolGate, isSubagentTool, loadDelegationGateFeatures, writeSuitSessionBoot, } from "../nucleus/delegation-gate.js";
11
11
  import { readFileSync } from "fs";
12
12
  import { join } from "path";
13
13
  // Re-export all public API for test compatibility
@@ -23,6 +23,15 @@ let _lastTuneToolCallCount = 0;
23
23
  export default async function xrayCodexPlugin(input) {
24
24
  const { directory: inputDirectory } = input;
25
25
  const directory = inputDirectory || process.cwd();
26
+ try {
27
+ writeSuitSessionBoot(directory, "opencode", {
28
+ source: "0xray/opencode-plugin",
29
+ hookEvent: process.env.XRAY_HOOK_EVENT || "session_start",
30
+ });
31
+ }
32
+ catch {
33
+ /* session-boot is best-effort */
34
+ }
26
35
  return {
27
36
  "experimental.chat.system.transform": async (_input, output) => {
28
37
  try {
@@ -40,7 +49,9 @@ export default async function xrayCodexPlugin(input) {
40
49
  });
41
50
  }
42
51
  if (output.system && Array.isArray(output.system)) {
43
- output.system = [leanPrompt];
52
+ const cardPath = path.join(directory, ".xray", "state", "STATION.md");
53
+ const card = fs.existsSync(cardPath) ? fs.readFileSync(cardPath, "utf8").trim() : "";
54
+ output.system = card ? [leanPrompt, card] : [leanPrompt];
44
55
  }
45
56
  }
46
57
  catch (error) {
@@ -84,7 +95,7 @@ export default async function xrayCodexPlugin(input) {
84
95
  throw new Error(`ENFORCER BLOCKED: ${qualityGateResult.violations.join("; ")}`);
85
96
  }
86
97
  logger.log(`✅ Quality gate passed for ${tool}`);
87
- const features = loadDelegationGateFeatures(directory);
98
+ const features = loadDelegationGateFeatures(directory, "opencode");
88
99
  let sessionId = process.env.GROK_SESSION_ID ?? null;
89
100
  try {
90
101
  const boot = JSON.parse(readFileSync(join(directory, ".xray", "state", "session-boot.json"), "utf8"));
@@ -23,6 +23,7 @@ export declare class PostProcessor {
23
23
  private escalationEngine;
24
24
  private successHandler;
25
25
  private triggers;
26
+ private metamorphosisEngines;
26
27
  constructor(stateManager: XrayStateManager, sessionMonitor?: SessionMonitor | null, config?: Partial<PostProcessorConfig>);
27
28
  /**
28
29
  * Generate automated framework report if conditions are met
@@ -25,6 +25,7 @@ import { defaultConfig } from "./config.js";
25
25
  import { frameworkReportingSystem } from "../reporting/framework-reporting-system.js";
26
26
  import { ReportContentValidator } from "../validation/report-content-validator.js";
27
27
  import { RegressionAnalysisService } from "./services/RegressionAnalysisService.js";
28
+ import { SelfProposalEngine } from "./metamorphosis/SelfProposalEngine.js";
28
29
  export class PostProcessor {
29
30
  stateManager;
30
31
  sessionMonitor;
@@ -39,6 +40,7 @@ export class PostProcessor {
39
40
  escalationEngine;
40
41
  successHandler;
41
42
  triggers;
43
+ metamorphosisEngines;
42
44
  constructor(stateManager, sessionMonitor = null, config = {}) {
43
45
  this.stateManager = stateManager;
44
46
  this.sessionMonitor = sessionMonitor;
@@ -56,6 +58,7 @@ export class PostProcessor {
56
58
  // Initialize escalation and success handlers
57
59
  this.escalationEngine = new EscalationEngine(this.config.escalation);
58
60
  this.successHandler = new SuccessHandler(this.config.success);
61
+ this.metamorphosisEngines = [new SelfProposalEngine({ projectRoot: process.cwd() })];
59
62
  // Initialize trigger mechanisms
60
63
  this.triggers = {
61
64
  gitHook: new GitHookTrigger(this),
@@ -736,6 +739,14 @@ All path violations will be automatically detected and blocked.
736
739
  };
737
740
  // Handle successful completion
738
741
  await this.successHandler.handleSuccess(context, result, monitoringResults);
742
+ for (const engine of this.metamorphosisEngines) {
743
+ try {
744
+ await engine.onPhase('post-process-complete', { context, result, monitoringResults });
745
+ }
746
+ catch (metaErr) {
747
+ await frameworkLogger.log('-post-processor', 'self-proposal-phase-error', 'warning', { error: String(metaErr) });
748
+ }
749
+ }
739
750
  // AGENTS.md auto-update with smart triggers
740
751
  // Only updates when agent-related files have changed
741
752
  const agentChangePatterns = [
@@ -397,10 +397,16 @@ fi
397
397
  (async () => {
398
398
  try {
399
399
  // Use dynamic import that works in both dev and consumer
400
- const basePath = process.env.XRAY_BASE_PATH || '.';
401
- const distPath = process.env.XRAY_DIST_PATH || 'dist';
402
- // First archive logs (compress and rotate) before cleanup
403
- const { archiveLogFiles } = await import(basePath + '/' + distPath + '/postprocessor/triggers/GitHookTrigger.js');
400
+ const { pathToFileURL } = await import('url');
401
+ const { existsSync } = await import('fs');
402
+ const { join } = await import('path');
403
+ const candidates = [
404
+ join(process.cwd(), 'node_modules/0xray/dist/postprocessor/triggers/GitHookTrigger.js'),
405
+ join(process.cwd(), 'dist/postprocessor/triggers/GitHookTrigger.js'),
406
+ ];
407
+ const triggerPath = candidates.find((p) => existsSync(p));
408
+ if (!triggerPath) return;
409
+ const { archiveLogFiles } = await import(pathToFileURL(triggerPath).href);
404
410
  const archiveResult = await archiveLogFiles({
405
411
  archiveDirectory: 'logs/framework',
406
412
  maxFileSizeMB: 10, // Archive if > 10MB
@@ -415,7 +421,7 @@ fi
415
421
  }
416
422
 
417
423
  // Then cleanup old files
418
- const { cleanupLogFiles } = await import(basePath + '/' + distPath + '/postprocessor/triggers/GitHookTrigger.js');
424
+ const { cleanupLogFiles } = await import(pathToFileURL(triggerPath).href);
419
425
  const result = await cleanupLogFiles({
420
426
  maxAgeHours: 24,
421
427
  excludePatterns: [
@@ -2,7 +2,7 @@
2
2
  * Session Summary Post-Processor
3
3
  *
4
4
  * Generates emoji-formatted session summaries after tool execution.
5
- * Uses features.json -> auto_reporting config for control.
5
+ * Uses features.json -> autonomous_reporting config for control.
6
6
  *
7
7
  * @since 2026-04-04
8
8
  */
@@ -2,7 +2,7 @@
2
2
  * Session Summary Post-Processor
3
3
  *
4
4
  * Generates emoji-formatted session summaries after tool execution.
5
- * Uses features.json -> auto_reporting config for control.
5
+ * Uses features.json -> autonomous_reporting config for control.
6
6
  *
7
7
  * @since 2026-04-04
8
8
  */
@@ -29,12 +29,15 @@ export class SessionSummaryProcessor extends PostProcessor {
29
29
  loadConfig() {
30
30
  try {
31
31
  const configData = featuresConfigLoader.loadConfig();
32
- const autoReporting = configData.auto_reporting;
32
+ const autoReporting = configData.autonomous_reporting ?? configData.auto_reporting;
33
33
  if (autoReporting) {
34
- this.config.enabled = autoReporting.mode !== "off";
35
- this.config.include_emojis = autoReporting.display?.indicators?.emojis !== false;
36
- this.config.include_recommendations = autoReporting.report_types?.session_summary?.include_recommendations !== false;
37
- this.config.include_agent_activities = autoReporting.report_types?.session_summary?.include_agent_activities !== false;
34
+ this.config.enabled = autoReporting.enabled !== false;
35
+ this.config.include_emojis =
36
+ autoReporting.include_agent_activities !== false;
37
+ this.config.include_recommendations =
38
+ autoReporting.include_recommendations !== false;
39
+ this.config.include_agent_activities =
40
+ autoReporting.include_agent_activities !== false;
38
41
  }
39
42
  }
40
43
  catch (error) {
package/opencode.json CHANGED
@@ -16,6 +16,94 @@
16
16
  },
17
17
  "global-git": {
18
18
  "enabled": false
19
+ },
20
+ "xray-governance": {
21
+ "type": "local",
22
+ "command": [
23
+ "npx",
24
+ "-y",
25
+ "0xray",
26
+ "mcp",
27
+ "governance"
28
+ ],
29
+ "enabled": true,
30
+ "environment": {
31
+ "XRAY_FORCE_MCP_GOVERNANCE": "true"
32
+ }
33
+ },
34
+ "xray-skills": {
35
+ "type": "local",
36
+ "command": [
37
+ "npx",
38
+ "-y",
39
+ "0xray",
40
+ "mcp",
41
+ "skills"
42
+ ],
43
+ "enabled": true
44
+ },
45
+ "xray-orchestrator": {
46
+ "type": "local",
47
+ "command": [
48
+ "npx",
49
+ "-y",
50
+ "0xray",
51
+ "mcp",
52
+ "orchestrator"
53
+ ],
54
+ "enabled": true
55
+ },
56
+ "xray-enforcer": {
57
+ "type": "local",
58
+ "command": [
59
+ "npx",
60
+ "-y",
61
+ "0xray",
62
+ "mcp",
63
+ "enforcer"
64
+ ],
65
+ "enabled": true
66
+ },
67
+ "xray-researcher": {
68
+ "type": "local",
69
+ "command": [
70
+ "npx",
71
+ "-y",
72
+ "0xray",
73
+ "mcp",
74
+ "researcher"
75
+ ],
76
+ "enabled": true
77
+ },
78
+ "xray-code-review": {
79
+ "type": "local",
80
+ "command": [
81
+ "npx",
82
+ "-y",
83
+ "0xray",
84
+ "mcp",
85
+ "code-review"
86
+ ],
87
+ "enabled": true
88
+ },
89
+ "xray-architect-tools": {
90
+ "type": "local",
91
+ "command": [
92
+ "npx",
93
+ "-y",
94
+ "0xray",
95
+ "mcp",
96
+ "architect-tools"
97
+ ],
98
+ "enabled": true
99
+ },
100
+ "repertoire": {
101
+ "type": "local",
102
+ "command": [
103
+ "node",
104
+ "/tmp/xray-v4-validate/node_modules/@0xray/repertoire/dist/mcp/server.js"
105
+ ],
106
+ "enabled": true
19
107
  }
20
108
  },
21
109
  "agent": {