@llm-dev-ops/agentics-cli 2.7.36 → 2.7.38

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 (95) hide show
  1. package/dist/adapters/base-adapter.d.ts.map +1 -1
  2. package/dist/adapters/base-adapter.js.map +1 -1
  3. package/dist/agents/repo-agent-runner.d.ts.map +1 -1
  4. package/dist/agents/repo-agent-runner.js +0 -2
  5. package/dist/agents/repo-agent-runner.js.map +1 -1
  6. package/dist/agents/system-prompts.d.ts.map +1 -1
  7. package/dist/agents/system-prompts.js +0 -19
  8. package/dist/agents/system-prompts.js.map +1 -1
  9. package/dist/cli/index.js +1 -1
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/commands/agents.d.ts +4 -24
  12. package/dist/commands/agents.d.ts.map +1 -1
  13. package/dist/commands/agents.js +30 -106
  14. package/dist/commands/agents.js.map +1 -1
  15. package/dist/mcp/agent-event-parser.d.ts +1 -11
  16. package/dist/mcp/agent-event-parser.d.ts.map +1 -1
  17. package/dist/mcp/agent-event-parser.js +7 -153
  18. package/dist/mcp/agent-event-parser.js.map +1 -1
  19. package/dist/mcp/mcp-server.js +0 -58
  20. package/dist/mcp/mcp-server.js.map +1 -1
  21. package/dist/pipeline/auto-chain.d.ts.map +1 -1
  22. package/dist/pipeline/auto-chain.js +27 -169
  23. package/dist/pipeline/auto-chain.js.map +1 -1
  24. package/dist/pipeline/local-fallback/phase5a-local-fallback.d.ts +21 -18
  25. package/dist/pipeline/local-fallback/phase5a-local-fallback.d.ts.map +1 -1
  26. package/dist/pipeline/local-fallback/phase5a-local-fallback.js +92 -397
  27. package/dist/pipeline/local-fallback/phase5a-local-fallback.js.map +1 -1
  28. package/dist/pipeline/phase2/phases/adr-generator.d.ts +29 -1
  29. package/dist/pipeline/phase2/phases/adr-generator.d.ts.map +1 -1
  30. package/dist/pipeline/phase2/phases/adr-generator.js +709 -1399
  31. package/dist/pipeline/phase2/phases/adr-generator.js.map +1 -1
  32. package/dist/pipeline/phase2/phases/ddd-generator.d.ts.map +1 -1
  33. package/dist/pipeline/phase2/phases/ddd-generator.js +7 -42
  34. package/dist/pipeline/phase2/phases/ddd-generator.js.map +1 -1
  35. package/dist/pipeline/phase2/phases/research-dossier.d.ts.map +1 -1
  36. package/dist/pipeline/phase2/phases/research-dossier.js +2 -33
  37. package/dist/pipeline/phase2/phases/research-dossier.js.map +1 -1
  38. package/dist/pipeline/phase2/phases/sparc-specification.d.ts.map +1 -1
  39. package/dist/pipeline/phase2/phases/sparc-specification.js +2 -27
  40. package/dist/pipeline/phase2/phases/sparc-specification.js.map +1 -1
  41. package/dist/pipeline/phase2/types.d.ts +19 -57
  42. package/dist/pipeline/phase2/types.d.ts.map +1 -1
  43. package/dist/pipeline/phase4-adrs/adr-index-extractor.d.ts +75 -0
  44. package/dist/pipeline/phase4-adrs/adr-index-extractor.d.ts.map +1 -0
  45. package/dist/pipeline/phase4-adrs/adr-index-extractor.js +200 -0
  46. package/dist/pipeline/phase4-adrs/adr-index-extractor.js.map +1 -0
  47. package/dist/pipeline/phase4-adrs/phase4-adrs-coordinator.d.ts.map +1 -1
  48. package/dist/pipeline/phase4-adrs/phase4-adrs-coordinator.js +70 -68
  49. package/dist/pipeline/phase4-adrs/phase4-adrs-coordinator.js.map +1 -1
  50. package/dist/pipeline/phase7/deliverables-registry.js +1 -1
  51. package/dist/pipeline/phase7/deliverables-registry.js.map +1 -1
  52. package/dist/pipeline/phases/adr-ddd-generator.d.ts.map +1 -1
  53. package/dist/pipeline/phases/adr-ddd-generator.js +48 -2
  54. package/dist/pipeline/phases/adr-ddd-generator.js.map +1 -1
  55. package/dist/pipeline/phases/prompt-generator.js +191 -80
  56. package/dist/pipeline/phases/prompt-generator.js.map +1 -1
  57. package/dist/pipeline/ruflo-phase-executor.d.ts +2 -5
  58. package/dist/pipeline/ruflo-phase-executor.d.ts.map +1 -1
  59. package/dist/pipeline/ruflo-phase-executor.js +72 -23
  60. package/dist/pipeline/ruflo-phase-executor.js.map +1 -1
  61. package/dist/pipeline/types.d.ts +14 -1
  62. package/dist/pipeline/types.d.ts.map +1 -1
  63. package/dist/routing/domain-boundary.d.ts +4 -20
  64. package/dist/routing/domain-boundary.d.ts.map +1 -1
  65. package/dist/routing/domain-boundary.js +6 -81
  66. package/dist/routing/domain-boundary.js.map +1 -1
  67. package/dist/routing/graph-router.d.ts.map +1 -1
  68. package/dist/routing/graph-router.js +0 -22
  69. package/dist/routing/graph-router.js.map +1 -1
  70. package/dist/synthesis/ask-artifact-writer.d.ts +1 -1
  71. package/dist/synthesis/ask-artifact-writer.d.ts.map +1 -1
  72. package/dist/synthesis/ask-artifact-writer.js +9 -9
  73. package/dist/synthesis/ask-artifact-writer.js.map +1 -1
  74. package/dist/synthesis/simulation-artifact-generator.d.ts +1 -27
  75. package/dist/synthesis/simulation-artifact-generator.d.ts.map +1 -1
  76. package/dist/synthesis/simulation-artifact-generator.js +38 -128
  77. package/dist/synthesis/simulation-artifact-generator.js.map +1 -1
  78. package/docs/ecosystem.graph.json +15 -65
  79. package/package.json +1 -1
  80. package/dist/cli/ui/heartbeat.d.ts +0 -88
  81. package/dist/cli/ui/heartbeat.d.ts.map +0 -1
  82. package/dist/cli/ui/heartbeat.js +0 -158
  83. package/dist/cli/ui/heartbeat.js.map +0 -1
  84. package/dist/config/qe-gating.d.ts +0 -81
  85. package/dist/config/qe-gating.d.ts.map +0 -1
  86. package/dist/config/qe-gating.js +0 -138
  87. package/dist/config/qe-gating.js.map +0 -1
  88. package/dist/pipeline/phase5-build/qe-gating-executor.d.ts +0 -73
  89. package/dist/pipeline/phase5-build/qe-gating-executor.d.ts.map +0 -1
  90. package/dist/pipeline/phase5-build/qe-gating-executor.js +0 -134
  91. package/dist/pipeline/phase5-build/qe-gating-executor.js.map +0 -1
  92. package/dist/synthesis/agent-fleet-decomposer.d.ts +0 -124
  93. package/dist/synthesis/agent-fleet-decomposer.d.ts.map +0 -1
  94. package/dist/synthesis/agent-fleet-decomposer.js +0 -696
  95. package/dist/synthesis/agent-fleet-decomposer.js.map +0 -1
