pi-ui-extend 0.1.8 → 0.1.11
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.
- package/README.md +57 -2
- package/bin/pix.mjs +4 -4
- package/dist/app/app.d.ts +4 -0
- package/dist/app/app.js +112 -45
- package/dist/app/{cli.d.ts → cli/cli.d.ts} +1 -1
- package/dist/app/{cli.js → cli/cli.js} +1 -1
- package/dist/app/{install.d.ts → cli/install.d.ts} +2 -0
- package/dist/app/{install.js → cli/install.js} +18 -3
- package/dist/app/{command-controller.d.ts → commands/command-controller.d.ts} +1 -1
- package/dist/app/{command-controller.js → commands/command-controller.js} +4 -0
- package/dist/app/{command-host.d.ts → commands/command-host.d.ts} +7 -3
- package/dist/app/{command-model-actions.d.ts → commands/command-model-actions.d.ts} +6 -1
- package/dist/app/{command-model-actions.js → commands/command-model-actions.js} +106 -2
- package/dist/app/{command-navigation-actions.d.ts → commands/command-navigation-actions.d.ts} +7 -2
- package/dist/app/{command-navigation-actions.js → commands/command-navigation-actions.js} +42 -19
- package/dist/app/{command-registry.d.ts → commands/command-registry.d.ts} +5 -1
- package/dist/app/{command-registry.js → commands/command-registry.js} +32 -0
- package/dist/app/{command-runtime.js → commands/command-runtime.js} +1 -1
- package/dist/app/{command-session-actions.d.ts → commands/command-session-actions.d.ts} +1 -0
- package/dist/app/{command-session-actions.js → commands/command-session-actions.js} +18 -8
- package/dist/app/{shell-controller.d.ts → commands/shell-controller.d.ts} +2 -1
- package/dist/app/{shell-controller.js → commands/shell-controller.js} +2 -2
- package/dist/app/{slash-commands.d.ts → commands/slash-commands.d.ts} +2 -2
- package/dist/app/{slash-commands.js → commands/slash-commands.js} +1 -1
- package/dist/app/constants.d.ts +1 -1
- package/dist/app/constants.js +1 -1
- package/dist/app/{extension-actions-controller.d.ts → extensions/extension-actions-controller.d.ts} +1 -1
- package/dist/app/{extension-actions-controller.js → extensions/extension-actions-controller.js} +1 -1
- package/dist/app/{extension-ui-controller.d.ts → extensions/extension-ui-controller.d.ts} +3 -3
- package/dist/app/{extension-ui-controller.js → extensions/extension-ui-controller.js} +3 -3
- package/dist/app/icons.js +1 -1
- package/dist/app/input/autocomplete-controller.d.ts +52 -0
- package/dist/app/input/autocomplete-controller.js +352 -0
- package/dist/app/{input-action-controller.d.ts → input/input-action-controller.d.ts} +8 -7
- package/dist/app/{input-action-controller.js → input/input-action-controller.js} +24 -3
- package/dist/app/{input-controller.d.ts → input/input-controller.d.ts} +4 -3
- package/dist/app/{input-controller.js → input/input-controller.js} +3 -1
- package/dist/app/{input-paste-handler.d.ts → input/input-paste-handler.d.ts} +2 -1
- package/dist/app/{input-paste-handler.js → input/input-paste-handler.js} +25 -21
- package/dist/app/{native-modifiers.js → input/native-modifiers.js} +2 -2
- package/dist/app/{prompt-enhancer-controller.d.ts → input/prompt-enhancer-controller.d.ts} +5 -5
- package/dist/app/{prompt-enhancer-controller.js → input/prompt-enhancer-controller.js} +3 -3
- package/dist/app/{voice-controller.d.ts → input/voice-controller.d.ts} +3 -1
- package/dist/app/{voice-controller.js → input/voice-controller.js} +29 -17
- package/dist/app/{model-ref.d.ts → model/model-ref.d.ts} +1 -1
- package/dist/app/{model-ref.js → model/model-ref.js} +1 -1
- package/dist/app/{model-usage-controller.js → model/model-usage-controller.js} +1 -1
- package/dist/app/{model-usage-status.d.ts → model/model-usage-status.d.ts} +10 -1
- package/dist/app/{model-usage-status.js → model/model-usage-status.js} +125 -35
- package/dist/app/{menu-items-controller.d.ts → popup/menu-items-controller.d.ts} +4 -4
- package/dist/app/{menu-items-controller.js → popup/menu-items-controller.js} +5 -5
- package/dist/app/{popup-action-controller.d.ts → popup/popup-action-controller.d.ts} +4 -4
- package/dist/app/{popup-action-controller.js → popup/popup-action-controller.js} +3 -3
- package/dist/app/{popup-menu-controller.d.ts → popup/popup-menu-controller.d.ts} +4 -4
- package/dist/app/{popup-menu-controller.js → popup/popup-menu-controller.js} +7 -7
- package/dist/app/process.d.ts +17 -0
- package/dist/app/process.js +68 -0
- package/dist/app/{conversation-entry-renderer.d.ts → rendering/conversation-entry-renderer.d.ts} +3 -3
- package/dist/app/{conversation-entry-renderer.js → rendering/conversation-entry-renderer.js} +20 -9
- package/dist/app/{conversation-shell-renderer.d.ts → rendering/conversation-shell-renderer.d.ts} +1 -1
- package/dist/app/{conversation-shell-renderer.js → rendering/conversation-shell-renderer.js} +1 -1
- package/dist/app/{conversation-tool-renderer.d.ts → rendering/conversation-tool-renderer.d.ts} +3 -3
- package/dist/app/{conversation-tool-renderer.js → rendering/conversation-tool-renderer.js} +10 -9
- package/dist/app/{conversation-viewport.d.ts → rendering/conversation-viewport.d.ts} +3 -3
- package/dist/app/{dcp-stats.js → rendering/dcp-stats.js} +1 -1
- package/dist/app/{editor-layout-renderer.d.ts → rendering/editor-layout-renderer.d.ts} +4 -3
- package/dist/app/{editor-layout-renderer.js → rendering/editor-layout-renderer.js} +13 -3
- package/dist/app/{editor-panels.d.ts → rendering/editor-panels.d.ts} +2 -2
- package/dist/app/{editor-panels.js → rendering/editor-panels.js} +4 -4
- package/dist/app/{message-content.d.ts → rendering/message-content.d.ts} +1 -1
- package/dist/app/{message-content.js → rendering/message-content.js} +66 -8
- package/dist/app/{render-controller.d.ts → rendering/render-controller.d.ts} +6 -6
- package/dist/app/{render-controller.js → rendering/render-controller.js} +11 -6
- package/dist/app/{render-text.d.ts → rendering/render-text.d.ts} +5 -2
- package/dist/app/{render-text.js → rendering/render-text.js} +53 -5
- package/dist/app/{status-line-renderer.d.ts → rendering/status-line-renderer.d.ts} +8 -4
- package/dist/app/{status-line-renderer.js → rendering/status-line-renderer.js} +73 -29
- package/dist/app/{tab-line-renderer.d.ts → rendering/tab-line-renderer.d.ts} +3 -3
- package/dist/app/{tab-line-renderer.js → rendering/tab-line-renderer.js} +2 -2
- package/dist/app/{toast-controller.d.ts → rendering/toast-controller.d.ts} +1 -1
- package/dist/app/{toast-controller.js → rendering/toast-controller.js} +2 -2
- package/dist/app/{toast-renderer.d.ts → rendering/toast-renderer.d.ts} +3 -3
- package/dist/app/{toast-renderer.js → rendering/toast-renderer.js} +3 -3
- package/dist/app/{tool-block-renderer.d.ts → rendering/tool-block-renderer.d.ts} +5 -5
- package/dist/app/{tool-block-renderer.js → rendering/tool-block-renderer.js} +15 -33
- package/dist/app/runtime.d.ts +6 -1
- package/dist/app/runtime.js +35 -2
- package/dist/app/{blink-controller.js → screen/blink-controller.js} +1 -1
- package/dist/app/{clipboard.d.ts → screen/clipboard.d.ts} +2 -2
- package/dist/app/{clipboard.js → screen/clipboard.js} +13 -18
- package/dist/app/{image-click-targets.d.ts → screen/image-click-targets.d.ts} +2 -2
- package/dist/app/{image-opener.d.ts → screen/image-opener.d.ts} +1 -1
- package/dist/app/{mouse-controller.d.ts → screen/mouse-controller.d.ts} +17 -10
- package/dist/app/{mouse-controller.js → screen/mouse-controller.js} +72 -29
- package/dist/app/{screen-selection.d.ts → screen/screen-selection.d.ts} +1 -1
- package/dist/app/{screen-styler.d.ts → screen/screen-styler.d.ts} +6 -3
- package/dist/app/{screen-styler.js → screen/screen-styler.js} +7 -6
- package/dist/app/{scroll-controller.d.ts → screen/scroll-controller.d.ts} +3 -3
- package/dist/app/{scroll-controller.js → screen/scroll-controller.js} +1 -1
- package/dist/app/{status-controller.d.ts → screen/status-controller.d.ts} +5 -2
- package/dist/app/{status-controller.js → screen/status-controller.js} +24 -9
- package/dist/app/{queued-message-controller.d.ts → session/queued-message-controller.d.ts} +9 -3
- package/dist/app/{queued-message-controller.js → session/queued-message-controller.js} +34 -23
- package/dist/app/{request-history.js → session/request-history.js} +2 -2
- package/dist/app/session/resume-session-loader.d.ts +15 -0
- package/dist/app/session/resume-session-loader.js +204 -0
- package/dist/app/{session-event-controller.d.ts → session/session-event-controller.d.ts} +8 -4
- package/dist/app/{session-event-controller.js → session/session-event-controller.js} +75 -8
- package/dist/app/{session-history.d.ts → session/session-history.d.ts} +1 -1
- package/dist/app/{session-history.js → session/session-history.js} +7 -6
- package/dist/app/{session-lifecycle-controller.d.ts → session/session-lifecycle-controller.d.ts} +7 -2
- package/dist/app/{session-lifecycle-controller.js → session/session-lifecycle-controller.js} +13 -5
- package/dist/app/{session-search.d.ts → session/session-search.d.ts} +1 -1
- package/dist/app/{session-search.js → session/session-search.js} +3 -3
- package/dist/app/{tabs-controller.d.ts → session/tabs-controller.d.ts} +11 -2
- package/dist/app/{tabs-controller.js → session/tabs-controller.js} +105 -9
- package/dist/app/{subagents-files.d.ts → subagents/subagents-files.d.ts} +1 -1
- package/dist/app/{subagents-files.js → subagents/subagents-files.js} +1 -1
- package/dist/app/{subagents-model.d.ts → subagents/subagents-model.d.ts} +1 -1
- package/dist/app/{subagents-model.js → subagents/subagents-model.js} +4 -4
- package/dist/app/{subagents-widget-controller.d.ts → subagents/subagents-widget-controller.d.ts} +1 -1
- package/dist/app/{subagents-widget-controller.js → subagents/subagents-widget-controller.js} +2 -2
- package/dist/app/{nerd-font-controller.js → terminal/nerd-font-controller.js} +16 -17
- package/dist/app/{terminal-bell-sound-controller.js → terminal/terminal-bell-sound-controller.js} +1 -1
- package/dist/app/{terminal-controller.d.ts → terminal/terminal-controller.d.ts} +1 -0
- package/dist/app/{terminal-controller.js → terminal/terminal-controller.js} +3 -2
- package/dist/app/{todo-model.d.ts → todo/todo-model.d.ts} +1 -1
- package/dist/app/{todo-model.js → todo/todo-model.js} +3 -3
- package/dist/app/{todo-widget-controller.d.ts → todo/todo-widget-controller.d.ts} +1 -1
- package/dist/app/{todo-widget-controller.js → todo/todo-widget-controller.js} +2 -2
- package/dist/app/types.d.ts +16 -2
- package/dist/app/{workspace-actions-controller.d.ts → workspace/workspace-actions-controller.d.ts} +2 -2
- package/dist/app/{workspace-actions-controller.js → workspace/workspace-actions-controller.js} +6 -6
- package/dist/app/{workspace-undo.d.ts → workspace/workspace-undo.d.ts} +1 -1
- package/dist/app/{workspace-undo.js → workspace/workspace-undo.js} +22 -20
- package/dist/config.d.ts +27 -0
- package/dist/config.js +174 -1
- package/dist/default-pix-config.js +38 -353
- package/dist/input-editor.d.ts +7 -1
- package/dist/input-editor.js +47 -6
- package/dist/main.js +2 -2
- package/dist/markdown-format.d.ts +1 -0
- package/dist/markdown-format.js +26 -1
- package/external/pi-tools-suite/README.md +78 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +4 -0
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +6 -1
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +1 -0
- package/external/pi-tools-suite/src/dcp/prompts.ts +5 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +314 -193
- package/external/pi-tools-suite/src/index.ts +1 -0
- package/external/pi-tools-suite/src/lib/lsp.ts +2 -1
- package/external/pi-tools-suite/src/lsp/_shared/output.ts +8 -7
- package/external/pi-tools-suite/src/lsp/manager.ts +4 -4
- package/external/pi-tools-suite/src/opencode-import/commands.ts +86 -0
- package/external/pi-tools-suite/src/opencode-import/importer.ts +208 -0
- package/external/pi-tools-suite/src/opencode-import/index.ts +25 -0
- package/external/pi-tools-suite/src/repo-discovery/index.ts +49 -2
- package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +9 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +1 -1
- package/package.json +1 -1
- /package/dist/app/{startup-checks.d.ts → cli/startup-checks.d.ts} +0 -0
- /package/dist/app/{startup-checks.js → cli/startup-checks.js} +0 -0
- /package/dist/app/{startup-info.d.ts → cli/startup-info.d.ts} +0 -0
- /package/dist/app/{startup-info.js → cli/startup-info.js} +0 -0
- /package/dist/app/{update.d.ts → cli/update.d.ts} +0 -0
- /package/dist/app/{update.js → cli/update.js} +0 -0
- /package/dist/app/{command-host.js → commands/command-host.js} +0 -0
- /package/dist/app/{command-runtime.d.ts → commands/command-runtime.d.ts} +0 -0
- /package/dist/app/{shell-command.d.ts → commands/shell-command.d.ts} +0 -0
- /package/dist/app/{shell-command.js → commands/shell-command.js} +0 -0
- /package/dist/app/{extension-event-bus.d.ts → extensions/extension-event-bus.d.ts} +0 -0
- /package/dist/app/{extension-event-bus.js → extensions/extension-event-bus.js} +0 -0
- /package/dist/app/{native-modifiers.d.ts → input/native-modifiers.d.ts} +0 -0
- /package/dist/app/{terminal-edit-shortcuts.d.ts → input/terminal-edit-shortcuts.d.ts} +0 -0
- /package/dist/app/{terminal-edit-shortcuts.js → input/terminal-edit-shortcuts.js} +0 -0
- /package/dist/app/{model-usage-controller.d.ts → model/model-usage-controller.d.ts} +0 -0
- /package/dist/app/{conversation-viewport.js → rendering/conversation-viewport.js} +0 -0
- /package/dist/app/{dcp-stats.d.ts → rendering/dcp-stats.d.ts} +0 -0
- /package/dist/app/{blink-controller.d.ts → screen/blink-controller.d.ts} +0 -0
- /package/dist/app/{file-link-opener.d.ts → screen/file-link-opener.d.ts} +0 -0
- /package/dist/app/{file-link-opener.js → screen/file-link-opener.js} +0 -0
- /package/dist/app/{file-links.d.ts → screen/file-links.d.ts} +0 -0
- /package/dist/app/{file-links.js → screen/file-links.js} +0 -0
- /package/dist/app/{image-click-targets.js → screen/image-click-targets.js} +0 -0
- /package/dist/app/{image-opener.js → screen/image-opener.js} +0 -0
- /package/dist/app/{screen-selection.js → screen/screen-selection.js} +0 -0
- /package/dist/app/{request-history.d.ts → session/request-history.d.ts} +0 -0
- /package/dist/app/{nerd-font-controller.d.ts → terminal/nerd-font-controller.d.ts} +0 -0
- /package/dist/app/{terminal-bell-sound-controller.d.ts → terminal/terminal-bell-sound-controller.d.ts} +0 -0
- /package/dist/app/{terminal-output-buffer.d.ts → terminal/terminal-output-buffer.d.ts} +0 -0
- /package/dist/app/{terminal-output-buffer.js → terminal/terminal-output-buffer.js} +0 -0
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { copyTextToClipboard } from "./clipboard.js";
|
|
2
|
-
import { stringifyUnknown } from "
|
|
3
|
-
import { horizontalPaddingLayout } from "
|
|
2
|
+
import { stringifyUnknown } from "../rendering/message-content.js";
|
|
3
|
+
import { horizontalPaddingLayout } from "../rendering/render-text.js";
|
|
4
4
|
import { orderedSelection, samePoint } from "./screen-selection.js";
|
|
5
5
|
import { openImageContent as openSystemImageContent } from "./image-opener.js";
|
|
6
|
-
import { stringDisplayWidth } from "
|
|
7
|
-
import { formatDcpStatsToast } from "
|
|
6
|
+
import { stringDisplayWidth } from "../../terminal-width.js";
|
|
7
|
+
import { formatDcpStatsToast } from "../rendering/dcp-stats.js";
|
|
8
8
|
import { detectFileLinks } from "./file-links.js";
|
|
9
9
|
import { openFileLink as openDetectedFileLink } from "./file-link-opener.js";
|
|
10
10
|
const CLICK_FLASH_MS = 100;
|
|
11
|
+
const LOST_MOUSE_RELEASE_SETTLE_MS = 180;
|
|
11
12
|
export class AppMouseController {
|
|
12
13
|
host;
|
|
13
14
|
popupMenus;
|
|
@@ -23,6 +24,7 @@ export class AppMouseController {
|
|
|
23
24
|
statusContextTarget;
|
|
24
25
|
statusModelUsageTarget;
|
|
25
26
|
statusUserJumpTarget;
|
|
27
|
+
statusDraftQueueTarget;
|
|
26
28
|
statusThinkingExpandTarget;
|
|
27
29
|
statusCompactToolsTarget;
|
|
28
30
|
statusTerminalBellSoundTarget;
|
|
@@ -40,6 +42,7 @@ export class AppMouseController {
|
|
|
40
42
|
autoScrollAccumulator = 0;
|
|
41
43
|
autoScrollLastTick = 0;
|
|
42
44
|
autoScrollCursorX = 1;
|
|
45
|
+
leftEdgeReleaseFallbackTimer;
|
|
43
46
|
clickFlash;
|
|
44
47
|
clickFlashTimer;
|
|
45
48
|
clickFlashDirty = false;
|
|
@@ -73,6 +76,8 @@ export class AppMouseController {
|
|
|
73
76
|
return;
|
|
74
77
|
if (event.button === 0 && this.withClickFlash(event, () => this.handleStatusModelUsageClick(event)))
|
|
75
78
|
return;
|
|
79
|
+
if (event.button === 0 && this.withClickFlash(event, () => this.handleStatusDraftQueueClick(event)))
|
|
80
|
+
return;
|
|
76
81
|
if (event.button === 0 && this.withClickFlash(event, () => this.handleStatusUserJumpClick(event)))
|
|
77
82
|
return;
|
|
78
83
|
if (event.button === 0 && this.withClickFlash(event, () => this.handleStatusThinkingExpandClick(event)))
|
|
@@ -284,6 +289,7 @@ export class AppMouseController {
|
|
|
284
289
|
this.statusThinkingTarget,
|
|
285
290
|
this.statusContextTarget,
|
|
286
291
|
this.statusModelUsageTarget,
|
|
292
|
+
this.statusDraftQueueTarget,
|
|
287
293
|
this.statusUserJumpTarget,
|
|
288
294
|
this.statusThinkingExpandTarget,
|
|
289
295
|
this.statusCompactToolsTarget,
|
|
@@ -350,7 +356,7 @@ export class AppMouseController {
|
|
|
350
356
|
const baseButton = event.button & 3;
|
|
351
357
|
const draggingLeftButton = (event.button & 32) !== 0 && baseButton === 0;
|
|
352
358
|
if (event.released) {
|
|
353
|
-
if (!this.scrollBarDragActive
|
|
359
|
+
if (!this.scrollBarDragActive)
|
|
354
360
|
return false;
|
|
355
361
|
this.scrollBarDragActive = false;
|
|
356
362
|
return true;
|
|
@@ -380,7 +386,7 @@ export class AppMouseController {
|
|
|
380
386
|
const baseButton = event.button & 3;
|
|
381
387
|
const draggingLeftButton = (event.button & 32) !== 0 && baseButton === 0;
|
|
382
388
|
if (event.released)
|
|
383
|
-
return this.finishInputScrollBarDrag(event
|
|
389
|
+
return this.finishInputScrollBarDrag(event);
|
|
384
390
|
if (event.button === 0 && onScrollBar) {
|
|
385
391
|
this.inputScrollBarDragActive = true;
|
|
386
392
|
this.scrollInputToTrackRow(editorRow, scrollBar.trackHeight, renderedInput.totalLineCount, renderedInput.visibleRowCount);
|
|
@@ -392,10 +398,10 @@ export class AppMouseController {
|
|
|
392
398
|
this.scrollInputToTrackRow(trackRow, scrollBar.trackHeight, renderedInput.totalLineCount, renderedInput.visibleRowCount);
|
|
393
399
|
return true;
|
|
394
400
|
}
|
|
395
|
-
finishInputScrollBarDrag(event
|
|
401
|
+
finishInputScrollBarDrag(event) {
|
|
396
402
|
if (!event.released)
|
|
397
403
|
return false;
|
|
398
|
-
if (!this.inputScrollBarDragActive
|
|
404
|
+
if (!this.inputScrollBarDragActive)
|
|
399
405
|
return false;
|
|
400
406
|
this.inputScrollBarDragActive = false;
|
|
401
407
|
return true;
|
|
@@ -507,6 +513,15 @@ export class AppMouseController {
|
|
|
507
513
|
this.host.render();
|
|
508
514
|
return true;
|
|
509
515
|
}
|
|
516
|
+
handleStatusDraftQueueClick(event) {
|
|
517
|
+
const target = this.statusDraftQueueTarget;
|
|
518
|
+
if (!target)
|
|
519
|
+
return false;
|
|
520
|
+
if (event.y !== target.row || event.x < target.startColumn || event.x >= target.endColumn)
|
|
521
|
+
return false;
|
|
522
|
+
void this.host.queueInputFromStatus?.();
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
510
525
|
handleStatusThinkingExpandClick(event) {
|
|
511
526
|
const target = this.statusThinkingExpandTarget;
|
|
512
527
|
if (!target)
|
|
@@ -634,42 +649,27 @@ export class AppMouseController {
|
|
|
634
649
|
return true;
|
|
635
650
|
}
|
|
636
651
|
handleMouseSelection(event) {
|
|
637
|
-
const point = { x: event.x, y: event.y };
|
|
638
652
|
const baseButton = event.button & 3;
|
|
639
653
|
const draggingLeftButton = (event.button & 32) !== 0 && baseButton === 0;
|
|
640
654
|
if (event.released) {
|
|
641
655
|
if (!this.mouseSelection)
|
|
642
656
|
return false;
|
|
643
|
-
this.
|
|
657
|
+
this.cancelLeftEdgeReleaseFallback();
|
|
644
658
|
this.updateSelectionCurrentFromMouse(event, { autoScroll: false });
|
|
645
|
-
|
|
646
|
-
this.mouseSelection = undefined;
|
|
647
|
-
if (!selection.moved && samePoint(selection.anchor, point)) {
|
|
648
|
-
this.host.render();
|
|
649
|
-
return false;
|
|
650
|
-
}
|
|
651
|
-
const selectedText = this.getSelectedText(selection);
|
|
652
|
-
this.host.render();
|
|
653
|
-
if (selectedText.trim().length === 0)
|
|
654
|
-
return true;
|
|
655
|
-
try {
|
|
656
|
-
this.copyTextToClipboard(selectedText);
|
|
657
|
-
this.host.showToast("Copied to clipboard", "success");
|
|
658
|
-
}
|
|
659
|
-
catch (error) {
|
|
660
|
-
this.host.showToast(`Copy failed: ${stringifyUnknown(error)}`, "error");
|
|
661
|
-
}
|
|
662
|
-
return true;
|
|
659
|
+
return this.finishMouseSelection();
|
|
663
660
|
}
|
|
664
661
|
if (draggingLeftButton) {
|
|
665
662
|
if (!this.mouseSelection)
|
|
666
663
|
return false;
|
|
667
664
|
this.updateSelectionCurrentFromMouse(event);
|
|
665
|
+
this.updateLeftEdgeReleaseFallback(event);
|
|
668
666
|
this.host.render();
|
|
669
667
|
return true;
|
|
670
668
|
}
|
|
671
669
|
if (event.button === 0) {
|
|
670
|
+
this.cancelLeftEdgeReleaseFallback();
|
|
672
671
|
this.stopAutoScroll();
|
|
672
|
+
const point = { x: event.x, y: event.y };
|
|
673
673
|
const conversationPoint = this.conversationPointFromMouse(event, false);
|
|
674
674
|
this.mouseSelection = conversationPoint
|
|
675
675
|
? {
|
|
@@ -685,6 +685,47 @@ export class AppMouseController {
|
|
|
685
685
|
}
|
|
686
686
|
return false;
|
|
687
687
|
}
|
|
688
|
+
finishMouseSelection() {
|
|
689
|
+
const selection = this.mouseSelection;
|
|
690
|
+
if (!selection)
|
|
691
|
+
return false;
|
|
692
|
+
this.cancelLeftEdgeReleaseFallback();
|
|
693
|
+
this.stopAutoScroll();
|
|
694
|
+
this.mouseSelection = undefined;
|
|
695
|
+
if (!selection.moved && samePoint(selection.anchor, selection.current)) {
|
|
696
|
+
this.host.render();
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
699
|
+
const selectedText = this.getSelectedText(selection);
|
|
700
|
+
this.host.render();
|
|
701
|
+
if (selectedText.trim().length === 0)
|
|
702
|
+
return true;
|
|
703
|
+
try {
|
|
704
|
+
this.copyTextToClipboard(selectedText);
|
|
705
|
+
this.host.showToast("Copied to clipboard", "success");
|
|
706
|
+
}
|
|
707
|
+
catch (error) {
|
|
708
|
+
this.host.showToast(`Copy failed: ${stringifyUnknown(error)}`, "error");
|
|
709
|
+
}
|
|
710
|
+
return true;
|
|
711
|
+
}
|
|
712
|
+
updateLeftEdgeReleaseFallback(event) {
|
|
713
|
+
if (!this.mouseSelection?.moved || event.x > 1) {
|
|
714
|
+
this.cancelLeftEdgeReleaseFallback();
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
this.cancelLeftEdgeReleaseFallback();
|
|
718
|
+
this.leftEdgeReleaseFallbackTimer = setTimeout(() => {
|
|
719
|
+
this.leftEdgeReleaseFallbackTimer = undefined;
|
|
720
|
+
this.finishMouseSelection();
|
|
721
|
+
}, LOST_MOUSE_RELEASE_SETTLE_MS);
|
|
722
|
+
}
|
|
723
|
+
cancelLeftEdgeReleaseFallback() {
|
|
724
|
+
if (!this.leftEdgeReleaseFallbackTimer)
|
|
725
|
+
return;
|
|
726
|
+
clearTimeout(this.leftEdgeReleaseFallbackTimer);
|
|
727
|
+
this.leftEdgeReleaseFallbackTimer = undefined;
|
|
728
|
+
}
|
|
688
729
|
syncConversationSelectionForRender(startLine, bodyHeight, topReservedRows, width) {
|
|
689
730
|
this.renderedConversationFrame = {
|
|
690
731
|
bodyHeight,
|
|
@@ -741,7 +782,9 @@ export class AppMouseController {
|
|
|
741
782
|
return this.getSelectedScreenText(selection.anchor, selection.current);
|
|
742
783
|
}
|
|
743
784
|
copyTextToClipboard(text) {
|
|
744
|
-
(this.host.copyTextToClipboard ?? copyTextToClipboard)(text)
|
|
785
|
+
void Promise.resolve((this.host.copyTextToClipboard ?? copyTextToClipboard)(text)).catch((error) => {
|
|
786
|
+
this.host.showToast(error instanceof Error ? error.message : String(error), "error");
|
|
787
|
+
});
|
|
745
788
|
}
|
|
746
789
|
getSelectedScreenText(anchor, current) {
|
|
747
790
|
const range = orderedSelection(anchor, current);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ScreenPoint } from "
|
|
1
|
+
import type { ScreenPoint } from "../types.js";
|
|
2
2
|
export declare function samePoint(left: ScreenPoint, right: ScreenPoint): boolean;
|
|
3
3
|
export declare function orderedSelection(anchor: ScreenPoint, current: ScreenPoint): {
|
|
4
4
|
start: ScreenPoint;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Theme } from "
|
|
2
|
-
import type { MouseSelection, RenderedLine, StyledSegment } from "
|
|
1
|
+
import { type Theme } from "../../theme.js";
|
|
2
|
+
import type { MouseSelection, RenderedLine, StyledSegment } from "../types.js";
|
|
3
3
|
export type ScreenStylerHost = {
|
|
4
4
|
readonly theme: Theme;
|
|
5
5
|
readonly cwd?: string;
|
|
@@ -24,7 +24,10 @@ export declare class ScreenStyler {
|
|
|
24
24
|
styleInputLine(row: number, text: string, tagSpans: readonly {
|
|
25
25
|
start: number;
|
|
26
26
|
end: number;
|
|
27
|
-
}[] | undefined,
|
|
27
|
+
}[] | undefined, suggestionSpans: readonly {
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
}[] | undefined, width: number, tagColor: string, suggestionColor: string, frameColor?: string): string;
|
|
28
31
|
private styleAnsiLine;
|
|
29
32
|
selectionRangeForRow(row: number, width: number): {
|
|
30
33
|
startIndex: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ANSI_RESET, colorize } from "
|
|
2
|
-
import { renderMarkdownLine } from "
|
|
3
|
-
import { syntaxHighlightSegmentsForLine } from "
|
|
4
|
-
import { padOrTrimPlain } from "
|
|
1
|
+
import { ANSI_RESET, colorize } from "../../theme.js";
|
|
2
|
+
import { renderMarkdownLine } from "../../markdown-format.js";
|
|
3
|
+
import { syntaxHighlightSegmentsForLine } from "../../syntax-highlight.js";
|
|
4
|
+
import { padOrTrimPlain } from "../rendering/render-text.js";
|
|
5
5
|
import { orderedSelection } from "./screen-selection.js";
|
|
6
6
|
export class ScreenStyler {
|
|
7
7
|
host;
|
|
@@ -72,14 +72,14 @@ export class ScreenStyler {
|
|
|
72
72
|
colorize(after, options),
|
|
73
73
|
].join("");
|
|
74
74
|
}
|
|
75
|
-
styleInputLine(row, text, tagSpans, width, tagColor, frameColor) {
|
|
75
|
+
styleInputLine(row, text, tagSpans, suggestionSpans, width, tagColor, suggestionColor, frameColor) {
|
|
76
76
|
const colors = this.host.theme.colors;
|
|
77
77
|
const baseOptions = { foreground: colors.inputForeground };
|
|
78
78
|
if (this.selectionRangeForRow(row, width))
|
|
79
79
|
return this.styleLine(row, text, width, baseOptions);
|
|
80
80
|
const plain = padOrTrimPlain(text, width);
|
|
81
81
|
const frameSpans = inputFrameSpans(plain, width, frameColor);
|
|
82
|
-
if ((!tagSpans || tagSpans.length === 0) && frameSpans.length === 0) {
|
|
82
|
+
if ((!tagSpans || tagSpans.length === 0) && (!suggestionSpans || suggestionSpans.length === 0) && frameSpans.length === 0) {
|
|
83
83
|
return hasAnsi(plain) ? this.styleAnsiLine(plain, baseOptions) : colorize(plain, baseOptions);
|
|
84
84
|
}
|
|
85
85
|
const chunks = [];
|
|
@@ -88,6 +88,7 @@ export class ScreenStyler {
|
|
|
88
88
|
const spans = [
|
|
89
89
|
...frameSpans,
|
|
90
90
|
...(tagSpans ?? []).map((span) => ({ ...span, foreground: tagColor, bold: true })),
|
|
91
|
+
...(suggestionSpans ?? []).map((span) => ({ ...span, foreground: suggestionColor })),
|
|
91
92
|
].sort((a, b) => a.start - b.start || a.end - b.end);
|
|
92
93
|
for (const span of spans) {
|
|
93
94
|
const start = Math.max(offset, Math.min(endOffset, span.start));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ConversationViewport } from "
|
|
2
|
-
import type { EditorLayoutRenderer } from "
|
|
3
|
-
import type { RenderedLine } from "
|
|
1
|
+
import type { ConversationViewport } from "../rendering/conversation-viewport.js";
|
|
2
|
+
import type { EditorLayoutRenderer } from "../rendering/editor-layout-renderer.js";
|
|
3
|
+
import type { RenderedLine } from "../types.js";
|
|
4
4
|
export type AppScrollMetrics = {
|
|
5
5
|
bodyHeight: number;
|
|
6
6
|
viewportColumns: number;
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type { Theme } from "
|
|
2
|
+
import type { Theme } from "../../theme.js";
|
|
3
3
|
import type { AppBlinkController } from "./blink-controller.js";
|
|
4
|
-
import type { SessionActivity } from "
|
|
4
|
+
import type { SessionActivity } from "../types.js";
|
|
5
5
|
export type AppStatusControllerHost = {
|
|
6
6
|
readonly cwd: string;
|
|
7
7
|
readonly theme: Theme;
|
|
8
8
|
readonly blinkController: AppBlinkController;
|
|
9
9
|
runtimeSession(): AgentSession | undefined;
|
|
10
|
+
render(): void;
|
|
10
11
|
};
|
|
11
12
|
export declare class AppStatusController {
|
|
12
13
|
private readonly host;
|
|
13
14
|
private status;
|
|
14
15
|
private statusFollowsSession;
|
|
15
16
|
private gitBranchCache;
|
|
17
|
+
private gitBranchLookupInFlight;
|
|
16
18
|
sessionActivity: SessionActivity;
|
|
17
19
|
get statusDotBright(): boolean;
|
|
18
20
|
constructor(host: AppStatusControllerHost);
|
|
@@ -31,5 +33,6 @@ export declare class AppStatusController {
|
|
|
31
33
|
roundedContextUsagePercent(session: AgentSession): number | undefined;
|
|
32
34
|
contextUsagePercentColor(percent: number): string;
|
|
33
35
|
private currentGitBranchName;
|
|
36
|
+
private refreshGitBranchName;
|
|
34
37
|
private startStatusBlink;
|
|
35
38
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
1
|
import { basename } from "node:path";
|
|
3
|
-
import { GIT_BRANCH_CACHE_MS } from "
|
|
2
|
+
import { GIT_BRANCH_CACHE_MS } from "../constants.js";
|
|
3
|
+
import { runProcess } from "../process.js";
|
|
4
4
|
const STATUS_DOT_BLINK_KEY = "status-dot";
|
|
5
5
|
export class AppStatusController {
|
|
6
6
|
host;
|
|
7
7
|
status = "starting";
|
|
8
8
|
statusFollowsSession = false;
|
|
9
9
|
gitBranchCache;
|
|
10
|
+
gitBranchLookupInFlight = false;
|
|
10
11
|
sessionActivity = "idle";
|
|
11
12
|
get statusDotBright() {
|
|
12
13
|
return this.host.blinkController.visible(STATUS_DOT_BLINK_KEY, false);
|
|
@@ -87,13 +88,27 @@ export class AppStatusController {
|
|
|
87
88
|
if (this.gitBranchCache && now - this.gitBranchCache.checkedAt < GIT_BRANCH_CACHE_MS) {
|
|
88
89
|
return this.gitBranchCache.branch;
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
if (!this.gitBranchLookupInFlight) {
|
|
92
|
+
this.gitBranchLookupInFlight = true;
|
|
93
|
+
void this.refreshGitBranchName();
|
|
94
|
+
}
|
|
95
|
+
return this.gitBranchCache?.branch;
|
|
96
|
+
}
|
|
97
|
+
async refreshGitBranchName() {
|
|
98
|
+
const previous = this.gitBranchCache?.branch;
|
|
99
|
+
try {
|
|
100
|
+
const result = await runProcess("git", ["-C", this.host.cwd, "branch", "--show-current"], {
|
|
101
|
+
timeoutMs: 150,
|
|
102
|
+
maxBufferBytes: 1024,
|
|
103
|
+
});
|
|
104
|
+
const branch = result.status === 0 ? result.stdout.trim() || undefined : undefined;
|
|
105
|
+
this.gitBranchCache = { checkedAt: Date.now(), branch };
|
|
106
|
+
if (branch !== previous)
|
|
107
|
+
this.host.render();
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
this.gitBranchLookupInFlight = false;
|
|
111
|
+
}
|
|
97
112
|
}
|
|
98
113
|
startStatusBlink() {
|
|
99
114
|
this.host.blinkController.setActive(STATUS_DOT_BLINK_KEY, true, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentSession, AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type { ImageContent } from "
|
|
3
|
-
import type { Entry, SessionActivity, SubmittedUserMessage } from "
|
|
2
|
+
import type { ImageContent } from "../../input-editor.js";
|
|
3
|
+
import type { Entry, SessionActivity, SubmittedUserMessage } from "../types.js";
|
|
4
4
|
export type AppQueuedMessageControllerHost = {
|
|
5
5
|
runtime(): AgentSessionRuntime | undefined;
|
|
6
6
|
requireRuntime(): AgentSessionRuntime;
|
|
@@ -19,6 +19,7 @@ export type AppQueuedMessageControllerHost = {
|
|
|
19
19
|
setInput(value: string): void;
|
|
20
20
|
insertInput(value: string): void;
|
|
21
21
|
attachImage(data: string, mimeType: string): void;
|
|
22
|
+
onDeferredUserMessagesChanged?(): void;
|
|
22
23
|
};
|
|
23
24
|
export declare class AppQueuedMessageController {
|
|
24
25
|
private readonly host;
|
|
@@ -28,6 +29,8 @@ export declare class AppQueuedMessageController {
|
|
|
28
29
|
private immediateSendInProgress;
|
|
29
30
|
constructor(host: AppQueuedMessageControllerHost);
|
|
30
31
|
reset(): void;
|
|
32
|
+
captureDeferredUserMessages(): SubmittedUserMessage[];
|
|
33
|
+
restoreDeferredUserMessages(messages: readonly SubmittedUserMessage[]): void;
|
|
31
34
|
createSubmittedUserMessage(promptText: string, displayText: string, images: ImageContent[]): SubmittedUserMessage;
|
|
32
35
|
submitUserMessage(message: SubmittedUserMessage): Promise<void>;
|
|
33
36
|
sendUserMessageToSession(message: SubmittedUserMessage, options?: {
|
|
@@ -44,11 +47,12 @@ export declare class AppQueuedMessageController {
|
|
|
44
47
|
cancelQueuedMessage(entryId: string): Promise<void>;
|
|
45
48
|
editQueuedMessage(entryId: string): Promise<void>;
|
|
46
49
|
sendQueuedMessageImmediately(entryId: string): Promise<void>;
|
|
50
|
+
private sendQueuedEntryImmediately;
|
|
47
51
|
findQueuedEntry(entryId: string): Extract<Entry, {
|
|
48
52
|
kind: "queued";
|
|
49
53
|
}> | undefined;
|
|
50
54
|
private shouldDeferUserMessage;
|
|
51
|
-
|
|
55
|
+
deferUserMessage(message: SubmittedUserMessage): void;
|
|
52
56
|
private rewriteSdkQueuedMessages;
|
|
53
57
|
private takeQueuedEntryForInterruptedSend;
|
|
54
58
|
private restoreSdkQueuedMessages;
|
|
@@ -59,4 +63,6 @@ export declare class AppQueuedMessageController {
|
|
|
59
63
|
private requeueRemovedEntry;
|
|
60
64
|
private restoreSubmittedMessageToEditor;
|
|
61
65
|
private restorableSubmittedMessageText;
|
|
66
|
+
private cloneSubmittedUserMessage;
|
|
67
|
+
private notifyDeferredUserMessagesChanged;
|
|
62
68
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createId } from "
|
|
2
|
-
import { stringifyUnknown, submittedUserDisplayText } from "
|
|
1
|
+
import { createId } from "../id.js";
|
|
2
|
+
import { stringifyUnknown, submittedUserDisplayText } from "../rendering/message-content.js";
|
|
3
3
|
export class AppQueuedMessageController {
|
|
4
4
|
host;
|
|
5
5
|
deferredUserMessages = [];
|
|
@@ -14,6 +14,14 @@ export class AppQueuedMessageController {
|
|
|
14
14
|
this.promptSubmissionInFlight = false;
|
|
15
15
|
this.flushingDeferredUserMessages = false;
|
|
16
16
|
}
|
|
17
|
+
captureDeferredUserMessages() {
|
|
18
|
+
return this.deferredUserMessages.map((message) => this.cloneSubmittedUserMessage(message));
|
|
19
|
+
}
|
|
20
|
+
restoreDeferredUserMessages(messages) {
|
|
21
|
+
this.deferredUserMessages.length = 0;
|
|
22
|
+
this.deferredUserMessages.push(...messages.map((message) => this.cloneSubmittedUserMessage(message)));
|
|
23
|
+
this.updateQueuedMessageStatus();
|
|
24
|
+
}
|
|
17
25
|
createSubmittedUserMessage(promptText, displayText, images) {
|
|
18
26
|
return {
|
|
19
27
|
id: createId("queued-user"),
|
|
@@ -55,8 +63,6 @@ export class AppQueuedMessageController {
|
|
|
55
63
|
}
|
|
56
64
|
if (this.totalQueuedMessageCount() > 0)
|
|
57
65
|
this.updateQueuedMessageStatus();
|
|
58
|
-
if (!this.flushingDeferredUserMessages)
|
|
59
|
-
void this.flushDeferredUserMessages();
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
async flushDeferredUserMessages() {
|
|
@@ -80,22 +86,14 @@ export class AppQueuedMessageController {
|
|
|
80
86
|
const message = this.deferredUserMessages.shift();
|
|
81
87
|
if (!message)
|
|
82
88
|
break;
|
|
89
|
+
this.notifyDeferredUserMessagesChanged();
|
|
83
90
|
this.updateQueuedMessageStatus();
|
|
84
|
-
if (!activeSession.isStreaming && this.deferredUserMessages.length > 0) {
|
|
85
|
-
void this.sendUserMessageToSession(message).catch((error) => {
|
|
86
|
-
this.deferredUserMessages.unshift(message);
|
|
87
|
-
this.updateQueuedMessageStatus();
|
|
88
|
-
this.host.addEntry({ id: createId("error"), kind: "error", text: `Queued message failed: ${stringifyUnknown(error)}` });
|
|
89
|
-
if (this.host.isRunning())
|
|
90
|
-
this.host.render();
|
|
91
|
-
});
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
91
|
try {
|
|
95
92
|
await this.sendUserMessageToSession(message);
|
|
96
93
|
}
|
|
97
94
|
catch (error) {
|
|
98
95
|
this.deferredUserMessages.unshift(message);
|
|
96
|
+
this.notifyDeferredUserMessagesChanged();
|
|
99
97
|
this.updateQueuedMessageStatus();
|
|
100
98
|
this.host.addEntry({ id: createId("error"), kind: "error", text: `Queued message failed: ${stringifyUnknown(error)}` });
|
|
101
99
|
break;
|
|
@@ -103,17 +101,11 @@ export class AppQueuedMessageController {
|
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
finally {
|
|
106
|
-
const shouldRetryFlush = this.deferredUserMessages.length > 0 && Boolean(this.host.runtime()?.session) && !this.host.runtime()?.session.isCompacting;
|
|
107
104
|
this.flushingDeferredUserMessages = false;
|
|
108
105
|
if (this.totalQueuedMessageCount() > 0)
|
|
109
106
|
this.updateQueuedMessageStatus();
|
|
110
107
|
if (this.host.isRunning())
|
|
111
108
|
this.host.render();
|
|
112
|
-
if (shouldRetryFlush) {
|
|
113
|
-
queueMicrotask(() => {
|
|
114
|
-
void this.flushDeferredUserMessages();
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
109
|
}
|
|
118
110
|
}
|
|
119
111
|
queuedMessageCounts() {
|
|
@@ -135,6 +127,8 @@ export class AppQueuedMessageController {
|
|
|
135
127
|
const session = this.host.runtime()?.session;
|
|
136
128
|
const sdkQueued = session?.clearQueue() ?? { steering: [], followUp: [] };
|
|
137
129
|
const deferred = this.deferredUserMessages.splice(0);
|
|
130
|
+
if (deferred.length > 0)
|
|
131
|
+
this.notifyDeferredUserMessagesChanged();
|
|
138
132
|
const restoredTexts = [
|
|
139
133
|
...sdkQueued.steering,
|
|
140
134
|
...deferred.map((message) => this.restorableSubmittedMessageText(message)),
|
|
@@ -186,6 +180,9 @@ export class AppQueuedMessageController {
|
|
|
186
180
|
const entry = this.findQueuedEntry(entryId);
|
|
187
181
|
if (!entry)
|
|
188
182
|
throw new Error("Queued message is no longer available");
|
|
183
|
+
await this.sendQueuedEntryImmediately(entry);
|
|
184
|
+
}
|
|
185
|
+
async sendQueuedEntryImmediately(entry) {
|
|
189
186
|
const session = this.host.requireRuntime().session;
|
|
190
187
|
const shouldInterrupt = session.isStreaming || session.isCompacting;
|
|
191
188
|
const taken = shouldInterrupt
|
|
@@ -224,8 +221,6 @@ export class AppQueuedMessageController {
|
|
|
224
221
|
this.immediateSendInProgress = false;
|
|
225
222
|
if (this.totalQueuedMessageCount() > 0)
|
|
226
223
|
this.updateQueuedMessageStatus();
|
|
227
|
-
if (!this.flushingDeferredUserMessages)
|
|
228
|
-
void this.flushDeferredUserMessages();
|
|
229
224
|
}
|
|
230
225
|
}
|
|
231
226
|
findQueuedEntry(entryId) {
|
|
@@ -233,11 +228,13 @@ export class AppQueuedMessageController {
|
|
|
233
228
|
return entry?.kind === "queued" ? entry : undefined;
|
|
234
229
|
}
|
|
235
230
|
shouldDeferUserMessage(session) {
|
|
236
|
-
return session.
|
|
231
|
+
return session.isStreaming || session.isCompacting || this.promptSubmissionInFlight;
|
|
237
232
|
}
|
|
238
233
|
deferUserMessage(message) {
|
|
239
234
|
this.deferredUserMessages.push(message);
|
|
235
|
+
this.notifyDeferredUserMessagesChanged();
|
|
240
236
|
this.updateQueuedMessageStatus();
|
|
237
|
+
this.host.showToast("Message queued; send it from the queue menu or status button", "info");
|
|
241
238
|
this.host.render();
|
|
242
239
|
}
|
|
243
240
|
async rewriteSdkQueuedMessages(update) {
|
|
@@ -282,6 +279,7 @@ export class AppQueuedMessageController {
|
|
|
282
279
|
if (!message)
|
|
283
280
|
throw new Error("Queued message is no longer available");
|
|
284
281
|
session.clearQueue();
|
|
282
|
+
this.notifyDeferredUserMessagesChanged();
|
|
285
283
|
return { removed: message, sdkMessagesToRestore: sdkMessages };
|
|
286
284
|
}
|
|
287
285
|
const messages = entry.queueSource === "sdk-steering" ? sdkMessages.steering : sdkMessages.followUp;
|
|
@@ -334,6 +332,7 @@ export class AppQueuedMessageController {
|
|
|
334
332
|
const [message] = this.deferredUserMessages.splice(entry.queueIndex, 1);
|
|
335
333
|
if (!message)
|
|
336
334
|
throw new Error("Queued message is no longer available");
|
|
335
|
+
this.notifyDeferredUserMessagesChanged();
|
|
337
336
|
return message;
|
|
338
337
|
}
|
|
339
338
|
const removed = await this.rewriteSdkQueuedMessages((steering, followUp) => {
|
|
@@ -350,6 +349,7 @@ export class AppQueuedMessageController {
|
|
|
350
349
|
if (typeof removed === "string")
|
|
351
350
|
return;
|
|
352
351
|
this.deferredUserMessages.splice(Math.min(entry.queueIndex, this.deferredUserMessages.length), 0, removed);
|
|
352
|
+
this.notifyDeferredUserMessagesChanged();
|
|
353
353
|
return;
|
|
354
354
|
}
|
|
355
355
|
if (typeof removed !== "string")
|
|
@@ -374,4 +374,15 @@ export class AppQueuedMessageController {
|
|
|
374
374
|
? message.promptText.replace(/\[Image \d+(?:: [^\]]+)?\]\s*/g, "").trimEnd()
|
|
375
375
|
: message.promptText.trimEnd();
|
|
376
376
|
}
|
|
377
|
+
cloneSubmittedUserMessage(message) {
|
|
378
|
+
return {
|
|
379
|
+
id: message.id,
|
|
380
|
+
promptText: message.promptText,
|
|
381
|
+
displayText: message.displayText,
|
|
382
|
+
images: message.images.map((image) => ({ ...image })),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
notifyDeferredUserMessagesChanged() {
|
|
386
|
+
this.host.onDeferredUserMessagesChanged?.();
|
|
387
|
+
}
|
|
377
388
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
4
|
-
import { REQUEST_HISTORY_MAX_BYTES, REQUEST_HISTORY_MAX_ENTRIES, REQUEST_HISTORY_MAX_ENTRY_BYTES, REQUEST_HISTORY_VERSION, } from "
|
|
5
|
-
import { isRecord } from "
|
|
4
|
+
import { REQUEST_HISTORY_MAX_BYTES, REQUEST_HISTORY_MAX_ENTRIES, REQUEST_HISTORY_MAX_ENTRY_BYTES, REQUEST_HISTORY_VERSION, } from "../constants.js";
|
|
5
|
+
import { isRecord } from "../guards.js";
|
|
6
6
|
export class AppRequestHistory {
|
|
7
7
|
host;
|
|
8
8
|
entries = [];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type SessionInfo } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
export type ResumeSessionLoadProgress = {
|
|
3
|
+
loaded: number;
|
|
4
|
+
total: number;
|
|
5
|
+
done: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type ResumeSessionLoaderOptions = {
|
|
8
|
+
cwd: string;
|
|
9
|
+
sessionDir?: string;
|
|
10
|
+
initialChunkSize?: number;
|
|
11
|
+
chunkSize?: number;
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
onChunk(sessions: readonly SessionInfo[], progress: ResumeSessionLoadProgress): void;
|
|
14
|
+
};
|
|
15
|
+
export declare function loadResumeSessionsInChunks(options: ResumeSessionLoaderOptions): Promise<SessionInfo[]>;
|