codingbuddy 4.5.0 → 5.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 (144) hide show
  1. package/dist/src/agent/agent.module.js +3 -1
  2. package/dist/src/agent/agent.module.js.map +1 -1
  3. package/dist/src/agent/agent.service.d.ts +11 -4
  4. package/dist/src/agent/agent.service.js +81 -13
  5. package/dist/src/agent/agent.service.js.map +1 -1
  6. package/dist/src/agent/agent.types.d.ts +41 -1
  7. package/dist/src/agent/agent.types.js.map +1 -1
  8. package/dist/src/collaboration/discussion-engine.d.ts +14 -0
  9. package/dist/src/collaboration/discussion-engine.js +49 -0
  10. package/dist/src/collaboration/discussion-engine.js.map +1 -0
  11. package/dist/src/collaboration/index.d.ts +5 -0
  12. package/dist/src/collaboration/index.js +22 -0
  13. package/dist/src/collaboration/index.js.map +1 -0
  14. package/dist/src/collaboration/opinion-adapter.d.ts +14 -0
  15. package/dist/src/collaboration/opinion-adapter.js +56 -0
  16. package/dist/src/collaboration/opinion-adapter.js.map +1 -0
  17. package/dist/src/collaboration/terminal-formatter.d.ts +5 -0
  18. package/dist/src/collaboration/terminal-formatter.js +57 -0
  19. package/dist/src/collaboration/terminal-formatter.js.map +1 -0
  20. package/dist/src/collaboration/types.d.ts +50 -0
  21. package/dist/src/collaboration/types.js +53 -0
  22. package/dist/src/collaboration/types.js.map +1 -0
  23. package/dist/src/config/config.schema.d.ts +8 -0
  24. package/dist/src/config/config.schema.js +4 -0
  25. package/dist/src/config/config.schema.js.map +1 -1
  26. package/dist/src/context/context-document.service.d.ts +1 -1
  27. package/dist/src/context/context-document.service.js +6 -2
  28. package/dist/src/context/context-document.service.js.map +1 -1
  29. package/dist/src/context/context-document.types.d.ts +18 -0
  30. package/dist/src/context/context-document.types.js +13 -1
  31. package/dist/src/context/context-document.types.js.map +1 -1
  32. package/dist/src/context/context-parser.utils.js +32 -0
  33. package/dist/src/context/context-parser.utils.js.map +1 -1
  34. package/dist/src/context/context-serializer.utils.d.ts +3 -2
  35. package/dist/src/context/context-serializer.utils.js +25 -1
  36. package/dist/src/context/context-serializer.utils.js.map +1 -1
  37. package/dist/src/keyword/explicit-pattern-matcher.d.ts +3 -0
  38. package/dist/src/keyword/explicit-pattern-matcher.js +34 -0
  39. package/dist/src/keyword/explicit-pattern-matcher.js.map +1 -0
  40. package/dist/src/keyword/keyword.module.js +17 -1
  41. package/dist/src/keyword/keyword.module.js.map +1 -1
  42. package/dist/src/keyword/keyword.service.d.ts +2 -0
  43. package/dist/src/keyword/keyword.service.js +8 -0
  44. package/dist/src/keyword/keyword.service.js.map +1 -1
  45. package/dist/src/keyword/keyword.types.d.ts +4 -1
  46. package/dist/src/keyword/keyword.types.js +7 -1
  47. package/dist/src/keyword/keyword.types.js.map +1 -1
  48. package/dist/src/keyword/primary-agent-resolver.d.ts +5 -2
  49. package/dist/src/keyword/primary-agent-resolver.js +22 -1
  50. package/dist/src/keyword/primary-agent-resolver.js.map +1 -1
  51. package/dist/src/keyword/strategies/act-agent.strategy.js +8 -0
  52. package/dist/src/keyword/strategies/act-agent.strategy.js.map +1 -1
  53. package/dist/src/keyword/strategies/index.d.ts +1 -1
  54. package/dist/src/keyword/strategies/index.js.map +1 -1
  55. package/dist/src/keyword/strategies/resolution-strategy.interface.d.ts +3 -0
  56. package/dist/src/mcp/handlers/agent.handler.d.ts +1 -0
  57. package/dist/src/mcp/handlers/agent.handler.js +46 -4
  58. package/dist/src/mcp/handlers/agent.handler.js.map +1 -1
  59. package/dist/src/mcp/handlers/context-document.handler.d.ts +3 -0
  60. package/dist/src/mcp/handlers/context-document.handler.js +91 -10
  61. package/dist/src/mcp/handlers/context-document.handler.js.map +1 -1
  62. package/dist/src/mcp/handlers/discussion.handler.d.ts +14 -0
  63. package/dist/src/mcp/handlers/discussion.handler.js +168 -0
  64. package/dist/src/mcp/handlers/discussion.handler.js.map +1 -0
  65. package/dist/src/mcp/handlers/discussion.types.d.ts +18 -0
  66. package/dist/src/mcp/handlers/discussion.types.js +11 -0
  67. package/dist/src/mcp/handlers/discussion.types.js.map +1 -0
  68. package/dist/src/mcp/handlers/index.d.ts +3 -0
  69. package/dist/src/mcp/handlers/index.js +7 -1
  70. package/dist/src/mcp/handlers/index.js.map +1 -1
  71. package/dist/src/mcp/handlers/mode.handler.d.ts +3 -0
  72. package/dist/src/mcp/handlers/mode.handler.js +58 -0
  73. package/dist/src/mcp/handlers/mode.handler.js.map +1 -1
  74. package/dist/src/mcp/handlers/pipeline.handler.d.ts +14 -0
  75. package/dist/src/mcp/handlers/pipeline.handler.js +137 -0
  76. package/dist/src/mcp/handlers/pipeline.handler.js.map +1 -0
  77. package/dist/src/mcp/mcp.module.js +5 -0
  78. package/dist/src/mcp/mcp.module.js.map +1 -1
  79. package/dist/src/parallel-validation/extract-file-paths.d.ts +1 -0
  80. package/dist/src/parallel-validation/extract-file-paths.js +19 -0
  81. package/dist/src/parallel-validation/extract-file-paths.js.map +1 -0
  82. package/dist/src/parallel-validation/index.d.ts +5 -0
  83. package/dist/src/parallel-validation/index.js +12 -0
  84. package/dist/src/parallel-validation/index.js.map +1 -0
  85. package/dist/src/parallel-validation/overlap-matrix.d.ts +10 -0
  86. package/dist/src/parallel-validation/overlap-matrix.js +23 -0
  87. package/dist/src/parallel-validation/overlap-matrix.js.map +1 -0
  88. package/dist/src/parallel-validation/parallel-validation.handler.d.ts +8 -0
  89. package/dist/src/parallel-validation/parallel-validation.handler.js +84 -0
  90. package/dist/src/parallel-validation/parallel-validation.handler.js.map +1 -0
  91. package/dist/src/parallel-validation/parallel-validation.types.d.ts +12 -0
  92. package/dist/src/parallel-validation/parallel-validation.types.js +3 -0
  93. package/dist/src/parallel-validation/parallel-validation.types.js.map +1 -0
  94. package/dist/src/parallel-validation/wave-splitter.d.ts +2 -0
  95. package/dist/src/parallel-validation/wave-splitter.js +39 -0
  96. package/dist/src/parallel-validation/wave-splitter.js.map +1 -0
  97. package/dist/src/pipeline/index.d.ts +5 -0
  98. package/dist/src/pipeline/index.js +14 -0
  99. package/dist/src/pipeline/index.js.map +1 -0
  100. package/dist/src/pipeline/pipeline.executors.d.ts +2 -0
  101. package/dist/src/pipeline/pipeline.executors.js +79 -0
  102. package/dist/src/pipeline/pipeline.executors.js.map +1 -0
  103. package/dist/src/pipeline/pipeline.module.d.ts +2 -0
  104. package/dist/src/pipeline/pipeline.module.js +21 -0
  105. package/dist/src/pipeline/pipeline.module.js.map +1 -0
  106. package/dist/src/pipeline/pipeline.service.d.ts +8 -0
  107. package/dist/src/pipeline/pipeline.service.js +89 -0
  108. package/dist/src/pipeline/pipeline.service.js.map +1 -0
  109. package/dist/src/pipeline/pipeline.types.d.ts +47 -0
  110. package/dist/src/pipeline/pipeline.types.js +33 -0
  111. package/dist/src/pipeline/pipeline.types.js.map +1 -0
  112. package/dist/src/rules/rule-tracker.d.ts +24 -0
  113. package/dist/src/rules/rule-tracker.js +74 -0
  114. package/dist/src/rules/rule-tracker.js.map +1 -0
  115. package/dist/src/shared/event-bridge-reader.d.ts +17 -0
  116. package/dist/src/shared/event-bridge-reader.js +56 -0
  117. package/dist/src/shared/event-bridge-reader.js.map +1 -0
  118. package/dist/src/tui/components/AgentDiscussionPanel.d.ts +8 -0
  119. package/dist/src/tui/components/AgentDiscussionPanel.js +21 -0
  120. package/dist/src/tui/components/AgentDiscussionPanel.js.map +1 -0
  121. package/dist/src/tui/components/AgentDiscussionPanel.spec.d.ts +1 -0
  122. package/dist/src/tui/components/AgentDiscussionPanel.spec.js +85 -0
  123. package/dist/src/tui/components/AgentDiscussionPanel.spec.js.map +1 -0
  124. package/dist/src/tui/components/agent-discussion-panel.pure.d.ts +10 -0
  125. package/dist/src/tui/components/agent-discussion-panel.pure.js +94 -0
  126. package/dist/src/tui/components/agent-discussion-panel.pure.js.map +1 -0
  127. package/dist/src/tui/components/index.d.ts +2 -0
  128. package/dist/src/tui/components/index.js +9 -1
  129. package/dist/src/tui/components/index.js.map +1 -1
  130. package/dist/src/tui/dashboard-app.js +3 -2
  131. package/dist/src/tui/dashboard-app.js.map +1 -1
  132. package/dist/src/tui/dashboard-types.d.ts +2 -0
  133. package/dist/src/tui/dashboard-types.js.map +1 -1
  134. package/dist/src/tui/events/index.d.ts +1 -1
  135. package/dist/src/tui/events/index.js.map +1 -1
  136. package/dist/src/tui/events/types.d.ts +6 -0
  137. package/dist/src/tui/events/types.js +1 -0
  138. package/dist/src/tui/events/types.js.map +1 -1
  139. package/dist/src/tui/hooks/use-dashboard-state.d.ts +4 -1
  140. package/dist/src/tui/hooks/use-dashboard-state.js +10 -0
  141. package/dist/src/tui/hooks/use-dashboard-state.js.map +1 -1
  142. package/dist/src/tui-bundle.mjs +297 -86
  143. package/dist/tsconfig.build.tsbuildinfo +1 -1
  144. package/package.json +14 -14
