0xray 3.4.9 → 3.5.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 (36) hide show
  1. package/.xray/features.json +2 -1
  2. package/AGENTS-consumer.md +1 -1
  3. package/AGENTS.md +1 -1
  4. package/README.md +1 -1
  5. package/SKILLS.md +1 -1
  6. package/dist/AGENTS.md +1 -1
  7. package/dist/CHANGELOG.md +32 -0
  8. package/dist/README.md +1 -1
  9. package/dist/SKILLS.md +1 -1
  10. package/dist/core/features-config.d.ts +2 -0
  11. package/dist/integrations/grok/hooks/grok-hook-utils.js +390 -16
  12. package/dist/integrations/grok/hooks/post-tool-use.js +62 -0
  13. package/dist/integrations/grok/hooks/pre-tool-use.js +43 -5
  14. package/dist/integrations/grok/hooks/session-start.js +8 -0
  15. package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +15 -0
  16. package/dist/mcps/orchestrator/config/agent-capabilities.d.ts +1 -1
  17. package/dist/mcps/orchestrator/config/agent-capabilities.js +23 -1
  18. package/dist/mcps/orchestrator/execution/execution-planner.js +2 -2
  19. package/dist/mcps/orchestrator/handlers/complexity-handler.d.ts +1 -0
  20. package/dist/mcps/orchestrator/handlers/complexity-handler.js +8 -1
  21. package/dist/mcps/orchestrator/handlers/task-handler.js +20 -3
  22. package/dist/nucleus/autonomy-kernel.d.ts +1 -1
  23. package/dist/nucleus/autonomy-kernel.js +5 -2
  24. package/dist/nucleus/lead-dev-plan-persistence.d.ts +43 -0
  25. package/dist/nucleus/lead-dev-plan-persistence.js +155 -0
  26. package/dist/nucleus/pending-delegations.d.ts +71 -0
  27. package/dist/nucleus/pending-delegations.js +285 -0
  28. package/package.json +6 -2
  29. package/scripts/mjs/verify-grok-delegation-gate.mjs +173 -0
  30. package/scripts/mjs/verify-orchestrator-behavior.mjs +168 -0
  31. package/src/integrations/grok/plugin/0xray/hooks/hooks.json +15 -0
  32. package/src/mcps/orchestrator/config/agent-capabilities.ts +26 -0
  33. package/src/mcps/orchestrator/execution/execution-planner.ts +2 -0
  34. package/src/mcps/orchestrator/handlers/complexity-handler.ts +9 -1
  35. package/src/mcps/orchestrator/handlers/task-handler.ts +53 -3
  36. package/xray/features.json +2 -1
@@ -13,6 +13,25 @@ import {
13
13
  toMemoryCapabilityMap,
14
14
  fromMemoryCapabilityMap,
15
15
  } from './memory-routing-bridge.js';
16
+ import { routeSubagent } from '../../../nucleus/autonomy-kernel.js';
17
+
18
+ /** routeSubagent names → AGENT_REGISTRY keys */
19
+ const ROUTE_AGENT_ALIASES: Record<string, string> = {
20
+ 'code-review': 'code-reviewer',
21
+ 'security-audit': 'security-auditor',
22
+ 'bug-triage': 'bug-triage-specialist',
23
+ 'architect-tools': 'architect',
24
+ };
25
+
26
+ function resolveRoutedAgent(
27
+ routed: string,
28
+ capabilities: Map<string, AgentCapability>,
29
+ ): string | null {
30
+ const candidate = ROUTE_AGENT_ALIASES[routed] ?? routed;
31
+ if (capabilities.has(candidate)) return candidate;
32
+ if (capabilities.has(routed)) return routed;
33
+ return null;
34
+ }
16
35
 
