@timurproko/a1 0.2.5 → 0.2.6-dev.727
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/bin/cli.js +13 -2
- package/bin/ui.js +13 -0
- package/dist/app/session-shell/prompt-suggestion-controller.d.ts +5 -4
- package/dist/app/session-shell/prompt-suggestion-controller.js +148 -58
- package/dist/app/session-shell/session-shell-root.d.ts +5 -1
- package/dist/app/session-shell/session-shell-root.js +13 -6
- package/dist/app/session-shell/session-shell.js +132 -51
- package/dist/app/session-shell/session-viewport-controller.js +33 -21
- package/dist/cli/dispatch.js +5 -3
- package/dist/cli/session-context.d.ts +5 -1
- package/dist/cli/session-context.js +25 -8
- package/dist/composition/owned-ui.d.ts +3 -0
- package/dist/composition/owned-ui.js +66 -6
- package/dist/composition/settings-route-host.js +4 -3
- package/dist/contracts/owned-ui/index.d.ts +4 -2
- package/dist/contracts/owned-ui/index.js +1 -1
- package/dist/contracts/owned-ui/model.d.ts +4 -0
- package/dist/contracts/owned-ui/suggestion-diagnostics.d.ts +5 -1
- package/dist/contracts/owned-ui/suggestion-diagnostics.js +3 -1
- package/dist/contracts/owned-ui/validation.js +7 -0
- package/dist/features/launch/index.d.ts +1 -1
- package/dist/features/launch/session-context.d.ts +17 -2
- package/dist/features/launch/session-context.js +9 -5
- package/dist/features/owned-ui/reference-routes.d.ts +1 -1
- package/dist/features/owned-ui/reference-routes.js +1 -1
- package/dist/features/owned-ui/settings-app.js +21 -39
- package/dist/features/prompt-suggestions/diagnostics.js +4 -1
- package/dist/foundation/lifecycle/index.d.ts +2 -2
- package/dist/foundation/lifecycle/index.js +1 -1
- package/dist/foundation/lifecycle/session-repository-context.d.ts +19 -2
- package/dist/foundation/lifecycle/session-repository-context.js +434 -66
- package/dist/foundation/process-containment/index.d.ts +1 -0
- package/dist/foundation/process-containment/index.js +1 -0
- package/dist/foundation/process-containment/native-process-inspector.d.ts +3 -0
- package/dist/foundation/process-containment/native-process-inspector.js +21 -0
- package/dist/foundation/release/progress-palette.generated.d.ts +2 -2
- package/dist/foundation/release/progress-palette.generated.js +2 -2
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/integrations/pi/components/components.js +2 -2
- package/dist/integrations/pi/components/index.d.ts +2 -2
- package/dist/integrations/pi/components/index.js +1 -1
- package/dist/integrations/pi/components/lazy-selectors.d.ts +42 -0
- package/dist/integrations/pi/components/lazy-selectors.js +32 -0
- package/dist/integrations/pi/components/modal-frame.js +3 -4
- package/dist/integrations/pi/components/models-dialog.js +5 -5
- package/dist/integrations/pi/components/prompt-input-port.d.ts +1 -0
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -2
- package/dist/integrations/pi/components/resources/builtin-themes.js +2 -2
- package/dist/integrations/pi/components/share-operation-dialog.js +3 -3
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +8 -7
- package/dist/integrations/pi/components/shell-extension-ui.d.ts +2 -0
- package/dist/integrations/pi/components/shell-extension-ui.js +20 -10
- package/dist/integrations/pi/components/shell-hotkey-sections.js +2 -2
- package/dist/integrations/pi/components/shell-presenters-info.js +10 -10
- package/dist/integrations/pi/components/shell-presenters-transcript.js +10 -10
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -6
- package/dist/integrations/pi/components/shell-shared-facade.js +1 -1
- package/dist/integrations/pi/components/skills-dialog.js +3 -3
- package/dist/integrations/pi/components/submitted-prompt-adapter.js +2 -3
- package/dist/integrations/pi/components/theme.d.ts +9 -0
- package/dist/integrations/pi/components/theme.js +30 -0
- package/dist/integrations/pi/components/tool-result-adapter.js +6 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
- package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +6 -6
- package/dist/integrations/pi/components/upstream/components/extension-input.js +4 -4
- package/dist/integrations/pi/components/upstream/components/extension-selector.js +4 -4
- package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +5 -5
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +8 -5
- package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +3 -3
- package/dist/integrations/pi/components/upstream/components/session-footer.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector.js +14 -20
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +3 -2
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +6 -3
- package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +2 -2
- package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +4 -0
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +11 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +27 -18
- package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +4 -4
- package/dist/integrations/pi/components/upstream/history/editor-core.js +11 -7
- package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
- package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
- package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
- package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
- package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +31 -0
- package/dist/integrations/pi/components/upstream/program-status-reporter.js +89 -0
- package/dist/integrations/pi/components/upstream/theme/system-theme.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/system-theme.js +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.d.ts +18 -1
- package/dist/integrations/pi/components/upstream/theme/theme.js +207 -10
- package/dist/integrations/pi/engine/pi-settings-metadata.json +1 -1
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/session-events.js +10 -2
- package/dist/integrations/pi/engine/transcript-projection.js +2 -1
- package/dist/integrations/pi/startup-public.js +306 -290
- package/dist/integrations/pi/startup-public.manifest.json +289 -265
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +8 -1
- package/dist/integrations/pi/tui-runtime/adapter.js +31 -1
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +3 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/product-identity.d.ts +2 -2
- package/dist/product-identity.js +2 -2
- package/dist/product-identity.json +3 -1
- package/dist/runtime-payload-inventory.json +3092 -2878
- package/dist/ui/components/prompt-input.d.ts +2 -0
- package/dist/ui/components/prompt-input.js +5 -1
- package/dist/ui/components/text-selection.d.ts +1 -1
- package/dist/ui/components/text-selection.js +3 -1
- package/dist/ui/components/theme.d.ts +2 -0
- package/dist/ui/components/transcript-viewport.d.ts +6 -4
- package/dist/ui/components/transcript-viewport.js +94 -16
- package/dist/ui/components/value-menu.d.ts +2 -0
- package/dist/ui/components/value-menu.js +13 -8
- package/dist/ui/settings/declarations.d.ts +26 -14
- package/dist/ui/settings/declarations.js +24 -11
- package/dist/ui/settings/migrations.js +16 -0
- package/docs/architecture/project-structure.md +4 -3
- package/docs/architecture/prompt-suggestions.md +14 -10
- package/docs/local-worktree-cleanup.md +23 -9
- package/docs/manual-owned-ui-checkpoint.md +1 -1
- package/docs/openspec-archive-automation.md +20 -19
- package/package.json +3 -3
|
@@ -7,8 +7,8 @@ export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, compone
|
|
|
7
7
|
export { renderPiShellHotkeySections } from "./shell-hotkey-sections.js";
|
|
8
8
|
export type { PiShellHotkeySection } from "./shell-hotkey-sections.js";
|
|
9
9
|
export type { PiExtensionUiBridge, PiExtensionUiBridgeHost, PiShellAuthProviderOption, PiShellAutocompleteCommand, PiShellClipboardContent, PiShellCommandMessagePresentation, PiShellComponentPort, PiShellEditorBodyGeometry, PiShellEditorOptions, PiShellEditorPointerEvent, PiShellEditorPort, PiShellEditorTextRange, PiShellExtensionRendererResolver, PiShellHeaderOptions, PiShellHeaderPort, PiShellHotkeysPresentation, PiShellImageAssetResolver, PiShellLoadedResourcesPort, PiShellLoginDialogPort, PiShellModelSelectorOptions, PiShellModelsDialogOptions, PiShellModelsDialogPort, PiShellPasteReservation, PiShellQueuedInputPort, PiShellResourceEntry, PiShellResourceSection, PiShellScopedModelDescriptor, PiShellScopedModelsSelectorOptions, PiShellScopedModelsSelectorPort, PiShellSelectorOption, PiShellSelectorOptions, PiShellSessionInfoPresentation, PiShellSettingsSelectorOptions, PiShellStartupNotice, PiShellStatusPlacement, PiShellStatusPort, PiShellSubmittedPromptComposer, PiShellTranscriptComponentPort, PiShellViewComponentPort, } from "./shell-components.js";
|
|
10
|
-
export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiThemeName, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, stopPiThemeWatcher, } from "./theme.js";
|
|
11
|
-
export type { PiColorMode, PiTerminalTheme, PiTerminalThemeDetection, PiTerminalThemeDetector, PiThemeBackground, PiThemeResult } from "./theme.js";
|
|
10
|
+
export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiAccentColor, currentPiThemeName, derivePiAccentProjection, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, setPiAccentColor, setPiPackageBorderProjectionEnabled, stopPiThemeWatcher, } from "./theme.js";
|
|
11
|
+
export type { PiAccentProjection, PiColorMode, PiTerminalTheme, PiTerminalThemeDetection, PiTerminalThemeDetector, PiThemeBackground, PiThemeResult } from "./theme.js";
|
|
12
12
|
export { OwnedPiThemeController } from "./upstream/theme/theme-controller.js";
|
|
13
13
|
export type { PiThemeRuntimePort, PiThemeSettingsPort } from "./upstream/theme/theme-controller.js";
|
|
14
14
|
export { PI_MODAL_CONTENT_PADDING_X, PiModalFrame, PiModalHeader, addPiModalHeader, adoptPiModalFrame, adoptPiModalHeader, } from "./modal-frame.js";
|
|
@@ -4,7 +4,7 @@ export { PiComponentConformanceError, runPiComponentConformance } from "./confor
|
|
|
4
4
|
export { createPiShellOperationLoader, createPiShellShareOperationDialog, } from "./share-operation-dialog.js";
|
|
5
5
|
export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, componentFromPort, componentPort, createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellShowImagesSelector, createPiShellSkillsSelector, createPiShellStatus, createPiShellThemeSelector, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, createTuiFacade, ensureTheme, formatSessionTokens, isAutocompleteProvider, isPiPromptStyleCompaction, isRecord, paintPiSubmittedPromptTimestamp, piShellHyperlink, piShellTruncateToWidth, piShellVisibleWidth, renderPiShellChangelogLines, renderPiShellCommandMessage, renderPiShellHotkeysLines, renderPiShellPackageUpdateNotice, renderPiShellReleaseUpdateBanner, renderPiShellReleaseUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, validatedAssistantMessage, } from "./shell-components.js";
|
|
6
6
|
export { renderPiShellHotkeySections } from "./shell-hotkey-sections.js";
|
|
7
|
-
export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiThemeName, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, stopPiThemeWatcher, } from "./theme.js";
|
|
7
|
+
export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiAccentColor, currentPiThemeName, derivePiAccentProjection, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, setPiAccentColor, setPiPackageBorderProjectionEnabled, stopPiThemeWatcher, } from "./theme.js";
|
|
8
8
|
export { OwnedPiThemeController } from "./upstream/theme/theme-controller.js";
|
|
9
9
|
export { PI_MODAL_CONTENT_PADDING_X, PiModalFrame, PiModalHeader, addPiModalHeader, adoptPiModalFrame, adoptPiModalHeader, } from "./modal-frame.js";
|
|
10
10
|
export { ModelsDialogComponent } from "./models-dialog.js";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { PiShellComponentPort } from "./shell-shared-facade.js";
|
|
2
|
+
import type { ThinkingSelectorLevel } from "./upstream/components/thinking-selector.js";
|
|
3
|
+
import type { FilterMode } from "./upstream/components/tree-selector.js";
|
|
4
|
+
type ThinkingSelectorModule = typeof import("./thinking-selector-dialog.js");
|
|
5
|
+
type TreeSelectorModule = typeof import("./upstream/components/tree-selector.js");
|
|
6
|
+
export interface PiShellLazyThinkingSelectorOptions {
|
|
7
|
+
readonly currentLevel: ThinkingSelectorLevel;
|
|
8
|
+
readonly availableLevels: readonly ThinkingSelectorLevel[];
|
|
9
|
+
readonly onSelect: (level: ThinkingSelectorLevel) => void;
|
|
10
|
+
readonly onCancel: () => void;
|
|
11
|
+
readonly onSelectAsDefault?: (level: ThinkingSelectorLevel) => void;
|
|
12
|
+
readonly defaultLevel?: ThinkingSelectorLevel;
|
|
13
|
+
readonly presentation?: {
|
|
14
|
+
readonly profile: "bare";
|
|
15
|
+
readonly cycleBinding: string | readonly string[];
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface PiShellLazyTreeSelectorOptions {
|
|
19
|
+
readonly tree: readonly unknown[];
|
|
20
|
+
readonly currentLeafId: string | null;
|
|
21
|
+
readonly terminalHeight: number;
|
|
22
|
+
readonly onSelect: (id: string) => void;
|
|
23
|
+
readonly onCancel: () => void;
|
|
24
|
+
readonly onLabelChange: (entryId: string, label: string | undefined) => void;
|
|
25
|
+
readonly onCopy?: (text: string | undefined) => void;
|
|
26
|
+
readonly initialSelectedId?: string;
|
|
27
|
+
readonly initialFilterMode?: FilterMode;
|
|
28
|
+
}
|
|
29
|
+
export interface PiShellLazySelectorLoader {
|
|
30
|
+
prepare(): Promise<void>;
|
|
31
|
+
createThinking(options: PiShellLazyThinkingSelectorOptions): Promise<PiShellComponentPort>;
|
|
32
|
+
createTree(options: PiShellLazyTreeSelectorOptions): Promise<PiShellComponentPort>;
|
|
33
|
+
}
|
|
34
|
+
export interface PiShellLazySelectorImports {
|
|
35
|
+
readonly thinking: () => Promise<ThinkingSelectorModule>;
|
|
36
|
+
readonly tree: () => Promise<TreeSelectorModule>;
|
|
37
|
+
}
|
|
38
|
+
/** Builds one idempotent selector loader; fulfilled, in-flight, and rejected imports remain shared. */
|
|
39
|
+
export declare function createPiShellLazySelectorLoader(imports?: PiShellLazySelectorImports): PiShellLazySelectorLoader;
|
|
40
|
+
/** Production selector loader, dynamically reached only after the first input-ready frame. */
|
|
41
|
+
export declare const piShellLazySelectors: PiShellLazySelectorLoader;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { componentPort, ensureTheme } from "./shell-shared-facade.js";
|
|
2
|
+
const DEFAULT_IMPORTS = {
|
|
3
|
+
thinking: () => import("./thinking-selector-dialog.js"),
|
|
4
|
+
tree: () => import("./upstream/components/tree-selector.js"),
|
|
5
|
+
};
|
|
6
|
+
/** Builds one idempotent selector loader; fulfilled, in-flight, and rejected imports remain shared. */
|
|
7
|
+
export function createPiShellLazySelectorLoader(imports = DEFAULT_IMPORTS) {
|
|
8
|
+
let thinkingSelectorModule;
|
|
9
|
+
let treeSelectorModule;
|
|
10
|
+
const loadThinkingSelector = () => thinkingSelectorModule ??= imports.thinking();
|
|
11
|
+
const loadTreeSelector = () => treeSelectorModule ??= imports.tree();
|
|
12
|
+
return {
|
|
13
|
+
async prepare() {
|
|
14
|
+
// Performance: allSettled observes background failures while retaining each rejected module for explicit route recovery.
|
|
15
|
+
await Promise.allSettled([loadThinkingSelector(), loadTreeSelector()]);
|
|
16
|
+
},
|
|
17
|
+
async createThinking(options) {
|
|
18
|
+
const { createPiShellThinkingSelector } = await loadThinkingSelector();
|
|
19
|
+
return createPiShellThinkingSelector(options.currentLevel, options.availableLevels, options.onSelect, options.onCancel, options.onSelectAsDefault, options.defaultLevel, options.presentation);
|
|
20
|
+
},
|
|
21
|
+
async createTree(options) {
|
|
22
|
+
ensureTheme();
|
|
23
|
+
const { TreeSelectorComponent } = await loadTreeSelector();
|
|
24
|
+
const selector = new TreeSelectorComponent([...options.tree], options.currentLeafId, options.terminalHeight, options.onSelect, options.onCancel, options.onLabelChange, options.initialSelectedId, options.initialFilterMode);
|
|
25
|
+
if (options.onCopy)
|
|
26
|
+
selector.onCopy = options.onCopy;
|
|
27
|
+
return componentPort(selector);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Production selector loader, dynamically reached only after the first input-ready frame. */
|
|
32
|
+
export const piShellLazySelectors = createPiShellLazySelectorLoader();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CancellableLoader, Container, Spacer, Text } from "@earendil-works/pi-tui";
|
|
2
2
|
import { DynamicBorder } from "../startup-public.js";
|
|
3
|
-
import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalShortcutHints } from "./theme.js";
|
|
3
|
+
import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalShortcutHints } from "./theme.js";
|
|
4
4
|
export const PI_MODAL_CONTENT_PADDING_X = 1;
|
|
5
5
|
/** Adds the standard navigation/select/close footer before a dependency component's bottom rule. */
|
|
6
6
|
export function addPiModalSelectFooter(container) {
|
|
@@ -14,14 +14,13 @@ export class PiCancellableOperationFrame extends Container {
|
|
|
14
14
|
constructor(tui, message) {
|
|
15
15
|
super();
|
|
16
16
|
const theme = piTheme();
|
|
17
|
-
const border = (text) => theme.fg("border", text);
|
|
18
17
|
this.#loader = new CancellableLoader(tui, text => theme.fg("accent", text), text => theme.fg("muted", text), message);
|
|
19
|
-
this.addChild(new DynamicBorder(
|
|
18
|
+
this.addChild(new DynamicBorder(paintPiBorder));
|
|
20
19
|
this.addChild(this.#loader);
|
|
21
20
|
this.addChild(new Spacer(1));
|
|
22
21
|
this.addChild(new Text(renderPiModalShortcutHints([DIALOG_CLOSE_SHORTCUT_HINT]), 0, 0));
|
|
23
22
|
this.addChild(new Spacer(1));
|
|
24
|
-
this.addChild(new DynamicBorder(
|
|
23
|
+
this.addChild(new DynamicBorder(paintPiBorder));
|
|
25
24
|
adoptPiModalFrame(this, { topIndex: 0, bottomIndex: this.children.length - 1 });
|
|
26
25
|
}
|
|
27
26
|
get signal() { return this.#loader.signal; }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Input, getKeybindings, matchesKey, truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
|
|
2
2
|
import { DynamicBorder } from "../startup-public.js";
|
|
3
3
|
import { PiModalFrame } from "./modal-frame.js";
|
|
4
|
-
import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalListRow, renderPiModalShortcutHints, } from "./theme.js";
|
|
4
|
+
import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalListRow, renderPiModalShortcutHints, } from "./theme.js";
|
|
5
5
|
function renderHintsWithClose(entries, width) {
|
|
6
6
|
const body = renderPiModalShortcutHints(entries.slice(0, -1));
|
|
7
7
|
const close = renderPiModalShortcutHints([DIALOG_CLOSE_SHORTCUT_HINT]);
|
|
@@ -51,7 +51,7 @@ export class ModelsDialogComponent {
|
|
|
51
51
|
invalidate: () => this.#input.invalidate(),
|
|
52
52
|
render: width => this.#renderBody(width),
|
|
53
53
|
};
|
|
54
|
-
#frame = new PiModalFrame(new DynamicBorder(), [this.#title, this.#body], new DynamicBorder());
|
|
54
|
+
#frame = new PiModalFrame(new DynamicBorder(paintPiBorder), [this.#title, this.#body], new DynamicBorder(paintPiBorder));
|
|
55
55
|
#callbacks;
|
|
56
56
|
#models = [];
|
|
57
57
|
#activeModelId;
|
|
@@ -286,9 +286,9 @@ export class ModelsDialogComponent {
|
|
|
286
286
|
const rows = this.#rows();
|
|
287
287
|
this.#clampSelection(rows);
|
|
288
288
|
push(theme.fg("dim", "Filter: ")
|
|
289
|
-
+ theme.fg(this.#filter === "all" ? "
|
|
289
|
+
+ theme.fg(this.#filter === "all" ? "mdHeading" : "dim", "all")
|
|
290
290
|
+ theme.fg("dim", " | ")
|
|
291
|
-
+ theme.fg(this.#filter === "scoped" ? "
|
|
291
|
+
+ theme.fg(this.#filter === "scoped" ? "mdHeading" : "dim", "scoped"));
|
|
292
292
|
push();
|
|
293
293
|
for (const line of this.#input.render(width))
|
|
294
294
|
push(line);
|
|
@@ -305,7 +305,7 @@ export class ModelsDialogComponent {
|
|
|
305
305
|
const scoped = this.#scopeIds.includes(row.fullId);
|
|
306
306
|
// Invariant: arrow, scope marker, model id, [provider], then the active checkmark.
|
|
307
307
|
const prefix = selected ? theme.fg("accent", "→ ") : " ";
|
|
308
|
-
const marker = scoped ? theme.fg("
|
|
308
|
+
const marker = scoped ? theme.fg("text", "●") : theme.fg("dim", "○");
|
|
309
309
|
const label = selected ? theme.fg("text", row.model.id) : row.model.id;
|
|
310
310
|
const provider = theme.fg("muted", `[${row.model.provider}]`);
|
|
311
311
|
const active = row.fullId === this.#activeModelId ? ` ${theme.fg("success", "✓")}` : "";
|
|
@@ -10,6 +10,7 @@ export interface PiShellPromptInputBody {
|
|
|
10
10
|
readonly topRule?: string | undefined;
|
|
11
11
|
readonly bottomRule?: string | undefined;
|
|
12
12
|
readonly after?: readonly string[];
|
|
13
|
+
readonly afterIndent?: number;
|
|
13
14
|
}
|
|
14
15
|
export interface PiShellPromptInputPresentation {
|
|
15
16
|
geometry(width: number, padding?: number): PiShellPromptInputGeometry;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.0
|
|
3
|
-
* commit
|
|
2
|
+
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
|
|
3
|
+
* commit abe508e1b89912adde45528136c3221eb69acdd7.
|
|
4
4
|
* Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
|
|
5
5
|
* Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
|
|
6
6
|
* Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.0
|
|
3
|
-
* commit
|
|
2
|
+
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.1.0 (MIT),
|
|
3
|
+
* commit abe508e1b89912adde45528136c3221eb69acdd7.
|
|
4
4
|
* Upstream dark.json SHA-256: c11a588b714d35300293079b425fb09a3693d4b2d453585d211b08163c648b75
|
|
5
5
|
* Upstream light.json SHA-256: f590c51c2bc8b238891efd0e983473ed2e2a6487b6692cc1d4b2845165e703f7
|
|
6
6
|
* Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CancellableLoader, Spacer, Text, } from "@earendil-works/pi-tui";
|
|
2
2
|
import { BorderedLoader, DynamicBorder } from "../startup-public.js";
|
|
3
3
|
import { adoptPiModalFrame, PiModalFrame } from "./modal-frame.js";
|
|
4
|
-
import { DIALOG_CLOSE_SHORTCUT_HINT, piTheme, renderPiModalShortcutHints } from "./theme.js";
|
|
4
|
+
import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, piTheme, renderPiModalShortcutHints } from "./theme.js";
|
|
5
5
|
import { componentPort, createTuiFacade, ensureTheme, } from "./shell-shared-facade.js";
|
|
6
6
|
/** Bare A1's titled share progress surface; the pinned comparison keeps its bordered loader. */
|
|
7
7
|
class ShareOperationDialog {
|
|
@@ -10,12 +10,12 @@ class ShareOperationDialog {
|
|
|
10
10
|
constructor(runtime, message) {
|
|
11
11
|
const theme = piTheme();
|
|
12
12
|
this.#loader = new CancellableLoader(createTuiFacade(runtime), text => theme.fg("accent", text), text => theme.fg("muted", text), message);
|
|
13
|
-
this.#frame = new PiModalFrame(new DynamicBorder(
|
|
13
|
+
this.#frame = new PiModalFrame(new DynamicBorder(paintPiBorder), [
|
|
14
14
|
new Text(theme.fg("accent", theme.bold("Share")), 0, 0),
|
|
15
15
|
this.#loader,
|
|
16
16
|
new Spacer(1),
|
|
17
17
|
new Text(renderPiModalShortcutHints([DIALOG_CLOSE_SHORTCUT_HINT]), 0, 0),
|
|
18
|
-
], new DynamicBorder(
|
|
18
|
+
], new DynamicBorder(paintPiBorder));
|
|
19
19
|
}
|
|
20
20
|
get signal() { return this.#loader.signal; }
|
|
21
21
|
invalidate() { this.#frame.invalidate(); }
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { getSelectListTheme } from "../startup-public.js";
|
|
2
1
|
import { CombinedAutocompleteProvider, matchesKey, setKeybindings, visibleWidth, } from "@earendil-works/pi-tui";
|
|
3
2
|
import { PROMPT_HISTORY_EDITOR_REPLACEMENT } from "../../../contracts/owned-ui/index.js";
|
|
4
3
|
import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
|
|
5
4
|
import { OwnedEditor } from "./upstream/components/owned-editor.js";
|
|
6
5
|
import { OwnedEditorUxInterception, createPromptSelectionInterceptor, editorVisualLineCount, } from "./owned-editor-ux.js";
|
|
7
|
-
import { PINNED_PI_LAYOUT, piTheme, renderPiListSelection, } from "./theme.js";
|
|
6
|
+
import { PINNED_PI_LAYOUT, getPiSelectListTheme, piTheme, renderPiListSelection, } from "./theme.js";
|
|
8
7
|
import { createTuiFacade, ensureTheme, isAutocompleteProvider, } from "./shell-shared-facade.js";
|
|
9
8
|
import { SKILLS_COMMAND_NAME, collapseSkillCommands, createSkillsTunnelProvider, } from "./skills-command.js";
|
|
10
9
|
/** A selected autocomplete row: its arrow/primary column, then the aligned description. */
|
|
11
10
|
const SELECTED_DESCRIBED_ROW = /^(→ .*?\S)(\s{2,}.*)$/u;
|
|
11
|
+
const INPUT_COUNTER_INSET = 3;
|
|
12
|
+
const INPUT_COUNTER_PREFIX = "── ";
|
|
12
13
|
function renderOwnedAutocompleteSelection(text) {
|
|
13
14
|
const theme = piTheme();
|
|
14
15
|
const row = SELECTED_DESCRIBED_ROW.exec(text);
|
|
@@ -70,7 +71,7 @@ export function createPiShellEditor(options) {
|
|
|
70
71
|
throw new Error("Persistent history requires the loaded owned editor");
|
|
71
72
|
}
|
|
72
73
|
const scrollInfo = { emitted: false, counter: undefined };
|
|
73
|
-
const selectListTheme =
|
|
74
|
+
const selectListTheme = getPiSelectListTheme();
|
|
74
75
|
let tunnelSkills = [];
|
|
75
76
|
const EditorClass = options.keybindingProfile === "a1" && options.persistentHistory === true ? options.historyEditor : OwnedEditor;
|
|
76
77
|
const editor = new EditorClass(tui, {
|
|
@@ -234,10 +235,10 @@ export function createPiShellEditor(options) {
|
|
|
234
235
|
const rowCount = editor.getRenderedBodyRowCount();
|
|
235
236
|
const menu = rows.slice(rowCount, scrollInfo.emitted ? -1 : undefined);
|
|
236
237
|
const label = scrollInfo.counter === undefined ? "" : `${scrollInfo.counter} `;
|
|
237
|
-
// Compatibility:
|
|
238
|
-
const counterBorder = label.length > 0 &&
|
|
239
|
-
? editor.borderColor(
|
|
240
|
-
+ editor.borderColor("─".repeat(width -
|
|
238
|
+
// Compatibility: share the history counter's three-cell inset and dim label style.
|
|
239
|
+
const counterBorder = label.length > 0 && INPUT_COUNTER_INSET + visibleWidth(label) <= width
|
|
240
|
+
? editor.borderColor(INPUT_COUNTER_PREFIX) + piTheme().fg("dim", label)
|
|
241
|
+
+ editor.borderColor("─".repeat(width - INPUT_COUNTER_INSET - visibleWidth(label)))
|
|
241
242
|
: editor.borderColor("─".repeat(width));
|
|
242
243
|
// Rationale: when the menu is open, drop the plain top border above the
|
|
243
244
|
// menu and instead show the counter on the border directly above the input
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type ExtensionUIContext } from "../startup-public.js";
|
|
2
|
+
import type { ProgramStatusBlocked } from "./upstream/program-status-reporter.js";
|
|
2
3
|
import type { OwnedUiExtensionOverlayHandle, OwnedUiExtensionOverlayOptions } from "../../../contracts/owned-ui/index.js";
|
|
3
4
|
import { type PiShellComponentPort, type PiShellEditorOptions } from "./shell-shared-facade.js";
|
|
4
5
|
export interface PiExtensionUiBridgeHost {
|
|
5
6
|
readonly runtime: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">;
|
|
6
7
|
readonly agentDir?: string;
|
|
7
8
|
setInputSurface(component: PiShellComponentPort | null): void;
|
|
9
|
+
setProgramStatusBlocked(status: ProgramStatusBlocked | undefined): void;
|
|
8
10
|
showOverlay(component: PiShellComponentPort, options?: OwnedUiExtensionOverlayOptions): OwnedUiExtensionOverlayHandle;
|
|
9
11
|
listenInput(handler: (data: string) => {
|
|
10
12
|
readonly consume?: boolean;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {} from "../startup-public.js";
|
|
2
2
|
import { ExtensionEditorComponent } from "./upstream/components/extension-editor.js";
|
|
3
3
|
import { ExtensionInputComponent } from "./upstream/components/extension-input.js";
|
|
4
4
|
import { ExtensionSelectorComponent } from "./upstream/components/extension-selector.js";
|
|
5
5
|
import { setKeybindings, Text, } from "@earendil-works/pi-tui";
|
|
6
6
|
import { KeybindingsManager, } from "./upstream/adjacent/core/keybindings.js";
|
|
7
|
-
import { PINNED_PI_LAYOUT, applyPiTheme, applyPiThemeInstance, getAvailablePiThemes, loadPiTheme, piTheme, } from "./theme.js";
|
|
7
|
+
import { PINNED_PI_LAYOUT, applyPiTheme, applyPiThemeInstance, getAvailablePiThemes, getPiSelectListTheme, loadPiTheme, piTheme, } from "./theme.js";
|
|
8
8
|
import { componentPort, createTuiFacade, ensureTheme, isRecord, withPiDialogCancel, } from "./shell-shared-facade.js";
|
|
9
9
|
/** Public ExtensionUIContext ported from pinned InteractiveMode without constructing it. */
|
|
10
10
|
export function createPiExtensionUiBridge(host) {
|
|
@@ -45,7 +45,7 @@ export function createPiExtensionUiBridge(host) {
|
|
|
45
45
|
disposers.delete(dispose);
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
|
-
const showInput = (create, options, retainSurfaceOnSettle = false) => new Promise(resolve => {
|
|
48
|
+
const showInput = (create, options, retainSurfaceOnSettle = false, blocked) => new Promise(resolve => {
|
|
49
49
|
let settled = false;
|
|
50
50
|
let surface;
|
|
51
51
|
let untrack = () => { };
|
|
@@ -56,10 +56,13 @@ export function createPiExtensionUiBridge(host) {
|
|
|
56
56
|
if (activeCancel === cancel)
|
|
57
57
|
activeCancel = undefined;
|
|
58
58
|
untrack();
|
|
59
|
-
|
|
59
|
+
const ownedSurface = activeSurface === surface;
|
|
60
|
+
if (retainSurfaceOnSettle && ownedSurface)
|
|
60
61
|
activeSurface = undefined;
|
|
61
62
|
else
|
|
62
63
|
closeSurface(surface);
|
|
64
|
+
if (ownedSurface)
|
|
65
|
+
host.setProgramStatusBlocked(undefined);
|
|
63
66
|
resolve(value);
|
|
64
67
|
};
|
|
65
68
|
const cancel = () => finish(undefined);
|
|
@@ -68,6 +71,7 @@ export function createPiExtensionUiBridge(host) {
|
|
|
68
71
|
if (!settled) {
|
|
69
72
|
activeCancel = cancel;
|
|
70
73
|
mountSurface(surface);
|
|
74
|
+
host.setProgramStatusBlocked(blocked);
|
|
71
75
|
}
|
|
72
76
|
});
|
|
73
77
|
const createFactoryComponent = (factory, ...arguments_) => {
|
|
@@ -85,14 +89,19 @@ export function createPiExtensionUiBridge(host) {
|
|
|
85
89
|
tui,
|
|
86
90
|
...(opts?.timeout === undefined ? {} : { timeout: opts.timeout }),
|
|
87
91
|
onToggleToolsExpanded: () => host.setToolsExpanded(!host.getToolsExpanded()),
|
|
88
|
-
})), opts),
|
|
92
|
+
})), opts, false, { kind: "question", message: title }),
|
|
89
93
|
async confirm(title, message, opts) {
|
|
90
|
-
|
|
94
|
+
const selected = await showInput((resolve, cancel) => componentPort(new ExtensionSelectorComponent(`${title}\n${message}`, ["Yes", "No"], resolve, cancel, {
|
|
95
|
+
tui,
|
|
96
|
+
...(opts?.timeout === undefined ? {} : { timeout: opts.timeout }),
|
|
97
|
+
onToggleToolsExpanded: () => host.setToolsExpanded(!host.getToolsExpanded()),
|
|
98
|
+
})), opts, false, { kind: "permission", message: title });
|
|
99
|
+
return selected === "Yes";
|
|
91
100
|
},
|
|
92
101
|
input: (title, placeholder, opts) => showInput((resolve, cancel) => componentPort(new ExtensionInputComponent(title, placeholder, resolve, cancel, {
|
|
93
102
|
tui,
|
|
94
103
|
...(opts?.timeout === undefined ? {} : { timeout: opts.timeout }),
|
|
95
|
-
})), opts),
|
|
104
|
+
})), opts, false, { kind: "question", message: title }),
|
|
96
105
|
notify: (message, type = "info") => host.notify(message, type),
|
|
97
106
|
onTerminalInput: handler => host.listenInput(handler),
|
|
98
107
|
setStatus: (key, text) => host.setStatus(key, text),
|
|
@@ -196,7 +205,7 @@ export function createPiExtensionUiBridge(host) {
|
|
|
196
205
|
pasteToEditor: text => host.pasteToEditor(text),
|
|
197
206
|
setEditorText: text => host.setEditorText(text),
|
|
198
207
|
getEditorText: () => host.getEditorText(),
|
|
199
|
-
editor: (title, prefill) => showInput((resolve, cancel) => componentPort(new ExtensionEditorComponent(tui, keybindings, title, prefill, resolve, cancel))),
|
|
208
|
+
editor: (title, prefill) => showInput((resolve, cancel) => componentPort(new ExtensionEditorComponent(tui, keybindings, title, prefill, resolve, cancel)), undefined, false, { kind: "question", message: title }),
|
|
200
209
|
addAutocompleteProvider: factory => host.addAutocompleteProvider(factory),
|
|
201
210
|
setEditorComponent(factory) {
|
|
202
211
|
customEditorFactory = factory;
|
|
@@ -207,7 +216,7 @@ export function createPiExtensionUiBridge(host) {
|
|
|
207
216
|
try {
|
|
208
217
|
const editor = Reflect.apply(factory, undefined, [tui, {
|
|
209
218
|
borderColor: (text) => piTheme().fg("borderMuted", text),
|
|
210
|
-
selectList:
|
|
219
|
+
selectList: getPiSelectListTheme(),
|
|
211
220
|
}, keybindings]);
|
|
212
221
|
if (!isComponent(editor))
|
|
213
222
|
throw new TypeError("extension editor factory returned a malformed editor");
|
|
@@ -247,10 +256,11 @@ export function createPiExtensionUiBridge(host) {
|
|
|
247
256
|
activeSurface?.dispose?.();
|
|
248
257
|
activeSurface = undefined;
|
|
249
258
|
host.setInputSurface(null);
|
|
259
|
+
host.setProgramStatusBlocked(undefined);
|
|
250
260
|
};
|
|
251
261
|
return {
|
|
252
262
|
context,
|
|
253
|
-
input: (title, placeholder, options) => showInput((resolve, cancel) => componentPort(new ExtensionInputComponent(title, placeholder, resolve, cancel, { tui })), undefined, options?.retainSurfaceOnSettle === true),
|
|
263
|
+
input: (title, placeholder, options) => showInput((resolve, cancel) => componentPort(new ExtensionInputComponent(title, placeholder, resolve, cancel, { tui })), undefined, options?.retainSurfaceOnSettle === true, { kind: "question", message: title }),
|
|
254
264
|
reset,
|
|
255
265
|
dispose() {
|
|
256
266
|
reset();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPiHotkeysMarkdownTheme } from "./theme.js";
|
|
2
2
|
import { Markdown } from "@earendil-works/pi-tui";
|
|
3
3
|
import { ensureTheme } from "./shell-shared-facade.js";
|
|
4
4
|
import { hotkeysMarkdown } from "./shell-presenters-info.js";
|
|
@@ -19,7 +19,7 @@ export function renderPiShellHotkeySections(presentation, width) {
|
|
|
19
19
|
while (section.lines.at(-1) === "")
|
|
20
20
|
section.lines.pop();
|
|
21
21
|
return sections.map(section => {
|
|
22
|
-
const rows = [...new Markdown(section.lines.join("\n"), 1, 1,
|
|
22
|
+
const rows = [...new Markdown(section.lines.join("\n"), 1, 1, getPiHotkeysMarkdownTheme()).render(width)];
|
|
23
23
|
while (rows[0]?.trim().length === 0)
|
|
24
24
|
rows.shift();
|
|
25
25
|
while (rows.at(-1)?.trim().length === 0)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DynamicBorder
|
|
1
|
+
import { DynamicBorder } from "../startup-public.js";
|
|
2
2
|
import { Container, getCapabilities, hyperlink, Markdown, Spacer, Text, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
3
|
import { PRODUCT_TEXT } from "../../../product-identity.js";
|
|
4
4
|
import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
|
|
5
|
-
import { PINNED_PI_LAYOUT, piTheme } from "./theme.js";
|
|
5
|
+
import { getPiHotkeysMarkdownTheme, getPiMarkdownTheme, paintPiBorder, PINNED_PI_LAYOUT, piTheme } from "./theme.js";
|
|
6
6
|
import { componentPort, ensureTheme, formatSessionTokens } from "./shell-shared-facade.js";
|
|
7
7
|
export function renderPiShellStatusText(message, width, outputPad = PINNED_PI_LAYOUT.outputPad) {
|
|
8
8
|
ensureTheme();
|
|
@@ -116,20 +116,20 @@ export function createPiShellCollapsedChangelog() {
|
|
|
116
116
|
ensureTheme();
|
|
117
117
|
const container = new Container();
|
|
118
118
|
container.addChild(new Spacer(1));
|
|
119
|
-
container.addChild(new DynamicBorder());
|
|
119
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
120
120
|
container.addChild(new Text(`${piTheme().bold(piTheme().fg("accent", "What's New"))}\n${piTheme().fg("muted", "Run /changelog to view the full release notes.")}`, 1, 0));
|
|
121
|
-
container.addChild(new DynamicBorder());
|
|
121
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
122
122
|
return componentPort(container);
|
|
123
123
|
}
|
|
124
124
|
export function createPiShellChangelog(markdown) {
|
|
125
125
|
ensureTheme();
|
|
126
126
|
const container = new Container();
|
|
127
127
|
container.addChild(new Spacer(1));
|
|
128
|
-
container.addChild(new DynamicBorder());
|
|
128
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
129
129
|
container.addChild(new Text(piTheme().bold(piTheme().fg("accent", "What's New")), 1, 0));
|
|
130
130
|
container.addChild(new Spacer(1));
|
|
131
131
|
container.addChild(changelogMarkdown(markdown));
|
|
132
|
-
container.addChild(new DynamicBorder());
|
|
132
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
133
133
|
return componentPort(container);
|
|
134
134
|
}
|
|
135
135
|
/** The changelog document rows the feed presenter shows, without its spacer, borders, and heading. */
|
|
@@ -138,7 +138,7 @@ export function renderPiShellChangelogLines(markdown, width) {
|
|
|
138
138
|
return changelogMarkdown(markdown).render(width);
|
|
139
139
|
}
|
|
140
140
|
function changelogMarkdown(markdown) {
|
|
141
|
-
return new Markdown(markdown.trim() || "No changelog entries found.", 1, 1,
|
|
141
|
+
return new Markdown(markdown.trim() || "No changelog entries found.", 1, 1, getPiMarkdownTheme());
|
|
142
142
|
}
|
|
143
143
|
function shortcutDisplay(key) {
|
|
144
144
|
// Platform: pinned Pi labels Alt as Option on macOS, including extension shortcuts.
|
|
@@ -152,11 +152,11 @@ export function createPiShellHotkeys(bindings, getShortcuts = () => [], profile
|
|
|
152
152
|
const markdown = hotkeysMarkdown(bindings, getShortcuts, profile);
|
|
153
153
|
const container = new Container();
|
|
154
154
|
container.addChild(new Spacer(1));
|
|
155
|
-
container.addChild(new DynamicBorder());
|
|
155
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
156
156
|
container.addChild(new Text(piTheme().bold(piTheme().fg("accent", "Keyboard Shortcuts")), 1, 0));
|
|
157
157
|
container.addChild(new Spacer(1));
|
|
158
158
|
container.addChild(hotkeysMarkdownComponent(markdown));
|
|
159
|
-
container.addChild(new DynamicBorder());
|
|
159
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
160
160
|
return componentPort(container);
|
|
161
161
|
}
|
|
162
162
|
/** The keyboard-shortcut document rows the feed presenter shows, without its spacer, borders, and heading. */
|
|
@@ -165,7 +165,7 @@ export function renderPiShellHotkeysLines(presentation, width) {
|
|
|
165
165
|
return hotkeysMarkdownComponent(hotkeysMarkdown(presentation.bindings, presentation.getShortcuts ?? (() => []), presentation.profile ?? "pi")).render(width);
|
|
166
166
|
}
|
|
167
167
|
function hotkeysMarkdownComponent(markdown) {
|
|
168
|
-
return new Markdown(markdown, 1, 1,
|
|
168
|
+
return new Markdown(markdown, 1, 1, getPiHotkeysMarkdownTheme());
|
|
169
169
|
}
|
|
170
170
|
export function hotkeysMarkdown(bindings, getShortcuts, profile) {
|
|
171
171
|
const keys = profile === "a1" ? KeybindingsManager.fromOwnedBindings(bindings) : new KeybindingsManager(bindings);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssistantMessageComponent, BashExecutionComponent, CompactionSummaryMessageComponent, CustomMessageComponent, DynamicBorder,
|
|
1
|
+
import { AssistantMessageComponent, BashExecutionComponent, CompactionSummaryMessageComponent, CustomMessageComponent, DynamicBorder, parseSkillBlock, UserMessageComponent, } from "../startup-public.js";
|
|
2
2
|
import { ToolExecutionComponent } from "./upstream/components/tool-execution.js";
|
|
3
3
|
import { SkillInvocationMessageComponent } from "./upstream/components/skill-invocation-message.js";
|
|
4
4
|
import { piToolArguments as toolArguments, updatePiToolResult as updateToolResult } from "./tool-result-adapter.js";
|
|
@@ -7,7 +7,7 @@ import { createMermaidMarkdownTransformer } from "./upstream/components/mermaid.
|
|
|
7
7
|
import { Container, Image, Spacer, Text, } from "@earendil-works/pi-tui";
|
|
8
8
|
import { createPiSubmittedPromptComponent, isPiPromptStyleCompaction, } from "./submitted-prompt-adapter.js";
|
|
9
9
|
export { isPiPromptStyleCompaction, paintPiSubmittedPromptTimestamp } from "./submitted-prompt-adapter.js";
|
|
10
|
-
import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
|
|
10
|
+
import { getPiMarkdownTheme, PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
|
|
11
11
|
import { componentPort, createTuiFacade, ensureTheme, isRecord, } from "./shell-shared-facade.js";
|
|
12
12
|
export function createPiShellTranscriptComponent(initial, cwd, extensions, submittedPrompt, initialOutputPad = PINNED_PI_LAYOUT.outputPad, initialHideThinkingBlock = false, initialMermaidRenderingMode = "off", initialShowImages = true, initialImageWidthCells = 80, imageAssets, presentation) {
|
|
13
13
|
ensureTheme();
|
|
@@ -146,7 +146,7 @@ function withTranscriptImages(component, block, assets, showImages, imageWidthCe
|
|
|
146
146
|
}
|
|
147
147
|
function renderWithOutputPad(component, kind, width, outputPad) {
|
|
148
148
|
const rows = component.render(width);
|
|
149
|
-
if (outputPad !== 0 ||
|
|
149
|
+
if (outputPad !== 0 || kind !== "bash")
|
|
150
150
|
return rows;
|
|
151
151
|
return rows.map(row => row.startsWith(" ") ? row.slice(1) : row);
|
|
152
152
|
}
|
|
@@ -177,7 +177,7 @@ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt,
|
|
|
177
177
|
const skill = parseSkillBlock(visibleBlock.text);
|
|
178
178
|
if (!skill)
|
|
179
179
|
return submittedPrompt ? createPiSubmittedPromptComponent(visibleBlock, submittedPrompt) : new UserMessageComponent(visibleBlock.text);
|
|
180
|
-
const invocation = new SkillInvocationMessageComponent(skill,
|
|
180
|
+
const invocation = new SkillInvocationMessageComponent(skill, getPiMarkdownTheme(), outputPad);
|
|
181
181
|
invocation.setExpanded(expanded);
|
|
182
182
|
if (!skill.userMessage)
|
|
183
183
|
return invocation;
|
|
@@ -192,7 +192,7 @@ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt,
|
|
|
192
192
|
return assistantComponent(block, outputPad, hideThinkingBlock, mermaidRenderingMode);
|
|
193
193
|
case "tool-call":
|
|
194
194
|
case "tool-result": {
|
|
195
|
-
const component = toolComponent(block, cwd, extensions, showImages, imageWidthCells, imageAssets, tui);
|
|
195
|
+
const component = toolComponent(block, cwd, extensions, outputPad, showImages, imageWidthCells, imageAssets, tui);
|
|
196
196
|
component.setExpanded(expanded);
|
|
197
197
|
return component;
|
|
198
198
|
}
|
|
@@ -206,7 +206,7 @@ function transcriptComponent(block, cwd, expanded, extensions, submittedPrompt,
|
|
|
206
206
|
summary: block.text,
|
|
207
207
|
tokensBefore: numericPayload(block, "tokensBefore"),
|
|
208
208
|
timestamp: numericPayload(block, "timestamp") || 0,
|
|
209
|
-
},
|
|
209
|
+
}, getPiMarkdownTheme());
|
|
210
210
|
component.setExpanded(expanded);
|
|
211
211
|
return component;
|
|
212
212
|
}
|
|
@@ -256,7 +256,7 @@ function updateTranscriptComponent(component, previous, next, expanded, imageAss
|
|
|
256
256
|
}
|
|
257
257
|
function assistantComponent(block, outputPad, hideThinkingBlock, mermaidRenderingMode) {
|
|
258
258
|
const transformer = createMermaidMarkdownTransformer({ getMode: () => mermaidRenderingMode, theme: piTheme() });
|
|
259
|
-
const component = new AssistantMessageComponent(undefined, hideThinkingBlock,
|
|
259
|
+
const component = new AssistantMessageComponent(undefined, hideThinkingBlock, getPiMarkdownTheme(), undefined, outputPad, [transformer]);
|
|
260
260
|
component.updateContent(validatedAssistantMessage(block), block.status === "live");
|
|
261
261
|
return component;
|
|
262
262
|
}
|
|
@@ -328,12 +328,12 @@ function validatedMessageRenderer(value) {
|
|
|
328
328
|
function isPiMessageRenderer(value) {
|
|
329
329
|
return typeof value === "function";
|
|
330
330
|
}
|
|
331
|
-
function toolComponent(block, cwd, extensions, showImages, imageWidthCells, imageAssets, tui) {
|
|
331
|
+
function toolComponent(block, cwd, extensions, outputPad, showImages, imageWidthCells, imageAssets, tui) {
|
|
332
332
|
const payload = blockPayload(block);
|
|
333
333
|
const toolCallId = stringPayload(payload, "toolCallId") ?? block.id;
|
|
334
334
|
const toolName = stringPayload(payload, "toolName") ?? block.title ?? "tool";
|
|
335
335
|
const argumentsPayload = toolArguments(block);
|
|
336
|
-
const component = new ToolExecutionComponent(toolName, toolCallId, argumentsPayload, { showImages, imageWidthCells }, validatedToolRenderers(extensions?.getToolRenderers(toolName)), tui ?? createTuiFacade({ getColumns: () => 80, getRows: () => 24, requestRender() { } }), cwd);
|
|
336
|
+
const component = new ToolExecutionComponent(toolName, toolCallId, argumentsPayload, { showImages, imageWidthCells, outputPad }, validatedToolRenderers(extensions?.getToolRenderers(toolName)), tui ?? createTuiFacade({ getColumns: () => 80, getRows: () => 24, requestRender() { } }), cwd);
|
|
337
337
|
applyToolState(component, block);
|
|
338
338
|
updateToolResult(component, block, imageAssets);
|
|
339
339
|
return component;
|
|
@@ -360,7 +360,7 @@ function customMessageComponent(block, expanded, extensions, outputPad) {
|
|
|
360
360
|
timestamp: numericPayload(block, "timestamp") || 0,
|
|
361
361
|
};
|
|
362
362
|
const renderer = validatedMessageRenderer(extensions?.getMessageRenderer(message.customType));
|
|
363
|
-
const component = new CustomMessageComponent(message, renderer,
|
|
363
|
+
const component = new CustomMessageComponent(message, renderer, getPiMarkdownTheme(), outputPad);
|
|
364
364
|
component.setExpanded(expanded);
|
|
365
365
|
return component;
|
|
366
366
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ArminComponent, DynamicBorder,
|
|
1
|
+
import { ArminComponent, DynamicBorder, LoginDialogComponent, ModelSelectorComponent, OAuthSelectorComponent, SettingsSelectorComponent, ShowImagesSelectorComponent, ThemeSelectorComponent, UserMessageSelectorComponent, } from "../startup-public.js";
|
|
2
2
|
import { EarendilAnnouncementComponent } from "./upstream/components/earendil-announcement.js";
|
|
3
3
|
import { ExtensionSelectorComponent } from "./upstream/components/extension-selector.js";
|
|
4
4
|
import { Box, Container, SelectList, Spacer, Text, } from "@earendil-works/pi-tui";
|
|
@@ -6,13 +6,13 @@ import { ScopedModelsSelectorComponent } from "./upstream/components/scoped-mode
|
|
|
6
6
|
import { addPiModalSelectFooter, adoptPiModalFrame, adoptPiModalHeader } from "./modal-frame.js";
|
|
7
7
|
import { ModelsDialogComponent } from "./models-dialog.js";
|
|
8
8
|
import { TrustSelectorComponent } from "./upstream/components/trust-selector.js";
|
|
9
|
-
import { canonicalizePiSettingsHint, DIALOG_CLOSE_SHORTCUT_HINT, PINNED_PI_LAYOUT, piTheme, renderPiModalShortcutHints, } from "./theme.js";
|
|
9
|
+
import { canonicalizePiSettingsHint, DIALOG_CLOSE_SHORTCUT_HINT, PINNED_PI_LAYOUT, getPiSelectListTheme, paintPiBorder, piTheme, renderPiModalShortcutHints, } from "./theme.js";
|
|
10
10
|
import { componentFromPort, componentPort, createTuiFacade, ensureTheme, isRecord, } from "./shell-shared-facade.js";
|
|
11
11
|
export { createPiShellSkillsSelector } from "./skills-dialog.js";
|
|
12
12
|
export function createPiShellSelector(options) {
|
|
13
13
|
ensureTheme();
|
|
14
14
|
const items = options.options.map(toSelectItem);
|
|
15
|
-
const list = new SelectList(items, options.maxVisible ?? Math.min(PINNED_PI_LAYOUT.selectorMaxVisible, Math.max(1, items.length)),
|
|
15
|
+
const list = new SelectList(items, options.maxVisible ?? Math.min(PINNED_PI_LAYOUT.selectorMaxVisible, Math.max(1, items.length)), getPiSelectListTheme());
|
|
16
16
|
if (options.onSelect !== undefined)
|
|
17
17
|
list.onSelect = item => options.onSelect?.(item.value);
|
|
18
18
|
if (options.onCancel !== undefined)
|
|
@@ -214,12 +214,11 @@ export function createPiShellEarendilAnnouncement() {
|
|
|
214
214
|
export function createPiShellReloadBox() {
|
|
215
215
|
ensureTheme();
|
|
216
216
|
const container = new Container();
|
|
217
|
-
|
|
218
|
-
container.addChild(new DynamicBorder(borderColor));
|
|
217
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
219
218
|
container.addChild(new Spacer(1));
|
|
220
219
|
container.addChild(new Text(piTheme().fg("muted", "Reloading keybindings, extensions, skills, prompts, themes, and context files..."), 0, 0));
|
|
221
220
|
container.addChild(new Spacer(1));
|
|
222
|
-
container.addChild(new DynamicBorder(
|
|
221
|
+
container.addChild(new DynamicBorder(paintPiBorder));
|
|
223
222
|
adoptPiModalFrame(container, { topIndex: 0, bottomIndex: container.children.length - 1 });
|
|
224
223
|
return componentPort(container);
|
|
225
224
|
}
|
|
@@ -14,7 +14,7 @@ export function createTuiFacade(options) {
|
|
|
14
14
|
get columns() { return Math.max(1, options.getColumns()); },
|
|
15
15
|
get rows() { return Math.max(1, options.getRows()); },
|
|
16
16
|
get kittyProtocolActive() { return false; },
|
|
17
|
-
moveBy() { }, hideCursor() { }, showCursor() { }, clearLine() { }, clearFromCursor() { }, clearScreen() { }, setTitle() { }, setProgress() { },
|
|
17
|
+
moveBy() { }, hideCursor() { }, showCursor() { }, clearLine() { }, clearFromCursor() { }, clearScreen() { }, setTitle() { }, setProgress() { }, setProgramStatus() { },
|
|
18
18
|
};
|
|
19
19
|
return {
|
|
20
20
|
mode: "regular",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DynamicBorder } from "../startup-public.js";
|
|
2
2
|
import { Container, getKeybindings, Input, Spacer, Text } from "@earendil-works/pi-tui";
|
|
3
3
|
import { addPiModalHeader, adoptPiModalFrame } from "./modal-frame.js";
|
|
4
|
-
import { DIALOG_CLOSE_SHORTCUT_HINT, PINNED_PI_LAYOUT, piTheme, renderPiModalListRow, renderPiModalShortcutHints, } from "./theme.js";
|
|
4
|
+
import { DIALOG_CLOSE_SHORTCUT_HINT, paintPiBorder, PINNED_PI_LAYOUT, piTheme, renderPiModalListRow, renderPiModalShortcutHints, } from "./theme.js";
|
|
5
5
|
import { componentPort, ensureTheme, piShellTruncateToWidth, piShellVisibleWidth } from "./shell-shared-facade.js";
|
|
6
6
|
import { skillMatchesQuery } from "./skills-command.js";
|
|
7
7
|
/** A single line clipped at the viewport width: no wrap, no ellipsis, padded to the full width. */
|
|
@@ -48,7 +48,7 @@ class SkillsSelectorComponent extends Container {
|
|
|
48
48
|
this.#onSelect = options.onSelect;
|
|
49
49
|
this.#onCancel = options.onCancel;
|
|
50
50
|
this.#searchInput.onSubmit = () => this.#selectCurrent();
|
|
51
|
-
const header = addPiModalHeader(this, new DynamicBorder(), new Text(piTheme().fg("accent", piTheme().bold("Skills")), 0, 0));
|
|
51
|
+
const header = addPiModalHeader(this, new DynamicBorder(paintPiBorder), new Text(piTheme().fg("accent", piTheme().bold("Skills")), 0, 0));
|
|
52
52
|
this.addChild(new Spacer(1));
|
|
53
53
|
this.addChild(this.#searchInput);
|
|
54
54
|
this.addChild(new Spacer(1));
|
|
@@ -61,7 +61,7 @@ class SkillsSelectorComponent extends Container {
|
|
|
61
61
|
{ key: bindings.getKeys("tui.select.confirm").join("/"), action: "select" },
|
|
62
62
|
DIALOG_CLOSE_SHORTCUT_HINT,
|
|
63
63
|
]), 0, 0));
|
|
64
|
-
this.addChild(new DynamicBorder());
|
|
64
|
+
this.addChild(new DynamicBorder(paintPiBorder));
|
|
65
65
|
adoptPiModalFrame(this, { topIndex: 0, bottomIndex: this.children.length - 1, header });
|
|
66
66
|
this.#updateList();
|
|
67
67
|
}
|