@@ -1371,12 +1371,12 @@ var require_eventemitter2 = __commonJS({
1371
1371
  });
1372
1372
 
1373
1373
  // src/tui/index.tsx
1374
- import React11 from "react";
1374
+ import React12 from "react";
1375
1375
  import { render } from "ink";
1376
1376
 
1377
1377
  // src/tui/dashboard-app.tsx
1378
- import React8, { useMemo as useMemo3 } from "react";
1379
- import { Box as Box8 } from "ink";
1378
+ import React9, { useMemo as useMemo4 } from "react";
1379
+ import { Box as Box9 } from "ink";
1380
1380
 
1381
1381
  // src/tui/hooks/use-terminal-size.ts
1382
1382
  import { useState, useEffect } from "react";
@@ -1496,7 +1496,8 @@ var TUI_EVENTS = Object.freeze({
1496
1496
  TOOL_INVOKED: "tool:invoked",
1497
1497
  OBJECTIVE_SET: "objective:set",
1498
1498
  SESSION_RESET: "session:reset",
1499
- CONTEXT_UPDATED: "context:updated"
1499
+ CONTEXT_UPDATED: "context:updated",
1500
+ DISCUSSION_ROUND_ADDED: "discussion:round-added"
1500
1501
  });
1501
1502
 
1502
1503
  // src/tui/events/parse-agent.ts
