@caupulican/pi-adaptative 0.78.2 → 0.78.4

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 (104) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +16 -14
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +1 -1
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-session.d.ts +1 -0
  7. package/dist/core/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +50 -25
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/extensions/types.d.ts +16 -1
  11. package/dist/core/extensions/types.d.ts.map +1 -1
  12. package/dist/core/extensions/types.js.map +1 -1
  13. package/dist/core/model-registry.d.ts.map +1 -1
  14. package/dist/core/model-registry.js +10 -0
  15. package/dist/core/model-registry.js.map +1 -1
  16. package/dist/core/model-resolver.d.ts.map +1 -1
  17. package/dist/core/model-resolver.js +1 -0
  18. package/dist/core/model-resolver.js.map +1 -1
  19. package/dist/core/prompt-templates.d.ts +3 -2
  20. package/dist/core/prompt-templates.d.ts.map +1 -1
  21. package/dist/core/prompt-templates.js +8 -3
  22. package/dist/core/prompt-templates.js.map +1 -1
  23. package/dist/core/provider-display-names.d.ts.map +1 -1
  24. package/dist/core/provider-display-names.js +1 -0
  25. package/dist/core/provider-display-names.js.map +1 -1
  26. package/dist/core/resource-loader.d.ts +5 -5
  27. package/dist/core/resource-loader.d.ts.map +1 -1
  28. package/dist/core/resource-loader.js +13 -11
  29. package/dist/core/resource-loader.js.map +1 -1
  30. package/dist/core/session-manager.d.ts.map +1 -1
  31. package/dist/core/session-manager.js +169 -80
  32. package/dist/core/session-manager.js.map +1 -1
  33. package/dist/core/settings-manager.d.ts +23 -0
  34. package/dist/core/settings-manager.d.ts.map +1 -1
  35. package/dist/core/settings-manager.js +19 -0
  36. package/dist/core/settings-manager.js.map +1 -1
  37. package/dist/core/skills.d.ts.map +1 -1
  38. package/dist/core/skills.js +3 -7
  39. package/dist/core/skills.js.map +1 -1
  40. package/dist/core/slash-commands.d.ts.map +1 -1
  41. package/dist/core/slash-commands.js +6 -3
  42. package/dist/core/slash-commands.js.map +1 -1
  43. package/dist/core/system-prompt.d.ts +3 -3
  44. package/dist/core/system-prompt.d.ts.map +1 -1
  45. package/dist/core/system-prompt.js +23 -18
  46. package/dist/core/system-prompt.js.map +1 -1
  47. package/dist/core/tools/find.d.ts.map +1 -1
  48. package/dist/core/tools/find.js +4 -3
  49. package/dist/core/tools/find.js.map +1 -1
  50. package/dist/core/tools/grep.d.ts.map +1 -1
  51. package/dist/core/tools/grep.js +4 -3
  52. package/dist/core/tools/grep.js.map +1 -1
  53. package/dist/core/tools/ls.d.ts.map +1 -1
  54. package/dist/core/tools/ls.js +1 -0
  55. package/dist/core/tools/ls.js.map +1 -1
  56. package/dist/core/tools/read.d.ts.map +1 -1
  57. package/dist/core/tools/read.js +8 -1
  58. package/dist/core/tools/read.js.map +1 -1
  59. package/dist/core/tools/render-utils.d.ts +1 -1
  60. package/dist/core/tools/render-utils.d.ts.map +1 -1
  61. package/dist/core/tools/render-utils.js +29 -4
  62. package/dist/core/tools/render-utils.js.map +1 -1
  63. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  64. package/dist/modes/interactive/components/footer.js +2 -2
  65. package/dist/modes/interactive/components/footer.js.map +1 -1
  66. package/dist/modes/interactive/components/index.d.ts +2 -0
  67. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  68. package/dist/modes/interactive/components/index.js +2 -0
  69. package/dist/modes/interactive/components/index.js.map +1 -1
  70. package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
  71. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  72. package/dist/modes/interactive/components/tool-execution.js +66 -8
  73. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  74. package/dist/modes/interactive/components/tool-group.d.ts +17 -0
  75. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -0
  76. package/dist/modes/interactive/components/tool-group.js +63 -0
  77. package/dist/modes/interactive/components/tool-group.js.map +1 -0
  78. package/dist/modes/interactive/components/tool-panel-registry.d.ts +23 -0
  79. package/dist/modes/interactive/components/tool-panel-registry.d.ts.map +1 -0
  80. package/dist/modes/interactive/components/tool-panel-registry.js +70 -0
  81. package/dist/modes/interactive/components/tool-panel-registry.js.map +1 -0
  82. package/dist/modes/interactive/interactive-mode.d.ts +6 -1
  83. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  84. package/dist/modes/interactive/interactive-mode.js +119 -60
  85. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  86. package/dist/utils/paths.d.ts.map +1 -1
  87. package/dist/utils/paths.js +4 -1
  88. package/dist/utils/paths.js.map +1 -1
  89. package/docs/extensions.md +6 -3
  90. package/docs/quickstart.md +5 -5
  91. package/docs/sdk.md +3 -3
  92. package/docs/settings.md +50 -0
  93. package/docs/skills.md +3 -3
  94. package/docs/usage.md +5 -5
  95. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  96. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  97. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  98. package/examples/extensions/sandbox/package-lock.json +2 -2
  99. package/examples/extensions/sandbox/package.json +1 -1
  100. package/examples/extensions/with-deps/package-lock.json +2 -2
  101. package/examples/extensions/with-deps/package.json +1 -1
  102. package/examples/sdk/07-context-files.ts +3 -14
  103. package/npm-shrinkwrap.json +388 -2704
  104. package/package.json +5 -5