@@ -17,7 +17,6 @@ import { execFileSync } from 'node:child_process';
17
17
  import { isTransientFailure, isTerminalFailure } from '../errors/transient.js';
18
18
  import { recordDegradation, drainDegradations } from '../observability/degradations.js';
19
19
  import { computePhase1Verdict } from '../pipeline/phase1-verdict.js';
20
- import { pipelineHeartbeat } from '../cli/ui/heartbeat.js';
21
20
  // ============================================================================
22
21
  // ADR-066: Copilot agents via claude --print (Claude Max — no API key needed)
23
22
  // ============================================================================
@@ -324,33 +323,12 @@ export const AGENT_DOMAINS = {
324
323
  },
325
324
  };
326
325
  /**
327
- * ADR-PIPELINE-087 §1 + 2.5.2 hotfix: domains that resolve through
328
- * AGENT_NAME_TO_DOMAIN but are NOT wired for direct cloud-function dispatch.
329
- *
330
- * Why: ADR-PIPELINE-080..086 added 14 AQE agents to the validation capability
331
- * as mandatory_agents. With 2.5.1 we registered AGENT_DOMAINS['quality-engineering']
332
- * and an adapter pointing at a guessed URL. Result: every ask call spawned 14
333
- * network attempts to a non-existent endpoint, each waiting out the per-call
334
- * timeout before the outer catch caught it. Stacked serially in
335
- * Promise.allSettled the delays were tolerable, but Claude Code's MCP client
336
- * tool-call budget is shorter than the pipeline wall time, so clients saw
337
- * "Tool result missing due to internal error."
338
- *
339
- * Resolution-only policy (2.5.2):
340
- * - `quality-engineering` (AQE): no cloud handler deployed at a URL the CLI
341
- * knows. Dispatch short-circuits with a clear 503 and zero network cost.
342
- * - `diligence-artifacts`: SPARC/ADR/DDD/Context Map work is driven by the
343
- * auto-chain phase coordinators (phase2/phase3/phase4), NOT by the graph-
344
- * routed direct-dispatch path. Skip the adapter.
345
- *
346
- * Net effect: the ADR-087 goal is preserved (no silent drops — classifier
347
- * selections resolve and are observable in `routing.unresolved === []`) while
348
- * the pipeline finishes inside Claude Code's tool-call window again.
349
- *
350
- * Landing 2 removes entries here as real handlers come online.
326
+ * Domains that resolve through AGENT_NAME_TO_DOMAIN but are NOT wired for
327
+ * direct cloud-function dispatch. `diligence-artifacts` SPARC/ADR/DDD/Context
328
+ * Map work is driven by the auto-chain phase coordinators (phase2/phase3/
329
+ * phase4), not by the graph-routed direct-dispatch path.
351
330
  */