@@ -2837,6 +2838,22 @@ var TestStrategyConfigSchema = z3.object({
2837
2838
  var AIConfigSchema = z3.object({
2838
2839
  defaultModel: z3.string().optional(),
2839
2840
  primaryAgent: z3.string().optional(),
2841
+ /**
2842
+ * Override default dispatch strength for parallel specialist agents.
2843
+ * - "auto": Always dispatch specialists automatically
2844
+ * - "recommend": Suggest dispatch (default for PLAN/ACT)
2845
+ * - "skip": Do not dispatch specialists
2846
+ *
2847
+ * Default varies by mode: EVAL="auto", PLAN/ACT="recommend"
2848
+ *
2849
+ * @example
2850
+ * ```javascript
2851
+ * ai: {
2852
+ * dispatchStrength: 'auto',
2853
+ * }
2854
+ * ```
2855
+ */
2856
+ dispatchStrength: z3.enum(["auto", "recommend", "skip"]).optional(),
2840
2857
  /**
2841
2858
  * List of agent names to exclude from automatic resolution.
2842
2859
  * Useful for project-specific exclusions (e.g., exclude mobile-developer for backend-only projects).
@@ -2862,7 +2879,27 @@ var AIConfigSchema = z3.object({
2862
2879
  * }
2863
2880
  * ```
2864
2881
  */
2865
- maxIncludedSkills: z3.number().int().min(0).max(10).optional()
2882
+ maxIncludedSkills: z3.number().int().min(0).max(10).optional(),
2883
+ /**
2884
+ * Enable/disable automatic plan-reviewer gate after PLAN completion.
2885
+ * When enabled, parse_mode PLAN response includes a planReviewGate recommendation.
2886
+ * Default: true (enabled)
2887
+ *
2888
+ * @example
2889
+ * ```javascript
2890
+ * ai: {
2891
+ * planReviewGate: false, // disable plan review gate
2892
+ * }
2893
+ * ```
2894
+ */
2895
+ planReviewGate: z3.boolean().optional(),
2896
+ /**
2897
+ * Enable/disable agent discussion integration in EVAL mode.
2898
+ * When enabled, parse_mode EVAL response includes agentDiscussion config
2899
+ * for structuring specialist findings as AgentOpinion protocol.
2900
+ * Default: true (enabled)
2901
+ */
2902
+ agentDiscussion: z3.boolean().optional()
2866
2903
  });
2867
2904
  var AutoConfigSchema = z3.object({
2868
2905
  maxIterations: z3.number().int().min(1).max(10).default(3)
@@ -2890,6 +2927,8 @@ var CodingBuddyConfigSchema = z3.object({
2890
2927
  auto: AutoConfigSchema.optional(),
2891
2928
  // Context document limits (DoS prevention)
2892
2929
  context: ContextConfigSchema.optional(),
2930
+ // Upstream Repository Mapping (for cross-repo issue creation)
2931
+ upstreamRepos: z3.record(z3.string(), z3.string()).optional(),
2893
2932
  // Additional Context
2894
2933
  keyFiles: z3.array(z3.string()).optional(),
2895
2934
  avoid: z3.array(z3.string()).optional(),
@@ -3997,7 +4036,8 @@ function createInitialDashboardState() {
3997
4036
  contextDecisions: [],
3998
4037
  contextNotes: [],
3999
4038
  contextMode: null,
4000
- contextStatus: null
4039
+ contextStatus: null,
4040
+ discussionRounds: []
4001
4041
  };
4002
4042
  }
4003
4043
  function cloneAgents(agents) {
@@ -4180,6 +4220,12 @@ function dashboardReducer(state, action) {
4180
4220
  contextStatus: status
4181
4221
  };
4182
4222
  }
4223
+ case "ADD_DISCUSSION_ROUND": {
4224
+ return {
4225
+ ...state,
4226
+ discussionRounds: [...state.discussionRounds, action.payload.round]
4227
+ };
4228
+ }
4183
4229
  case "SESSION_RESET":
4184
4230
  return createInitialDashboardState();
4185
4231
  case "CLEANUP_STALE_AGENTS": {
@@ -4224,6 +4270,7 @@ function useDashboardState(eventBus) {
4224
4270
  const onObjectiveSet = (p) => dispatch({ type: "OBJECTIVE_SET", payload: p });
4225
4271
  const onSessionReset = (p) => dispatch({ type: "SESSION_RESET", payload: p });
4226
4272
  const onContextUpdated = (p) => dispatch({ type: "CONTEXT_UPDATED", payload: p });
4273
+ const onDiscussionRoundAdded = (p) => dispatch({ type: "ADD_DISCUSSION_ROUND", payload: p });
4227
4274
  eventBus.on(TUI_EVENTS.AGENT_ACTIVATED, onActivated);
4228
4275
  eventBus.on(TUI_EVENTS.AGENT_DEACTIVATED, onDeactivated);
4229
4276
  eventBus.on(TUI_EVENTS.MODE_CHANGED, onModeChanged);
@@ -4237,6 +4284,7 @@ function useDashboardState(eventBus) {
4237
4284
  eventBus.on(TUI_EVENTS.OBJECTIVE_SET, onObjectiveSet);
4238
4285
  eventBus.on(TUI_EVENTS.SESSION_RESET, onSessionReset);
4239
4286
  eventBus.on(TUI_EVENTS.CONTEXT_UPDATED, onContextUpdated);
4287
+ eventBus.on(TUI_EVENTS.DISCUSSION_ROUND_ADDED, onDiscussionRoundAdded);
4240
4288
  return () => {
4241
4289
  eventBus.off(TUI_EVENTS.AGENT_ACTIVATED, onActivated);
4242
4290
  eventBus.off(TUI_EVENTS.AGENT_DEACTIVATED, onDeactivated);
@@ -4251,6 +4299,7 @@ function useDashboardState(eventBus) {
4251
4299
  eventBus.off(TUI_EVENTS.OBJECTIVE_SET, onObjectiveSet);
4252
4300
  eventBus.off(TUI_EVENTS.SESSION_RESET, onSessionReset);
4253
4301
  eventBus.off(TUI_EVENTS.CONTEXT_UPDATED, onContextUpdated);
4302
+ eventBus.off(TUI_EVENTS.DISCUSSION_ROUND_ADDED, onDiscussionRoundAdded);
4254
4303
  };
4255
4304
  }, [eventBus]);
4256
4305
  useEffect3(() => {
@@ -5081,9 +5130,157 @@ function FlowMap({
5081
5130
  );
5082
5131
  }
5083
5132
 
5133
+ // src/tui/components/AgentDiscussionPanel.tsx
5134
+ import React3, { useMemo as useMemo2 } from "react";
5135
+ import { Box as Box3, Text as Text3 } from "ink";
5136
+
5137
+ // src/collaboration/types.ts
5138
+ var STANCES = Object.freeze(["approve", "concern", "reject"]);
5139
+ var STANCE_ICONS = Object.freeze({
5140
+ approve: "\u2705",
5141
+ concern: "\u26A0\uFE0F",
5142
+ reject: "\u274C"
5143
+ });
5144
+ function calculateConsensus(opinions) {
5145
+ const approveCount = opinions.filter((o) => o.stance === "approve").length;
5146
+ const concernCount = opinions.filter((o) => o.stance === "concern").length;
5147
+ const rejectCount = opinions.filter((o) => o.stance === "reject").length;
5148
+ return {
5149
+ totalAgents: opinions.length,
5150
+ approveCount,
5151
+ concernCount,
5152
+ rejectCount,
5153
+ reached: opinions.length > 0 && rejectCount === 0,
5154
+ criticalCount: rejectCount
5155
+ };
5156
+ }
5157
+
5158
+ // src/tui/components/agent-discussion-panel.pure.ts
5159
+ var CROSS_REVIEW_VERBS = {
5160
+ approve: "agrees",
5161
+ concern: "notes",
5162
+ reject: "disagrees"
5163
+ };
5164
+ function renderOpinionLine(opinion, stanceHistory) {
5165
+ const avatar = getAgentAvatar(opinion.agentName);
5166
+ const icon = STANCE_ICONS[opinion.stance];
5167
+ let suffix = "";
5168
+ if (stanceHistory && stanceHistory.length > 1) {
5169
+ const lastStance = stanceHistory[stanceHistory.length - 1];
5170
+ const prevStance = stanceHistory[stanceHistory.length - 2];
5171
+ if (lastStance !== prevStance) {
5172
+ suffix = ` (${prevStance === "reject" || prevStance === "concern" ? "revised" : "alt"})`;
5173
+ }
5174
+ }
5175
+ return {
5176
+ text: `${avatar} ${opinion.agentName} ${icon} ${opinion.stance}${suffix}: "${opinion.reasoning}"`,
5177
+ type: "opinion"
5178
+ };
5179
+ }
5180
+ function renderCrossReviewLine(review, agentNames) {
5181
+ const fromAvatar = getAgentAvatar(agentNames[review.fromAgentId] ?? "unknown");
5182
+ const fromName = agentNames[review.fromAgentId] ?? review.fromAgentId;
5183
+ const toAvatar = getAgentAvatar(agentNames[review.toAgentId] ?? "unknown");
5184
+ const toName = agentNames[review.toAgentId] ?? review.toAgentId;
5185
+ const verb = CROSS_REVIEW_VERBS[review.stance];
5186
+ return {
5187
+ text: `${fromAvatar} ${fromName} \u2192 ${toAvatar} ${toName} ${verb}: "${review.comment}"`,
5188
+ type: "cross-review"
5189
+ };
5190
+ }
5191
+ function renderConsensusLine(consensus) {
5192
+ const icon = consensus.reached ? "\u2705" : "\u274C";
5193
+ return {
5194
+ text: `${icon} Consensus: ${consensus.approveCount}/${consensus.totalAgents} | Critical: ${consensus.criticalCount}`,
5195
+ type: "consensus"
5196
+ };
5197
+ }
5198
+ function buildAgentNameMap(rounds) {
5199
+ const map = {};
5200
+ for (const round of rounds) {
5201
+ for (const opinion of round.opinions) {
5202
+ map[opinion.agentId] = opinion.agentName;
5203
+ }
5204
+ }
5205
+ return map;
5206
+ }
5207
+ function buildStanceHistories(rounds) {
5208
+ const histories = {};
5209
+ for (const round of rounds) {
5210
+ for (const opinion of round.opinions) {
5211
+ if (!histories[opinion.agentId]) {
5212
+ histories[opinion.agentId] = [];
5213
+ }
5214
+ histories[opinion.agentId].push(opinion.stance);
5215
+ }
5216
+ }
5217
+ return histories;
5218
+ }
5219
+ function renderDiscussionPanel(rounds, _width) {
5220
+ if (rounds.length === 0) {
5221
+ return [{ text: "No agent discussion yet", type: "empty" }];
5222
+ }
5223
+ const lines = [];
5224
+ const agentNames = buildAgentNameMap(rounds);
5225
+ const stanceHistories = buildStanceHistories(rounds);
5226
+ const latestRound = rounds[rounds.length - 1];
5227
+ lines.push({ text: `\u2500\u2500 Agent Discussion \u2500\u2500`, type: "header" });
5228
+ for (const opinion of latestRound.opinions) {
5229
+ lines.push(renderOpinionLine(opinion, stanceHistories[opinion.agentId]));
5230
+ }
5231
+ for (const review of latestRound.crossReviews) {
5232
+ lines.push(renderCrossReviewLine(review, agentNames));
5233
+ }
5234
+ const consensus = calculateConsensus(latestRound.opinions);
5235
+ lines.push(renderConsensusLine(consensus));
5236
+ return lines;
5237
+ }
5238
+
5239
+ // src/tui/components/AgentDiscussionPanel.tsx
5240
+ var LINE_COLORS = {
5241
+ opinion: "white",
5242
+ "cross-review": "cyan",
5243
+ consensus: "green",
5244
+ header: "magenta",
5245
+ empty: "gray"
5246
+ };
5247
+ function AgentDiscussionPanel({
5248
+ rounds,
5249
+ width,
5250
+ height
5251
+ }) {
5252
+ const lines = useMemo2(
5253
+ () => renderDiscussionPanel(rounds, width),
5254
+ [rounds, width]
5255
+ );
5256
+ const maxLines = Math.max(0, height - 2);
5257
+ const visibleLines = lines.slice(0, maxLines);
5258
+ return /* @__PURE__ */ React3.createElement(
5259
+ Box3,
5260
+ {
5261
+ flexDirection: "column",
5262
+ width,
5263
+ height,
5264
+ borderStyle: "round",
5265
+ borderColor: BORDER_COLORS.panel
5266
+ },
5267
+ visibleLines.map((line, i) => /* @__PURE__ */ React3.createElement(
5268
+ Text3,
5269
+ {
5270
+ key: i,
5271
+ color: LINE_COLORS[line.type],
5272
+ bold: line.type === "header" || line.type === "consensus",
5273
+ dimColor: line.type === "empty",
5274
+ wrap: "truncate"
5275
+ },
5276
+ line.text
5277
+ ))
5278
+ );
5279
+ }
5280
+
5084
5281
  // src/tui/components/FocusedAgentPanel.tsx
5085
- import React4 from "react";
5086
- import { Box as Box4, Text as Text4 } from "ink";
5282
+ import React5 from "react";
5283
+ import { Box as Box5, Text as Text5 } from "ink";
5087
5284
 
5088
5285
  // src/tui/components/focused-agent.pure.ts
5089
5286
  function formatObjective(objectives, maxLines = 3) {
@@ -5129,8 +5326,8 @@ function formatEnhancedChecklist(tasks, maxItems = 6) {
5129
5326
  }
5130
5327
 
5131
5328
  // src/tui/components/ContextSection.tsx
5132
- import React3 from "react";
5133
- import { Box as Box3, Text as Text3 } from "ink";
5329
+ import React4 from "react";
5330
+ import { Box as Box4, Text as Text4 } from "ink";
5134
5331
 
5135
5332
  // src/tui/components/context-section.pure.ts
5136
5333
  function formatContextDecisions(decisions, maxItems = 5) {
@@ -5160,27 +5357,27 @@ function ContextSection({
5160
5357
  const hasDecisions = decisions.length > 0;
5161
5358
  const hasNotes = notes.length > 0;
5162
5359
  if (!hasDecisions && !hasNotes) return null;
5163
- return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, hasDecisions && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true, bold: true }, "Decisions"), formatContextDecisions(decisions)?.split("\n").map((line, i) => /* @__PURE__ */ React3.createElement(Text3, { key: i, color: "cyan" }, line))), hasNotes && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true, bold: true }, "Notes"), formatContextNotes(notes)?.split("\n").map((line, i) => /* @__PURE__ */ React3.createElement(Text3, { key: i, dimColor: true }, line))));
5360
+ return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, hasDecisions && /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Text4, { dimColor: true, bold: true }, "Decisions"), formatContextDecisions(decisions)?.split("\n").map((line, i) => /* @__PURE__ */ React4.createElement(Text4, { key: i, color: "cyan" }, line))), hasNotes && /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Text4, { dimColor: true, bold: true }, "Notes"), formatContextNotes(notes)?.split("\n").map((line, i) => /* @__PURE__ */ React4.createElement(Text4, { key: i, dimColor: true }, line))));
5164
5361
  }
