lsd-pi 1.3.9 → 1.3.10

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 (46) hide show
  1. package/dist/resources/extensions/mcp-client/index.js +191 -83
  2. package/dist/resources/extensions/mcp-client/mcp-manager-component.js +220 -0
  3. package/dist/resources/extensions/slash-commands/plan.js +67 -13
  4. package/dist/resources/extensions/subagent/agents.js +7 -0
  5. package/dist/resources/extensions/subagent/index.js +25 -8
  6. package/dist/resources/extensions/subagent/model-resolution.js +1 -0
  7. package/package.json +1 -1
  8. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +104 -2
  9. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -1
  10. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +39 -2
  11. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  12. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +135 -18
  13. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  14. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +21 -2
  15. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -1
  16. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +146 -8
  17. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -1
  18. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +51 -13
  19. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -1
  20. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  21. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +75 -4
  22. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  23. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  24. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  25. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  26. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  27. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  28. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +31 -2
  29. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  30. package/packages/pi-coding-agent/package.json +1 -1
  31. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +129 -2
  32. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +158 -18
  33. package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +163 -9
  34. package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +60 -13
  35. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +86 -5
  36. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -0
  37. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +31 -2
  38. package/pkg/package.json +1 -1
  39. package/src/resources/extensions/mcp-client/index.ts +212 -90
  40. package/src/resources/extensions/mcp-client/mcp-manager-component.ts +256 -0
  41. package/src/resources/extensions/mcp-client/tests/mcp-manager-component.test.ts +141 -0
  42. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +18 -2
  43. package/src/resources/extensions/slash-commands/plan.ts +70 -13
  44. package/src/resources/extensions/subagent/agents.ts +9 -0
  45. package/src/resources/extensions/subagent/index.ts +30 -8
  46. package/src/resources/extensions/subagent/model-resolution.ts +1 -0