17
36
  const DEFAULT_AGENT_CAPABILITIES: Record<string, AgentCapability> = Object.fromEntries(
18
37
  Object.entries(AGENT_REGISTRY).map(([name, entry]) => [
@@ -81,7 +100,14 @@ export class AgentCapabilitiesManager {
81
100
  requiredCapabilities: string[],
82
101
  complexity: number,
83
102
  operationDescription = '',
103
+ taskType = '',
84
104
  ): string | null {
105
+ if (taskType.trim()) {
106
+ const routed = routeSubagent(taskType);
107
+ const resolved = resolveRoutedAgent(routed, this.capabilities);
108
+ if (resolved) return resolved;
109
+ }
110
+
85
111
  const provider = getProvider();
86
112
 
87
113
  if (provider.id !== 'null' && operationDescription) {
@@ -243,6 +243,7 @@ export class ExecutionPlanner {
243
243
  requiredCaps,
244
244
  complexity,
245
245
  operationDescription,
246
+ task.type,
246
247
  ) || 'orchestrator';
247
248
 
248
249
  if (!agentAssignments.has(agent)) {
@@ -298,6 +299,7 @@ export class ExecutionPlanner {
298
299
  requiredCaps,
299
300
  complexity,
300
301
  task.description,
302
+ task.type,
301
303
  ) || 'orchestrator';
302
304
 
303
305
  if (!assignments.has(agent)) {
@@ -10,6 +10,8 @@ import {
10
10
  isLeadDevModeActive,
11
11
  persistLeadDevPlan,
12
12
  } from '../../../nucleus/autonomy-kernel.js';
13
+ import { bindPlanToSession } from '../../../nucleus/lead-dev-plan-persistence.js';
14
+ import { clearPendingDelegations } from '../../../nucleus/pending-delegations.js';
13
15
  import { getExecutionPlanner } from '../execution/execution-planner.js';
14
16
  import { addObservations, extractComplexityObservations } from '../aside-context.js';
15
17
  import type { OrchestrationTask, ComplexityAnalysis } from '../types.js';
@@ -65,7 +67,7 @@ export class ComplexityHandler {
65
67
  * Handle analyze-complexity request
66
68
  */
67
69
  async handleAnalyzeComplexity(
68
- args: { tasks: AnalyzeComplexityInput[] },
70
+ args: { tasks: AnalyzeComplexityInput[]; sessionId?: string },
69
71
  asideId?: string,
70
72
  ): Promise<{ content: Array<{ type: string; text: string }> }> {
71
73
  const tasks = normalizeAnalyzeTasks(args.tasks ?? []);
@@ -96,18 +98,24 @@ export class ComplexityHandler {
96
98
  primaryDescription,
97
99
  taskTypes.length ? taskTypes : ['implement'],
98
100
  planTaskInputs,
101
+ analysis.overallComplexity,
99
102
  )
100
103
  : null;
101
104
 
102
105
  if (leadDevPlan) {
103
106
  try {
107
+ const sessionId = args.sessionId ?? `analyze-${Date.now()}`;
108
+ clearPendingDelegations();
104
109
  const planPath = persistLeadDevPlan(leadDevPlan);
110
+ const bound = bindPlanToSession(sessionId);
105
111
  await frameworkLogger.log(
106
112
  'orchestrator.server',
107
113
  'lead-dev-plan-persisted',
108
114
  'info',
109
115
  {
110
116
  planPath,
117
+ sessionId,
118
+ planGeneration: bound?.planGeneration,
111
119
  phaseCount: leadDevPlan.phases.length,
112
120
  todoCount: leadDevPlan.phases.reduce((n, p) => n + p.todos.length, 0),
113
121
  },
@@ -9,6 +9,11 @@ import { getExecutionPlanner } from '../execution/execution-planner.js';
9
9
  import { mcpClientManager } from '../../../mcps/mcp-client.js';
10
10
  import { addObservations, extractOrchestrationObservations, spawnAside } from '../aside-context.js';
11
11
  import { getProvider } from '../config/memory-routing-bridge.js';
12
+ import {
13
+ delegationSummaryForResponse,
14
+ recordDeferredDelegations,
15
+ type PendingDelegation,
16
+ } from '../../../nucleus/pending-delegations.js';
12
17
  import type { OrchestrationResult, OrchestrationTask } from '../types.js';
13
18
 
14
19
  export interface TaskHandlerDeps {
@@ -66,6 +71,7 @@ export class TaskHandler {
66
71
  };
67
72
 
68
73
  const startTime = Date.now();
74
+ let pendingDelegations: PendingDelegation[] = [];
69
75
 
70
76
  try {
71
77
  // Validate tasks
@@ -90,6 +96,16 @@ export class TaskHandler {
90
96
 
91
97
  const results = await this.executePlan(executionPlan, sessionId, timeout);
92
98
 
99
+ if (results.deferredRecords.length > 0) {
100
+ pendingDelegations = recordDeferredDelegations(sessionId, results.deferredRecords);
101
+ await frameworkLogger.log(
102
+ 'orchestrator.task-handler',
103
+ 'pending-delegations-recorded',
104
+ 'info',
105
+ { count: pendingDelegations.length, sessionId },
106
+ );
107
+ }
108
+
93
109
  // Feed per-task outcomes back to memory provider (not aggregate session stats)
94
110
  if (memoryProvider.ingestFeedback) {
95
111
  const outcomeByKey = new Map(
@@ -150,7 +166,12 @@ export class TaskHandler {
150
166
 
151
167
  orchestrationResult.duration = Date.now() - startTime;
152
168
 
153
- const response = this.formatOrchestrationResponse(description, orchestrationResult, executionMode);
169
+ const response = this.formatOrchestrationResponse(
170
+ description,
171
+ orchestrationResult,
172
+ executionMode,
173
+ pendingDelegations,
174
+ );
154
175
 
155
176
  return { content: [{ type: 'text', text: response }] };
156
177
  }
@@ -173,6 +194,12 @@ export class TaskHandler {
173
194
  bottlenecks: string[];
174
195
  recommendations: string[];
175
196
  agentOutputs?: Record<string, string>;
197
+ deferredRecords: Array<{
198
+ taskId: string;
199
+ agent: string;
200
+ description: string;
201
+ type?: string;
202
+ }>;
176
203
  taskOutcomes: Array<{
177
204
  taskId: string;
178
205
  agent: string;
@@ -185,6 +212,12 @@ export class TaskHandler {
185
212
  let failedTasks = 0;
186
213
  let deferredTasks = 0;
187
214
  const agentOutputs: Record<string, string> = {};
215
+ const deferredRecords: Array<{
216
+ taskId: string;
217
+ agent: string;
218
+ description: string;
219
+ type?: string;
220
+ }> = [];
188
221
  const taskOutcomes: Array<{
189
222
  taskId: string;
190
223
  agent: string;
@@ -245,6 +278,12 @@ export class TaskHandler {
245
278
  } else {
246
279
  for (const task of tasks) {
247
280
  deferredTasks++;
281
+ deferredRecords.push({
282
+ taskId: task.id,
283
+ agent,
284
+ description: task.description,
285
+ type: task.type,
286
+ });
248
287
  taskOutcomes.push({
249
288
  taskId: task.id,
250
289
  agent,
@@ -288,6 +327,7 @@ export class TaskHandler {
288
327
  bottlenecks,
289
328
  recommendations,
290
329
  agentOutputs,
330
+ deferredRecords,
291
331
  taskOutcomes,
292
332
  };
293
333
  }
@@ -329,8 +369,18 @@ export class TaskHandler {
329
369
  private formatOrchestrationResponse(
330
370
  description: string,
331
371
  result: OrchestrationResult,
332
- executionMode: string
372
+ executionMode: string,
373
+ pendingDelegations: PendingDelegation[] = [],
333
374
  ): string {
375
+ const delegationsBlock =
376
+ pendingDelegations.length > 0
377
+ ? `\n**Delegations (host Task required):**\n\`\`\`json\n${JSON.stringify(
378
+ { delegations: delegationSummaryForResponse(pendingDelegations) },
379
+ null,
380
+ 2,
381
+ )}\n\`\`\`\n`
382
+ : '';
383
+
334
384
  return `🎯 Orchestration Complete: "${description}"
335
385
 
336
386
  **Session ID:** ${result.sessionId}
@@ -355,6 +405,6 @@ ${result.recommendations.length > 0 ? result.recommendations.map((r) => `•
355
405
 
356
406
  ${result.agentOutputs && Object.keys(result.agentOutputs).length > 0
357
407
  ? `**Agent Outputs (real MCP responses):**\n${Object.entries(result.agentOutputs).map(([k, v]) => `• ${k}: ${v.substring(0, 200)}${v.length > 200 ? '...' : ''}`).join('\n')}\n`
358
- : ''}`;
408
+ : ''}${delegationsBlock}`;
359
409
  }
360
410
  }
@@ -35,7 +35,8 @@
35
35
  "per_suite_test_triage": true,
36
36
  "phased_plan_threshold": 25,
37
37
  "auto_consult_major_work": true,
38
- "no_new_surface": true
38
+ "no_new_surface": true,
39
+ "auto_chain_delegations": true
39
40
  },
40
41
  "autonomous_reporting": {
41
42
  "enabled": true,