5165
5362
 
5166
5363
  // src/tui/components/FocusedAgentPanel.tsx
5167
5364
  function SectionDivider({ title }) {
5168
- return /* @__PURE__ */ React4.createElement(Text4, { color: "magenta" }, formatSectionDivider(title));
5365
+ return /* @__PURE__ */ React5.createElement(Text5, { color: "magenta" }, formatSectionDivider(title));
5169
5366
  }
5170
5367
  function LogSection({
5171
5368
  logs,
5172
5369
  eventLog
5173
5370
  }) {
5174
- if (!logs) return /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, "No events");
5371
+ if (!logs) return /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "No events");
5175
5372
  const logLines = logs.split("\n");
5176
5373
  const offset = eventLog.length - logLines.length;
5177
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, logLines.map((line, i) => {
5374
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, logLines.map((line, i) => {
5178
5375
  const ev = eventLog[offset + i];
5179
5376
  const isError = ev?.level === "error";
5180
5377
  const spaceIdx = line.indexOf(" ");
5181
5378
  const timestamp = spaceIdx > 0 ? line.slice(0, spaceIdx) : line;
5182
5379
  const message = spaceIdx > 0 ? line.slice(spaceIdx + 1) : "";
5183
- return /* @__PURE__ */ React4.createElement(Box4, { key: i, gap: 1 }, /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, timestamp), /* @__PURE__ */ React4.createElement(Text4, { color: isError ? "red" : void 0 }, message));
5380
+ return /* @__PURE__ */ React5.createElement(Box5, { key: i, gap: 1 }, /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, timestamp), /* @__PURE__ */ React5.createElement(Text5, { color: isError ? "red" : void 0 }, message));
5184
5381
  }));
