zelari-code 1.18.1 → 1.19.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.
@@ -24290,6 +24290,53 @@ var init_fileStateStore = __esm({
24290
24290
  }
24291
24291
  });
24292
24292
 
24293
+ // packages/core/dist/shared/eventBus.js
24294
+ var init_eventBus = __esm({
24295
+ "packages/core/dist/shared/eventBus.js"() {
24296
+ "use strict";
24297
+ }
24298
+ });
24299
+
24300
+ // packages/core/dist/events/index.js
24301
+ var init_events2 = __esm({
24302
+ "packages/core/dist/events/index.js"() {
24303
+ "use strict";
24304
+ init_events();
24305
+ init_eventBus();
24306
+ }
24307
+ });
24308
+
24309
+ // packages/core/dist/types/context.js
24310
+ var init_context = __esm({
24311
+ "packages/core/dist/types/context.js"() {
24312
+ "use strict";
24313
+ }
24314
+ });
24315
+
24316
+ // packages/core/dist/types/systemTypes.js
24317
+ var init_systemTypes = __esm({
24318
+ "packages/core/dist/types/systemTypes.js"() {
24319
+ "use strict";
24320
+ }
24321
+ });
24322
+
24323
+ // packages/core/dist/types/knowledge.js
24324
+ var init_knowledge = __esm({
24325
+ "packages/core/dist/types/knowledge.js"() {
24326
+ "use strict";
24327
+ }
24328
+ });
24329
+
24330
+ // packages/core/dist/types/index.js
24331
+ var init_types = __esm({
24332
+ "packages/core/dist/types/index.js"() {
24333
+ "use strict";
24334
+ init_context();
24335
+ init_systemTypes();
24336
+ init_knowledge();
24337
+ }
24338
+ });
24339
+
24293
24340
  // packages/core/dist/agents/roles.js