@@ -58,6 +58,8 @@ import { SessionSelectorComponent } from "./components/session-selector.js";
58
58
  import { SettingsSelectorComponent } from "./components/settings-selector.js";
59
59
  import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
60
60
  import { ToolExecutionComponent } from "./components/tool-execution.js";
61
+ import { ToolGroupComponent } from "./components/tool-group.js";
62
+ import { getToolPanelActionKey, ToolPanelRegistry } from "./components/tool-panel-registry.js";
61
63
  import { TreeSelectorComponent } from "./components/tree-selector.js";
62
64
  import { UserMessageComponent } from "./components/user-message.js";
63
65
  import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
@@ -166,8 +168,8 @@ export class InteractiveMode {
166
168
  // Streaming message tracking
167
169
  streamingComponent = undefined;
168
170
  streamingMessage = undefined;
169
- // Tool execution tracking: toolCallId -> component
170
- pendingTools = new Map();
171
+ // Tool execution tracking and session-scoped reusable panels
172
+ toolPanels = new ToolPanelRegistry();
171
173
  // Tool output expansion state
172
174
  toolOutputExpanded = false;
173
175
  // Thinking block visibility state
@@ -1249,7 +1251,7 @@ export class InteractiveMode {
1249
1251
  this.compactionQueuedMessages = [];
1250
1252
  this.streamingComponent = undefined;
1251
1253
  this.streamingMessage = undefined;
1252
- this.pendingTools.clear();
1254
+ this.clearRenderedToolPanelState();
1253
1255
  this.renderInitialMessages();
1254
1256
  }
1255
1257
  /**
@@ -1258,6 +1260,60 @@ export class InteractiveMode {
1258
1260
  getRegisteredToolDefinition(toolName) {
1259
1261
  return this.session.getToolDefinition(toolName);
1260
1262
  }
1263
+ getToolPanelScope() {
1264
+ return {
1265
+ sessionId: this.sessionManager.getSessionId?.(),
1266
+ sessionFile: this.sessionManager.getSessionFile?.(),
1267
+ cwd: this.sessionManager.getCwd(),
1268
+ };
1269
+ }
1270
+ appendToolExecutionComponent(component, allowGrouping) {
1271
+ const toolGroup = allowGrouping ? component.toolGroup?.trim() : undefined;
1272
+ if (!toolGroup) {
1273
+ this.chatContainer.addChild(component);
1274
+ return;
1275
+ }
1276
+ const children = this.chatContainer.children;
1277
+ const lastChild = children[children.length - 1];
1278
+ if (lastChild instanceof ToolGroupComponent && lastChild.toolGroup === toolGroup) {
1279
+ lastChild.addTool(component);
1280
+ return;
1281
+ }
1282
+ if (lastChild instanceof ToolExecutionComponent && lastChild.toolGroup?.trim() === toolGroup) {
1283
+ const group = new ToolGroupComponent(toolGroup, [lastChild, component]);
1284
+ group.setExpanded(this.toolOutputExpanded);
1285
+ children[children.length - 1] = group;
1286
+ return;
1287
+ }
1288
+ this.chatContainer.addChild(component);
1289
+ }
1290
+ attachToolExecutionComponent(toolName, toolCallId, args) {
1291
+ const actionKey = getToolPanelActionKey(this.getToolPanelScope(), toolName, args);
1292
+ const toolDefinition = this.getRegisteredToolDefinition(toolName);
1293
+ const existing = this.toolPanels.getReusable(actionKey);
1294
+ if (existing) {
1295
+ this.chatContainer.removeChild(existing);
1296
+ existing.resetInvocation(toolName, toolCallId, args, toolDefinition);
1297
+ existing.setExpanded(this.toolOutputExpanded);
1298
+ this.chatContainer.addChild(existing);
1299
+ this.toolPanels.register(toolCallId, existing, actionKey);
1300
+ return existing;
1301
+ }
1302
+ const component = new ToolExecutionComponent(toolName, toolCallId, args, {
1303
+ showImages: this.settingsManager.getShowImages(),
1304
+ imageWidthCells: this.settingsManager.getImageWidthCells(),
1305
+ }, toolDefinition, this.ui, this.sessionManager.getCwd());
1306
+ component.setExpanded(this.toolOutputExpanded);
1307
+ this.appendToolExecutionComponent(component, !actionKey);
1308
+ this.toolPanels.register(toolCallId, component, actionKey);
1309
+ return component;
1310
+ }
1311
+ clearActiveToolCalls() {
1312
+ this.toolPanels.clearActive();
1313
+ }
1314
+ clearRenderedToolPanelState() {
1315
+ this.toolPanels.clearAll();
1316
+ }
1261
1317
  /**
1262
1318
  * Set up keyboard shortcuts registered by extensions.
1263
1319
  */
@@ -1813,7 +1869,7 @@ export class InteractiveMode {
1813
1869
  this.editorContainer.clear();
1814
1870
  this.editorContainer.addChild(this.editor);
1815
1871
  this.editor.setText(savedText);
1816
- this.ui.setFocus(this.editor);
1872
+ this.ui.restoreFocus(this.editor);
1817
1873
  this.ui.requestRender();
1818
1874
  };
1819
1875
  return new Promise((resolve, reject) => {
@@ -1941,7 +1997,7 @@ export class InteractiveMode {
1941
1997
  this.defaultEditor.onAction("app.model.cycleBackward", () => this.cycleModel("backward"));
1942
1998
  // Global debug handler on TUI (works regardless of focus)
1943
1999
  this.ui.onDebug = () => this.handleDebugCommand();
1944
- this.defaultEditor.onAction("app.model.select", () => this.showModelSelector());
2000
+ this.defaultEditor.onAction("app.model.select", () => void this.showModelSelector());
1945
2001
  this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
1946
2002
  this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
1947
2003
  this.defaultEditor.onAction("app.editor.external", () => this.openExternalEditor());
@@ -2045,14 +2101,14 @@ export class InteractiveMode {
2045
2101
  this.editor.setText("");
2046
2102
  return;
2047
2103
  }
2048
- if (text === "/fork") {
2049
- this.showUserMessageSelector();
2104
+ if (text === "/fork" || text.startsWith("/fork ")) {
2105
+ this.showUserMessageSelector(text.slice("/fork".length).trim() || undefined);
2050
2106
  this.editor.setText("");
2051
2107
  return;
2052
2108
  }
2053
- if (text === "/clone") {
2109
+ if (text === "/clone" || text.startsWith("/clone ")) {
2054
2110
  this.editor.setText("");
2055
- await this.handleCloneCommand();
2111
+ await this.handleCloneCommand(text.slice("/clone".length).trim() || undefined);
2056
2112
  return;
2057
2113
  }
2058
2114
  if (text === "/tree") {
@@ -2070,9 +2126,9 @@ export class InteractiveMode {
2070
2126
  this.editor.setText("");
2071
2127
  return;
2072
2128
  }
2073
- if (text === "/new") {
2129
+ if (text === "/new" || text.startsWith("/new ")) {
2074
2130
  this.editor.setText("");
2075
- await this.handleClearCommand();
2131
+ await this.handleClearCommand(text.slice("/new".length).trim() || undefined);
2076
2132
  return;
2077
2133
  }
2078
2134
  if (text === "/compact" || text.startsWith("/compact ")) {
@@ -2174,7 +2230,7 @@ export class InteractiveMode {
2174
2230
  this.footer.invalidate();
2175
2231
  switch (event.type) {
2176
2232
  case "agent_start":
2177
- this.pendingTools.clear();
2233
+ this.clearActiveToolCalls();
2178
2234
  if (this.settingsManager.getShowTerminalProgress()) {
2179
2235
  this.ui.terminal.setProgress(true);
2180
2236
  }
@@ -2236,17 +2292,11 @@ export class InteractiveMode {
2236
2292
  this.streamingComponent.updateContent(this.streamingMessage);
2237
2293
  for (const content of this.streamingMessage.content) {
2238
2294
  if (content.type === "toolCall") {
2239
- if (!this.pendingTools.has(content.id)) {
2240
- const component = new ToolExecutionComponent(content.name, content.id, content.arguments, {
2241
- showImages: this.settingsManager.getShowImages(),
2242
- imageWidthCells: this.settingsManager.getImageWidthCells(),
2243
- }, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
2244
- component.setExpanded(this.toolOutputExpanded);
2245
- this.chatContainer.addChild(component);
2246
- this.pendingTools.set(content.id, component);
2295
+ if (!this.toolPanels.hasActive(content.id)) {
2296
+ this.attachToolExecutionComponent(content.name, content.id, content.arguments);
2247
2297
  }
2248
2298
  else {
2249
- const component = this.pendingTools.get(content.id);
2299
+ const component = this.toolPanels.getActive(content.id);
2250
2300
  if (component) {
2251
2301
  component.updateArgs(content.arguments);
2252
2302
  }
@@ -2275,17 +2325,17 @@ export class InteractiveMode {
2275
2325
  if (!errorMessage) {
2276
2326
  errorMessage = this.streamingMessage.errorMessage || "Error";
2277
2327
  }
2278
- for (const [, component] of this.pendingTools.entries()) {
2328
+ for (const [, component] of this.toolPanels.activeEntries()) {
2279
2329
  component.updateResult({
2280
2330
  content: [{ type: "text", text: errorMessage }],
2281
2331
  isError: true,
2282
2332
  });
2283
2333
  }
2284
- this.pendingTools.clear();
2334
+ this.clearActiveToolCalls();
2285
2335
  }
2286
2336
  else {
2287
2337
  // Args are now complete - trigger diff computation for edit tools
2288
- for (const [, component] of this.pendingTools.entries()) {
2338
+ for (const [, component] of this.toolPanels.activeEntries()) {
2289
2339
  component.setArgsComplete();
2290
2340
  }
2291
2341
  }
@@ -2296,22 +2346,15 @@ export class InteractiveMode {
2296
2346
  this.ui.requestRender();
2297
2347
  break;
2298
2348
  case "tool_execution_start": {
2299
- let component = this.pendingTools.get(event.toolCallId);
2300
- if (!component) {
2301
- component = new ToolExecutionComponent(event.toolName, event.toolCallId, event.args, {
2302
- showImages: this.settingsManager.getShowImages(),
2303
- imageWidthCells: this.settingsManager.getImageWidthCells(),
2304
- }, this.getRegisteredToolDefinition(event.toolName), this.ui, this.sessionManager.getCwd());
2305
- component.setExpanded(this.toolOutputExpanded);
2306
- this.chatContainer.addChild(component);
2307
- this.pendingTools.set(event.toolCallId, component);
2308
- }
2349
+ let component = this.toolPanels.getActive(event.toolCallId);
2350
+ if (!component)
2351
+ component = this.attachToolExecutionComponent(event.toolName, event.toolCallId, event.args);
2309
2352
  component.markExecutionStarted();
2310
2353
  this.ui.requestRender();
2311
2354
  break;
2312
2355
  }
2313
2356
  case "tool_execution_update": {
2314
- const component = this.pendingTools.get(event.toolCallId);
2357
+ const component = this.toolPanels.getActive(event.toolCallId);
2315
2358
  if (component) {
2316
2359
  component.updateResult({ ...event.partialResult, isError: false }, true);
2317
2360
  this.ui.requestRender();
@@ -2319,10 +2362,10 @@ export class InteractiveMode {
2319
2362
  break;
2320
2363
  }
2321
2364
  case "tool_execution_end": {
2322
- const component = this.pendingTools.get(event.toolCallId);
2365
+ const component = this.toolPanels.getActive(event.toolCallId);
2323
2366
  if (component) {
2324
2367
  component.updateResult({ ...event.result, isError: event.isError });
2325
- this.pendingTools.delete(event.toolCallId);
2368
+ this.toolPanels.finish(event.toolCallId);
2326
2369
  this.ui.requestRender();
2327
2370
  }
2328
2371
  break;
@@ -2341,7 +2384,7 @@ export class InteractiveMode {
2341
2384
  this.streamingComponent = undefined;
2342
2385
  this.streamingMessage = undefined;
2343
2386
  }
2344
- this.pendingTools.clear();
2387
+ this.clearActiveToolCalls();
2345
2388
  await this.checkShutdownRequested();
2346
2389
  this.ui.requestRender();
2347
2390
  break;
@@ -2564,7 +2607,7 @@ export class InteractiveMode {
2564
2607
  * @param options.populateHistory Add user messages to editor history
2565
2608
  */
2566
2609
  renderSessionContext(sessionContext, options = {}) {
2567
- this.pendingTools.clear();
2610
+ this.clearRenderedToolPanelState();
2568
2611
  const renderedPendingTools = new Map();
2569
2612
  if (options.updateFooter) {
2570
2613
  this.footer.invalidate();
@@ -2577,12 +2620,7 @@ export class InteractiveMode {
2577
2620
  // Render tool call components
2578
2621
  for (const content of message.content) {
2579
2622
  if (content.type === "toolCall") {
2580
- const component = new ToolExecutionComponent(content.name, content.id, content.arguments, {
2581
- showImages: this.settingsManager.getShowImages(),
2582
- imageWidthCells: this.settingsManager.getImageWidthCells(),
2583
- }, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
2584
- component.setExpanded(this.toolOutputExpanded);
2585
- this.chatContainer.addChild(component);
2623
+ const component = this.attachToolExecutionComponent(content.name, content.id, content.arguments);
2586
2624
  if (message.stopReason === "aborted" || message.stopReason === "error") {
2587
2625
  let errorMessage;
2588
2626
  if (message.stopReason === "aborted") {
@@ -2596,6 +2634,7 @@ export class InteractiveMode {
2596
2634
  errorMessage = message.errorMessage || "Error";
2597
2635
  }
2598
2636
  component.updateResult({ content: [{ type: "text", text: errorMessage }], isError: true });
2637
+ this.toolPanels.finish(content.id);
2599
2638
  }
2600
2639
  else {
2601
2640
  renderedPendingTools.set(content.id, component);
@@ -2609,6 +2648,7 @@ export class InteractiveMode {
2609
2648
  if (component) {
2610
2649
  component.updateResult(message);
2611
2650
  renderedPendingTools.delete(message.toolCallId);
2651
+ this.toolPanels.finish(message.toolCallId);
2612
2652
  }
2613
2653
  }
2614
2654
  else {
@@ -2616,9 +2656,6 @@ export class InteractiveMode {
2616
2656
  this.addMessageToChat(message, options);
2617
2657
  }
2618
2658
  }
2619
- for (const [toolCallId, component] of renderedPendingTools) {
2620
- this.pendingTools.set(toolCallId, component);
2621
- }
2622
2659
  this.ui.requestRender();
2623
2660
  }
2624
2661
  renderInitialMessages() {
@@ -3215,7 +3252,7 @@ export class InteractiveMode {
3215
3252
  const done = () => {
3216
3253
  this.editorContainer.clear();
3217
3254
  this.editorContainer.addChild(this.editor);
3218
- this.ui.setFocus(this.editor);
3255
+ this.ui.restoreFocus(this.editor);
3219
3256
  };
3220
3257
  const { component, focus } = create(done);
3221
3258
  this.editorContainer.clear();
@@ -3260,7 +3297,7 @@ export class InteractiveMode {
3260
3297
  onShowImagesChange: (enabled) => {
3261
3298
  this.settingsManager.setShowImages(enabled);
3262
3299
  for (const child of this.chatContainer.children) {
3263
- if (child instanceof ToolExecutionComponent) {
3300
+ if (child instanceof ToolExecutionComponent || child instanceof ToolGroupComponent) {
3264
3301
  child.setShowImages(enabled);
3265
3302
  }
3266
3303
  }
@@ -3268,7 +3305,7 @@ export class InteractiveMode {
3268
3305
  onImageWidthCellsChange: (width) => {
3269
3306
  this.settingsManager.setImageWidthCells(width);
3270
3307
  for (const child of this.chatContainer.children) {
3271
- if (child instanceof ToolExecutionComponent) {
3308
+ if (child instanceof ToolExecutionComponent || child instanceof ToolGroupComponent) {
3272
3309
  child.setImageWidthCells(width);
3273
3310
  }
3274
3311
  }
@@ -3382,7 +3419,7 @@ export class InteractiveMode {
3382
3419
  }
3383
3420
  async handleModelCommand(searchTerm) {
3384
3421
  if (!searchTerm) {
3385
- this.showModelSelector();
3422
+ await this.showModelSelector();
3386
3423
  return;
3387
3424
  }
3388
3425
  const model = await this.findExactModelMatch(searchTerm);
@@ -3400,7 +3437,7 @@ export class InteractiveMode {
3400
3437
  }
3401
3438
  return;
3402
3439
  }
3403
- this.showModelSelector(searchTerm);
3440
+ await this.showModelSelector(searchTerm);
3404
3441
  }
3405
3442
  async findExactModelMatch(searchTerm) {
3406
3443
  const models = await this.getModelCandidates();
@@ -3452,7 +3489,19 @@ export class InteractiveMode {
3452
3489
  // Ignore auth lookup failures for warning-only checks.
3453
3490
  }
3454
3491
  }
3455
- showModelSelector(initialSearchInput) {
3492
+ async showModelSelector(initialSearchInput) {
3493
+ try {
3494
+ await this.session.extensionRunner.emit({
3495
+ type: "model_selector_open",
3496
+ currentModel: this.session.model,
3497
+ scopedModels: this.session.scopedModels,
3498
+ initialSearchInput,
3499
+ });
3500
+ }
3501
+ catch (error) {
3502
+ this.showError(error instanceof Error ? error.message : String(error));
3503
+ return;
3504
+ }
3456
3505
  this.showSelector((done) => {
3457
3506
  const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, async (model) => {
3458
3507
  try {
@@ -3541,7 +3590,7 @@ export class InteractiveMode {
3541
3590
  return { component: selector, focus: selector };
3542
3591
  });
3543
3592
  }
3544
- showUserMessageSelector() {
3593
+ showUserMessageSelector(newSessionName) {
3545
3594
  const userMessages = this.session.getUserMessagesForForking();
3546
3595
  if (userMessages.length === 0) {
3547
3596
  this.showStatus("No messages to fork from");
@@ -3558,9 +3607,12 @@ export class InteractiveMode {
3558
3607
  return;
3559
3608
  }
3560
3609
  this.renderCurrentSessionState();
3610
+ if (newSessionName) {
3611
+ this.session.setSessionName(newSessionName);
3612
+ }
3561
3613
  this.editor.setText(result.selectedText ?? "");
3562
3614
  done();
3563
- this.showStatus("Forked to new session");
3615
+ this.showStatus(newSessionName ? `Forked to new session: ${newSessionName}` : "Forked to new session");
3564
3616
  }
3565
3617
  catch (error) {
3566
3618
  done();
@@ -3573,7 +3625,7 @@ export class InteractiveMode {
3573
3625
  return { component: selector, focus: selector.getMessageList() };
3574
3626
  });
3575
3627
  }
3576
- async handleCloneCommand() {
3628
+ async handleCloneCommand(newSessionName) {
3577
3629
  const leafId = this.sessionManager.getLeafId();
3578
3630
  if (!leafId) {
3579
3631
  this.showStatus("Nothing to clone yet");
@@ -3586,8 +3638,11 @@ export class InteractiveMode {
3586
3638
  return;
3587
3639
  }
3588
3640
  this.renderCurrentSessionState();
3641
+ if (newSessionName) {
3642
+ this.session.setSessionName(newSessionName);
3643
+ }
3589
3644
  this.editor.setText("");
3590
- this.showStatus("Cloned to new session");
3645
+ this.showStatus(newSessionName ? `Cloned to new session: ${newSessionName}` : "Cloned to new session");
3591
3646
  }
3592
3647
  catch (error) {
3593
3648
  this.showError(error instanceof Error ? error.message : String(error));
@@ -4537,7 +4592,7 @@ export class InteractiveMode {
4537
4592
  this.chatContainer.addChild(new DynamicBorder());
4538
4593
  this.ui.requestRender();
4539
4594
  }
4540
- async handleClearCommand() {
4595
+ async handleClearCommand(newSessionName) {
4541
4596
  if (this.loadingAnimation) {
4542
4597
  this.loadingAnimation.stop();
4543
4598
  this.loadingAnimation = undefined;
@@ -4549,8 +4604,12 @@ export class InteractiveMode {
4549
4604
  return;
4550
4605
  }
4551
4606
  this.renderCurrentSessionState();
4607
+ if (newSessionName) {
4608
+ this.session.setSessionName(newSessionName);
4609
+ }
4552
4610
  this.chatContainer.addChild(new Spacer(1));
4553
- this.chatContainer.addChild(new Text(`${theme.fg("accent", "✓ New session started")}`, 1, 1));
4611
+ const label = newSessionName ? `✓ New session started: ${newSessionName}` : "✓ New session started";
4612
+ this.chatContainer.addChild(new Text(`${theme.fg("accent", label)}`, 1, 1));
4554
4613
  this.ui.requestRender();
4555
4614
  }
4556
4615
  catch (error) {