5185
5382
  }
5186
5383
  function FocusedAgentPanel({
@@ -5196,8 +5393,8 @@ function FocusedAgentPanel({
5196
5393
  height
5197
5394
  }) {
5198
5395
  if (!agent) {
5199
- return /* @__PURE__ */ React4.createElement(
5200
- Box4,
5396
+ return /* @__PURE__ */ React5.createElement(
5397
+ Box5,
5201
5398
  {
5202
5399
  borderStyle: "single",
5203
5400
  borderColor: BORDER_COLORS.panel,
@@ -5205,7 +5402,7 @@ function FocusedAgentPanel({
5205
5402
  width,
5206
5403
  height
5207
5404
  },
5208
- /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, "No agent focused")
5405
+ /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "No agent focused")
5209
5406
  );
5210
5407
  }
5211
5408
  const avatar = getAgentAvatar(agent.name);
@@ -5218,8 +5415,8 @@ function FocusedAgentPanel({
5218
5415
  const isRunning = agent.status === "running";
5219
5416
  const showSpinner = isRunning && tick != null;
5220
5417
  const showElapsed = isRunning && now != null && agent.startedAt != null;
5221
- return /* @__PURE__ */ React4.createElement(
5222
- Box4,
5418
+ return /* @__PURE__ */ React5.createElement(
5419
+ Box5,
5223
5420
  {
5224
5421
  borderStyle: "single",
5225
5422
  borderColor: BORDER_COLORS.panel,
@@ -5227,22 +5424,22 @@ function FocusedAgentPanel({
5227
5424
  width,
5228
5425
  height
5229
5426
  },
5230
- /* @__PURE__ */ React4.createElement(Box4, { gap: 2 }, /* @__PURE__ */ React4.createElement(Text4, null, avatar), /* @__PURE__ */ React4.createElement(Text4, { bold: true }, agent.name), showSpinner ? /* @__PURE__ */ React4.createElement(Text4, { color: "cyan" }, spinnerFrame(tick)) : /* @__PURE__ */ React4.createElement(Text4, { color: statusColor, bold: true }, icon), /* @__PURE__ */ React4.createElement(Text4, { color: statusColor }, statusLabel), showElapsed && /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, formatElapsed(agent.startedAt, now)), /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, agent.stage)),
5231
- /* @__PURE__ */ React4.createElement(Box4, { gap: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "magenta" }, progressBar.bar), /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, progressBar.label)),
5232
- /* @__PURE__ */ React4.createElement(SectionDivider, { title: "Objective" }),
5233
- objective ? /* @__PURE__ */ React4.createElement(Text4, null, objective) : /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, "No objectives"),
5234
- /* @__PURE__ */ React4.createElement(SectionDivider, { title: "Skills" }),
5235
- activeSkills.length > 0 ? activeSkills.map((s, i) => /* @__PURE__ */ React4.createElement(Text4, { key: i }, " ", s)) : /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, "No skills"),
5236
- /* @__PURE__ */ React4.createElement(SectionDivider, { title: "Context" }),
5237
- contextDecisions.length > 0 || contextNotes.length > 0 ? /* @__PURE__ */ React4.createElement(ContextSection, { decisions: contextDecisions, notes: contextNotes, width }) : /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, "No context"),
5238
- /* @__PURE__ */ React4.createElement(SectionDivider, { title: "Event Log" }),
5239
- /* @__PURE__ */ React4.createElement(LogSection, { logs, eventLog })
5427
+ /* @__PURE__ */ React5.createElement(Box5, { gap: 2 }, /* @__PURE__ */ React5.createElement(Text5, null, avatar), /* @__PURE__ */ React5.createElement(Text5, { bold: true }, agent.name), showSpinner ? /* @__PURE__ */ React5.createElement(Text5, { color: "cyan" }, spinnerFrame(tick)) : /* @__PURE__ */ React5.createElement(Text5, { color: statusColor, bold: true }, icon), /* @__PURE__ */ React5.createElement(Text5, { color: statusColor }, statusLabel), showElapsed && /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, formatElapsed(agent.startedAt, now)), /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, agent.stage)),
5428
+ /* @__PURE__ */ React5.createElement(Box5, { gap: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "magenta" }, progressBar.bar), /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, progressBar.label)),
5429
+ /* @__PURE__ */ React5.createElement(SectionDivider, { title: "Objective" }),
5430
+ objective ? /* @__PURE__ */ React5.createElement(Text5, null, objective) : /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "No objectives"),
5431
+ /* @__PURE__ */ React5.createElement(SectionDivider, { title: "Skills" }),
5432
+ activeSkills.length > 0 ? activeSkills.map((s, i) => /* @__PURE__ */ React5.createElement(Text5, { key: i }, " ", s)) : /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "No skills"),
5433
+ /* @__PURE__ */ React5.createElement(SectionDivider, { title: "Context" }),
5434
+ contextDecisions.length > 0 || contextNotes.length > 0 ? /* @__PURE__ */ React5.createElement(ContextSection, { decisions: contextDecisions, notes: contextNotes, width }) : /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "No context"),
5435
+ /* @__PURE__ */ React5.createElement(SectionDivider, { title: "Event Log" }),
5436
+ /* @__PURE__ */ React5.createElement(LogSection, { logs, eventLog })
5240
5437
  );
5241
5438
  }
5242
5439
 
5243
5440
  // src/tui/components/ChecklistPanel.tsx
5244
- import React5 from "react";
5245
- import { Box as Box5, Text as Text5 } from "ink";
5441
+ import React6 from "react";
5442
+ import { Box as Box6, Text as Text6 } from "ink";
5246
5443
 
5247
5444
  // src/tui/components/checklist-panel.pure.ts