24294
24341
  function resolveRoleSystemPrompt(agent, runMode = "implementation") {
24295
24342
  const parts = [agent.systemPrompt];
@@ -27144,7 +27191,7 @@ var init_missionBrief = __esm({
27144
27191
  });
27145
27192
 
27146
27193
  // packages/core/dist/council/verification/types.js
27147
- var init_types = __esm({
27194
+ var init_types2 = __esm({
27148
27195
  "packages/core/dist/council/verification/types.js"() {
27149
27196
  "use strict";
27150
27197
  }
@@ -27348,7 +27395,7 @@ var init_autofix = __esm({
27348
27395
  var init_verification = __esm({
27349
27396
  "packages/core/dist/council/verification/index.js"() {
27350
27397
  "use strict";
27351
- init_types();
27398
+ init_types2();
27352
27399
  init_runChecks();
27353
27400
  init_honesty();
27354
27401
  init_parseCssMotion();
@@ -27366,7 +27413,7 @@ var init_verification = __esm({
27366
27413
  });
27367
27414
 
27368
27415
  // packages/core/dist/council/lessons/types.js
27369
- var init_types2 = __esm({
27416
+ var init_types3 = __esm({
27370
27417
  "packages/core/dist/council/lessons/types.js"() {
27371
27418
  "use strict";
27372
27419
  }
@@ -27619,7 +27666,7 @@ var init_recallLessons = __esm({
27619
27666
  var init_lessons = __esm({
27620
27667
  "packages/core/dist/council/lessons/index.js"() {
27621
27668
  "use strict";
27622
- init_types2();
27669
+ init_types3();
27623
27670
  init_io();
27624
27671
  init_isAnswerLeak();
27625
27672
  init_signatures();
@@ -27629,7 +27676,7 @@ var init_lessons = __esm({
27629
27676
  });
27630
27677
 
27631
27678
  // packages/core/dist/council/completion/types.js
27632
- var init_types3 = __esm({
27679
+ var init_types4 = __esm({
27633
27680
  "packages/core/dist/council/completion/types.js"() {
27634
27681
  "use strict";
27635
27682
  }
@@ -27710,7 +27757,7 @@ var init_buildCompletion = __esm({
27710
27757
  var init_completion2 = __esm({
27711
27758
  "packages/core/dist/council/completion/index.js"() {
27712
27759
  "use strict";
27713
- init_types3();
27760
+ init_types4();
27714
27761
  init_buildCompletion();
27715
27762
  }
27716
27763
  });
@@ -28025,6 +28072,34 @@ var init_council = __esm({
28025
28072
  }
28026
28073
  });
28027
28074
 
28075
+ // packages/core/dist/memory/types.js
28076
+ var init_types5 = __esm({
28077
+ "packages/core/dist/memory/types.js"() {
28078
+ "use strict";
28079
+ }
28080
+ });
28081
+
28082
+ // packages/core/dist/state/index.js
28083
+ var init_state = __esm({
28084
+ "packages/core/dist/state/index.js"() {
28085
+ "use strict";
28086
+ }
28087
+ });
28088
+
28089
+ // packages/core/dist/index.js
28090
+ var init_dist = __esm({
28091
+ "packages/core/dist/index.js"() {
28092
+ "use strict";
28093
+ init_events2();
28094
+ init_types();
28095
+ init_harness();
28096
+ init_council();
28097
+ init_skills2();
28098
+ init_types5();
28099
+ init_state();
28100
+ }
28101
+ });
28102
+
28028
28103
  // src/cli/utils/envNumber.ts
28029
28104
  function envNumber(raw, opts) {
28030
28105
  const { default: def, min, max } = opts;
@@ -31751,6 +31826,45 @@ var init_councilFeedback = __esm({
31751
31826
  }
31752
31827
  });
31753
31828
 
31829
+ // src/cli/buildPolicy.ts
31830
+ var buildPolicy_exports = {};
31831
+ __export(buildPolicy_exports, {
31832
+ describeBuildPolicy: () => describeBuildPolicy,
31833
+ resolveAgentMissionToolBudget: () => resolveAgentMissionToolBudget,
31834
+ shouldAllowCouncilBuild: () => shouldAllowCouncilBuild,
31835
+ shouldBuildViaAgent: () => shouldBuildViaAgent
31836
+ });
31837
+ function shouldBuildViaAgent(env = process.env) {
31838
+ if (shouldAllowCouncilBuild(env)) return false;
31839
+ if (env.ZELARI_BUILD_VIA_AGENT === "0") return false;
31840
+ return true;
31841
+ }
31842
+ function shouldAllowCouncilBuild(env = process.env) {
31843
+ return env.ZELARI_COUNCIL_CAN_BUILD === "1";
31844
+ }
31845
+ function resolveAgentMissionToolBudget(env = process.env) {
31846
+ const raw = env.ZELARI_MODE_MAX_TOOLS_AGENT;
31847
+ if (raw === void 0 || raw === "") return DEFAULT_AGENT_TOOL_BUDGET;
31848
+ const n = Number.parseInt(raw, 10);
31849
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_AGENT_TOOL_BUDGET;
31850
+ }
31851
+ function describeBuildPolicy(env = process.env) {
31852
+ const viaAgent = shouldBuildViaAgent(env);
31853
+ const councilBuild = shouldAllowCouncilBuild(env);
31854
+ const parts = [
31855
+ viaAgent ? "zelari build@agent (default)" : "zelari build@council (legacy)",
31856
+ councilBuild ? "council may implement" : "council plan-only unless ZELARI_COUNCIL_CAN_BUILD=1"
31857
+ ];
31858
+ return parts.join(" \xB7 ");
31859
+ }
31860
+ var DEFAULT_AGENT_TOOL_BUDGET;
31861
+ var init_buildPolicy = __esm({
31862
+ "src/cli/buildPolicy.ts"() {
31863
+ "use strict";
31864
+ DEFAULT_AGENT_TOOL_BUDGET = 40;
31865
+ }
31866
+ });
31867
+
31754
31868
  // src/cli/checkpoint/checkpointManager.ts
31755
31869
  import { execFile as execFile2 } from "node:child_process";
31756
31870
  import { promisify } from "node:util";
@@ -32211,6 +32325,10 @@ async function runZelariMission(userMessage, brief, deps) {
32211
32325
  deps.emit(
32212
32326
  `[zelari] design-phase (fuori budget) \xB7 step ${step} \xB7 slice ${brief.sliceMvp.id}`
32213
32327
  );
32328
+ } else if (deps.buildViaAgent) {
32329
+ deps.emit(
32330
+ `[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 build@agent \xB7 slice ${brief.sliceMvp.id}`
32331
+ );
32214
32332
  } else if (implementerRetry) {
32215
32333
  deps.emit(
32216
32334
  `[zelari] implementazione ${implStep}/${maxIter} \xB7 step ${step} \xB7 roster ridotto (Minosse+Lucifero) \xB7 slice ${brief.sliceMvp.id}`
@@ -32255,7 +32373,14 @@ async function runZelariMission(userMessage, brief, deps) {
32255
32373
  iteration: step
32256
32374
  }
32257
32375
  );
32258
- state2.lastCompletionOk = result.completionOk;
32376
+ let completionOk = result.completionOk;
32377
+ if (runMode === "implementation" && completionOk && typeof result.writeCount === "number" && result.writeCount === 0) {
32378
+ completionOk = false;
32379
+ deps.emit(
32380
+ "[zelari] completion.ok ignored: implementation slice wrote 0 project files"
32381
+ );
32382
+ }
32383
+ state2.lastCompletionOk = completionOk;
32259
32384
  state2.updatedAt = now().toISOString();
32260
32385
  if (runMode === "design-phase") {
32261
32386
  pendingDesign = false;
@@ -32263,7 +32388,7 @@ async function runZelariMission(userMessage, brief, deps) {
32263
32388
  continue;
32264
32389
  }
32265
32390
  const wrote = typeof result.writeCount === "number" && result.writeCount > 0;
32266
- if (result.completionOk || wrote) {
32391
+ if (completionOk || wrote) {
32267
32392
  const hard = result.completionOk === true;
32268
32393
  const commitRes = await tryStateCommit({
32269
32394
  projectRoot: deps.projectRoot,
@@ -32299,7 +32424,7 @@ async function runZelariMission(userMessage, brief, deps) {
32299
32424
  deps.emit(`[zelari] state commit skipped: ${commitRes.error}`);
32300
32425
  }
32301
32426
  }
32302
- if (result.completionOk) {
32427
+ if (completionOk) {
32303
32428
  state2.status = "success";
32304
32429
  await writeMissionState(deps.projectRoot, state2);
32305
32430
  deps.emit(
@@ -32343,6 +32468,290 @@ var init_zelariMission = __esm({
32343
32468
  }
32344
32469
  });
32345
32470
 
32471
+ // src/cli/missionSlice.ts
32472
+ var missionSlice_exports = {};
32473
+ __export(missionSlice_exports, {
32474
+ AGENT_MISSION_IMPLEMENTER_PREAMBLE: () => AGENT_MISSION_IMPLEMENTER_PREAMBLE,
32475
+ buildAgentMissionUserPrompt: () => buildAgentMissionUserPrompt,
32476
+ createWriteCounter: () => createWriteCounter,
32477
+ runAgentMissionSlice: () => runAgentMissionSlice
32478
+ });
32479
+ function createWriteCounter() {
32480
+ const state2 = { successfulWrites: 0, emittedWrites: 0 };
32481
+ const pending = /* @__PURE__ */ new Map();
32482
+ return {
32483
+ state: state2,
32484
+ onEvent(event) {
32485
+ if (event.type === "tool_execution_start") {
32486
+ const name = event.toolName ?? event.name ?? "";
32487
+ const id = event.toolCallId ?? "";
32488
+ if (id && name) pending.set(id, name);
32489
+ if (MUTATING.has(name)) state2.emittedWrites += 1;
32490
+ return;
32491
+ }
32492
+ if (event.type === "tool_execution_end") {
32493
+ const id = event.toolCallId ?? "";
32494
+ const name = pending.get(id) ?? event.toolName ?? event.name ?? "";
32495
+ if (id) pending.delete(id);
32496
+ if (!MUTATING.has(name) || event.isError) return;
32497
+ const result = String(event.result ?? "");
32498
+ const zeroEdit = name === "edit_file" && /occurrencesReplaced["']?\s*[:=]\s*0\b|0 occurrence|no changes/i.test(
32499
+ result
32500
+ );
32501
+ if (!zeroEdit) state2.successfulWrites += 1;
32502
+ }
32503
+ }
32504
+ };
32505
+ }
32506
+ function buildAgentMissionUserPrompt(slicePrompt, ragContext) {
32507
+ const body = `${AGENT_MISSION_IMPLEMENTER_PREAMBLE}
32508
+
32509
+ ${slicePrompt}`;
32510
+ if (ragContext?.trim()) {
32511
+ return `${body}
32512
+
32513
+ ## Memory context
32514
+ ${ragContext.trim()}`;
32515
+ }
32516
+ return body;
32517
+ }
32518
+ async function runAgentMissionSlice(deps) {
32519
+ const env = deps.env ?? process.env;
32520
+ const provider = deps.provider ?? "openai-compatible";
32521
+ const sessionId = deps.sessionId ?? crypto.randomUUID();
32522
+ const maxToolCalls = resolveAgentMissionToolBudget(env);
32523
+ const maxToolLoop = envNumber(env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, {
32524
+ default: 30,
32525
+ min: 1
32526
+ });
32527
+ const maxToolLoopHard = envNumber(env.ZELARI_MAX_TOOL_LOOP_HARD, {
32528
+ default: 0,
32529
+ min: 0
32530
+ });
32531
+ const writeRetry = deps.writeRetry !== false;
32532
+ const toolSpecs = deps.toolRegistry.toOpenAITools().map((t) => ({
32533
+ name: t.function.name,
32534
+ description: t.function.description,
32535
+ parameters: t.function.parameters
32536
+ }));
32537
+ const toolNames = toolSpecs.map((t) => t.name);
32538
+ let languageDirective;
32539
+ try {
32540
+ languageDirective = buildLanguagePolicyModuleFor(deps.slicePrompt).content;
32541
+ } catch {
32542
+ languageDirective = "# Response Language\nReply in the user's language when possible, otherwise Italian.";
32543
+ }
32544
+ const rolePrompt = [
32545
+ "# Platform",
32546
+ `platform: ${process.platform}`,
32547
+ `shell: ${process.platform === "win32" ? "cmd.exe / Git Bash (auto-detected)" : "/bin/sh"}`,
32548
+ "",
32549
+ "# Working Directory",
32550
+ `You are running in: ${deps.projectRoot}`,
32551
+ "All relative file paths are resolved against this directory.",
32552
+ "The shell is NON-INTERACTIVE (stdin closed): pass non-interactive flags (--yes, --force, --template).",
32553
+ "",
32554
+ "# Work phase: BUILD (Zelari mission implementation slice)",
32555
+ "IMPLEMENT ON DISK. Prior design under .zelari/ is a SPEC, not proof of delivery.",
32556
+ "You MUST call write_file and/or edit_file before claiming done."
32557
+ ].join("\n");
32558
+ const headlessRole = {
32559
+ id: "mission-agent",
32560
+ name: "Zelari Code",
32561
+ codename: "zelari-build",
32562
+ role: "mission implementer",
32563
+ color: "#00d9a3",
32564
+ avatar: "\u25C6",
32565
+ tools: toolNames,
32566
+ systemPrompt: rolePrompt
32567
+ };
32568
+ let systemPrompt;
32569
+ try {
32570
+ systemPrompt = buildSystemPrompt(
32571
+ headlessRole,
32572
+ {
32573
+ tools: getAllTools(),
32574
+ toolNames,
32575
+ mode: "agent",
32576
+ projectInstructions: deps.projectInstructions || void 0,
32577
+ workspaceContext: deps.workspaceContext || void 0,
32578
+ ragContext: void 0,
32579
+ aiConfig: {
32580
+ enabledSkills: [],
32581
+ enabledTools: toolNames,
32582
+ customPromptModules: [
32583
+ SINGLE_AGENT_IDENTITY_MODULE,
32584
+ {
32585
+ type: "language-policy",
32586
+ title: "Response Language",
32587
+ priority: 5,
32588
+ content: languageDirective
32589
+ }
32590
+ ],
32591
+ agentSkillConfigs: []
32592
+ }
32593
+ }
32594
+ );
32595
+ } catch {
32596
+ systemPrompt = [
32597
+ "You are zelari-code, implementing a mission slice. Write real files.",
32598
+ languageDirective,
32599
+ deps.workspaceContext ?? ""
32600
+ ].filter(Boolean).join("\n\n");
32601
+ }
32602
+ const userContent = buildAgentMissionUserPrompt(
32603
+ deps.slicePrompt,
32604
+ deps.ragContext
32605
+ );
32606
+ async function runPass(messages, passId) {
32607
+ const counter = createWriteCounter();
32608
+ const harness = new AgentHarness({
32609
+ model: deps.model,
32610
+ provider,
32611
+ sessionId: passId,
32612
+ messages,
32613
+ tools: toolSpecs,
32614
+ toolRegistry: deps.toolRegistry,
32615
+ providerStream: deps.providerStream,
32616
+ cwd: deps.projectRoot,
32617
+ maxToolCallsPerTurn: maxToolCalls,
32618
+ maxToolLoopIterations: maxToolLoop,
32619
+ ...maxToolLoopHard > 0 ? { maxToolLoopHardCap: maxToolLoopHard } : {}
32620
+ });
32621
+ let text = "";
32622
+ let errored2 = false;
32623
+ try {
32624
+ for await (const event of harness.run()) {
32625
+ counter.onEvent(event);
32626
+ if (deps.onEvent) await deps.onEvent(event);
32627
+ if (event.type === "message_delta" && typeof event.delta === "string") {
32628
+ text += event.delta;
32629
+ }
32630
+ if (event.type === "agent_end" && event.reason === "error") {
32631
+ errored2 = true;
32632
+ }
32633
+ if (event.type === "error" && event.severity === "fatal") {
32634
+ errored2 = true;
32635
+ }
32636
+ }
32637
+ } catch {
32638
+ errored2 = true;
32639
+ }
32640
+ if (!text.trim()) {
32641
+ const all = harness.getMessages();
32642
+ for (let i = all.length - 1; i >= 0; i--) {
32643
+ const m = all[i];
32644
+ if (m?.role === "assistant" && (m.content ?? "").trim()) {
32645
+ text = m.content ?? "";
32646
+ break;
32647
+ }
32648
+ }
32649
+ }
32650
+ return {
32651
+ text,
32652
+ successfulWrites: counter.state.successfulWrites,
32653
+ emittedWrites: counter.state.emittedWrites,
32654
+ errored: errored2,
32655
+ messages: harness.getMessages()
32656
+ };
32657
+ }
32658
+ const initial = [
32659
+ { role: "system", content: systemPrompt },
32660
+ { role: "user", content: userContent }
32661
+ ];
32662
+ let pass = await runPass(initial, sessionId);
32663
+ let totalWrites = pass.successfulWrites;
32664
+ let totalEmitted = pass.emittedWrites;
32665
+ let synthesisText = pass.text;
32666
+ let errored = pass.errored;
32667
+ if (writeRetry && totalWrites === 0 && !errored) {
32668
+ deps.emit?.(
32669
+ "[zelari] build@agent: 0 write \u2014 forcing implementation retry"
32670
+ );
32671
+ const retryPrompt = buildImplementationWriteRetryPrompt(deps.slicePrompt);
32672
+ const retryMessages = [
32673
+ { role: "system", content: systemPrompt },
32674
+ ...pass.messages.filter((m) => m.role !== "system"),
32675
+ { role: "user", content: retryPrompt }
32676
+ ];
32677
+ const retry = await runPass(retryMessages, `${sessionId}-write-retry`);
32678
+ totalWrites += retry.successfulWrites;
32679
+ totalEmitted += retry.emittedWrites;
32680
+ if (retry.text.trim()) {
32681
+ synthesisText = synthesisText ? `${synthesisText}
32682
+
32683
+ ${retry.text}` : retry.text;
32684
+ }
32685
+ errored = errored || retry.errored;
32686
+ }
32687
+ const cleaned = cleanAgentContent(synthesisText, {
32688
+ stripQuestion: false,
32689
+ stripThink: false
32690
+ });
32691
+ let completionOk = false;
32692
+ let degraded = false;
32693
+ if (deps.runCompletionHook) {
32694
+ try {
32695
+ const hook = await deps.runCompletionHook({
32696
+ synthesisText: cleaned,
32697
+ writeCount: totalWrites,
32698
+ errored
32699
+ });
32700
+ completionOk = hook.completionOk;
32701
+ degraded = hook.degraded;
32702
+ } catch {
32703
+ }
32704
+ }
32705
+ if (!deps.runCompletionHook) {
32706
+ const d = detectDegradedRun({
32707
+ chairmanErrored: errored,
32708
+ luciferWriteCount: totalWrites,
32709
+ synthesisText: cleaned,
32710
+ runMode: "implementation"
32711
+ });
32712
+ degraded = d.degraded;
32713
+ completionOk = totalWrites > 0 && !errored && !degraded;
32714
+ }
32715
+ if (totalWrites === 0) {
32716
+ if (completionOk) {
32717
+ deps.emit?.(
32718
+ "[zelari] build@agent: completion.ok overridden \u2014 0 project writes (not done)"
32719
+ );
32720
+ }
32721
+ completionOk = false;
32722
+ const d = detectDegradedRun({
32723
+ chairmanErrored: errored,
32724
+ luciferWriteCount: 0,
32725
+ synthesisText: cleaned || "completato",
32726
+ runMode: "implementation"
32727
+ });
32728
+ if (d.degraded) degraded = true;
32729
+ else degraded = true;
32730
+ }
32731
+ void totalEmitted;
32732
+ return {
32733
+ completionOk,
32734
+ ran: true,
32735
+ synthesisText: cleaned || void 0,
32736
+ writeCount: totalWrites,
32737
+ degraded
32738
+ };
32739
+ }
32740
+ var MUTATING, AGENT_MISSION_IMPLEMENTER_PREAMBLE;
32741
+ var init_missionSlice = __esm({
32742
+ "src/cli/missionSlice.ts"() {
32743
+ "use strict";
32744
+ init_harness();
32745
+ init_skills2();
32746
+ init_council();
32747
+ init_dist();
32748
+ init_buildPolicy();
32749
+ init_envNumber();
32750
+ MUTATING = /* @__PURE__ */ new Set(["write_file", "edit_file", "apply_diff"]);
32751
+ AGENT_MISSION_IMPLEMENTER_PREAMBLE = "You are the sole implementer for this Zelari mission slice. A multi-agent council may already have produced a plan under `.zelari/` \u2014 treat it as a SPEC to apply on disk. You MUST create or modify real project files with write_file / edit_file. Prose without successful writes is a failed slice.";
32752
+ }
32753
+ });
32754
+
32346
32755
  // src/cli/utils/prereqChecks.ts
32347
32756
  var prereqChecks_exports = {};
32348
32757
  __export(prereqChecks_exports, {
@@ -36934,14 +37343,7 @@ init_keyStore();
36934
37343
  init_toolRegistry();
36935
37344
  init_skills2();
36936
37345
  init_fileStateStore();
36937
-
36938
- // packages/core/dist/events/index.js
36939
- init_events();
36940
-
36941
- // packages/core/dist/index.js
36942
- init_harness();
36943
- init_council();
36944
- init_skills2();
37346
+ init_dist();
36945
37347
 
36946
37348
  // src/cli/hooks/messageHelpers.ts
36947
37349
  function appendSystem(setMessages, content, ts = Date.now()) {
@@ -37883,8 +38285,23 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
37883
38285
  onCancel: () => finish(null)
37884
38286
  });
37885
38287
  }) : void 0;
38288
+ let phaseRunMode = overrides.runMode ?? (workPhase === "plan" ? "design-phase" : "implementation");
38289
+ let softGatedToDesign = false;
38290
+ if (phaseRunMode === "implementation") {
38291
+ const { shouldAllowCouncilBuild: shouldAllowCouncilBuild2 } = await Promise.resolve().then(() => (init_buildPolicy(), buildPolicy_exports));
38292
+ const allowed = overrides.allowCouncilBuild === true || shouldAllowCouncilBuild2();
38293
+ if (!allowed) {
38294
+ phaseRunMode = "design-phase";
38295
+ softGatedToDesign = true;
38296
+ appendSystem(
38297
+ setMessages,
38298
+ "[council] build soft-gate: implementation disabled for free-form council (experiment: multi-agent = plan). Forced design-phase + plan tools. Set ZELARI_COUNCIL_CAN_BUILD=1 to let Lucifero implement, or use mode agent/zelari for on-disk work.",
38299
+ Date.now()
38300
+ );
38301
+ }
38302
+ }
37886
38303
  const { registry: councilToolRegistry } = createBuiltinToolRegistry({
37887
- planMode: workPhase === "plan",
38304
+ planMode: workPhase === "plan" || softGatedToDesign,
37888
38305
  onAskUser: onAskUserCouncil
37889
38306
  });
37890
38307
  const workspaceCtx = createWorkspaceContext2();
@@ -37894,7 +38311,6 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
37894
38311
  if (!td) continue;
37895
38312
  councilToolRegistry.register(td);
37896
38313
  }
37897
- const phaseRunMode = overrides.runMode ?? (workPhase === "plan" ? "design-phase" : "implementation");
37898
38314
  try {
37899
38315
  const { registerMcpTools: registerMcpTools2 } = await Promise.resolve().then(() => (init_mcpManager(), mcpManager_exports));
37900
38316
  const mcp = await registerMcpTools2(councilToolRegistry, process.cwd(), {
@@ -38405,30 +38821,132 @@ async function runZelariMissionInTui(userMessage, deps, emit) {
38405
38821
  default: 30,
38406
38822
  min: 1
38407
38823
  });
38824
+ const { shouldBuildViaAgent: shouldBuildViaAgent2 } = await Promise.resolve().then(() => (init_buildPolicy(), buildPolicy_exports));
38825
+ const buildViaAgent = shouldBuildViaAgent2();
38826
+ if (buildViaAgent) {
38827
+ emit(
38828
+ "[zelari] policy: design@council \xB7 build@agent (ZELARI_BUILD_VIA_AGENT; set=0 for legacy council impl)"
38829
+ );
38830
+ }
38408
38831
  try {
38409
38832
  await runZelariMission2(userMessage, brief, {
38410
38833
  projectRoot,
38411
38834
  memory,
38412
38835
  emit,
38836
+ buildViaAgent,
38413
38837
  runSlice: async ({
38414
38838
  userMessage: slicePrompt,
38415
38839
  runMode,
38416
38840
  ragContext,
38417
38841
  implementerRetry
38418
38842
  }) => {
38419
- const r = await dispatchCouncilPromptImpl(slicePrompt, deps, {
38420
- ragContext,
38421
- runMode,
38422
- maxToolCallsChairman: chairmanBudget,
38423
- ...implementerRetry ? { skipSpecialists: true } : {}
38843
+ if (runMode === "design-phase" || !buildViaAgent) {
38844
+ const r = await dispatchCouncilPromptImpl(slicePrompt, deps, {
38845
+ ragContext,
38846
+ runMode,
38847
+ maxToolCallsChairman: chairmanBudget,
38848
+ ...implementerRetry ? { skipSpecialists: true } : {},
38849
+ // Mission may need Lucifero to write even when free-form council is plan-only.
38850
+ allowCouncilBuild: true
38851
+ });
38852
+ return {
38853
+ completionOk: r.completionOk,
38854
+ ran: r.ran,
38855
+ synthesisText: r.synthesisText,
38856
+ writeCount: r.writeCount,
38857
+ degraded: r.degraded
38858
+ };
38859
+ }
38860
+ const { runAgentMissionSlice: runAgentMissionSlice2 } = await Promise.resolve().then(() => (init_missionSlice(), missionSlice_exports));
38861
+ const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
38862
+ const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
38863
+ const { createWorkspaceContext: createWorkspaceContext2 } = await Promise.resolve().then(() => (init_stubs(), stubs_exports));
38864
+ const { runPostCouncilHook: runPostCouncilHook2 } = await Promise.resolve().then(() => (init_postCouncilHook(), postCouncilHook_exports));
38865
+ const { detectDegradedRun: detectDegradedRun2 } = await Promise.resolve().then(() => (init_council(), council_exports));
38866
+ const envConfig2 = await providerFromEnv();
38867
+ if (!envConfig2) {
38868
+ emit(
38869
+ "[zelari] build@agent aborted: missing API key for active provider"
38870
+ );
38871
+ return { completionOk: false, ran: false };
38872
+ }
38873
+ const { registry: toolRegistry } = createBuiltinToolRegistry({
38874
+ planMode: false
38424
38875
  });
38425
- return {
38426
- completionOk: r.completionOk,
38427
- ran: r.ran,
38428
- synthesisText: r.synthesisText,
38429
- writeCount: r.writeCount,
38430
- degraded: r.degraded
38431
- };
38876
+ try {
38877
+ const { registerMcpTools: registerMcpTools2 } = await Promise.resolve().then(() => (init_mcpManager(), mcpManager_exports));
38878
+ await registerMcpTools2(toolRegistry, projectRoot);
38879
+ } catch {
38880
+ }
38881
+ const durableState = await loadDurableContext2(projectRoot);
38882
+ const composed = composeProjectContext2({
38883
+ mode: "zelari",
38884
+ cwd: projectRoot,
38885
+ userMessage: slicePrompt,
38886
+ memoryHits: ragContext,
38887
+ durableState: durableState || void 0,
38888
+ includeLessons: true,
38889
+ includeDurableState: false
38890
+ });
38891
+ for (const w of composed.warnings) {
38892
+ emit(w);
38893
+ }
38894
+ const workspaceCtx = createWorkspaceContext2(projectRoot);
38895
+ const { setMessages: setMessages2, writerRef, setBusy } = deps;
38896
+ setBusy(true);
38897
+ try {
38898
+ return await runAgentMissionSlice2({
38899
+ projectRoot,
38900
+ model: envConfig2.model,
38901
+ provider: "openai-compatible",
38902
+ providerStream: openaiCompatibleProvider(envConfig2),
38903
+ toolRegistry,
38904
+ slicePrompt,
38905
+ ragContext: composed.ragContext ?? ragContext,
38906
+ workspaceContext: composed.workspaceContext,
38907
+ projectInstructions: composed.projectInstructions,
38908
+ emit,
38909
+ onEvent: async (event) => {
38910
+ if (writerRef.current) await writerRef.current.append(event);
38911
+ if (event.type === "tool_execution_start") {
38912
+ const name = event.toolName ?? "tool";
38913
+ appendSystem(
38914
+ setMessages2,
38915
+ `[build@agent] \u2192 ${name}`,
38916
+ Date.now()
38917
+ );
38918
+ }
38919
+ },
38920
+ runCompletionHook: async ({ synthesisText, writeCount, errored }) => {
38921
+ const d = detectDegradedRun2({
38922
+ chairmanErrored: errored,
38923
+ luciferWriteCount: writeCount,
38924
+ synthesisText,
38925
+ runMode: "implementation"
38926
+ });
38927
+ if (d.degraded) {
38928
+ appendSystem(
38929
+ setMessages2,
38930
+ `[zelari] DEGRADED_RUN \u2014 ${d.reasons.join("; ")}`,
38931
+ Date.now()
38932
+ );
38933
+ }
38934
+ const hook = await runPostCouncilHook2(workspaceCtx, {
38935
+ runMode: "implementation",
38936
+ userMessage,
38937
+ synthesisText: synthesisText || void 0,
38938
+ degradedRun: d.degraded,
38939
+ degradedReasons: d.reasons
38940
+ });
38941
+ return {
38942
+ completionOk: hook.completion?.completion?.ok ?? false,
38943
+ degraded: d.degraded
38944
+ };
38945
+ }
38946
+ });
38947
+ } finally {
38948
+ setBusy(false);
38949
+ }
38432
38950
  }
38433
38951
  });
38434
38952
  } catch (err) {
@@ -39438,11 +39956,11 @@ function parseMode(input) {
39438
39956
  function describeMode(mode) {
39439
39957
  switch (mode) {
39440
39958
  case "council":
39441
- return "council \u2014 6-member pipeline (Caronte\u2026Lucifero)";
39959
+ return "council \u2014 multi-member plan/design (Caronte\u2026Lucifero; build needs ZELARI_COUNCIL_CAN_BUILD=1)";
39442
39960
  case "zelari":
39443
- return "zelari \u2014 autonomous multi-run mission";
39961
+ return "zelari \u2014 mission: plan@council \u2192 build@agent (legacy: ZELARI_BUILD_VIA_AGENT=0)";
39444
39962
  default:
39445
- return "agent \u2014 single LLM turn";
39963
+ return "agent \u2014 single LLM turn (default implementer)";
39446
39964
  }
39447
39965
  }
39448
39966
 
@@ -42103,6 +42621,7 @@ function emitEvent(event) {
42103
42621
 
42104
42622
  // src/cli/runHeadless.ts
42105
42623
  init_harness();
42624
+ init_dist();
42106
42625
  init_conversationContext();
42107
42626
  init_council();
42108
42627
  init_toolRegistry();
@@ -42112,6 +42631,7 @@ init_phaseState();
42112
42631
  init_phase();
42113
42632
 
42114
42633
  // src/cli/utils/streamScrub.ts
42634
+ init_dist();
42115
42635
  function createStreamScrubber() {
42116
42636
  let rawBuf = "";
42117
42637
  let emittedLen = 0;
@@ -42566,8 +43086,18 @@ async function buildCouncilToolRegistry(planMode, opts) {
42566
43086
  async function runHeadlessCouncil(opts, provider, model, providerStream) {
42567
43087
  const { dispatchCouncil: dispatchCouncil2 } = await Promise.resolve().then(() => (init_councilDispatcher(), councilDispatcher_exports));
42568
43088
  const sessionId = crypto.randomUUID();
43089
+ const { shouldAllowCouncilBuild: shouldAllowCouncilBuild2 } = await Promise.resolve().then(() => (init_buildPolicy(), buildPolicy_exports));
43090
+ let councilRunMode = planModeFromOpts(opts) ? "design-phase" : "implementation";
43091
+ let softGated = false;
43092
+ if (councilRunMode === "implementation" && !shouldAllowCouncilBuild2()) {
43093
+ councilRunMode = "design-phase";
43094
+ softGated = true;
43095
+ process.stderr.write(
43096
+ "[zelari-code --headless] council build soft-gate: forced design-phase (set ZELARI_COUNCIL_CAN_BUILD=1 to allow Lucifero implement)\n"
43097
+ );
43098
+ }
42569
43099
  const { toolRegistry } = await buildCouncilToolRegistry(
42570
- planModeFromOpts(opts),
43100
+ planModeFromOpts(opts) || softGated,
42571
43101
  opts
42572
43102
  );
42573
43103
  const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
@@ -42607,7 +43137,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
42607
43137
  sessionId,
42608
43138
  tools: toolRegistry,
42609
43139
  feedbackStore,
42610
- runMode: planModeFromOpts(opts) ? "design-phase" : "implementation",
43140
+ runMode: councilRunMode,
42611
43141
  workspaceContext: composed.workspaceContext,
42612
43142
  ...composed.ragContext ? { ragContext: composed.ragContext } : {},
42613
43143
  maxToolLoopIterations: envNumber(process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, {
@@ -42695,6 +43225,8 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
42695
43225
  default: 30,
42696
43226
  min: 1
42697
43227
  });
43228
+ const { shouldBuildViaAgent: shouldBuildViaAgent2 } = await Promise.resolve().then(() => (init_buildPolicy(), buildPolicy_exports));
43229
+ const buildViaAgent = shouldBuildViaAgent2();
42698
43230
  const emit = (message) => {
42699
43231
  if (opts.output === "json") {
42700
43232
  emitEvent({ type: "log", message });
@@ -42714,6 +43246,11 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
42714
43246
  const missionTask = buildCouncilTaskWithHistory(opts.task, historySeed);
42715
43247
  emit(`[zelari] mission brief
42716
43248
  ${JSON.stringify({ deliverable: brief.deliverableThisMission, mvp: brief.sliceMvp?.title }, null, 0)}`);
43249
+ if (buildViaAgent) {
43250
+ emit(
43251
+ "[zelari] policy: design@council \xB7 build@agent (set ZELARI_BUILD_VIA_AGENT=0 for legacy)"
43252
+ );
43253
+ }
42717
43254
  let exitCode = 0;
42718
43255
  let lastMissionAssistant = "";
42719
43256
  try {
@@ -42721,129 +43258,199 @@ ${JSON.stringify({ deliverable: brief.deliverableThisMission, mvp: brief.sliceMv
42721
43258
  projectRoot,
42722
43259
  memory,
42723
43260
  emit,
43261
+ buildViaAgent,
42724
43262
  runSlice: async ({
42725
43263
  userMessage: slicePrompt,
42726
43264
  runMode,
42727
43265
  ragContext,
42728
43266
  implementerRetry
42729
43267
  }) => {
42730
- const sessionId = crypto.randomUUID();
42731
- const fullPrompt = ragContext ? `${slicePrompt}
43268
+ const effectiveRunMode = planModeFromOpts(opts) ? "design-phase" : runMode;
43269
+ if (effectiveRunMode === "design-phase" || !buildViaAgent) {
43270
+ const sessionId = crypto.randomUUID();
43271
+ const fullPrompt = ragContext ? `${slicePrompt}
42732
43272
 
42733
43273
  ## Memory context
42734
43274
  ${ragContext}` : slicePrompt;
42735
- let synthesisText = "";
42736
- let writeCount = 0;
42737
- let chairmanErrored = false;
42738
- let membersCompleted = 0;
42739
- const scrub = createStreamScrubber();
43275
+ let synthesisText = "";
43276
+ let writeCount = 0;
43277
+ let chairmanErrored = false;
43278
+ let membersCompleted = 0;
43279
+ const scrub = createStreamScrubber();
43280
+ const { composeProjectContext: composeProjectContext3 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
43281
+ const { loadDurableContext: loadDurableContext3 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
43282
+ const memOnly = ragContext?.trim() ? ragContext : void 0;
43283
+ const durableState2 = await loadDurableContext3(projectRoot);
43284
+ const composed2 = composeProjectContext3({
43285
+ mode: "zelari",
43286
+ cwd: projectRoot,
43287
+ userMessage: slicePrompt,
43288
+ memoryHits: memOnly,
43289
+ durableState: durableState2 || void 0,
43290
+ includeLessons: true,
43291
+ includeDurableState: false
43292
+ });
43293
+ for await (const event of dispatchCouncil2(fullPrompt, {
43294
+ apiKey: "REDACTED",
43295
+ model,
43296
+ provider: "openai-compatible",
43297
+ providerStream,
43298
+ sessionId,
43299
+ tools: toolRegistry,
43300
+ feedbackStore,
43301
+ runMode: effectiveRunMode,
43302
+ maxToolCallsChairman: chairmanBudget,
43303
+ ...implementerRetry ? { skipSpecialists: true } : {},
43304
+ workspaceContext: composed2.workspaceContext,
43305
+ ...composed2.ragContext ? { ragContext: composed2.ragContext } : {},
43306
+ maxToolLoopIterations: envNumber(process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, {
43307
+ default: 30,
43308
+ min: 1
43309
+ }),
43310
+ ...(() => {
43311
+ const hard = envNumber(process.env.ZELARI_MAX_TOOL_LOOP_HARD, {
43312
+ default: 0,
43313
+ min: 0
43314
+ });
43315
+ return hard > 0 ? { maxToolLoopHardCap: hard } : {};
43316
+ })()
43317
+ })) {
43318
+ if (event.type === "message_start") {
43319
+ scrub.reset();
43320
+ }
43321
+ if (event.type === "message_delta" && typeof event.delta === "string") {
43322
+ synthesisText += event.delta;
43323
+ const cleanDelta = scrub.push(event.delta);
43324
+ if (opts.output === "json") {
43325
+ if (cleanDelta.length > 0) emitEvent({ ...event, delta: cleanDelta });
43326
+ } else if (opts.output === "plain" && cleanDelta.length > 0) {
43327
+ process.stdout.write(cleanDelta);
43328
+ }
43329
+ } else if (opts.output === "json") {
43330
+ emitEvent(event);
43331
+ }
43332
+ if (event.type === "tool_execution_end") {
43333
+ const name = event.toolName ?? event.name ?? "";
43334
+ if (name === "write_file" || name === "edit_file" || name === "apply_diff") {
43335
+ writeCount += 1;
43336
+ }
43337
+ }
43338
+ if (event.type === "agent_end") {
43339
+ membersCompleted += 1;
43340
+ if (event.reason === "error") chairmanErrored = true;
43341
+ }
43342
+ if (event.type === "error" && event.severity === "fatal") {
43343
+ chairmanErrored = true;
43344
+ exitCode = 2;
43345
+ }
43346
+ }
43347
+ let completionOk = false;
43348
+ let degraded = false;
43349
+ try {
43350
+ const { detectDegradedRun: detectDegradedRun3 } = await Promise.resolve().then(() => (init_council(), council_exports));
43351
+ const d = detectDegradedRun3({
43352
+ chairmanErrored,
43353
+ councilAborted: false,
43354
+ luciferWriteCount: writeCount,
43355
+ synthesisText,
43356
+ runMode: effectiveRunMode
43357
+ });
43358
+ degraded = d.degraded;
43359
+ const hook = await runPostCouncilHook2(workspaceCtx, {
43360
+ runMode: effectiveRunMode,
43361
+ userMessage: opts.task,
43362
+ synthesisText: synthesisText || void 0,
43363
+ degradedRun: d.degraded,
43364
+ degradedReasons: d.reasons
43365
+ });
43366
+ completionOk = hook.completion?.completion?.ok ?? false;
43367
+ if (completionOk) {
43368
+ emit(`[zelari] slice completion ok`);
43369
+ }
43370
+ } catch {
43371
+ }
43372
+ if (synthesisText.trim()) {
43373
+ lastMissionAssistant = cleanAgentContent(synthesisText, {
43374
+ stripQuestion: false,
43375
+ stripThink: false
43376
+ });
43377
+ }
43378
+ return {
43379
+ completionOk,
43380
+ ran: membersCompleted > 0 || synthesisText.length > 0,
43381
+ synthesisText: synthesisText || void 0,
43382
+ writeCount,
43383
+ degraded
43384
+ };
43385
+ }
43386
+ const { runAgentMissionSlice: runAgentMissionSlice2 } = await Promise.resolve().then(() => (init_missionSlice(), missionSlice_exports));
43387
+ const { createBuiltinToolRegistry: createBuiltinToolRegistry2 } = await Promise.resolve().then(() => (init_toolRegistry(), toolRegistry_exports));
42740
43388
  const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
42741
43389
  const { loadDurableContext: loadDurableContext2 } = await Promise.resolve().then(() => (init_loadDurableContext(), loadDurableContext_exports));
42742
- const memOnly = ragContext?.trim() ? ragContext : void 0;
43390
+ const { detectDegradedRun: detectDegradedRun2 } = await Promise.resolve().then(() => (init_council(), council_exports));
43391
+ const { registry: agentRegistry } = createBuiltinToolRegistry2({
43392
+ planMode: false
43393
+ });
43394
+ await registerHeadlessMcp(agentRegistry, opts);
42743
43395
  const durableState = await loadDurableContext2(projectRoot);
42744
43396
  const composed = composeProjectContext2({
42745
43397
  mode: "zelari",
42746
43398
  cwd: projectRoot,
42747
43399
  userMessage: slicePrompt,
42748
- memoryHits: memOnly,
43400
+ memoryHits: ragContext?.trim() ? ragContext : void 0,
42749
43401
  durableState: durableState || void 0,
42750
43402
  includeLessons: true,
42751
43403
  includeDurableState: false
42752
43404
  });
42753
- for await (const event of dispatchCouncil2(fullPrompt, {
42754
- apiKey: "REDACTED",
43405
+ const sliceResult = await runAgentMissionSlice2({
43406
+ projectRoot,
42755
43407
  model,
42756
43408
  provider: "openai-compatible",
42757
43409
  providerStream,
42758
- sessionId,
42759
- tools: toolRegistry,
42760
- feedbackStore,
42761
- runMode: planModeFromOpts(opts) ? "design-phase" : runMode,
42762
- maxToolCallsChairman: chairmanBudget,
42763
- ...implementerRetry ? { skipSpecialists: true } : {},
43410
+ toolRegistry: agentRegistry,
43411
+ slicePrompt,
43412
+ ragContext: composed.ragContext ?? ragContext,
42764
43413
  workspaceContext: composed.workspaceContext,
42765
- ...composed.ragContext ? { ragContext: composed.ragContext } : {},
42766
- maxToolLoopIterations: envNumber(process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, {
42767
- default: 30,
42768
- min: 1
42769
- }),
42770
- ...(() => {
42771
- const hard = envNumber(process.env.ZELARI_MAX_TOOL_LOOP_HARD, {
42772
- default: 0,
42773
- min: 0
42774
- });
42775
- return hard > 0 ? { maxToolLoopHardCap: hard } : {};
42776
- })()
42777
- })) {
42778
- if (event.type === "message_start") {
42779
- scrub.reset();
42780
- }
42781
- if (event.type === "message_delta" && typeof event.delta === "string") {
42782
- synthesisText += event.delta;
42783
- const cleanDelta = scrub.push(event.delta);
42784
- if (opts.output === "json") {
42785
- if (cleanDelta.length > 0) emitEvent({ ...event, delta: cleanDelta });
42786
- } else if (opts.output === "plain" && cleanDelta.length > 0) {
42787
- process.stdout.write(cleanDelta);
42788
- }
42789
- } else {
43414
+ projectInstructions: composed.projectInstructions,
43415
+ emit,
43416
+ onEvent: async (event) => {
42790
43417
  if (opts.output === "json") {
42791
- emitEvent(event);
43418
+ if (event.type === "message_delta" && typeof event.delta === "string") {
43419
+ emitEvent(event);
43420
+ } else {
43421
+ emitEvent(event);
43422
+ }
43423
+ } else if (opts.output === "plain" && event.type === "message_delta" && typeof event.delta === "string") {
43424
+ process.stdout.write(event.delta);
42792
43425
  }
42793
- }
42794
- if (event.type === "tool_execution_end") {
42795
- const name = event.toolName ?? event.name ?? "";
42796
- if (name === "write_file" || name === "edit_file" || name === "apply_diff") {
42797
- writeCount += 1;
43426
+ },
43427
+ runCompletionHook: async ({ synthesisText, writeCount, errored }) => {
43428
+ const d = detectDegradedRun2({
43429
+ chairmanErrored: errored,
43430
+ luciferWriteCount: writeCount,
43431
+ synthesisText,
43432
+ runMode: "implementation"
43433
+ });
43434
+ const hook = await runPostCouncilHook2(workspaceCtx, {
43435
+ runMode: "implementation",
43436
+ userMessage: opts.task,
43437
+ synthesisText: synthesisText || void 0,
43438
+ degradedRun: d.degraded,
43439
+ degradedReasons: d.reasons
43440
+ });
43441
+ if (hook.completion?.completion?.ok) {
43442
+ emit(`[zelari] slice completion ok`);
42798
43443
  }
43444
+ return {
43445
+ completionOk: hook.completion?.completion?.ok ?? false,
43446
+ degraded: d.degraded
43447
+ };
42799
43448
  }
42800
- if (event.type === "agent_end") {
42801
- membersCompleted += 1;
42802
- if (event.reason === "error") chairmanErrored = true;
42803
- }
42804
- if (event.type === "error" && event.severity === "fatal") {
42805
- chairmanErrored = true;
42806
- exitCode = 2;
42807
- }
42808
- }
42809
- let completionOk = false;
42810
- let degraded = false;
42811
- try {
42812
- const { detectDegradedRun: detectDegradedRun2 } = await Promise.resolve().then(() => (init_council(), council_exports));
42813
- const d = detectDegradedRun2({
42814
- chairmanErrored,
42815
- councilAborted: false,
42816
- luciferWriteCount: writeCount,
42817
- synthesisText,
42818
- runMode
42819
- });
42820
- degraded = d.degraded;
42821
- const hook = await runPostCouncilHook2(workspaceCtx, {
42822
- runMode,
42823
- userMessage: opts.task,
42824
- synthesisText: synthesisText || void 0,
42825
- degradedRun: d.degraded,
42826
- degradedReasons: d.reasons
42827
- });
42828
- completionOk = hook.completion?.completion?.ok ?? false;
42829
- if (completionOk) {
42830
- emit(`[zelari] slice completion ok`);
42831
- }
42832
- } catch {
42833
- }
42834
- if (synthesisText.trim()) {
42835
- lastMissionAssistant = cleanAgentContent(synthesisText, {
42836
- stripQuestion: false,
42837
- stripThink: false
42838
- });
43449
+ });
43450
+ if (sliceResult.synthesisText?.trim()) {
43451
+ lastMissionAssistant = sliceResult.synthesisText;
42839
43452
  }
42840
- return {
42841
- completionOk,
42842
- ran: membersCompleted > 0 || synthesisText.length > 0,
42843
- synthesisText: synthesisText || void 0,
42844
- writeCount,
42845
- degraded
42846
- };
43453
+ return sliceResult;
42847
43454
  }
42848
43455
  });
42849
43456
  if (state2.status === "error") exitCode = exitCode || 3;