@@ -113,15 +113,19 @@ function createHost(options: { collapseToolCalls?: boolean; collapsedToolCallsEx
113
113
  }
114
114
 
115
115
  function addPendingTool(host: any, toolCallId: string, elapsed: number): { hidden?: boolean; component: any } {
116
- const state: { hidden?: boolean; component: any } = { hidden: false, component: undefined };
116
+ const state: { hidden?: boolean; component: any; indented?: boolean } = { hidden: false, component: undefined, indented: false };
117
117
  const component = {
118
118
  render: () => (state.hidden ? [] : ["tool"]),
119
119
  updateResult: () => { },
120
+ updateArgs: () => { },
120
121
  setHidden: (hidden: boolean) => {
121
122
  state.hidden = hidden;
122
123
  },
123
124
  isHidden: () => !!state.hidden,
124
125
  setArgsComplete: () => { },
126
+ setIndented: (indented: boolean) => {
127
+ state.indented = indented;
128
+ },
125
129
  getElapsed: () => elapsed,
126
130
  };
127
131
  state.component = component;
@@ -175,7 +179,7 @@ describe("chat-controller collapsed tool summary lifecycle", () => {
175
179
  assert.equal(summaryLines(host).length, 1);
176
180
  });
177
181
 
178
- it("reveals initially hidden on-error tools when they fail", async () => {
182
+ it("keeps on-error tools visible when they fail", async () => {
179
183
  const host = createHost();
180
184
 
181
185
  await handleAgentEvent(host, {
@@ -186,7 +190,7 @@ describe("chat-controller collapsed tool summary lifecycle", () => {
186
190
  await handleAgentEvent(host, toolStartEvent("tool-1", "bash", { command: "exit 1" }));
187
191
  const pending = host.pendingTools.get("tool-1");
188
192
  assert.ok(pending);
189
- assert.equal(pending.isHidden(), true);
193
+ assert.equal(pending.isHidden(), false);
190
194
 
191
195
  await handleAgentEvent(host, {
192
196
  type: "tool_execution_end",
@@ -228,7 +232,7 @@ describe("chat-controller collapsed tool summary lifecycle", () => {
228
232
  assert.ok(stripAnsi(summaries[0].render(160).join("\n")).includes("reading 2 files · 1.0s"));
229
233
  });
230
234
 
231
- it("does not group web fetches", async () => {
235
+ it("keeps last grouped tool label visible after completion", async () => {
232
236
  const host = createHost();
233
237
 
234
238
  await handleAgentEvent(host, {
@@ -236,19 +240,35 @@ describe("chat-controller collapsed tool summary lifecycle", () => {
236
240
  message: assistantMessage(),
237
241
  });
238
242
 
239
- addPendingTool(host, "tool-1", 200);
243
+ await handleAgentEvent(host, toolStartEvent("tool-1", "read", { path: "README.md" }));
244
+ await handleAgentEvent(host, toolEndEvent("tool-1", "read"));
245
+
246
+ const summaries = summaryLines(host);
247
+ assert.equal(summaries.length, 1);
248
+ assert.ok(stripAnsi(summaries[0].render(160).join("\n")).includes("└ README.md"));
249
+ });
250
+
251
+ it("keeps non-groupable web fetches visible", async () => {
252
+ const host = createHost();
253
+
254
+ await handleAgentEvent(host, {
255
+ type: "message_start",
256
+ message: assistantMessage(),
257
+ });
258
+
259
+ const first = addPendingTool(host, "tool-1", 200);
240
260
  await handleAgentEvent(host, toolEndEvent("tool-1", "fetch_page"));
241
261
 
242
- addPendingTool(host, "tool-2", 300);
262
+ const second = addPendingTool(host, "tool-2", 300);
243
263
  await handleAgentEvent(host, toolEndEvent("tool-2", "fetch_page"));
244
264
 
245
265
  const summaries = summaryLines(host);
246
- assert.equal(summaries.length, 2);
247
- assert.ok(stripAnsi(summaries[0].render(160).join("\n")).includes("reading 1 page · 0.2s"));
248
- assert.ok(stripAnsi(summaries[1].render(160).join("\n")).includes("reading 1 page · 0.3s"));
266
+ assert.equal(summaries.length, 0);
267
+ assert.equal(first.hidden, false);
268
+ assert.equal(second.hidden, false);
249
269
  });
250
270
 
251
- it("keeps different collapsed tool types in separate summaries", async () => {
271
+ it("groups mixed collapsed file/nav tools into one summary", async () => {
252
272
  const host = createHost();
253
273
 
254
274
  await handleAgentEvent(host, {
@@ -263,9 +283,10 @@ describe("chat-controller collapsed tool summary lifecycle", () => {
263
283
  await handleAgentEvent(host, toolEndEvent("tool-2", "find"));
264
284
 
265
285
  const summaries = summaryLines(host);
266
- assert.equal(summaries.length, 2);
267
- assert.ok(stripAnsi(summaries[0].render(160).join("\n")).includes("reading 1 file · 0.2s"));
268
- assert.ok(stripAnsi(summaries[1].render(160).join("\n")).includes("finding 1 path · 0.3s"));
286
+ assert.equal(summaries.length, 1);
287
+ const rendered = stripAnsi(summaries[0].render(160).join("\n"));
288
+ assert.ok(rendered.includes("reading 1 file"));
289
+ assert.ok(rendered.includes("finding 1 path"));
269
290
  });
270
291
 
271
292
  it("resets grouping after visible tool result", async () => {
@@ -345,6 +366,32 @@ describe("chat-controller collapsed tool summary lifecycle", () => {
345
366
  assert.ok(stripAnsi(summaries[1].render(160).join("\n")).includes("0.4s"));
346
367
  });
347
368
 
369
+ it("stops grouped spinner on aborted assistant message", async () => {
370
+ const host = createHost();
371
+
372
+ await handleAgentEvent(host, {
373
+ type: "message_start",
374
+ message: assistantMessage(),
375
+ });
376
+
377
+ await handleAgentEvent(host, toolStartEvent("tool-1", "read", { path: "README.md" }));
378
+
379
+ await handleAgentEvent(host, {
380
+ type: "message_end",
381
+ message: {
382
+ ...assistantMessage(),
383
+ stopReason: "aborted",
384
+ errorMessage: "Operation aborted",
385
+ },
386
+ } as any);
387
+
388
+ const summaries = summaryLines(host);
389
+ assert.equal(summaries.length, 1);
390
+ const rendered = stripAnsi(summaries[0].render(160).join("\n"));
391
+ assert.ok(!rendered.includes("…"));
392
+ assert.ok(rendered.includes("README.md") || rendered === "");
393
+ });
394
+
348
395
  it("keeps collapsed tool calls visible in intermediate mode", async () => {
349
396
  const host = createHost({ collapseToolCalls: true, collapsedToolCallsExpanded: true });
350
397
 
@@ -1,5 +1,5 @@
1
1
  import { spawn } from "node:child_process";
2
- import { Loader, Spacer, Text } from "@gsd/pi-tui";
2
+ import { Loader, Markdown, Spacer, Text } from "@gsd/pi-tui";
3
3
 
4
4
  import type { InteractiveModeEvent, InteractiveModeStateHost } from "../interactive-mode-state.js";
5
5
  import { theme } from "../theme/theme.js";
@@ -51,6 +51,14 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
51
51
  host.collapsedToolSummaryLine = undefined;
52
52
  };
53
53
 
54
+ const clearPendingCollapsedToolSummaries = (): void => {
55
+ for (const child of host.chatContainer.children) {
56
+ if (child instanceof ToolSummaryLine && child.hasPendingTools()) {
57
+ child.clearPendingTools();
58
+ }
59
+ }
60
+ };
61
+
54
62
  // Tools that always render as their own visible row, never folded into a summary line
55
63
  const ALWAYS_DIRECT_TOOLS = new Set([
56
64
  "bash", "bg_shell",
@@ -94,14 +102,13 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
94
102
  return undefined;
95
103
  };
96
104
 
97
- const appendCollapsedToolSummary = (
105
+ const findOrCreateSummaryForPending = (
98
106
  toolName: string,
99
- elapsed: number,
100
107
  anchor?: { render: (width: number) => string[] },
101
108
  ): ToolSummaryLine => {
102
109
  let summary = findAdjacentCollapsedToolSummary(toolName, anchor);
103
110
  if (!summary) {
104
- summary = new ToolSummaryLine();
111
+ summary = new ToolSummaryLine(host.ui);
105
112
  summary.setHidden(host.collapsedToolCallsExpanded);
106
113
  if (anchor) {
107
114
  const anchorIndex = host.chatContainer.children.indexOf(anchor);
@@ -115,10 +122,47 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
115
122
  }
116
123
  }
117
124
  host.collapsedToolSummaryLine = summary;
125
+ return summary;
126
+ };
127
+
128
+ const findCollapsedSummaryByPendingTool = (toolCallId: string): ToolSummaryLine | undefined => {
129
+ for (const child of host.chatContainer.children) {
130
+ if (child instanceof ToolSummaryLine && child.hasPendingTool(toolCallId)) {
131
+ return child;
132
+ }
133
+ }
134
+ return undefined;
135
+ };
136
+
137
+ const appendCollapsedToolSummary = (
138
+ toolName: string,
139
+ elapsed: number,
140
+ anchor?: { render: (width: number) => string[] },
141
+ ): ToolSummaryLine => {
142
+ const summary = findOrCreateSummaryForPending(toolName, anchor);
118
143
  summary.addTool(toolName, elapsed);
119
144
  return summary;
120
145
  };
121
146
 
147
+ const clearStreamingPostToolComponents = (): void => {
148
+ for (const entry of host.streamingPostToolComponents) {
149
+ host.chatContainer.removeChild(entry.component);
150
+ }
151
+ host.streamingPostToolComponents = [];
152
+ };
153
+
154
+ /**
155
+ * Find the index of the last tool-type content block (toolCall or serverToolUse).
156
+ */
157
+ const findLastToolBlockIndex = (content: Array<{ type: string }>): number => {
158
+ for (let i = content.length - 1; i >= 0; i--) {
159
+ if (content[i].type === "toolCall" || content[i].type === "serverToolUse") {
160
+ return i;
161
+ }
162
+ }
163
+ return -1;
164
+ };
165
+
122
166
  switch (event.type) {
123
167
  case "session_state_changed":
124
168
  switch (event.reason) {
@@ -128,6 +172,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
128
172
  resetCollapsedToolSummary();
129
173
  host.streamingComponent = undefined;
130
174
  host.streamingMessage = undefined;
175
+ host.streamingPostToolComponents = [];
131
176
  host.pendingTools.clear();
132
177
  host.clearAgentPtyComponents();
133
178
  host.pendingMessagesContainer.clear();
@@ -222,7 +267,15 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
222
267
  if (host.streamingComponent && event.message.role === "assistant") {
223
268
  host.streamingMessage = event.message;
224
269
  host.streamingComponent.updateContent(host.streamingMessage);
225
- for (const content of host.streamingMessage.content) {
270
+
271
+ // Remove previously added post-tool text components (they'll be re-created below)
272
+ clearStreamingPostToolComponents();
273
+
274
+ const lastToolIdx = findLastToolBlockIndex(host.streamingMessage.content);
275
+
276
+ for (let ci = 0; ci < host.streamingMessage.content.length; ci++) {
277
+ const content = host.streamingMessage.content[ci];
278
+
226
279
  // Keep collapsed summary active across assistant text updates.
227
280
  // Streamed message updates include all prior text blocks, so resetting
228
281
  // here fragments one contiguous collapsed-tool group into many lines.
@@ -252,12 +305,15 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
252
305
  if (adjacentSummary) {
253
306
  component.setIndented(true);
254
307
  }
308
+ const summary = findOrCreateSummaryForPending(content.name, component);
309
+ summary.addPendingTool(content.id, content.name, content.arguments ?? {});
255
310
  }
256
311
  component.setHidden(shouldHide);
257
312
  host.pendingTools.set(content.id, component);
258
313
  host.updateEditorExpandHint();
259
314
  } else {
260
315
  host.pendingTools.get(content.id)?.updateArgs(content.arguments);
316
+ findCollapsedSummaryByPendingTool(content.id)?.updatePendingToolArgs(content.id, content.arguments ?? {});
261
317
  }
262
318
  } else if (content.type === "serverToolUse") {
263
319
  if (!host.pendingTools.has(content.id)) {
@@ -282,6 +338,8 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
282
338
  if (adjacentSummary) {
283
339
  component.setIndented(true);
284
340
  }
341
+ const summary = findOrCreateSummaryForPending(content.name, component);
342
+ summary.addPendingTool(content.id, content.name, content.input ?? {});
285
343
  }
286
344
  component.setHidden(shouldHide);
287
345
  host.pendingTools.set(content.id, component);
@@ -304,6 +362,22 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
304
362
  });
305
363
  }
306
364
  }
365
+ } else if (content.type === "text" && content.text.trim() && ci > lastToolIdx && lastToolIdx >= 0) {
366
+ // Text blocks that appear AFTER tool blocks need to be rendered
367
+ // after the tool rows to preserve content order.
368
+ const mdTheme = host.getMarkdownThemeWithSettings();
369
+ const component = new Markdown(content.text.trim(), 1, 0, mdTheme);
370
+ host.chatContainer.addChild(component);
371
+ host.streamingPostToolComponents.push({ index: ci, component });
372
+ } else if (content.type === "thinking" && content.thinking.trim() && ci > lastToolIdx && lastToolIdx >= 0 && !host.hideThinkingBlock) {
373
+ // Thinking blocks after tool blocks — render in correct position.
374
+ const mdTheme = host.getMarkdownThemeWithSettings();
375
+ const component = new Markdown(content.thinking.trim(), 1, 0, mdTheme, {
376
+ color: (text: string) => theme.fg("thinkingText", text),
377
+ italic: true,
378
+ });
379
+ host.chatContainer.addChild(component);
380
+ host.streamingPostToolComponents.push({ index: ci, component });
307
381
  }
308
382
  }
309
383
  host.ui.requestRender();
@@ -332,6 +406,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
332
406
  component.updateResult({ content: [{ type: "text", text: errorMessage }], isError: true });
333
407
  }
334
408
  host.pendingTools.clear();
409
+ clearPendingCollapsedToolSummaries();
335
410
  } else {
336
411
  host.playNotificationSoundOnAgentEnd = true;
337
412
  for (const [, component] of host.pendingTools.entries()) {
@@ -375,6 +450,8 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
375
450
  if (adjacentSummary) {
376
451
  component.setIndented(true);
377
452
  }
453
+ const summary = findOrCreateSummaryForPending(event.toolName, component);
454
+ summary.addPendingTool(event.toolCallId, event.toolName, event.args ?? {});
378
455
  }
379
456
  component.setHidden(shouldHide);
380
457
  host.pendingTools.set(event.toolCallId, component);
@@ -428,11 +505,13 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
428
505
  component.updateResult({ ...event.result, isError: event.isError });
429
506
  const collapseToolCalls = host.settingsManager.getCollapseToolCalls?.() ?? false;
430
507
  if (collapseToolCalls && shouldCollapse(event.toolName, event.isError) && !ALWAYS_DIRECT_TOOLS.has(event.toolName)) {
508
+ findCollapsedSummaryByPendingTool(event.toolCallId)?.removePendingTool(event.toolCallId);
431
509
  appendCollapsedToolSummary(event.toolName, component.getElapsed(), component);
432
510
  component.setHidden(!host.collapsedToolCallsExpanded);
433
511
  component.setIndented(false);
434
512
  host.updateEditorExpandHint();
435
513
  } else {
514
+ findCollapsedSummaryByPendingTool(event.toolCallId)?.removePendingTool(event.toolCallId);
436
515
  component.setHidden(false);
437
516
  resetCollapsedToolSummary();
438
517
  }
@@ -452,8 +531,10 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
452
531
  host.chatContainer.removeChild(host.streamingComponent);
453
532
  host.streamingComponent = undefined;
454
533
  host.streamingMessage = undefined;
534
+ clearStreamingPostToolComponents();
455
535
  }
456
536
  host.pendingTools.clear();
537
+ clearPendingCollapsedToolSummaries();
457
538
  resetCollapsedToolSummary();
458
539
  // Update hint: show expand/collapse if tool outputs exist, else clear
459
540
  host.defaultEditor.bottomHint = "";
@@ -26,6 +26,7 @@ export interface InteractiveModeStateHost {
26
26
  workingMessages: string[];
27
27
  streamingComponent?: any;
28
28
  streamingMessage?: any;
29
+ streamingPostToolComponents: Array<{ index: number; component: any }>;
29
30
  retryEscapeHandler?: () => void;
30
31
  retryLoader?: any;
31
32
  autoCompactionLoader?: any;
@@ -318,6 +318,7 @@ export class InteractiveMode {
318
318
  // Streaming message tracking
319
319
  private streamingComponent: AssistantMessageComponent | undefined = undefined;
320
320
  private streamingMessage: AssistantMessage | undefined = undefined;
321
+ streamingPostToolComponents: Array<{ index: number; component: any }> = [];
321
322
 
322
323
  // Tool execution tracking: toolCallId -> component
323
324
  private pendingTools = new Map<string, ToolExecutionComponent>();
@@ -2773,9 +2774,24 @@ export class InteractiveMode {
2773
2774
  for (const message of sessionContext.messages) {
2774
2775
  // Assistant messages need special handling for tool calls
2775
2776
  if (message.role === "assistant") {
2777
+ // Render content blocks in order to preserve correct visual ordering.
2778
+ // Text/thinking blocks before tools go into AssistantMessageComponent.
2779
+ // Tool blocks are added as separate ToolExecutionComponent instances.
2780
+ // Text/thinking blocks after tools are added as individual Markdown components.
2781
+ const lastToolIdx = (() => {
2782
+ for (let i = message.content.length - 1; i >= 0; i--) {
2783
+ if (message.content[i].type === "toolCall" || message.content[i].type === "serverToolUse") return i;
2784
+ }
2785
+ return -1;
2786
+ })();
2787
+
2788
+ // Phase 1: Render pre-tool text/thinking via AssistantMessageComponent
2776
2789
  this.addMessageToChat(message);
2777
- // Render tool call components
2778
- for (const content of message.content) {
2790
+
2791
+ // Phase 2: Render tool blocks and post-tool text/thinking in content order
2792
+ for (let ci = 0; ci < message.content.length; ci++) {
2793
+ const content = message.content[ci];
2794
+
2779
2795
  if (content.type === "toolCall") {
2780
2796
  const component = new ToolExecutionComponent(
2781
2797
  content.name,
@@ -2837,6 +2853,19 @@ export class InteractiveMode {
2837
2853
  // No result yet (aborted stream?) - show as pending
2838
2854
  this.pendingTools.set(content.id, component);
2839
2855
  }
2856
+ } else if (ci > lastToolIdx && lastToolIdx >= 0) {
2857
+ // Text/thinking blocks after tools — render as individual components
2858
+ // to maintain correct visual ordering relative to tool rows.
2859
+ if (content.type === "text" && content.text.trim()) {
2860
+ const md = new Markdown(content.text.trim(), 1, 0, this.getMarkdownThemeWithSettings());
2861
+ this.chatContainer.addChild(md);
2862
+ } else if (content.type === "thinking" && content.thinking.trim() && !this.hideThinkingBlock) {
2863
+ const md = new Markdown(content.thinking.trim(), 1, 0, this.getMarkdownThemeWithSettings(), {
2864
+ color: (text: string) => theme.fg("thinkingText", text),
2865
+ italic: true,
2866
+ });
2867
+ this.chatContainer.addChild(md);
2868
+ }
2840
2869
  }
2841
2870
  }
2842
2871
  } else if (message.role === "toolResult") {
package/pkg/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lsd-pi",
3
- "version": "1.3.9",
3
+ "version": "1.3.10",
4
4
  "piConfig": {
5
5
  "name": "lsd",
6
6
  "configDir": ".lsd"