5248
5445
  function resolveChecklistTasks(tasks, contextDecisions, contextNotes) {
@@ -5270,8 +5467,8 @@ function ChecklistPanel({
5270
5467
  }) {
5271
5468
  const resolvedTasks = resolveChecklistTasks(tasks, contextDecisions, contextNotes);
5272
5469
  const checklist = formatEnhancedChecklist(resolvedTasks);
5273
- return /* @__PURE__ */ React5.createElement(
5274
- Box5,
5470
+ return /* @__PURE__ */ React6.createElement(
5471
+ Box6,
5275
5472
  {
5276
5473
  borderStyle: "single",
5277
5474
  borderColor: BORDER_COLORS.panel,
@@ -5279,17 +5476,17 @@ function ChecklistPanel({
5279
5476
  width,
5280
5477
  height
5281
5478
  },
5282
- /* @__PURE__ */ React5.createElement(Text5, { bold: true, dimColor: true }, "\u2500\u2500\u2500 Checklist"),
5479
+ /* @__PURE__ */ React6.createElement(Text6, { bold: true, dimColor: true }, "\u2500\u2500\u2500 Checklist"),
5283
5480
  checklist.split("\n").map((line, i) => {
5284
5481
  const isCompleted = line.includes("\u2714");
5285
- return /* @__PURE__ */ React5.createElement(Text5, { key: i, color: isCompleted ? "green" : void 0 }, line);
5482
+ return /* @__PURE__ */ React6.createElement(Text6, { key: i, color: isCompleted ? "green" : void 0 }, line);
5286
5483
  })
5287
5484
  );
5288
5485
  }
5289
5486
 
5290
5487
  // src/tui/components/StageHealthBar.tsx
5291
- import React6 from "react";
5292
- import { Box as Box6, Text as Text6 } from "ink";
5488
+ import React7 from "react";
5489
+ import { Box as Box7, Text as Text7 } from "ink";
5293
5490
 
5294
5491
  // src/tui/components/stage-health.pure.ts
5295
5492
  function formatCount(n) {
@@ -5357,29 +5554,29 @@ function StageStatDisplay({
5357
5554
  const parts = [];
5358
5555
  if (stats.running > 0)
5359
5556
  parts.push(
5360
- /* @__PURE__ */ React6.createElement(Text6, { key: "r", color: "green" }, " ", "\u25CF ", stats.running, " running")
5557
+ /* @__PURE__ */ React7.createElement(Text7, { key: "r", color: "green" }, " ", "\u25CF ", stats.running, " running")
5361
5558
  );
5362
5559
  if (stats.blocked > 0)
5363
5560
  parts.push(
5364
- /* @__PURE__ */ React6.createElement(Text6, { key: "b", color: "yellow" }, " ", "\u23F8 ", stats.blocked, " blocked")
5561
+ /* @__PURE__ */ React7.createElement(Text7, { key: "b", color: "yellow" }, " ", "\u23F8 ", stats.blocked, " blocked")
5365
5562
  );
5366
5563
  if (stats.waiting > 0)
5367
5564
  parts.push(
5368
- /* @__PURE__ */ React6.createElement(Text6, { key: "w", dimColor: true }, " ", "\u25CB ", stats.waiting, " waiting")
5565
+ /* @__PURE__ */ React7.createElement(Text7, { key: "w", dimColor: true }, " ", "\u25CB ", stats.waiting, " waiting")
5369
5566
  );
5370
5567
  if (stats.done > 0)
5371
5568
  parts.push(
5372
- /* @__PURE__ */ React6.createElement(Text6, { key: "d", color: "green" }, " ", "\u2713 ", stats.done)
5569
+ /* @__PURE__ */ React7.createElement(Text7, { key: "d", color: "green" }, " ", "\u2713 ", stats.done)
5373
5570
  );
5374
5571
  if (stats.error > 0)
5375
5572
  parts.push(
5376
- /* @__PURE__ */ React6.createElement(Text6, { key: "e", color: "red", bold: true }, " ", "! ", stats.error, " err")
5573
+ /* @__PURE__ */ React7.createElement(Text7, { key: "e", color: "red", bold: true }, " ", "! ", stats.error, " err")
5377
5574
  );
5378
5575
  if (parts.length === 0)
5379
5576
  parts.push(
5380
- /* @__PURE__ */ React6.createElement(Text6, { key: "idle", dimColor: true }, " ", "idle")
5577
+ /* @__PURE__ */ React7.createElement(Text7, { key: "idle", dimColor: true }, " ", "idle")
5381
5578
  );
5382
- return /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text6, { color, bold: true }, mode, ":"), parts);
5579
+ return /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text7, { color, bold: true }, mode, ":"), parts);
5383
5580
  }
5384
5581
  function StageHealthBar({
5385
5582
  stageHealth,
@@ -5393,24 +5590,24 @@ function StageHealthBar({
5393
5590
  now: _now
5394
5591
  }) {
5395
5592
  const hasActivity = activityHistory && activityHistory.length > 0;
5396
- return /* @__PURE__ */ React6.createElement(
5397
- Box6,
5593
+ return /* @__PURE__ */ React7.createElement(
5594
+ Box7,
5398
5595
  {
5399
5596
  borderStyle: "double",
5400
5597
  borderColor: BORDER_COLORS.panel,
5401
5598
  width,
5402
5599
  flexDirection: "column"
5403
5600
  },
5404
- /* @__PURE__ */ React6.createElement(Box6, null, hasActivity && /* @__PURE__ */ React6.createElement(Box6, { gap: 1, marginRight: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "cyan" }, renderSparkline(
5601
+ /* @__PURE__ */ React7.createElement(Box7, null, hasActivity && /* @__PURE__ */ React7.createElement(Box7, { gap: 1, marginRight: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "cyan" }, renderSparkline(
5405
5602
  activityHistory.map((s) => s.toolCalls),
5406
5603
  10
5407
- )), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, computeThroughput(activityHistory))), /* @__PURE__ */ React6.createElement(Box6, { gap: 2 }, ["PLAN", "ACT", "EVAL"].map((mode) => /* @__PURE__ */ React6.createElement(StageStatDisplay, { key: mode, mode, stats: stageHealth[mode] }))), /* @__PURE__ */ React6.createElement(Box6, { flexGrow: 1 }), /* @__PURE__ */ React6.createElement(Box6, { gap: 2 }, bottlenecks.length > 0 && /* @__PURE__ */ React6.createElement(Text6, { color: "red", bold: true }, "\u26A1 Bottlenecks: ", bottlenecks.join(" / ")), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, "\u{1F916} ", formatCount(agentCount)), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, "\u2699 ", formatCount(skillCount)), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, "\u{1F527} ", formatCount(toolCount))))
5604
+ )), /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, computeThroughput(activityHistory))), /* @__PURE__ */ React7.createElement(Box7, { gap: 2 }, ["PLAN", "ACT", "EVAL"].map((mode) => /* @__PURE__ */ React7.createElement(StageStatDisplay, { key: mode, mode, stats: stageHealth[mode] }))), /* @__PURE__ */ React7.createElement(Box7, { flexGrow: 1 }), /* @__PURE__ */ React7.createElement(Box7, { gap: 2 }, bottlenecks.length > 0 && /* @__PURE__ */ React7.createElement(Text7, { color: "red", bold: true }, "\u26A1 Bottlenecks: ", bottlenecks.join(" / ")), /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, "\u{1F916} ", formatCount(agentCount)), /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, "\u2699 ", formatCount(skillCount)), /* @__PURE__ */ React7.createElement(Text7, { dimColor: true }, "\u{1F527} ", formatCount(toolCount))))
5408
5605
  );
