pi-ui-extend 1.0.41 → 1.0.45
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 +50 -13
- package/dist/app/app.d.ts +13 -0
- package/dist/app/app.js +158 -8
- package/dist/app/cli/install.js +2 -2
- package/dist/app/commands/command-controller.d.ts +4 -0
- package/dist/app/commands/command-controller.js +11 -0
- package/dist/app/commands/command-git-actions.d.ts +25 -0
- package/dist/app/commands/command-git-actions.js +381 -0
- package/dist/app/commands/command-host.d.ts +4 -0
- package/dist/app/commands/command-host.js +5 -2
- package/dist/app/commands/command-model-actions.d.ts +1 -0
- package/dist/app/commands/command-model-actions.js +57 -35
- package/dist/app/commands/command-navigation-actions.d.ts +1 -0
- package/dist/app/commands/command-navigation-actions.js +16 -3
- package/dist/app/commands/command-registry.d.ts +2 -0
- package/dist/app/commands/command-registry.js +15 -1
- package/dist/app/commands/command-session-actions.js +9 -3
- package/dist/app/commands/reload-context-inventory.d.ts +11 -0
- package/dist/app/commands/reload-context-inventory.js +70 -0
- package/dist/app/extensions/extension-actions-controller.d.ts +1 -0
- package/dist/app/extensions/extension-actions-controller.js +6 -0
- package/dist/app/extensions/subagent-catalog-state.d.ts +9 -0
- package/dist/app/extensions/subagent-catalog-state.js +23 -0
- package/dist/app/input/autocomplete-controller.js +61 -34
- package/dist/app/input/input-action-controller.d.ts +2 -0
- package/dist/app/input/input-action-controller.js +8 -1
- package/dist/app/input/input-controller.d.ts +2 -1
- package/dist/app/input/input-controller.js +7 -2
- package/dist/app/input/prompt-enhancer-controller.js +53 -35
- package/dist/app/input/voice-controller.d.ts +41 -45
- package/dist/app/input/voice-controller.js +351 -419
- package/dist/app/model/model-usage-controller.js +17 -7
- package/dist/app/model/model-usage-status.d.ts +4 -1
- package/dist/app/model/model-usage-status.js +270 -46
- package/dist/app/popup/menu-items-controller.d.ts +13 -3
- package/dist/app/popup/menu-items-controller.js +37 -21
- package/dist/app/popup/popup-action-controller.d.ts +12 -2
- package/dist/app/popup/popup-action-controller.js +77 -24
- package/dist/app/popup/popup-menu-controller.d.ts +36 -14
- package/dist/app/popup/popup-menu-controller.js +239 -69
- package/dist/app/rendering/dcp-stats.d.ts +9 -4
- package/dist/app/rendering/dcp-stats.js +40 -425
- package/dist/app/rendering/editor-panels.js +10 -4
- package/dist/app/rendering/popup-menu-renderer.d.ts +3 -5
- package/dist/app/rendering/popup-menu-renderer.js +42 -37
- package/dist/app/rendering/render-controller.js +23 -2
- package/dist/app/rendering/status-line-renderer.d.ts +5 -0
- package/dist/app/rendering/status-line-renderer.js +41 -5
- package/dist/app/rendering/tab-line-renderer.js +26 -20
- package/dist/app/runtime.d.ts +12 -1
- package/dist/app/runtime.js +120 -12
- package/dist/app/screen/mouse-controller.d.ts +2 -0
- package/dist/app/screen/mouse-controller.js +17 -7
- package/dist/app/screen/status-controller.d.ts +4 -0
- package/dist/app/screen/status-controller.js +5 -0
- package/dist/app/session/lazy-session-manager.js +34 -0
- package/dist/app/session/session-event-controller.d.ts +1 -0
- package/dist/app/session/session-event-controller.js +10 -1
- package/dist/app/session/session-history.d.ts +1 -0
- package/dist/app/session/session-history.js +12 -1
- package/dist/app/session/session-lifecycle-controller.d.ts +7 -1
- package/dist/app/session/session-lifecycle-controller.js +16 -1
- package/dist/app/session/tabs-controller.d.ts +26 -1
- package/dist/app/session/tabs-controller.js +454 -147
- package/dist/app/subagents/subagents-files.js +60 -1
- package/dist/app/subagents/subagents-model.d.ts +1 -0
- package/dist/app/subagents/subagents-model.js +18 -2
- package/dist/app/subagents/subagents-widget-controller.d.ts +1 -0
- package/dist/app/subagents/subagents-widget-controller.js +6 -0
- package/dist/app/types.d.ts +16 -1
- package/dist/app/workspace/workspace-actions-controller.js +10 -2
- package/dist/app/workspace/workspace-undo.d.ts +1 -0
- package/dist/app/workspace/workspace-undo.js +1 -0
- package/dist/bundled-extensions/question/index.js +9 -1
- package/dist/bundled-extensions/question/remote.d.ts +4 -0
- package/dist/bundled-extensions/question/remote.js +33 -0
- package/dist/bundled-extensions/telegram-connector/bot.d.ts +43 -0
- package/dist/bundled-extensions/telegram-connector/bot.js +166 -0
- package/dist/bundled-extensions/telegram-connector/config.d.ts +8 -0
- package/dist/bundled-extensions/telegram-connector/config.js +87 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.d.ts +66 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.js +413 -0
- package/dist/bundled-extensions/telegram-connector/index.d.ts +3 -0
- package/dist/bundled-extensions/telegram-connector/index.js +195 -0
- package/dist/bundled-extensions/terminal-bell/index.d.ts +0 -8
- package/dist/bundled-extensions/terminal-bell/index.js +0 -76
- package/dist/bundled-extensions/workspace-undo/index.d.ts +26 -0
- package/dist/bundled-extensions/workspace-undo/index.js +191 -0
- package/dist/config.d.ts +21 -2
- package/dist/config.js +159 -32
- package/dist/default-pix-config.js +25 -5
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +88 -62
- package/dist/schemas/pi-tools-suite-schema.js +54 -83
- package/dist/schemas/pix-schema.d.ts +19 -2
- package/dist/schemas/pix-schema.js +47 -5
- package/dist/schemas/tasks-schema.d.ts +18 -0
- package/dist/schemas/tasks-schema.js +41 -0
- package/docs/concurrency.md +9 -1
- package/docs/desktop-mvp.md +22 -6
- package/docs/desktop-task-manager.md +148 -84
- package/docs/release.md +30 -6
- package/external/pi-tools-suite/README.md +197 -84
- package/external/pi-tools-suite/docs/evals.md +1 -1
- package/external/pi-tools-suite/docs/session-recovery.md +47 -14
- package/external/pi-tools-suite/docs/subagent-model-pools.md +48 -30
- package/external/pi-tools-suite/docs/ui-qa-subagent.md +440 -0
- package/external/pi-tools-suite/package.json +6 -1
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +2 -1
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +9 -3
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +41 -3
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +94 -21
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +5 -17
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +72 -7
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +13 -1
- package/external/pi-tools-suite/src/async-subagents/agents/frontier-review.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/implement.md +1 -1
- package/external/pi-tools-suite/src/async-subagents/agents/presets.jsonc +16 -0
- package/external/pi-tools-suite/src/async-subagents/agents/research.md +5 -3
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/browser.mjs +346 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/desktop.mjs +1038 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/tui.mjs +759 -0
- package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/scripts/browser-qa-runner.mjs +32 -23
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/chrome-devtools/chrome-devtools-provider.mjs +895 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/linux/linux-atspi.py +494 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/macos/macos-accessibility.swift +1085 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/bridge-client.mjs +50 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/native-terminal-host.mjs +501 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/windows/windows-uia.ps1 +454 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-auth.md +114 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-chrome-devtools.md +91 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-playwright.md +145 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser.md +82 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-linux.md +26 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-macos.md +29 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-windows.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop.md +54 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-native-terminal.md +59 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-pty.md +37 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui.md +60 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/scripts/ui-qa-runner.mjs +535 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa.md +75 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +15 -71
- package/external/pi-tools-suite/src/async-subagents/core/activity.ts +33 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +16 -2
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +160 -327
- package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +2 -1
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +158 -33
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +21 -5
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +40 -26
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +40 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +7 -0
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +51 -45
- package/external/pi-tools-suite/src/async-subagents/index.ts +69 -5
- package/external/pi-tools-suite/src/async-subagents/lib.ts +16 -9
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/types.ts +1 -0
- package/external/pi-tools-suite/src/coding-discipline/index.ts +90 -59
- package/external/pi-tools-suite/src/config.ts +55 -1
- package/external/pi-tools-suite/src/context-gateway/accounting-log.ts +282 -0
- package/external/pi-tools-suite/src/context-gateway/config.ts +77 -3
- package/external/pi-tools-suite/src/context-gateway/efficiency.ts +414 -0
- package/external/pi-tools-suite/src/context-gateway/enforcement.ts +222 -0
- package/external/pi-tools-suite/src/context-gateway/index.ts +206 -19
- package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +7 -7
- package/external/pi-tools-suite/src/context-gateway/telemetry.ts +101 -28
- package/external/pi-tools-suite/src/context-gateway/types.ts +16 -3
- package/external/pi-tools-suite/src/context-inventory.ts +99 -0
- package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +39 -4
- package/external/pi-tools-suite/src/dcp/auto-compress.ts +128 -49
- package/external/pi-tools-suite/src/dcp/commands.ts +32 -156
- package/external/pi-tools-suite/src/dcp/compress-tool.ts +177 -46
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +6 -58
- package/external/pi-tools-suite/src/dcp/compression-preview.ts +9 -0
- package/external/pi-tools-suite/src/dcp/compression-progress.ts +22 -0
- package/external/pi-tools-suite/src/dcp/config.ts +114 -17
- package/external/pi-tools-suite/src/dcp/conversation-index.ts +36 -9
- package/external/pi-tools-suite/src/dcp/diagnostics.ts +41 -0
- package/external/pi-tools-suite/src/dcp/fresh-tool-results.ts +38 -0
- package/external/pi-tools-suite/src/dcp/index.ts +338 -66
- package/external/pi-tools-suite/src/dcp/journal.ts +126 -4
- package/external/pi-tools-suite/src/dcp/progress-controller.ts +2 -1
- package/external/pi-tools-suite/src/dcp/prompts.ts +83 -192
- package/external/pi-tools-suite/src/dcp/protected-continuity.ts +175 -0
- package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +93 -3
- package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +6 -10
- package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +36 -33
- package/external/pi-tools-suite/src/dcp/pruner-tools.ts +6 -3
- package/external/pi-tools-suite/src/dcp/pruner.ts +1 -0
- package/external/pi-tools-suite/src/dcp/routine-pressure.ts +86 -0
- package/external/pi-tools-suite/src/dcp/state.ts +9 -0
- package/external/pi-tools-suite/src/dcp/statistics.d.ts +8 -0
- package/external/pi-tools-suite/src/dcp/statistics.js +156 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +78 -22
- package/external/pi-tools-suite/src/index.ts +7 -1
- package/external/pi-tools-suite/src/lib/project.ts +36 -1
- package/external/pi-tools-suite/src/model-tools/index.ts +10 -7
- package/external/pi-tools-suite/src/repo-discovery/index.ts +304 -4
- package/external/pi-tools-suite/src/resource-registry/index.ts +2551 -0
- package/external/pi-tools-suite/src/session-recovery/index.ts +17 -0
- package/external/pi-tools-suite/src/shell-command-policy.ts +219 -0
- package/external/pi-tools-suite/src/todo/index.ts +21 -0
- package/external/pi-tools-suite/src/todo/todo.ts +19 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +47 -19
- package/package.json +10 -9
- package/schemas/pi-tools-suite.json +466 -287
- package/schemas/pix.json +129 -11
- package/schemas/tasks.json +131 -0
- package/skills/simplify/SKILL.md +33 -5
- package/docs/desktop-markdown-media.md +0 -77
- package/external/pi-tools-suite/docs/browser-qa-subagent.md +0 -177
- package/external/pi-tools-suite/docs/dcp-emergency-current-turn.md +0 -102
- package/external/pi-tools-suite/src/async-subagents/agents/browser-qa.md +0 -598
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +0 -54
- package/external/pi-tools-suite/src/skill-installer/index.ts +0 -333
- package/skills/playwright-cli/SKILL.md +0 -420
- package/skills/playwright-cli/references/element-attributes.md +0 -23
- package/skills/playwright-cli/references/playwright-tests.md +0 -50
- package/skills/playwright-cli/references/request-mocking.md +0 -87
- package/skills/playwright-cli/references/running-code.md +0 -241
- package/skills/playwright-cli/references/session-management.md +0 -273
- package/skills/playwright-cli/references/spec-driven-testing.md +0 -311
- package/skills/playwright-cli/references/storage-state.md +0 -290
- package/skills/playwright-cli/references/test-generation.md +0 -142
- package/skills/playwright-cli/references/tracing.md +0 -154
- package/skills/playwright-cli/references/video-recording.md +0 -147
- package/skills/spec-lite/SKILL.md +0 -140
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-auth.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-flow.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.LICENSE +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.mjs +0 -0
|
@@ -4,7 +4,7 @@ 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
6
|
import { sliceByDisplayColumns, stringDisplayWidth } from "../../terminal-width.js";
|
|
7
|
-
import {
|
|
7
|
+
import { loadDcpStatsToast } 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
|
import { APP_ICONS } from "../icons.js";
|
|
@@ -133,10 +133,10 @@ export class AppMouseController {
|
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
135
|
if (target?.kind === "popup-menu") {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
const active = this.popupMenus.selectActivePopupMenuIndex(target.index);
|
|
137
|
+
if (active !== "model" || this.popupMenus.modelVisibilityModeActive()) {
|
|
138
|
+
void this.popupActions.submitActivePopupMenu();
|
|
139
|
+
}
|
|
140
140
|
this.showClickFlashForEvent(event);
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
@@ -145,6 +145,11 @@ export class AppMouseController {
|
|
|
145
145
|
this.showClickFlashForEvent(event);
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
|
+
if (target?.kind === "model-visibility-clear") {
|
|
149
|
+
this.popupActions.clearVisibleModels();
|
|
150
|
+
this.showClickFlashForEvent(event);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
148
153
|
if (target?.kind === "todo-panel") {
|
|
149
154
|
this.host.setTodoPanelExpanded(!this.host.getTodoPanelExpanded());
|
|
150
155
|
this.showClickFlashForEvent(event);
|
|
@@ -488,8 +493,13 @@ export class AppMouseController {
|
|
|
488
493
|
const session = this.host.runtimeSession();
|
|
489
494
|
if (!session)
|
|
490
495
|
return false;
|
|
491
|
-
const
|
|
492
|
-
|
|
496
|
+
const model = session.model;
|
|
497
|
+
const sessionId = session.sessionManager.getSessionId?.();
|
|
498
|
+
void loadDcpStatsToast(session).then((message) => {
|
|
499
|
+
if (this.host.runtimeSession() !== session || session.model !== model || session.sessionManager.getSessionId?.() !== sessionId)
|
|
500
|
+
return;
|
|
501
|
+
this.host.showToast(message, "info", { variant: "dialog" });
|
|
502
|
+
});
|
|
493
503
|
return true;
|
|
494
504
|
}
|
|
495
505
|
handleStatusModelUsageClick(event) {
|
|
@@ -7,6 +7,10 @@ export type AppStatusControllerHost = {
|
|
|
7
7
|
readonly theme: Theme;
|
|
8
8
|
readonly blinkController: AppBlinkController;
|
|
9
9
|
runtimeSession(): AgentSession | undefined;
|
|
10
|
+
draftModelStatus?(): {
|
|
11
|
+
modelLabel: string;
|
|
12
|
+
thinkingLabel: string;
|
|
13
|
+
} | undefined;
|
|
10
14
|
render(): void;
|
|
11
15
|
};
|
|
12
16
|
export declare class AppStatusController {
|
|
@@ -25,6 +25,11 @@ export class AppStatusController {
|
|
|
25
25
|
this.status = session ? this.formatSessionStatus(session) : "no session";
|
|
26
26
|
}
|
|
27
27
|
currentStatus() {
|
|
28
|
+
if (!this.host.runtimeSession() && (this.status === "new conversation" || this.status === "no session")) {
|
|
29
|
+
const draft = this.host.draftModelStatus?.();
|
|
30
|
+
if (draft)
|
|
31
|
+
return `${draft.modelLabel} ${APP_ICONS.lightbulb} ${draft.thinkingLabel}`;
|
|
32
|
+
}
|
|
28
33
|
if (!this.statusFollowsSession)
|
|
29
34
|
return this.status;
|
|
30
35
|
const session = this.host.runtimeSession();
|
|
@@ -22,6 +22,7 @@ class LazySessionManager {
|
|
|
22
22
|
labelsById = new Map();
|
|
23
23
|
leafId = null;
|
|
24
24
|
hydrated;
|
|
25
|
+
contextManager;
|
|
25
26
|
tailEntryCount;
|
|
26
27
|
tailStartOffset = 0;
|
|
27
28
|
constructor(sessionPath, options = {}) {
|
|
@@ -74,6 +75,7 @@ class LazySessionManager {
|
|
|
74
75
|
this.byId.clear();
|
|
75
76
|
this.labelsById.clear();
|
|
76
77
|
this.leafId = null;
|
|
78
|
+
this.contextManager = undefined;
|
|
77
79
|
mkdirSync(this.sessionDirPath, { recursive: true });
|
|
78
80
|
this.sessionFilePath = join(this.sessionDirPath, `${timestamp.replace(/[:.]/g, "-")}_${sessionId}.jsonl`);
|
|
79
81
|
writeFileSync(this.sessionFilePath, `${JSON.stringify(header)}\n`, "utf8");
|
|
@@ -103,6 +105,11 @@ class LazySessionManager {
|
|
|
103
105
|
getEntries() {
|
|
104
106
|
return this.hydrated?.getEntries() ?? [...this.entries];
|
|
105
107
|
}
|
|
108
|
+
// Before hydration this is a presentation/file tail, NOT selected ancestry:
|
|
109
|
+
// it can omit old ancestors and contain abandoned side-branch entries.
|
|
110
|
+
// Lineage-sensitive callers must use readFullBranchEntries(); retry proofs
|
|
111
|
+
// must follow parentId, never compare positions in this cache. See
|
|
112
|
+
// specs/dcp-statistics.md#lazy-tail-retry-invariant and its regression tests.
|
|
106
113
|
getBranch(fromId) {
|
|
107
114
|
if (this.hydrated)
|
|
108
115
|
return this.hydrated.getBranch(fromId);
|
|
@@ -161,6 +168,8 @@ class LazySessionManager {
|
|
|
161
168
|
buildContextEntries() {
|
|
162
169
|
if (this.hydrated)
|
|
163
170
|
return this.hydrated.buildContextEntries();
|
|
171
|
+
if (this.tailStartOffset > 0)
|
|
172
|
+
return this.completeContextManager().buildContextEntries();
|
|
164
173
|
const entries = this.contextEntries();
|
|
165
174
|
const byId = new Map(entries.map((entry) => [entry.id, entry]));
|
|
166
175
|
return buildSdkContextEntries(entries, entries.at(-1)?.id ?? null, byId);
|
|
@@ -168,6 +177,8 @@ class LazySessionManager {
|
|
|
168
177
|
buildSessionContext() {
|
|
169
178
|
if (this.hydrated)
|
|
170
179
|
return this.hydrated.buildSessionContext();
|
|
180
|
+
if (this.tailStartOffset > 0)
|
|
181
|
+
return this.completeContextManager().buildSessionContext();
|
|
171
182
|
const entries = this.contextEntries();
|
|
172
183
|
const byId = new Map(entries.map((entry) => [entry.id, entry]));
|
|
173
184
|
return buildSessionContext(entries, entries.at(-1)?.id ?? null, byId);
|
|
@@ -212,6 +223,7 @@ class LazySessionManager {
|
|
|
212
223
|
return;
|
|
213
224
|
}
|
|
214
225
|
this.leafId = branchFromId;
|
|
226
|
+
this.contextManager = undefined;
|
|
215
227
|
}
|
|
216
228
|
resetLeaf() {
|
|
217
229
|
if (this.hydrated) {
|
|
@@ -219,6 +231,7 @@ class LazySessionManager {
|
|
|
219
231
|
return;
|
|
220
232
|
}
|
|
221
233
|
this.leafId = null;
|
|
234
|
+
this.contextManager = undefined;
|
|
222
235
|
}
|
|
223
236
|
createBranchedSession(leafId) {
|
|
224
237
|
return this.hydrate().createBranchedSession(leafId);
|
|
@@ -292,9 +305,29 @@ class LazySessionManager {
|
|
|
292
305
|
hydrate() {
|
|
293
306
|
if (!this.hydrated) {
|
|
294
307
|
this.hydrated = SessionManager.open(this.sessionFilePath, this.sessionDirPath, this.cwdPath);
|
|
308
|
+
this.contextManager = undefined;
|
|
295
309
|
}
|
|
296
310
|
return this.hydrated;
|
|
297
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* The tail cache is a presentation/history optimisation, not a valid model
|
|
314
|
+
* context boundary. If older entries exist, reconstruct provider context from
|
|
315
|
+
* the complete persisted session while leaving the facade itself lazy so the
|
|
316
|
+
* UI can continue paging old history on demand.
|
|
317
|
+
*/
|
|
318
|
+
completeContextManager() {
|
|
319
|
+
if (!this.contextManager) {
|
|
320
|
+
const manager = SessionManager.open(this.sessionFilePath, this.sessionDirPath, this.cwdPath);
|
|
321
|
+
if (this.leafId === null) {
|
|
322
|
+
manager.resetLeaf();
|
|
323
|
+
}
|
|
324
|
+
else if (manager.getLeafId() !== this.leafId && manager.getEntry(this.leafId)) {
|
|
325
|
+
manager.branch(this.leafId);
|
|
326
|
+
}
|
|
327
|
+
this.contextManager = manager;
|
|
328
|
+
}
|
|
329
|
+
return this.contextManager;
|
|
330
|
+
}
|
|
298
331
|
async loadHeaderAsync(cwdOverride) {
|
|
299
332
|
const existingHeader = await readSessionHeaderFast(this.sessionFilePath);
|
|
300
333
|
if (existingHeader)
|
|
@@ -335,6 +368,7 @@ class LazySessionManager {
|
|
|
335
368
|
this.entries.push(entry);
|
|
336
369
|
this.byId.set(entry.id, entry);
|
|
337
370
|
this.leafId = entry.id;
|
|
371
|
+
this.contextManager = undefined;
|
|
338
372
|
return entry.id;
|
|
339
373
|
}
|
|
340
374
|
newEntry(type, payload) {
|
|
@@ -91,6 +91,7 @@ export declare class AppSessionEventController {
|
|
|
91
91
|
private currentThinkingEntryStartedAt;
|
|
92
92
|
private thinkingElapsedRenderTimer;
|
|
93
93
|
private assistantMessageClosed;
|
|
94
|
+
private currentAssistantTerminalErrorRendered;
|
|
94
95
|
private assistantTextBuffer;
|
|
95
96
|
constructor(host: AppSessionEventControllerHost);
|
|
96
97
|
snapshotState(): AppSessionEventControllerState;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isRetryableAssistantError } from "@earendil-works/pi-ai";
|
|
2
2
|
import { createId } from "../id.js";
|
|
3
3
|
import { extractImageContents, renderContent, renderUserMessageContent, stringifyUnknown } from "../rendering/message-content.js";
|
|
4
|
-
import { customMessageEntry, extensionSessionEntry, loadSessionHistoryEntries, loadSessionHistoryEntriesAsync } from "./session-history.js";
|
|
4
|
+
import { assistantTerminalErrorText, customMessageEntry, extensionSessionEntry, loadSessionHistoryEntries, loadSessionHistoryEntriesAsync } from "./session-history.js";
|
|
5
5
|
import { sessionHistoryDisplayMessages, sessionHistoryDisplayMessagesFromEntries, sessionHistoryFullBranchEntries, sessionHistoryOlderMessagesReader } from "./pix-system-message.js";
|
|
6
6
|
import { THINKING_TOOL_NAME } from "../constants.js";
|
|
7
7
|
import { isRecord } from "../guards.js";
|
|
@@ -34,6 +34,7 @@ export class AppSessionEventController {
|
|
|
34
34
|
currentThinkingEntryStartedAt;
|
|
35
35
|
thinkingElapsedRenderTimer;
|
|
36
36
|
assistantMessageClosed = false;
|
|
37
|
+
currentAssistantTerminalErrorRendered = false;
|
|
37
38
|
assistantTextBuffer = "";
|
|
38
39
|
constructor(host) {
|
|
39
40
|
this.host = host;
|
|
@@ -586,6 +587,7 @@ export class AppSessionEventController {
|
|
|
586
587
|
}
|
|
587
588
|
if (isRecord(message) && message.role === "assistant") {
|
|
588
589
|
this.assistantMessageClosed = false;
|
|
590
|
+
this.currentAssistantTerminalErrorRendered = false;
|
|
589
591
|
this.clearCurrentAssistantState();
|
|
590
592
|
}
|
|
591
593
|
}
|
|
@@ -601,6 +603,12 @@ export class AppSessionEventController {
|
|
|
601
603
|
this.renderAssistantToolCallsFromMessage(message);
|
|
602
604
|
this.finishCurrentThinkingEntry();
|
|
603
605
|
this.flushAssistantTextBuffer(true);
|
|
606
|
+
const terminalError = assistantTerminalErrorText(message);
|
|
607
|
+
if (terminalError && !this.currentAssistantTerminalErrorRendered) {
|
|
608
|
+
this.addEntry({ id: createId("error"), kind: "error", text: terminalError });
|
|
609
|
+
this.currentAssistantTerminalErrorRendered = true;
|
|
610
|
+
this.showManualRetryOnTerminalError(message);
|
|
611
|
+
}
|
|
604
612
|
this.clearCurrentAssistantState();
|
|
605
613
|
this.assistantMessageClosed = true;
|
|
606
614
|
}
|
|
@@ -726,6 +734,7 @@ export class AppSessionEventController {
|
|
|
726
734
|
this.host.setSessionActivity(this.host.runtime()?.session.isStreaming ? "running" : "idle");
|
|
727
735
|
const errorText = assistantEvent.error.errorMessage ?? assistantEvent.reason;
|
|
728
736
|
this.addEntry({ id: createId("error"), kind: "error", text: errorText });
|
|
737
|
+
this.currentAssistantTerminalErrorRendered = true;
|
|
729
738
|
this.showManualRetryOnTerminalError(assistantEvent.error);
|
|
730
739
|
break;
|
|
731
740
|
}
|
|
@@ -41,4 +41,5 @@ export declare function customMessageEntry(message: Record<string, unknown>): En
|
|
|
41
41
|
export declare function extensionSessionEntry(value: unknown): Extract<Entry, {
|
|
42
42
|
kind: "extension-entry";
|
|
43
43
|
}> | undefined;
|
|
44
|
+
export declare function assistantTerminalErrorText(message: Record<string, unknown>): string | undefined;
|
|
44
45
|
export {};
|
|
@@ -4,6 +4,7 @@ import { isOnlyHiddenMetadata } from "../../markdown-format.js";
|
|
|
4
4
|
import { extractImageContents, renderContent, renderUserMessageContent, stringifyUnknown } from "../rendering/message-content.js";
|
|
5
5
|
import { THINKING_TOOL_NAME } from "../constants.js";
|
|
6
6
|
import { PIX_EXTENSION_ENTRY_ROLE, PIX_SESSION_ENTRY_ID_FIELD, PIX_SYSTEM_DISPLAY_ENTRY_CUSTOM_TYPE, PIX_SYSTEM_MESSAGE_CUSTOM_TYPE, PIX_THINKING_LEVEL_FIELD } from "./pix-system-message.js";
|
|
7
|
+
import { WORKSPACE_MUTATION_ENTRY_TYPE } from "../workspace/workspace-undo.js";
|
|
7
8
|
const HISTORICAL_SUBAGENTS_OBSERVATION = { showSnapshot: false };
|
|
8
9
|
const DEFAULT_HISTORY_CHUNK_SIZE = 50;
|
|
9
10
|
const DEFAULT_HISTORY_TAIL_MESSAGE_COUNT = 80;
|
|
@@ -189,7 +190,7 @@ export function customMessageEntry(message) {
|
|
|
189
190
|
export function extensionSessionEntry(value) {
|
|
190
191
|
if (!isRecord(value) || value.type !== "custom" || typeof value.id !== "string" || typeof value.customType !== "string")
|
|
191
192
|
return undefined;
|
|
192
|
-
if (value.customType === PIX_SYSTEM_DISPLAY_ENTRY_CUSTOM_TYPE)
|
|
193
|
+
if (value.customType === PIX_SYSTEM_DISPLAY_ENTRY_CUSTOM_TYPE || value.customType === WORKSPACE_MUTATION_ENTRY_TYPE)
|
|
193
194
|
return undefined;
|
|
194
195
|
return {
|
|
195
196
|
id: `extension-entry-${value.id}`,
|
|
@@ -198,6 +199,12 @@ export function extensionSessionEntry(value) {
|
|
|
198
199
|
expanded: false,
|
|
199
200
|
};
|
|
200
201
|
}
|
|
202
|
+
export function assistantTerminalErrorText(message) {
|
|
203
|
+
if (message.stopReason !== "error")
|
|
204
|
+
return undefined;
|
|
205
|
+
const errorMessage = typeof message.errorMessage === "string" ? message.errorMessage.trim() : "";
|
|
206
|
+
return errorMessage || "Request failed before the assistant produced a response.";
|
|
207
|
+
}
|
|
201
208
|
function renderAssistantHistoryMessage(message, toolResults, options) {
|
|
202
209
|
const content = message.content;
|
|
203
210
|
if (!Array.isArray(content))
|
|
@@ -273,4 +280,8 @@ function renderAssistantHistoryMessage(message, toolResults, options) {
|
|
|
273
280
|
if (assistantText && !isOnlyHiddenMetadata(assistantText)) {
|
|
274
281
|
options.addEntry({ id: createId("assistant"), kind: "assistant", text: assistantText });
|
|
275
282
|
}
|
|
283
|
+
const terminalError = assistantTerminalErrorText(message);
|
|
284
|
+
if (terminalError) {
|
|
285
|
+
options.addEntry({ id: createId("error"), kind: "error", text: terminalError });
|
|
286
|
+
}
|
|
276
287
|
}
|
|
@@ -3,7 +3,12 @@ import type { InputEditor } from "../../input-editor.js";
|
|
|
3
3
|
import type { AppOptions, Entry, PixExtensionUIContext, SessionActivity } from "../types.js";
|
|
4
4
|
export type AppSessionLifecycleHost = {
|
|
5
5
|
options: AppOptions;
|
|
6
|
-
|
|
6
|
+
prepareStartupRuntime?(): Promise<{
|
|
7
|
+
sessionPath?: string;
|
|
8
|
+
} | null>;
|
|
9
|
+
createRuntime(options?: {
|
|
10
|
+
sessionPath?: string;
|
|
11
|
+
}): Promise<AgentSessionRuntime>;
|
|
7
12
|
entries: Entry[];
|
|
8
13
|
runtime(): AgentSessionRuntime | undefined;
|
|
9
14
|
setRuntime(runtime: AgentSessionRuntime | undefined): void;
|
|
@@ -27,6 +32,7 @@ export type AppSessionLifecycleHost = {
|
|
|
27
32
|
handleExtensionError(error: ExtensionError): void;
|
|
28
33
|
handleSessionEvent(event: AgentSessionEvent): void;
|
|
29
34
|
bindAgentPause(session: AgentSession): void;
|
|
35
|
+
contextInventoryText?(runtime: AgentSessionRuntime, heading: string): string;
|
|
30
36
|
addEntry(entry: Entry): void;
|
|
31
37
|
setStatus(status: string): void;
|
|
32
38
|
showToast(message: string, kind: "success" | "error" | "warning" | "info"): void;
|
|
@@ -32,7 +32,16 @@ export class AppSessionLifecycleController {
|
|
|
32
32
|
});
|
|
33
33
|
try {
|
|
34
34
|
await this.host.loadStartupConfig();
|
|
35
|
-
const
|
|
35
|
+
const startupRuntime = await this.host.prepareStartupRuntime?.();
|
|
36
|
+
if (startupRuntime === null) {
|
|
37
|
+
this.host.setRuntime(undefined);
|
|
38
|
+
this.host.setSessionStatus(undefined);
|
|
39
|
+
this.host.setSessionActivity("idle");
|
|
40
|
+
await this.host.restoreTabsAfterStartup();
|
|
41
|
+
this.host.render();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const runtime = await this.host.createRuntime(startupRuntime ?? undefined);
|
|
36
45
|
if (!this.host.isRunning()) {
|
|
37
46
|
await this.host.disposeRuntimeForQuit(runtime);
|
|
38
47
|
return;
|
|
@@ -44,6 +53,12 @@ export class AppSessionLifecycleController {
|
|
|
44
53
|
await this.bindCurrentSession({ awaitExtensions: false });
|
|
45
54
|
});
|
|
46
55
|
await this.bindCurrentSession({ awaitExtensions: false });
|
|
56
|
+
if (runtime.session.messages.length === 0) {
|
|
57
|
+
await this.awaitCurrentSessionExtensions(runtime);
|
|
58
|
+
const text = this.host.contextInventoryText?.(runtime, `Empty tab ready. cwd=${runtime.cwd}`);
|
|
59
|
+
if (text)
|
|
60
|
+
this.host.addEntry({ id: createId("system"), kind: "system", text });
|
|
61
|
+
}
|
|
47
62
|
if (runtime.modelFallbackMessage) {
|
|
48
63
|
this.host.addEntry({ id: createId("system"), kind: "system", text: runtime.modelFallbackMessage });
|
|
49
64
|
}
|
|
@@ -16,8 +16,11 @@ export type AppTabsControllerHost = {
|
|
|
16
16
|
readonly maxProjectSessions?: number | (() => number | undefined);
|
|
17
17
|
readonly blinkController: AppBlinkController;
|
|
18
18
|
runtime(): AgentSessionRuntime | undefined;
|
|
19
|
-
createRuntimeForNewSession(): Promise<AgentSessionRuntime>;
|
|
19
|
+
createRuntimeForNewSession(modelRef?: string): Promise<AgentSessionRuntime>;
|
|
20
20
|
createRuntimeForSession(sessionPath: string): Promise<AgentSessionRuntime>;
|
|
21
|
+
draftModelOverrideRef?(): string | undefined;
|
|
22
|
+
resetDraftModelSelection?(): void;
|
|
23
|
+
deactivateRuntimeForDraft?(): void;
|
|
21
24
|
awaitCurrentSessionExtensions?(runtime?: AgentSessionRuntime): Promise<void>;
|
|
22
25
|
activateRuntime(runtime: AgentSessionRuntime, options?: BindCurrentSessionOptions): Promise<void>;
|
|
23
26
|
disposeRuntime(runtime: AgentSessionRuntime): Promise<void>;
|
|
@@ -43,6 +46,9 @@ export type AppTabsControllerHost = {
|
|
|
43
46
|
restoreAutoUserMessages?(messages: readonly SubmittedUserMessage[]): void;
|
|
44
47
|
captureDeferredUserMessages?(): readonly SubmittedUserMessage[];
|
|
45
48
|
restoreDeferredUserMessages?(messages: readonly SubmittedUserMessage[]): void;
|
|
49
|
+
openDraftSessionSelector?(): void;
|
|
50
|
+
closeDraftSessionSelector?(): void;
|
|
51
|
+
contextInventoryText?(runtime: AgentSessionRuntime, heading: string): string;
|
|
46
52
|
addEntry(entry: Entry): void;
|
|
47
53
|
showToast(message: string, kind: "success" | "error" | "warning" | "info"): void;
|
|
48
54
|
render(): void;
|
|
@@ -63,6 +69,7 @@ export declare class AppTabsController {
|
|
|
63
69
|
private readonly tabIdsNeedingHistoryReload;
|
|
64
70
|
private readonly historyInvalidationGenerationByTabId;
|
|
65
71
|
private readonly runtimeOwnershipGenerationByTabId;
|
|
72
|
+
private readonly touchedDraftTabIds;
|
|
66
73
|
private readonly orphanRuntimeDisposals;
|
|
67
74
|
private readonly lifecycleMutationQueue;
|
|
68
75
|
private activeTabId;
|
|
@@ -73,6 +80,9 @@ export declare class AppTabsController {
|
|
|
73
80
|
private lifecycleGeneration;
|
|
74
81
|
private lifecycleMutationRunning;
|
|
75
82
|
private saveTabsWriteTail;
|
|
83
|
+
private startupSavedTabs;
|
|
84
|
+
private startupPrepared;
|
|
85
|
+
private startupRuntimePlan;
|
|
76
86
|
private restored;
|
|
77
87
|
private retentionCleanupRunning;
|
|
78
88
|
private retentionCleanupScheduled;
|
|
@@ -87,6 +97,9 @@ export declare class AppTabsController {
|
|
|
87
97
|
markTerminalBellAttention(sessionPath: string | undefined): void;
|
|
88
98
|
tabPanelRows(terminalRows: number): number;
|
|
89
99
|
activeInputTabId(): string | undefined;
|
|
100
|
+
isDraftTabActive(): boolean;
|
|
101
|
+
openSessionPaths(): readonly string[];
|
|
102
|
+
noteActiveDraftInputChanged(): void;
|
|
90
103
|
inputStateForTab(tabId: string | undefined): TabInputState | undefined;
|
|
91
104
|
setInputStateForTab(tabId: string | undefined, state: TabInputState): Promise<void>;
|
|
92
105
|
disposeInactiveRuntimes(disposeRuntime?: (runtime: AgentSessionRuntime) => Promise<void>): Promise<void>;
|
|
@@ -98,18 +111,28 @@ export declare class AppTabsController {
|
|
|
98
111
|
save?: boolean;
|
|
99
112
|
force?: boolean;
|
|
100
113
|
}): void;
|
|
114
|
+
prepareStartupRuntime(): Promise<{
|
|
115
|
+
sessionPath?: string;
|
|
116
|
+
} | null>;
|
|
101
117
|
restoreAfterStartup(): Promise<void>;
|
|
102
118
|
private restoreAfterStartupMutation;
|
|
103
119
|
openNewTab(): Promise<void>;
|
|
104
120
|
private openNewTabMutation;
|
|
121
|
+
materializeActiveDraftTab(): Promise<AgentSessionRuntime | undefined>;
|
|
122
|
+
private materializeActiveDraftTabMutation;
|
|
123
|
+
openSessionInActiveDraftTab(sessionPath: string): Promise<boolean>;
|
|
124
|
+
private openSessionInActiveDraftTabMutation;
|
|
125
|
+
private ownsDraftLifecycle;
|
|
105
126
|
openSessionInNewTab(sessionPath: string): Promise<boolean>;
|
|
106
127
|
private openSessionInNewTabMutation;
|
|
107
128
|
forkSessionEntryInNewTab(entryId: string): Promise<boolean>;
|
|
108
129
|
private forkSessionEntryInNewTabMutation;
|
|
109
130
|
switchToTab(tabId: string): Promise<void>;
|
|
110
131
|
private switchToTabMutation;
|
|
132
|
+
private switchDraftToPersistedTab;
|
|
111
133
|
closeTab(tabId: string): Promise<void>;
|
|
112
134
|
private closeTabMutation;
|
|
135
|
+
private closeDraftTabMutation;
|
|
113
136
|
private replaceLastTabWithNewSession;
|
|
114
137
|
private loadActiveSessionHistory;
|
|
115
138
|
private cancelHistoryLoad;
|
|
@@ -117,6 +140,8 @@ export declare class AppTabsController {
|
|
|
117
140
|
private runtimeForCommand;
|
|
118
141
|
private idleRuntime;
|
|
119
142
|
private activeTab;
|
|
143
|
+
private createDraftTab;
|
|
144
|
+
private activateDraftTab;
|
|
120
145
|
private clearStartupTabPlaceholders;
|
|
121
146
|
private storeActiveRuntime;
|
|
122
147
|
private storeActiveSessionView;
|