352
331
  export const RESOLUTION_ONLY_DOMAINS = new Set([
353
- 'quality-engineering',
354
332
  'diligence-artifacts',
355
333
  ]);
356
334
  export function isResolutionOnlyDomain(domain) {
@@ -402,12 +380,7 @@ export async function executeAgentsHealthCommand(domain, options) {
402
380
  }
403
381
  export async function executeAgentsInvokeCommand(domain, agent, payload, options) {
404
382
  const start = Date.now();
405
- // ADR-PIPELINE-087 §1 + 2.5.2 hotfix: short-circuit resolution-only domains
406
- // BEFORE the AGENT_DOMAINS check, the adapter creation, and any network I/O.
407
- // These domains are resolved for routing visibility but have no direct
408
- // dispatch handler — attempting a cloud call would stack per-invocation
409
- // timeouts and blow Claude Code's MCP client budget (see the RESOLUTION_ONLY
410
- // block comment above). Fast-fail with a structured 503 instead.
383
+ // Short-circuit resolution-only domains (no direct dispatch handler).
411
384
  if (RESOLUTION_ONLY_DOMAINS.has(domain)) {
412
385
  return {
413
386
  domain,
@@ -415,11 +388,7 @@ export async function executeAgentsInvokeCommand(domain, agent, payload, options
415
388
  status: 503,
416
389
  response: {
417
390
  status: 'resolution-only',
418
- reason: `${domain}/${agent} is registered in the router for classification visibility but is not wired for direct cloud-function dispatch. `
419
- + (domain === 'diligence-artifacts'
420
- ? 'SPARC/ADR/DDD artifacts are produced by the auto-chain phase coordinators (phase2/phase3/phase4).'
421
- : 'AQE agents will be wired to a real handler in a follow-up landing.'),
422
- adr: 'ADR-PIPELINE-087',
391
+ reason: `${domain}/${agent} is registered in the router for classification visibility but is not wired for direct cloud-function dispatch. SPARC/ADR/DDD artifacts are produced by the auto-chain phase coordinators (phase2/phase3/phase4).`,
423
392
  },
424
393
  timing: Date.now() - start,
425
394
  };
@@ -3779,20 +3748,27 @@ export async function executeNaturalLanguageRoute(query, options) {
3779
3748
  // Top-of-function entry banner — fires within microseconds of dispatch so
3780
3749
  // the user sees the route is executing even if subsequent operations
3781
3750
  // (graph load, ruvector simulation, fleet dispatch) take a while.
3782
- // ADR-PIPELINE-100 §D5 — emit AGENTICS_TRACE_ID=<id> as the very first
3783
- // line so the MCP server's fast-return path can grab it within the first
3784
- // 100ms and return a "pipeline started, tail this log" response to the
3785
- // caller without blocking on the rest of the run.
3786
- process.stderr.write(`AGENTICS_TRACE_ID=${correlationId}\n`);
3787
3751
  process.stderr.write(`[agentics] route entered — query="${query.slice(0, 100)}${query.length > 100 ? '…' : ''}" depth=${options.depth ?? 'lite'} trace=${correlationId.slice(0, 8)}\n`);
3788
- // ADR-PIPELINE-099 D3 process-wide heartbeat. Survives across the
3789
- // executeNaturalLanguageRoute executeAutoChain handoff (the previous
3790
- // per-call heartbeat died at the function boundary, leaving Phases 2–7
3791
- // silent for minutes at a time). Idempotent auto-chain calls start()
3792
- // again with no effect. Stop happens at the end of executeAutoChain or
3793
- // via the singleton's exit handlers.
3794
- pipelineHeartbeat.start('agentics ask');
3795
- pipelineHeartbeat.setPhase('Phase 1 — Fleet Dispatch + Simulation');
3752
+ // Global 10-second heartbeat. Ticks until process exit (`unref()` keeps it
3753
+ // from blocking termination). When any other code emits its own output the
3754
+ // tick still fires but that's acceptable better noisy than silent. The
3755
+ // heartbeat suppresses itself via `lastOutputAt` if other writes have
3756
+ // happened recently.
3757
+ let lastOutputAt = Date.now();
3758
+ const realStderrWrite = process.stderr.write.bind(process.stderr);
3759
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3760
+ process.stderr.write = (chunk, ...rest) => {
3761
+ lastOutputAt = Date.now();
3762
+ return realStderrWrite(chunk, ...rest);
3763
+ };
3764
+ const heartbeat = setInterval(() => {
3765
+ if (Date.now() - lastOutputAt < 9_000)
3766
+ return; // something else just wrote
3767
+ const elapsedSec = Math.floor((Date.now() - start) / 1000);
3768
+ realStderrWrite(`[agentics] ⏳ still working — ${elapsedSec}s elapsed\n`);
3769
+ lastOutputAt = Date.now();
3770
+ }, 10_000);
3771
+ heartbeat.unref();
3796
3772
  // ========================================================================
3797
3773
  // ADR-030: Capability Graph Routing
3798
3774
  //
@@ -3835,7 +3811,6 @@ export async function executeNaturalLanguageRoute(query, options) {
3835
3811
  console.error(graphResult.routing.explanation);
3836
3812
  // Run ruvector simulation first (same as full-fleet path, ADR-016)
3837
3813
  console.error(' [RUVECTOR] Running simulation before graph-routed dispatch (ADR-016)...');
3838
- pipelineHeartbeat.setActivity(`ruvector: simulating ${graphResult.routing.totalAgents}-agent graph route`);
3839
3814
  const simResult = await (async () => {
3840
3815
  const MAX_RETRIES = 3;
3841
3816
  let lastErr;
@@ -3874,21 +3849,8 @@ export async function executeNaturalLanguageRoute(query, options) {
3874
3849
  const REPO_LOCAL_DOMAINS = new Set(['copilot']);
3875
3850
  const prevLocalAgents = process.env['AGENTICS_LOCAL_AGENTS'];
3876
3851
  console.error(` Dispatching ${graphResult.agents.length} graph-routed agents...`);
3877
- pipelineHeartbeat.setActivity(`fleet: dispatching ${graphResult.agents.length} graph-routed agents`);
3878
3852
  const agentPromises = [];
3879
- // ADR-PIPELINE-100 D2 emit a `[FLEET-CALL]` line as each agent
3880
- // STARTS and a result line when each FINISHES. The fleet runs in
3881
- // parallel via Promise.allSettled, so without these lines the user
3882
- // sees nothing for 1-3 minutes between the dispatch banner and the
3883
- // aggregate result. Pre-2.7.27 builds had this same silence — it
3884
- // never went away by itself when the heartbeat singleton was added.
3885
- const fleetTotal = graphResult.agents.length;
3886
- let fleetStartedCount = 0;
3887
- let fleetFinishedCount = 0;
3888
- graphResult.agents.forEach((ref, idx) => {
3889
- const agentStart = Date.now();
3890
- fleetStartedCount++;
3891
- process.stderr.write(` [FLEET-CALL] [${String(idx + 1).padStart(3, ' ')}/${fleetTotal}] → ${ref.domain}/${ref.agent}\n`);
3853
+ for (const ref of graphResult.agents) {
3892
3854
  agentPromises.push((async () => {
3893
3855
  try {
3894
3856
  if (!REPO_LOCAL_DOMAINS.has(ref.domain)) {
@@ -3902,25 +3864,12 @@ export async function executeNaturalLanguageRoute(query, options) {
3902
3864
  }
3903
3865
  const payload = buildDomainPayload(ref.domain, ref.agent, query, correlationId);
3904
3866
  const result = await executeAgentsInvokeCommand(ref.domain, ref.agent, payload, options);
3905
- const elapsed = ((Date.now() - agentStart) / 1000).toFixed(1);
3906
- fleetFinishedCount++;
3907
- const status = result.status ?? 200;
3908
- const ok = status >= 200 && status < 300;
3909
- process.stderr.write(` [FLEET-CALL] [${String(idx + 1).padStart(3, ' ')}/${fleetTotal}] ${ok ? '✓' : '✗'} ${ref.domain}/${ref.agent} (${elapsed}s, ${fleetFinishedCount}/${fleetTotal} done)\n`);
3910
- pipelineHeartbeat.setActivity(`fleet: ${fleetFinishedCount}/${fleetTotal} agents complete`);
3911
- return { kind: 'agent', domain: ref.domain, agent: ref.agent, status, response: result.response };
3867
+ return { kind: 'agent', domain: ref.domain, agent: ref.agent, status: result.status ?? 200, response: result.response };
3912
3868
  }
3913
3869
  catch (err) {
3914
- fleetFinishedCount++;
3915
- const elapsed = ((Date.now() - agentStart) / 1000).toFixed(1);
3916
- const errMsg = err instanceof Error ? err.message.slice(0, 80) : String(err).slice(0, 80);
3917
- process.stderr.write(` [FLEET-CALL] [${String(idx + 1).padStart(3, ' ')}/${fleetTotal}] ✗ ${ref.domain}/${ref.agent} (${elapsed}s) — ${errMsg}\n`);
3918
3870
  return { kind: 'agent', domain: ref.domain, agent: ref.agent, status: 502, response: { error: err instanceof Error ? err.message : String(err) } };
3919
3871
  }
3920
3872
  })());
3921
- });
3922
- if (fleetStartedCount > 0) {
3923
- process.stderr.write(` [FLEET-CALL] all ${fleetStartedCount} agents in flight — awaiting responses...\n`);
3924
3873
  }
3925
3874
  const allResults = await Promise.allSettled([Promise.resolve(simResult), ...agentPromises]);
3926
3875
  const elapsed = Date.now() - start;
@@ -4210,7 +4159,6 @@ export async function executeNaturalLanguageRoute(query, options) {
4210
4159
  { domain: 'platform', agent: 'risk-score' },
4211
4160
  ];
4212
4161
  console.error(`Dispatching ${fleetAgents.length} agents across ALL 27 domains + ruvector simulation`);
4213
- pipelineHeartbeat.setActivity(`fleet: dispatching ${fleetAgents.length} agents across 27 domains`);
4214
4162
  // ========================================================================
4215
4163
  // ADR-016: Run ruvector simulation BEFORE fleet dispatch (sequential).
4216
4164
  //
@@ -4223,7 +4171,6 @@ export async function executeNaturalLanguageRoute(query, options) {
4223
4171
  // start the fleet. Adds ~5s latency but guarantees simulation success.
4224
4172
  // ========================================================================
4225
4173
  console.error(' [RUVECTOR] Running simulation before fleet dispatch (ADR-016)...');
4226
- pipelineHeartbeat.setActivity('ruvector: pre-fleet simulation');
4227
4174
  const simResult = await (async () => {
4228
4175
  const MAX_RETRIES = 3;
4229
4176
  let lastErr;
@@ -4270,24 +4217,12 @@ export async function executeNaturalLanguageRoute(query, options) {
4270
4217
  const WAVE_SIZE = 15;
4271
4218
  const WAVE_DELAY_MS = 2000;
4272
4219
  const agentPromises = [];
4273
- // ADR-PIPELINE-100 D2 — per-agent visibility for the full-fleet path.
4274
- // Without these per-call lines the user sees a "Wave N/M" banner then
4275
- // 1-3 minutes of silence per wave, then nothing until ALL waves
4276
- // finish. The user explicitly demanded "I should see them being
4277
- // called" — these are the lines that satisfy that.
4278
- const fleetTotal = fleetAgents.length;
4279
- let fleetFinishedCount = 0;
4280
- let agentDispatchIdx = 0;
4281
4220
  for (let i = 0; i < fleetAgents.length; i += WAVE_SIZE) {
4282
4221
  const wave = fleetAgents.slice(i, i + WAVE_SIZE);
4283
4222
  const waveNum = Math.floor(i / WAVE_SIZE) + 1;
4284
4223
  const totalWaves = Math.ceil(fleetAgents.length / WAVE_SIZE);
4285
- console.error(` Wave ${waveNum}/${totalWaves}: dispatching ${wave.length} agents (${wave.map(a => `${a.domain}/${a.agent}`).slice(0, 3).join(', ')}${wave.length > 3 ? '...' : ''})`);
4224
+ console.error(` Wave ${waveNum}/${totalWaves}: ${wave.length} agents (${wave.map(a => `${a.domain}/${a.agent}`).slice(0, 3).join(', ')}${wave.length > 3 ? '...' : ''})`);
4286
4225
  for (const { domain, agent } of wave) {
4287
- agentDispatchIdx++;
4288
- const myIdx = agentDispatchIdx;
4289
- const agentStart = Date.now();
4290
- process.stderr.write(` [FLEET-CALL] [${String(myIdx).padStart(3, ' ')}/${fleetTotal}] → ${domain}/${agent}\n`);
4291
4226
  agentPromises.push((async () => {
4292
4227
  try {
4293
4228
  // Toggle repo-local per-agent: only copilot uses repo-local
@@ -4302,19 +4237,9 @@ export async function executeNaturalLanguageRoute(query, options) {
4302
4237
  }
4303
4238
  const payload = buildDomainPayload(domain, agent, query, correlationId);
4304
4239
  const result = await executeAgentsInvokeCommand(domain, agent, payload, options);
4305
- fleetFinishedCount++;
4306
- const elapsed = ((Date.now() - agentStart) / 1000).toFixed(1);
4307
- const status = result.status ?? 200;
4308
- const ok = status >= 200 && status < 300;
4309
- process.stderr.write(` [FLEET-CALL] [${String(myIdx).padStart(3, ' ')}/${fleetTotal}] ${ok ? '✓' : '✗'} ${domain}/${agent} (${elapsed}s, ${fleetFinishedCount}/${fleetTotal} done)\n`);
4310
- pipelineHeartbeat.setActivity(`fleet: ${fleetFinishedCount}/${fleetTotal} agents complete`);
4311
- return { kind: 'agent', domain, agent, status, response: result.response };
4240
+ return { kind: 'agent', domain, agent, status: result.status ?? 200, response: result.response };
4312
4241
  }
4313
4242
  catch (err) {
4314
- fleetFinishedCount++;
4315
- const elapsed = ((Date.now() - agentStart) / 1000).toFixed(1);
4316
- const errMsg = err instanceof Error ? err.message.slice(0, 80) : String(err).slice(0, 80);
4317
- process.stderr.write(` [FLEET-CALL] [${String(myIdx).padStart(3, ' ')}/${fleetTotal}] ✗ ${domain}/${agent} (${elapsed}s) — ${errMsg}\n`);
4318
4243
  return { kind: 'agent', domain, agent, status: 502, response: { error: err instanceof Error ? err.message : String(err) } };
4319
4244
  }
4320
4245
  })());
@@ -4324,7 +4249,6 @@ export async function executeNaturalLanguageRoute(query, options) {
4324
4249
  await new Promise(resolve => setTimeout(resolve, WAVE_DELAY_MS));
4325
4250
  }
4326
4251
  }
4327
- process.stderr.write(` [FLEET-CALL] all ${fleetTotal} agents in flight — awaiting final responses...\n`);
4328
4252
  const allResults = await Promise.allSettled([Promise.resolve(simResult), ...agentPromises]);
4329
4253
  const elapsed = Date.now() - start;
4330
4254
  // Restore repo-local mode setting