5409
5606
  }
5410
5607
 
5411
5608
  // src/tui/components/ActivityVisualizer.tsx
5412
- import React7, { useMemo as useMemo2 } from "react";
5413
- import { Box as Box7, Text as Text7 } from "ink";
5609
+ import React8, { useMemo as useMemo3 } from "react";
5610
+ import { Box as Box8, Text as Text8 } from "ink";
5414
5611
 
5415
5612
  // src/tui/utils/display-width.ts
5416
5613
  function isWide(code) {
@@ -5579,11 +5776,11 @@ function ActivityVisualizer({
5579
5776
  const treeWidth = Math.floor(width * 0.6);
5580
5777
  const cardWidth = width - treeWidth;
5581
5778
  const contentHeight = Math.max(1, height - 2);
5582
- const treeLines = useMemo2(
5779
+ const treeLines = useMemo3(
5583
5780
  () => renderAgentTree(agents, edges, activeSkills, Math.max(1, treeWidth - 2), contentHeight),
5584
5781
  [agents, edges, activeSkills, treeWidth, contentHeight]
5585
5782
  );
5586
- const cardLines = useMemo2(
5783
+ const cardLines = useMemo3(
5587
5784
  () => renderAgentStatusCard(
5588
5785
  focusedAgent,
5589
5786
  currentMode,
@@ -5595,10 +5792,10 @@ function ActivityVisualizer({
5595
5792
  [focusedAgent, currentMode, objectives, activeSkills, cardWidth, contentHeight]
5596
5793
  );
5597
5794
  if (width <= 0 || height <= 0) {
5598
- return /* @__PURE__ */ React7.createElement(Box7, null);
5795
+ return /* @__PURE__ */ React8.createElement(Box8, null);
5599
5796
  }
5600
- return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "row", width, height }, /* @__PURE__ */ React7.createElement(
5601
- Box7,
5797
+ return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "row", width, height }, /* @__PURE__ */ React8.createElement(
5798
+ Box8,
5602
5799
  {
5603
5800
  borderStyle: "single",
5604
5801
  borderColor: BORDER_COLORS.panel,
@@ -5606,9 +5803,9 @@ function ActivityVisualizer({
5606
5803
  width: treeWidth,
5607
5804
  height
5608
5805
  },
5609
- treeLines.map((line, i) => /* @__PURE__ */ React7.createElement(Text7, { key: i }, line))
5610
- ), /* @__PURE__ */ React7.createElement(
5611
- Box7,
5806
+ treeLines.map((line, i) => /* @__PURE__ */ React8.createElement(Text8, { key: i }, line))
5807
+ ), /* @__PURE__ */ React8.createElement(
5808
+ Box8,
5612
5809
  {
5613
5810
  borderStyle: "single",
5614
5811
  borderColor: BORDER_COLORS.panel,
@@ -5616,7 +5813,7 @@ function ActivityVisualizer({
5616
5813
  width: cardWidth,
5617
5814
  height
5618
5815
  },
5619
- cardLines.map((line, i) => /* @__PURE__ */ React7.createElement(Text7, { key: i }, line))
5816
+ cardLines.map((line, i) => /* @__PURE__ */ React8.createElement(Text8, { key: i }, line))
5620
5817
  ));
5621
5818
  }
5622
5819
 
@@ -5703,17 +5900,17 @@ function DashboardApp({
5703
5900
  }) {
5704
5901
  const { columns, rows, layoutMode } = useTerminalSize();
5705
5902
  const tick = useTick(1e3);
5706
- const now = useMemo3(() => Date.now(), [tick]);
5903
+ const now = useMemo4(() => Date.now(), [tick]);
5707
5904
  const internalState = useDashboardState(externalState ? void 0 : eventBus);
5708
5905
  const state = externalState ?? internalState;
5709
5906
  const focusedAgent = state.focusedAgentId ? state.agents.get(state.focusedAgentId) ?? null : null;
5710
- const stageHealth = useMemo3(() => computeStageHealth(state.agents), [state.agents]);
5711
- const bottlenecks = useMemo3(() => detectBottlenecks(state.eventLog), [state.eventLog]);
5712
- const grid = useMemo3(
5907
+ const stageHealth = useMemo4(() => computeStageHealth(state.agents), [state.agents]);
5908
+ const bottlenecks = useMemo4(() => detectBottlenecks(state.eventLog), [state.eventLog]);
5909
+ const grid = useMemo4(
5713
5910
  () => computeGridLayout(columns, rows, layoutMode),
5714
5911
  [columns, rows, layoutMode]
5715
5912
  );
5716
- return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", width: grid.total.width, height: grid.total.height }, /* @__PURE__ */ React8.createElement(
5913
+ return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", width: grid.total.width, height: grid.total.height }, /* @__PURE__ */ React9.createElement(
5717
5914
  HeaderBar,
5718
5915
  {
5719
5916
  workspace: workspaceProp ?? state.workspace,
@@ -5724,7 +5921,7 @@ function DashboardApp({
5724
5921
  tick,
5725
5922
  now
5726
5923
  }
5727
- ), layoutMode === "narrow" ? /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column" }, grid.checklistPanel.height > 0 && /* @__PURE__ */ React8.createElement(
5924
+ ), layoutMode === "narrow" ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column" }, grid.checklistPanel.height > 0 && /* @__PURE__ */ React9.createElement(
5728
5925
  ChecklistPanel,
5729
5926
  {
5730
5927
  tasks: state.tasks,
@@ -5733,7 +5930,7 @@ function DashboardApp({
5733
5930
  width: grid.checklistPanel.width,
5734
5931
  height: grid.checklistPanel.height
5735
5932
  }
5736
- ), /* @__PURE__ */ React8.createElement(
5933
+ ), /* @__PURE__ */ React9.createElement(
5737
5934
  FocusedAgentPanel,
5738
5935
  {
5739
5936
  agent: focusedAgent,
@@ -5747,7 +5944,14 @@ function DashboardApp({
5747
5944
  tick,
5748
5945
  now
5749
5946
  }
5750
- ), /* @__PURE__ */ React8.createElement(
5947
+ ), state.discussionRounds.length > 0 ? /* @__PURE__ */ React9.createElement(
5948
+ AgentDiscussionPanel,
5949
+ {
5950
+ rounds: state.discussionRounds,
5951
+ width: grid.flowMap.width,
5952
+ height: grid.flowMap.height
5953
+ }
5954
+ ) : /* @__PURE__ */ React9.createElement(
5751
5955
  FlowMap,
5752
5956
  {
5753
5957
  agents: state.agents,
@@ -5759,14 +5963,21 @@ function DashboardApp({
5759
5963
  tick,
5760
5964
  now
5761
5965
  }
5762
- )) : /* @__PURE__ */ React8.createElement(
5763
- Box8,
5966
+ )) : /* @__PURE__ */ React9.createElement(
5967
+ Box9,
5764
5968
  {
5765
5969
  flexDirection: "row",
5766
5970
  width: grid.total.width,
5767
5971
  height: grid.checklistPanel.height + grid.focusedAgent.height
5768
5972
  },
5769
- /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", width: grid.flowMap.width }, /* @__PURE__ */ React8.createElement(
5973
+ /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", width: grid.flowMap.width }, state.discussionRounds.length > 0 ? /* @__PURE__ */ React9.createElement(
5974
+ AgentDiscussionPanel,
5975
+ {
5976
+ rounds: state.discussionRounds,
5977
+ width: grid.flowMap.width,
5978
+ height: grid.flowMap.height
5979
+ }
5980
+ ) : /* @__PURE__ */ React9.createElement(
5770
5981
  FlowMap,
5771
5982
  {
5772
5983
  agents: state.agents,
@@ -5778,7 +5989,7 @@ function DashboardApp({
5778
5989
  tick,
5779
5990
  now
5780
5991
  }
5781
- ), /* @__PURE__ */ React8.createElement(
5992
+ ), /* @__PURE__ */ React9.createElement(
5782
5993
  ActivityVisualizer,
5783
5994
  {
5784
5995
  currentMode: state.currentMode,
@@ -5791,7 +6002,7 @@ function DashboardApp({
5791
6002
  height: grid.monitorPanel.height
5792
6003
  }
5793
6004
  )),
5794
- /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", width: grid.checklistPanel.width }, /* @__PURE__ */ React8.createElement(
6005
+ /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", width: grid.checklistPanel.width }, /* @__PURE__ */ React9.createElement(
5795
6006
  ChecklistPanel,
5796
6007
  {
5797
6008
  tasks: state.tasks,
@@ -5800,7 +6011,7 @@ function DashboardApp({
5800
6011
  width: grid.checklistPanel.width,
5801
6012
  height: grid.checklistPanel.height
5802
6013
  }
5803
- ), /* @__PURE__ */ React8.createElement(
6014
+ ), /* @__PURE__ */ React9.createElement(
5804
6015
  FocusedAgentPanel,
5805
6016
  {
5806
6017
  agent: focusedAgent,
@@ -5815,7 +6026,7 @@ function DashboardApp({
5815
6026
  now
5816
6027
  }
5817
6028
  ))
5818
- ), /* @__PURE__ */ React8.createElement(
6029
+ ), /* @__PURE__ */ React9.createElement(
5819
6030
  StageHealthBar,
5820
6031
  {
5821
6032
  stageHealth,
@@ -5832,8 +6043,8 @@ function DashboardApp({
5832
6043
  }
5833
6044
 
5834
6045
  // src/tui/multi-session-app.tsx
5835
- import React10, { useMemo as useMemo4, useCallback as useCallback2 } from "react";
5836
- import { Box as Box10, useInput } from "ink";
6046
+ import React11, { useMemo as useMemo5, useCallback as useCallback2 } from "react";
6047
+ import { Box as Box11, useInput } from "ink";
5837
6048
  import * as path8 from "path";
5838
6049
 
5839
6050
  // src/tui/hooks/use-multi-session-state.ts
@@ -5989,8 +6200,8 @@ function useMultiSessionState(manager) {
5989
6200
  }
5990
6201
 
5991
6202
  // src/tui/components/SessionTabBar.tsx
5992
- import React9 from "react";
5993
- import { Box as Box9, Text as Text8 } from "ink";
6203
+ import React10 from "react";
6204
+ import { Box as Box10, Text as Text9 } from "ink";
5994
6205
 
5995
6206
  // src/tui/components/session-tab-bar.pure.ts
5996
6207
  var STATUS_ICONS2 = {
@@ -6044,14 +6255,14 @@ function SessionTabBar({
6044
6255
  if (formatted === "") {
6045
6256
  return null;
6046
6257
  }
6047
- return /* @__PURE__ */ React9.createElement(Box9, { width, height: 1 }, /* @__PURE__ */ React9.createElement(Text8, null, formatted));
6258
+ return /* @__PURE__ */ React10.createElement(Box10, { width, height: 1 }, /* @__PURE__ */ React10.createElement(Text9, null, formatted));
6048
6259
  }
6049
6260
 
6050
6261
  // src/tui/multi-session-app.tsx
6051
6262
  function MultiSessionApp({ manager }) {
6052
6263
  const { columns, layoutMode } = useTerminalSize();
6053
6264
  const { sessions, activeSessionPid, switchNext, switchPrev, switchByIndex } = useMultiSessionState(manager);
6054
- const tabs = useMemo4(() => {
6265
+ const tabs = useMemo5(() => {
6055
6266
  let index = 0;
6056
6267
  const result = [];
6057
6268
  for (const [pid, sessionState] of sessions) {
@@ -6066,13 +6277,13 @@ function MultiSessionApp({ manager }) {
6066
6277
  }
6067
6278
  return result;
6068
6279
  }, [sessions, activeSessionPid]);
6069
- const activeEventBus = useMemo4(() => {
6280
+ const activeEventBus = useMemo5(() => {
6070
6281
  if (activeSessionPid === null) return void 0;
6071
6282
  const managedSessions = manager.getSessions();
6072
6283
  const found = managedSessions.find((s) => s.instance.pid === activeSessionPid);
6073
6284
  return found?.eventBus;
6074
6285
  }, [manager, activeSessionPid]);
6075
- const activeProjectRoot = useMemo4(() => {
6286
+ const activeProjectRoot = useMemo5(() => {
6076
6287
  if (activeSessionPid === null) return void 0;
6077
6288
  return sessions.get(activeSessionPid)?.projectRoot;
6078
6289
  }, [sessions, activeSessionPid]);
@@ -6094,7 +6305,7 @@ function MultiSessionApp({ manager }) {
6094
6305
  [switchNext, switchPrev, switchByIndex]
6095
6306
  );
6096
6307
  useInput(handleInput);
6097
- return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(SessionTabBar, { sessions: tabs, width: columns, layoutMode }), /* @__PURE__ */ React10.createElement(
6308
+ return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(SessionTabBar, { sessions: tabs, width: columns, layoutMode }), /* @__PURE__ */ React11.createElement(
6098
6309
  DashboardApp,
6099
6310
  {
6100
6311
  key: activeSessionPid ?? "none",
@@ -6142,10 +6353,10 @@ function createDefaultAgentState(params) {
6142
6353
  // src/tui/index.tsx
6143
6354
  function startTui(options) {
6144
6355
  const renderOptions = options.stdout ? { stdout: options.stdout } : {};
6145
- return render(/* @__PURE__ */ React11.createElement(DashboardApp, { eventBus: options.eventBus }), renderOptions);
6356
+ return render(/* @__PURE__ */ React12.createElement(DashboardApp, { eventBus: options.eventBus }), renderOptions);
6146
6357
  }
6147
6358
  function renderMultiSession(options) {
6148
- return render(/* @__PURE__ */ React11.createElement(MultiSessionApp, { manager: options.manager }));
6359
+ return render(/* @__PURE__ */ React12.createElement(MultiSessionApp, { manager: options.manager }));
6149
6360
  }
6150
6361
  export {
6151
6362
  AGENT_STATUSES,