@timurproko/a1 0.2.7-dev.820 → 0.2.7-dev.828
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 +7 -1
- package/bin/automatic-update.js +7 -0
- package/bin/tab-launch-context.d.ts +1 -0
- package/bin/tab-launch-context.js +3 -3
- package/bin/ui.js +96 -66
- package/dist/app/session-shell/session-shell-root.d.ts +13 -6
- package/dist/app/session-shell/session-shell-root.js +9 -5
- package/dist/app/session-shell/session-shell.js +68 -18
- package/dist/app/session-shell/shell-host.js +6 -3
- package/dist/app/session-shell/transcript-document.js +1 -1
- package/dist/cli/tabs.d.ts +1 -1
- package/dist/cli/tabs.js +10 -14
- package/dist/composition/owned-settings.d.ts +12 -0
- package/dist/composition/owned-settings.js +36 -0
- package/dist/composition/owned-ui.d.ts +5 -14
- package/dist/composition/owned-ui.js +93 -63
- package/dist/composition/resident-tab-bridge.d.ts +10 -1
- package/dist/composition/resident-tab-bridge.js +21 -0
- package/dist/composition/settings-route-host.d.ts +12 -2
- package/dist/composition/settings-route-host.js +27 -9
- package/dist/composition/settings-search-input.d.ts +9 -0
- package/dist/composition/settings-search-input.js +58 -0
- package/dist/composition/utility-tab.d.ts +28 -0
- package/dist/composition/utility-tab.js +242 -0
- package/dist/contracts/owned-ui/session-backend.d.ts +2 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +7 -3
- package/dist/contracts/presentation/index.d.ts +11 -0
- package/dist/contracts/presentation/index.js +12 -0
- package/dist/features/launch/development-launch.js +6 -0
- package/dist/features/launch/profile-paths.js +4 -0
- package/dist/features/owned-ui/plus-menu-dialog.d.ts +22 -0
- package/dist/features/owned-ui/plus-menu-dialog.js +76 -0
- package/dist/features/owned-ui/project-trust-dialog.d.ts +1 -1
- package/dist/features/owned-ui/project-trust-dialog.js +6 -8
- package/dist/features/owned-ui/project-trust-prompt.d.ts +1 -0
- package/dist/features/owned-ui/project-trust-prompt.js +7 -3
- package/dist/features/owned-ui/reference-screen-app.d.ts +2 -0
- package/dist/features/owned-ui/reference-screen-app.js +12 -2
- package/dist/features/owned-ui/settings-app.d.ts +10 -3
- package/dist/features/owned-ui/settings-app.js +98 -45
- package/dist/features/owned-ui/settings-search-input.d.ts +29 -0
- package/dist/features/owned-ui/settings-search-input.js +1 -0
- package/dist/features/prompt-history/index.d.ts +1 -1
- package/dist/features/prompt-history/paths.d.ts +2 -1
- package/dist/features/prompt-history/paths.js +10 -2
- package/dist/features/prompt-history/service.d.ts +5 -0
- package/dist/features/prompt-history/service.js +1 -1
- package/dist/features/resident-tab/shortcut-declarations.d.ts +1 -1
- package/dist/features/resident-tab/shortcut-declarations.js +2 -0
- package/dist/foundation/launch-context/index.d.ts +2 -0
- package/dist/foundation/launch-context/index.js +1 -0
- package/dist/foundation/lifecycle/session-repository-context.js +16 -2
- package/dist/foundation/release/automatic-update.d.ts +37 -0
- package/dist/foundation/release/automatic-update.js +265 -0
- package/dist/foundation/release/bootstrap.d.ts +1 -9
- package/dist/foundation/release/bootstrap.js +7 -3
- package/dist/foundation/release/early-accent.d.ts +12 -0
- package/dist/foundation/release/early-accent.js +59 -0
- package/dist/foundation/release/index.d.ts +1 -1
- package/dist/foundation/release/index.js +1 -1
- package/dist/foundation/release/latest-release.d.ts +3 -2
- package/dist/foundation/release/latest-release.js +1 -1
- package/dist/foundation/release/progress-palette.generated.d.ts +137 -3
- package/dist/foundation/release/progress-palette.generated.js +137 -3
- package/dist/foundation/release/release-gc.js +19 -4
- package/dist/foundation/release/update-execution-lease.d.ts +36 -0
- package/dist/foundation/release/update-execution-lease.js +145 -0
- package/dist/foundation/release/update.d.ts +9 -7
- package/dist/foundation/release/update.js +244 -175
- package/dist/foundation/resident-tabs/bridge-client.d.ts +9 -2
- package/dist/foundation/resident-tabs/bridge-client.js +19 -7
- package/dist/foundation/resident-tabs/maintenance.d.ts +2 -6
- package/dist/foundation/resident-tabs/maintenance.js +5 -23
- package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +34 -0
- package/dist/foundation/resident-tabs/progress-observation-schema.js +1 -0
- package/dist/foundation/resident-tabs/progress-observation.d.ts +3 -6
- package/dist/foundation/resident-tabs/progress-observation.js +43 -12
- package/dist/foundation/resident-tabs/release-holds.js +3 -14
- package/dist/foundation/resident-tabs/routes.d.ts +5 -0
- package/dist/foundation/resident-tabs/routes.js +5 -0
- package/dist/integrations/pi/components/editor-interaction.d.ts +2 -0
- package/dist/integrations/pi/components/modal-frame.d.ts +17 -1
- package/dist/integrations/pi/components/modal-frame.js +48 -9
- package/dist/integrations/pi/components/models-dialog.js +4 -52
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +3 -0
- package/dist/integrations/pi/components/owned-editor-ux.js +75 -4
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +57 -37
- package/dist/integrations/pi/components/shell-footer-status.js +19 -3
- package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +4 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +9 -2
- package/dist/integrations/pi/components/skills-dialog.js +2 -2
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +7 -5
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +15 -8
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +3 -3
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +2 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.js +26 -23
- package/dist/integrations/pi/components/upstream/components/session-selector.js +7 -6
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +7 -6
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +9 -8
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +6 -4
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +8 -8
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +10 -10
- package/dist/integrations/pi/components/upstream/history/editor-core.js +2 -0
- package/dist/integrations/pi/components/upstream/theme/theme.d.ts +2 -0
- package/dist/integrations/pi/components/upstream/theme/theme.js +5 -1
- package/dist/integrations/pi/engine/adapter.js +7 -2
- package/dist/integrations/pi/engine/offline-settings-port.d.ts +23 -0
- package/dist/integrations/pi/engine/offline-settings-port.js +53 -0
- package/dist/integrations/pi/engine/ports.d.ts +1 -1
- package/dist/integrations/pi/engine/ports.js +4 -0
- package/dist/integrations/pi/engine/settings-bridge.d.ts +5 -0
- package/dist/integrations/pi/engine/settings-bridge.js +13 -0
- package/dist/integrations/pi/engine/settings-port.js +1 -14
- package/dist/integrations/pi/engine/workflow-runner.js +9 -2
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/darwin-arm64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +1 -1
- package/dist/native/darwin-x64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/linux-x64/terminal-host.manifest.json +3 -3
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host.manifest.json +3 -3
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/product-identity.d.ts +1 -1
- package/dist/product-identity.js +2 -2
- package/dist/product-identity.json +2 -0
- package/dist/ui/apps/host.d.ts +2 -0
- package/dist/ui/apps/host.js +7 -1
- package/dist/ui/components/dialog-panel.js +35 -30
- package/dist/ui/components/line-input.d.ts +3 -0
- package/dist/ui/components/line-input.js +3 -1
- package/dist/ui/components/prompt-input.d.ts +3 -2
- package/dist/ui/components/prompt-input.js +6 -4
- package/dist/ui/components/spans.js +2 -2
- package/dist/ui/components/surface.js +4 -2
- package/dist/ui/components/text.d.ts +3 -6
- package/dist/ui/components/text.js +6 -8
- package/dist/ui/settings/declarations.d.ts +56 -10
- package/dist/ui/settings/declarations.js +38 -9
- package/dist/ui/settings/early-accent.d.ts +81 -0
- package/dist/ui/settings/early-accent.js +50 -0
- package/dist/ui/settings/manager.js +7 -3
- package/dist/ui/settings/migrations.js +15 -0
- package/dist/ui/settings/progress-palette.generated.d.ts +139 -0
- package/dist/ui/settings/progress-palette.generated.js +139 -0
- package/dist/ui/settings/sections.d.ts +4 -0
- package/dist/ui/settings/sections.js +9 -3
- package/docs/architecture/resident-tabs.md +48 -17
- package/docs/architecture/tool-image-presentation.md +2 -1
- package/docs/features/prompt-history.md +41 -20
- package/docs/validation.md +25 -5
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import type { SessionSelection } from "../foundation/lifecycle/session-selection
|
|
|
4
4
|
import { type PiEngineHostOptions } from "../integrations/pi/engine/host.js";
|
|
5
5
|
import type { PiProjectTrustPreflightPrompt } from "../integrations/pi/engine/project-trust-preflight.js";
|
|
6
6
|
import type { PiSessionForkPrompt } from "../integrations/pi/engine/session-selection.js";
|
|
7
|
-
import { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
7
|
+
import type { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
8
8
|
import type { OwnedUiApplicationPort, PresentationTerminalPort } from "../contracts/presentation/index.js";
|
|
9
9
|
import type { ReleaseNoteCatalog } from "../features/owned-ui/release-notes.js";
|
|
10
10
|
import type { TabBridgeClient } from "../foundation/resident-tabs/bridge-client.js";
|
|
@@ -20,17 +20,11 @@ export interface OwnedUiCompositionOptions {
|
|
|
20
20
|
readonly sessionPath?: string;
|
|
21
21
|
readonly sessionSelection?: SessionSelection;
|
|
22
22
|
readonly sessionForkPrompt?: PiSessionForkPrompt;
|
|
23
|
-
/**
|
|
24
|
-
* A1 profile whose settings this session reads and writes. Omitted keeps the
|
|
25
|
-
* session settings-free, which is what the pinned comparison paths use.
|
|
26
|
-
*/
|
|
23
|
+
/** A1 settings profile; comparison paths omit it. */
|
|
27
24
|
readonly profileId?: string;
|
|
28
25
|
/** Hide resident-only tab controls for the explicit direct single-agent launch. */
|
|
29
26
|
readonly hideTabSettings?: boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Whether A1's product-specific surfaces are reachable. Comparison profiles
|
|
32
|
-
* use the same composition with those surfaces withheld.
|
|
33
|
-
*/
|
|
27
|
+
/** `off` withholds A1-specific surfaces from comparison profiles. */
|
|
34
28
|
readonly ownedSurfaces?: "on" | "off";
|
|
35
29
|
readonly projectTrustPrompt?: PiProjectTrustPreflightPrompt;
|
|
36
30
|
/** Explicit local diagnostic destination; ignored by comparison/settings-free compositions. */
|
|
@@ -39,18 +33,16 @@ export interface OwnedUiCompositionOptions {
|
|
|
39
33
|
readonly clipboardDiagnosticsPath?: string;
|
|
40
34
|
/** Deterministic release-note seams for composition tests. */
|
|
41
35
|
readonly packageVersion?: string;
|
|
36
|
+
readonly notificationVersion?: string | undefined;
|
|
42
37
|
readonly releaseNotes?: ReleaseNoteCatalog;
|
|
43
38
|
/** Startup release-availability seam; defaults to the throttled registry check. */
|
|
44
39
|
readonly checkForNewerRelease?: (options: StartupReleaseCheckOptions) => Promise<AvailableRelease | null>;
|
|
45
|
-
/** Exact native process inspection injected by the shipped entry; absent SDK seams do not publish claims. */
|
|
46
40
|
readonly inspectProcess?: (pid: number) => Promise<NativeProcessIdentity | null>;
|
|
47
|
-
/** Private credentials were consumed by the entry before composition or extensions loaded. */
|
|
48
41
|
readonly tab?: {
|
|
49
42
|
readonly bridge: TabBridgeClient;
|
|
50
43
|
readonly dataDir: string;
|
|
51
44
|
readonly incarnation: number;
|
|
52
45
|
};
|
|
53
|
-
/** One prompt-adjacent notice explaining why a resident launch fell back. */
|
|
54
46
|
readonly residentFallbackNotice?: string;
|
|
55
47
|
}
|
|
56
48
|
export interface OwnedUiComposition {
|
|
@@ -69,5 +61,4 @@ export declare function residentStartupPresentation(resident: boolean, fallbackN
|
|
|
69
61
|
};
|
|
70
62
|
export declare function composeOwnedUiApplication(options?: OwnedUiCompositionOptions): Promise<OwnedUiApplicationPort>;
|
|
71
63
|
export declare function composeOwnedUi(options?: OwnedUiCompositionOptions): Promise<OwnedUiComposition>;
|
|
72
|
-
|
|
73
|
-
export declare function watchSharedSettings(settings: Pick<OwnedSettingsManager, "file" | "refresh">): () => void;
|
|
64
|
+
export { watchSharedSettings } from "./owned-settings.js";
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import { unwatchFile, watchFile } from "node:fs";
|
|
2
1
|
import { SuggestionDiagnosticCapture } from "../features/prompt-suggestions/diagnostics.js";
|
|
3
2
|
import { PRODUCT_IDENTITY } from "../product-identity.js";
|
|
4
3
|
import { PromptHistoryService } from "../features/prompt-history/service.js";
|
|
5
4
|
import { PromptImageSidecar } from "../features/prompt-history/image-sidecar.js";
|
|
6
5
|
import { resolvePromptHistoryPath } from "../features/prompt-history/paths.js";
|
|
7
|
-
import {
|
|
6
|
+
import { resolvePromptHistoryDataDir } from "../features/launch/profile-paths.js";
|
|
8
7
|
import { resolveProductPaths } from "../foundation/lifecycle/paths.js";
|
|
8
|
+
import { MAX_CLIPBOARD_TEXT_BYTES } from "../contracts/owned-ui/index.js";
|
|
9
9
|
import { applyConfiguredPiTheme, getAvailablePiThemes, setPiAccentColor, setPiPackageBorderProjectionEnabled } from "../integrations/pi/components/upstream/theme/theme.js";
|
|
10
10
|
import { createPiEngineHost } from "../integrations/pi/engine/host.js";
|
|
11
11
|
import { createPiSessionPresenters } from "../integrations/pi/session-presenters/index.js";
|
|
12
12
|
import { ClipboardDiagnosticCapture } from "../app/session-shell/clipboard-diagnostics.js";
|
|
13
13
|
import { createOwnedUiClipboardServices } from "../app/session-shell/clipboard-services.js";
|
|
14
|
+
import { writeSystemClipboardText } from "../app/session-shell/system-clipboard.js";
|
|
14
15
|
import { createPiKeybindingsHost } from "../integrations/pi/components/shell-shared-facade.js";
|
|
15
16
|
import { OwnedUiSessionPresenter, OwnedUiTerminalHost, sessionTerminalHostOptions, } from "../app/session-shell/session-shell.js";
|
|
16
|
-
import { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
17
17
|
import { createPiTerminalBridge } from "../integrations/pi/tui-runtime/presentation-adapter.js";
|
|
18
18
|
import { createOwnedRouteHost } from "./settings-route-host.js";
|
|
19
19
|
import { renderPiShellChangelogLines } from "../integrations/pi/components/shell-presenters-info.js";
|
|
20
20
|
import { nativeHyperlinkStyle } from "../ui/components/spans.js";
|
|
21
21
|
import { ResidentTabRecovery } from "../foundation/resident-tabs/recovery.js";
|
|
22
|
-
import { bindResidentTabBridge, correlateResidentTabSubmission, currentBackendSessionFile, residentTabKeybindings } from "./resident-tab-bridge.js";
|
|
22
|
+
import { bindResidentTabBridge, closeResidentUtilityRoute, correlateResidentTabSubmission, currentBackendSessionFile, residentRouteHostOptions, residentTabKeybindings } from "./resident-tab-bridge.js";
|
|
23
23
|
import { SessionRuntimeRegistry } from "./session-runtime-registry.js";
|
|
24
24
|
import { readPackageVersion, StartupReleaseNote } from "./startup-route.js";
|
|
25
|
+
import { createOwnedSettingsManager, watchSharedSettings } from "./owned-settings.js";
|
|
25
26
|
export { bindResidentTabBridge, correlateResidentTabSubmission } from "./resident-tab-bridge.js";
|
|
26
27
|
export function residentStartupPresentation(resident, fallbackNotice) {
|
|
27
28
|
if (resident)
|
|
@@ -39,20 +40,14 @@ export async function composeOwnedUi(options = {}) {
|
|
|
39
40
|
inspectProcess: options.inspectProcess,
|
|
40
41
|
});
|
|
41
42
|
const productPaths = resolveProductPaths();
|
|
42
|
-
const profilePaths = resolveLaunchProfilePaths();
|
|
43
43
|
// Rationale: the manager reads the engine's settings port lazily, after the session exists.
|
|
44
44
|
let backend;
|
|
45
45
|
const settings = options.profileId === undefined
|
|
46
46
|
? null
|
|
47
|
-
:
|
|
48
|
-
profileDir: profilePaths.agentProfile,
|
|
47
|
+
: createOwnedSettingsManager({
|
|
49
48
|
profileId: options.profileId,
|
|
50
|
-
namespace: PRODUCT_IDENTITY.commandName,
|
|
51
|
-
legacyConfigDir: productPaths.configDir,
|
|
52
49
|
agentProvider: () => backend.settingsPort(),
|
|
53
|
-
...(options.hideTabSettings ? {
|
|
54
|
-
hiddenAgentSettingIds: ["fullscreenWheelScrollLines"],
|
|
55
|
-
agentSettingLabelOverrides: { fullscreenCopyOnSelect: "Copy on select" },
|
|
50
|
+
...(options.hideTabSettings ? { hideTabSettings: true } : {}),
|
|
56
51
|
});
|
|
57
52
|
const tabBridge = options.tab?.bridge ?? null;
|
|
58
53
|
if (tabBridge !== null)
|
|
@@ -130,12 +125,15 @@ export async function composeOwnedUi(options = {}) {
|
|
|
130
125
|
host.setAccentColor(accent);
|
|
131
126
|
tabBridge?.accent(accent);
|
|
132
127
|
});
|
|
133
|
-
// Rationale:
|
|
134
|
-
// change saved in
|
|
135
|
-
const unwatchSharedSettings = settings === null || !ownedSurfaces
|
|
128
|
+
// Rationale: resident tabs and separate solo agents share a settings document; a live scope
|
|
129
|
+
// change saved in either reaches the others only by rereading that document.
|
|
130
|
+
const unwatchSharedSettings = settings === null || !ownedSurfaces
|
|
136
131
|
? () => { }
|
|
137
132
|
: watchSharedSettings(settings);
|
|
138
133
|
const unsubscribeAccent = () => { unwatchSharedSettings(); unsubscribeAccentChange(); };
|
|
134
|
+
// Invariant: the Settings search and agent prompt borrow the same resolved Pi keybindings.
|
|
135
|
+
const keybindingsHost = createPiKeybindingsHost({ profile: ownedSurfaces ? "a1" : "pi", agentDir: backend.identity.agentDir });
|
|
136
|
+
const keybindings = residentTabKeybindings(tabBridge, backend.identity.agentDir, keybindingsHost);
|
|
139
137
|
// Rationale: Routes open only after shell construction.
|
|
140
138
|
const references = {
|
|
141
139
|
changelog: async (input) => {
|
|
@@ -151,9 +149,8 @@ export async function composeOwnedUi(options = {}) {
|
|
|
151
149
|
},
|
|
152
150
|
session: () => import("./session-info-reference.js").then(m => m.loadSessionInfoReference(backend)),
|
|
153
151
|
};
|
|
154
|
-
const routeHost = settings === null || !ownedSurfaces ? null
|
|
155
|
-
|
|
156
|
-
});
|
|
152
|
+
const routeHost = settings === null || !ownedSurfaces ? null
|
|
153
|
+
: createOwnedRouteHost(settings, references, settingsRouteOptions(tabBridge, keybindings, backend.identity.agentDir, cwd));
|
|
157
154
|
const viewportSettings = settings === null || !ownedSurfaces ? null : {
|
|
158
155
|
snapshot: () => viewportSettingsSnapshot(settings),
|
|
159
156
|
onChange: listener => settings.onChange(() => listener(viewportSettingsSnapshot(settings))),
|
|
@@ -181,26 +178,11 @@ export async function composeOwnedUi(options = {}) {
|
|
|
181
178
|
// Rationale: one listener covers both the A1 presentation choice and the engine skill-command toggle.
|
|
182
179
|
onChange: (listener) => settings.onChange(() => listener()),
|
|
183
180
|
};
|
|
184
|
-
const
|
|
185
|
-
const historyProfileLocation = settings === null || !ownedSurfaces || !settings.value("promptHistoryEnabled")
|
|
186
|
-
? null
|
|
187
|
-
: resolvePromptHistoryPath(resolvePromptHistoryDataDir(), backend.identity.agentDir);
|
|
188
|
-
const promptHistory = historyProfileLocation === null ? null : {
|
|
189
|
-
limit: typeof historyLimit === "number" ? historyLimit : 100,
|
|
190
|
-
store: new PromptHistoryService({
|
|
191
|
-
dataDir: resolvePromptHistoryDataDir(),
|
|
192
|
-
profileRoot: backend.identity.agentDir,
|
|
193
|
-
limit: typeof historyLimit === "number" ? historyLimit : 100,
|
|
194
|
-
}),
|
|
195
|
-
imageSidecar: new PromptImageSidecar(historyProfileLocation.imagesDir),
|
|
196
|
-
};
|
|
181
|
+
const promptHistory = createPromptHistoryConfiguration(settings, backend, ownedSurfaces);
|
|
197
182
|
const clipboardDestination = options.clipboardDiagnosticsPath ?? process.env[PRODUCT_IDENTITY.environment.clipboardDiagnostics];
|
|
198
183
|
const clipboardDiagnostics = settings !== null && ownedSurfaces && clipboardDestination?.trim()
|
|
199
184
|
? new ClipboardDiagnosticCapture(clipboardDestination) : null;
|
|
200
|
-
// Invariant: process-wide services are created once here and borrowed by every session shell.
|
|
201
|
-
// keybinding registry is applied before any presenter is built, so none of them reads Pi's defaults.
|
|
202
|
-
const keybindingsHost = createPiKeybindingsHost({ profile: ownedSurfaces ? "a1" : "pi", agentDir: backend.identity.agentDir });
|
|
203
|
-
const keybindings = residentTabKeybindings(tabBridge, backend.identity.agentDir, keybindingsHost);
|
|
185
|
+
// Invariant: process-wide services are created once here and borrowed by every session shell.
|
|
204
186
|
const clipboardServices = ownedSurfaces ? createOwnedUiClipboardServices() : null;
|
|
205
187
|
let createdTerminalHost;
|
|
206
188
|
let terminalHost;
|
|
@@ -216,10 +198,7 @@ export async function composeOwnedUi(options = {}) {
|
|
|
216
198
|
...(ownedSurfaces ? { sessionLayout: "custom-viewport" } : {}),
|
|
217
199
|
...(tabBridge === null || tabRecovery === null ? {} : { residentTab: {
|
|
218
200
|
requestDetach: () => tabBridge.requestDetach(),
|
|
219
|
-
closeOwnedRoute: route =>
|
|
220
|
-
if (tabBridge.tabId.startsWith("settings-") && route === "settings")
|
|
221
|
-
void tabBridge.requestClose();
|
|
222
|
-
},
|
|
201
|
+
closeOwnedRoute: route => closeResidentUtilityRoute(tabBridge, route),
|
|
223
202
|
reportStatus: status => tabBridge.status(status),
|
|
224
203
|
admit: input => tabRecovery.admit({ ...input, incarnation: options.tab.incarnation }),
|
|
225
204
|
dispatched: () => tabRecovery.dispatched(),
|
|
@@ -290,18 +269,13 @@ export async function composeOwnedUi(options = {}) {
|
|
|
290
269
|
// Rationale: pinned Pi's version check is unreachable because the owned shell never runs its
|
|
291
270
|
// InteractiveMode, so A1 checks its own channel. The result is never awaited on the startup path;
|
|
292
271
|
// settings are read here because the runner resolves them only just before start.
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
...(settings === null || !ownedSurfaces ? {} : { settingEnabled: settings.value("updateCheck") }),
|
|
301
|
-
});
|
|
302
|
-
if (release !== null)
|
|
303
|
-
backend.extensions.announceReleaseUpdate(release);
|
|
304
|
-
};
|
|
272
|
+
const releaseUpdates = createStartupReleaseUpdateObservation({
|
|
273
|
+
backend,
|
|
274
|
+
configDir: productPaths.configDir,
|
|
275
|
+
mode: settings === null || !ownedSurfaces ? "auto" : settings.value("updateCheck"),
|
|
276
|
+
packageVersion: releaseNote.packageVersion, notificationVersion: options.notificationVersion,
|
|
277
|
+
checkForNewerRelease: options.checkForNewerRelease,
|
|
278
|
+
});
|
|
305
279
|
const exitNoticePath = process.env[PRODUCT_IDENTITY.environment.exitNoticePath];
|
|
306
280
|
// Security: tools the agent runs must never see, or rewrite, this instance's notice.
|
|
307
281
|
delete process.env[PRODUCT_IDENTITY.environment.exitNoticePath];
|
|
@@ -314,11 +288,12 @@ export async function composeOwnedUi(options = {}) {
|
|
|
314
288
|
exitNotice = import("../app/session-shell/exit-notice.js")
|
|
315
289
|
.then(module => module.armExitNotice(backend, exitNoticePath), () => null);
|
|
316
290
|
presenter.start();
|
|
317
|
-
|
|
291
|
+
releaseUpdates.start();
|
|
318
292
|
},
|
|
319
293
|
flush: () => backend.session.flushEvents(),
|
|
320
294
|
waitUntilStopped: () => presenter.waitUntilStopped(),
|
|
321
295
|
dispose: async () => {
|
|
296
|
+
releaseUpdates.stop();
|
|
322
297
|
try {
|
|
323
298
|
await terminalHost.dispose();
|
|
324
299
|
// Invariant: cleared only once the terminal is restored; a failed dispose leaves it armed.
|
|
@@ -343,20 +318,75 @@ export async function composeOwnedUi(options = {}) {
|
|
|
343
318
|
};
|
|
344
319
|
return { application, settings };
|
|
345
320
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
const
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
321
|
+
function createPromptHistoryConfiguration(settings, backend, ownedSurfaces) {
|
|
322
|
+
const limit = settings?.value("promptHistoryMaxItems") ?? 100;
|
|
323
|
+
const scope = settings?.value("promptHistoryScope") ?? "unique";
|
|
324
|
+
const enabled = settings !== null && ownedSurfaces && settings.value("promptHistoryEnabled");
|
|
325
|
+
const sessionId = enabled ? backend.identity.currentHistorySessionId() : null;
|
|
326
|
+
if (settings === null || !enabled || (scope === "unique" && sessionId === null))
|
|
327
|
+
return null;
|
|
328
|
+
const dataDir = resolvePromptHistoryDataDir();
|
|
329
|
+
const forScope = (selected, id) => {
|
|
330
|
+
if (selected === "unique" && id === null)
|
|
331
|
+
return null;
|
|
332
|
+
const location = resolvePromptHistoryPath(dataDir, backend.identity.agentDir, process.platform, selected, id ?? "");
|
|
333
|
+
return {
|
|
334
|
+
store: new PromptHistoryService({ dataDir, profileRoot: backend.identity.agentDir, limit, scope: selected, sessionId: id ?? "" }),
|
|
335
|
+
imageSidecar: new PromptImageSidecar(location.imagesDir),
|
|
336
|
+
};
|
|
337
|
+
};
|
|
338
|
+
return {
|
|
339
|
+
limit, scope,
|
|
340
|
+
...(sessionId === null ? {} : { sessionId }),
|
|
341
|
+
forScope,
|
|
342
|
+
onScopeChange: (listener) => settings.onChange(() => listener(settings.value("promptHistoryScope"))),
|
|
343
|
+
...forScope(scope, sessionId),
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function createStartupReleaseUpdateObservation(input) {
|
|
347
|
+
const controller = new AbortController();
|
|
348
|
+
const observe = async () => {
|
|
349
|
+
const check = input.checkForNewerRelease
|
|
350
|
+
?? (await import("../foundation/release/latest-release.js")).checkForNewerRelease;
|
|
351
|
+
const runningVersion = input.packageVersion ?? await readPackageVersion();
|
|
352
|
+
const discoveryVersion = input.mode === "notify" ? input.notificationVersion ?? runningVersion : runningVersion;
|
|
353
|
+
const release = await check({
|
|
354
|
+
runningVersion: discoveryVersion,
|
|
355
|
+
configDir: input.configDir,
|
|
356
|
+
interactive: process.stdout.isTTY === true,
|
|
357
|
+
settingMode: input.mode,
|
|
358
|
+
});
|
|
359
|
+
if (release === null || controller.signal.aborted)
|
|
360
|
+
return;
|
|
361
|
+
if (input.mode === "notify") {
|
|
362
|
+
input.backend.extensions.announceReleaseUpdate(release);
|
|
363
|
+
return;
|
|
353
364
|
}
|
|
354
|
-
|
|
355
|
-
|
|
365
|
+
if (input.mode === "auto") {
|
|
366
|
+
const installed = await import("../foundation/release/automatic-update.js")
|
|
367
|
+
.then(module => module.requestAutomaticUpdate({ release, runningVersion, signal: controller.signal }));
|
|
368
|
+
if (installed !== null && !controller.signal.aborted) {
|
|
369
|
+
input.backend.extensions.announceReleaseUpdate({ status: "installed", version: installed });
|
|
370
|
+
}
|
|
356
371
|
}
|
|
357
372
|
};
|
|
358
|
-
|
|
359
|
-
|
|
373
|
+
return {
|
|
374
|
+
start() { void observe().catch(() => undefined); },
|
|
375
|
+
stop() { controller.abort(); },
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
export { watchSharedSettings } from "./owned-settings.js";
|
|
379
|
+
function settingsRouteOptions(tabBridge, keybindings, agentDir, cwd) {
|
|
380
|
+
return {
|
|
381
|
+
...residentRouteHostOptions(tabBridge),
|
|
382
|
+
keybindings,
|
|
383
|
+
agentDir,
|
|
384
|
+
cwd,
|
|
385
|
+
copyText: text => {
|
|
386
|
+
if (Buffer.byteLength(text) <= MAX_CLIPBOARD_TEXT_BYTES)
|
|
387
|
+
void writeSystemClipboardText(text).catch(() => { });
|
|
388
|
+
},
|
|
389
|
+
};
|
|
360
390
|
}
|
|
361
391
|
function quitOutroSettingsSnapshot(settings) {
|
|
362
392
|
return {
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import type { TabBridgeClient } from "../foundation/resident-tabs/bridge-client.js";
|
|
2
|
+
import { type ResidentTabRoute } from "../foundation/resident-tabs/routes.js";
|
|
2
3
|
import type { ResidentTabRecovery } from "../foundation/resident-tabs/recovery.js";
|
|
3
4
|
import type { PiKeybindingsHost } from "../integrations/pi/components/shell-shared-facade.js";
|
|
4
5
|
import type { ComposedSessionBackend } from "./session-backend.js";
|
|
6
|
+
import type { OwnedRouteHostOptions } from "./settings-route-host.js";
|
|
5
7
|
/**
|
|
6
8
|
* The keybindings the shells borrow. Inside a resident tab the host dispatches and labels the tab
|
|
7
9
|
* shortcuts this child projects from its effective declarations, so the projection is published now
|
|
8
10
|
* and again after every customization reload.
|
|
9
11
|
*/
|
|
10
12
|
export declare function residentTabKeybindings(tabBridge: TabBridgeClient | null, agentDir: string, keybindingsHost: PiKeybindingsHost): PiKeybindingsHost;
|
|
13
|
+
/**
|
|
14
|
+
* How owned screens are presented in a resident tab: a Settings or Changelog tab's screen is the tab, and the Plus menu entry opens
|
|
15
|
+
* the tab bar's own Plus Menu dialog while this tab's controlling client can show it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function residentRouteHostOptions(tabBridge: TabBridgeClient | null): OwnedRouteHostOptions;
|
|
18
|
+
/** Closes a utility tab when its own screen closes. Invariant: a utility tab's screen is the tab. */
|
|
19
|
+
export declare function closeResidentUtilityRoute(tabBridge: Pick<TabBridgeClient, "tabId" | "requestClose">, route: string): void;
|
|
11
20
|
export declare function bindResidentTabBridge(tabBridge: TabBridgeClient, backend: Pick<ComposedSessionBackend, "identity" | "session" | "workflows" | "generateResidentTabName">, recovery?: Pick<ResidentTabRecovery, "settled"> | null, options?: {
|
|
12
21
|
readonly autoName?: boolean;
|
|
13
|
-
readonly openRoute?: (route:
|
|
22
|
+
readonly openRoute?: (route: ResidentTabRoute) => void;
|
|
14
23
|
}): Promise<() => void>;
|
|
15
24
|
export declare function correlateResidentTabSubmission(recovery: Pick<ResidentTabRecovery, "correlated" | "settled">, backend: Pick<ComposedSessionBackend, "identity" | "session">, submissionId: string, entryId: string): Promise<void>;
|
|
16
25
|
export declare function currentBackendSessionFile(backend: Pick<ComposedSessionBackend, "identity">): string | null;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { residentUtilityRoute } from "../foundation/resident-tabs/routes.js";
|
|
1
2
|
import { deriveResidentTabStatus } from "../features/resident-tab/status-deriver.js";
|
|
2
3
|
import { projectResidentTabShortcuts } from "../features/resident-tab/shortcut-projection.js";
|
|
3
4
|
import { readShortcutBindingsFile } from "../features/resident-tab/shortcut-bindings-file.js";
|
|
@@ -16,6 +17,26 @@ export function residentTabKeybindings(tabBridge, agentDir, keybindingsHost) {
|
|
|
16
17
|
publish();
|
|
17
18
|
return { ...keybindingsHost, reload: () => { keybindingsHost.reload(); publish(); } };
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* How owned screens are presented in a resident tab: a Settings or Changelog tab's screen is the tab, and the Plus menu entry opens
|
|
22
|
+
* the tab bar's own Plus Menu dialog while this tab's controlling client can show it.
|
|
23
|
+
*/
|
|
24
|
+
export function residentRouteHostOptions(tabBridge) {
|
|
25
|
+
return {
|
|
26
|
+
...(tabBridge === null ? {} : { tabRoute: residentUtilityRoute(tabBridge.tabId) }),
|
|
27
|
+
configurePlusMenu: () => {
|
|
28
|
+
if (tabBridge === null || !tabBridge.available || tabBridge.captureAttachment() === null)
|
|
29
|
+
return false;
|
|
30
|
+
void tabBridge.requestAction("configure-plus");
|
|
31
|
+
return true;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Closes a utility tab when its own screen closes. Invariant: a utility tab's screen is the tab. */
|
|
36
|
+
export function closeResidentUtilityRoute(tabBridge, route) {
|
|
37
|
+
if (residentUtilityRoute(tabBridge.tabId) === route)
|
|
38
|
+
void tabBridge.requestClose();
|
|
39
|
+
}
|
|
19
40
|
export async function bindResidentTabBridge(tabBridge, backend, recovery = null, options = {}) {
|
|
20
41
|
await tabBridge.start().catch(() => false);
|
|
21
42
|
tabBridge.status("starting");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReferenceDocumentProvider } from "../features/owned-ui/reference-screen-app.js";
|
|
2
2
|
import type { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
3
3
|
import type { UiRouteHost, UiRouteInput } from "../ui/apps/contracts.js";
|
|
4
|
+
import type { PiKeybindingsHost } from "../integrations/pi/components/shell-shared-facade.js";
|
|
4
5
|
/** Styled document rows for one content width. */
|
|
5
6
|
export type OwnedReferenceRows = NonNullable<ReferenceDocumentProvider["rows"]>;
|
|
6
7
|
/** Documents supplied by composition so the route host never reads shell data itself. */
|
|
@@ -11,8 +12,17 @@ export interface OwnedReferenceProviders {
|
|
|
11
12
|
}
|
|
12
13
|
/** How the settings route is presented. */
|
|
13
14
|
export interface OwnedRouteHostOptions {
|
|
14
|
-
/**
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The route whose screen is this resident utility tab. That screen is the tab, so it offers no
|
|
17
|
+
* screen-level close: neither Esc nor one Ctrl+C dismisses it, and it shows no close hint.
|
|
18
|
+
*/
|
|
19
|
+
readonly tabRoute?: string | null;
|
|
20
|
+
/** Opens the tab bar's own Plus Menu dialog; false when no tab bar can show it. */
|
|
21
|
+
readonly configurePlusMenu?: () => boolean;
|
|
22
|
+
readonly keybindings?: PiKeybindingsHost;
|
|
23
|
+
readonly agentDir?: string;
|
|
24
|
+
readonly cwd?: string;
|
|
25
|
+
readonly copyText?: (text: string) => void;
|
|
16
26
|
}
|
|
17
27
|
/** Declares settings and lazy document routes. */
|
|
18
28
|
export declare function createOwnedRouteHost(settings: OwnedSettingsManager, references?: OwnedReferenceProviders, options?: OwnedRouteHostOptions): UiRouteHost;
|
|
@@ -11,13 +11,14 @@ export function createOwnedRouteHost(settings, references, options = {}) {
|
|
|
11
11
|
if (!routes.has(route))
|
|
12
12
|
return null;
|
|
13
13
|
if (route === SETTINGS_ROUTE) {
|
|
14
|
-
return deferredSurface(SETTINGS_APP_ID, "settings", () => loadSettingsSurface(settings, options
|
|
14
|
+
return deferredSurface(SETTINGS_APP_ID, "settings", () => loadSettingsSurface(settings, options));
|
|
15
15
|
}
|
|
16
16
|
const changelog = route === CHANGELOG_ROUTE;
|
|
17
17
|
const session = route === "session";
|
|
18
18
|
const title = session ? "Session Info" : changelog ? input ? "What's New" : "Changelog" : HOTKEYS_TITLE;
|
|
19
19
|
const document = session ? references.session() : changelog ? references.changelog(input) : references.hotkeys();
|
|
20
|
-
|
|
20
|
+
const pinned = options.tabRoute === route;
|
|
21
|
+
return deferredSurface(route, title, () => loadReferenceSurface(settings, route, title, document, pinned));
|
|
21
22
|
},
|
|
22
23
|
};
|
|
23
24
|
}
|
|
@@ -61,12 +62,27 @@ function deferredSurface(id, label, load) {
|
|
|
61
62
|
onExitRequested: listener => { onExit = listener; },
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
|
-
async function loadSettingsSurface(settings,
|
|
65
|
-
const { SettingsApp } = await
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
async function loadSettingsSurface(settings, options) {
|
|
66
|
+
const [{ SettingsApp }, { createSettingsSearchInputFactory }] = await Promise.all([
|
|
67
|
+
import("../features/owned-ui/settings-app.js"),
|
|
68
|
+
import("./settings-search-input.js"),
|
|
69
|
+
]);
|
|
70
|
+
const pinned = options.tabRoute === SETTINGS_ROUTE;
|
|
71
|
+
const searchInputFactory = createSettingsSearchInputFactory({
|
|
72
|
+
...(options.keybindings === undefined ? {} : { keybindings: options.keybindings }),
|
|
73
|
+
...(options.agentDir === undefined ? {} : { agentDir: options.agentDir }),
|
|
74
|
+
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
|
|
75
|
+
});
|
|
76
|
+
// Invariant: a pinned Settings tab closes as a tab; neither Esc nor one unclaimed Ctrl+C dismisses its screen.
|
|
77
|
+
return hostApp(SETTINGS_APP_ID, SETTINGS_ROUTE, () => new SettingsApp(settings, {
|
|
78
|
+
pinned,
|
|
79
|
+
searchInputFactory,
|
|
80
|
+
configurePlusMenu: options.configurePlusMenu ?? null,
|
|
81
|
+
...(options.copyText === undefined ? {} : { copyText: options.copyText }),
|
|
82
|
+
}), !pinned, true);
|
|
68
83
|
}
|
|
69
|
-
async function loadReferenceSurface(settings,
|
|
84
|
+
async function loadReferenceSurface(settings, route, title, document, pinned) {
|
|
85
|
+
const id = route;
|
|
70
86
|
// Rationale: the app module and the document load together, so a document that fails
|
|
71
87
|
// to render is reported by the placeholder rather than by a screen that never fills.
|
|
72
88
|
const [{ ReferenceScreenApp }, content] = await Promise.all([import("../features/owned-ui/reference-screen-app.js"), document]);
|
|
@@ -79,9 +95,10 @@ async function loadReferenceSurface(settings, id, route, title, document) {
|
|
|
79
95
|
scrollbarStyle: settings.value("scrollbarStyle"),
|
|
80
96
|
scrollbarSpeed: settings.value("scrollbarSpeed"),
|
|
81
97
|
}),
|
|
82
|
-
|
|
98
|
+
pinned,
|
|
99
|
+
}), !pinned);
|
|
83
100
|
}
|
|
84
|
-
async function hostApp(id, route, create, closeOnInterrupt = true) {
|
|
101
|
+
async function hostApp(id, route, create, closeOnInterrupt = true, appInputBeforeInterrupt = false) {
|
|
85
102
|
const [{ UiAppHost }, { UiAppRegistry }] = await Promise.all([
|
|
86
103
|
import("../ui/apps/host.js"),
|
|
87
104
|
import("../ui/apps/registry.js"),
|
|
@@ -96,6 +113,7 @@ async function hostApp(id, route, create, closeOnInterrupt = true) {
|
|
|
96
113
|
const host = new UiAppHost({
|
|
97
114
|
registry,
|
|
98
115
|
closeOnInterrupt,
|
|
116
|
+
appInputBeforeInterrupt,
|
|
99
117
|
theme: pinnedTheme(),
|
|
100
118
|
surface: {
|
|
101
119
|
size: () => size,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SettingsSearchInputFactory } from "../features/owned-ui/settings-search-input.js";
|
|
2
|
+
import { type PiKeybindingsHost } from "../integrations/pi/components/shell-shared-facade.js";
|
|
3
|
+
export interface SettingsSearchInputFactoryOptions {
|
|
4
|
+
readonly keybindings?: PiKeybindingsHost;
|
|
5
|
+
readonly agentDir?: string;
|
|
6
|
+
readonly cwd?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Builds Settings search from the same configurable owned editor used by the agent prompt. */
|
|
9
|
+
export declare function createSettingsSearchInputFactory(options?: SettingsSearchInputFactoryOptions): SettingsSearchInputFactory;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { editorInsertedText } from "../integrations/pi/components/owned-editor-ux.js";
|
|
2
|
+
import { createPiShellEditor } from "../integrations/pi/components/shell-editor-autocomplete.js";
|
|
3
|
+
import { piShellTruncateToWidth, piShellVisibleWidth, } from "../integrations/pi/components/shell-shared-facade.js";
|
|
4
|
+
import { backgroundSgrSpan } from "../ui/components/spans.js";
|
|
5
|
+
import { caretCell } from "../ui/components/line-input.js";
|
|
6
|
+
import { PromptInput } from "../ui/components/prompt-input.js";
|
|
7
|
+
/** Builds Settings search from the same configurable owned editor used by the agent prompt. */
|
|
8
|
+
export function createSettingsSearchInputFactory(options = {}) {
|
|
9
|
+
return {
|
|
10
|
+
isTextInput: data => {
|
|
11
|
+
const text = editorInsertedText(data);
|
|
12
|
+
return text !== undefined && /[^\p{Cc}]/u.test(text);
|
|
13
|
+
},
|
|
14
|
+
create: surface => createSettingsSearchInput(surface, options),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function createSettingsSearchInput(surface, options) {
|
|
18
|
+
let columns = 80;
|
|
19
|
+
const editor = createPiShellEditor({
|
|
20
|
+
keybindingProfile: "a1",
|
|
21
|
+
inputCapabilities: {
|
|
22
|
+
singleLine: true,
|
|
23
|
+
paste: false,
|
|
24
|
+
autocomplete: false,
|
|
25
|
+
placeholder: "Search settings",
|
|
26
|
+
},
|
|
27
|
+
...(options.keybindings === undefined ? {} : { keybindings: options.keybindings }),
|
|
28
|
+
...(options.agentDir === undefined ? {} : { agentDir: options.agentDir }),
|
|
29
|
+
cwd: options.cwd ?? process.cwd(),
|
|
30
|
+
getColumns: () => columns,
|
|
31
|
+
getRows: surface.getRows,
|
|
32
|
+
requestRender: surface.requestRender,
|
|
33
|
+
onSubmit: () => { },
|
|
34
|
+
onCopyText: text => surface.copyText(text),
|
|
35
|
+
paintEditorSelection: (line, from, to, atomic) => backgroundSgrSpan(line, from, to, atomic ? "\u001b[7m" : "\u001b[27m\u001b[48;2;38;79;120m", atomic ? "\u001b[27m" : "\u001b[49m", piShellVisibleWidth),
|
|
36
|
+
promptPresentation: {
|
|
37
|
+
input: new PromptInput({ fg: (token, text) => surface.theme.fg(token, text) }, {
|
|
38
|
+
measure: piShellVisibleWidth,
|
|
39
|
+
truncate: piShellTruncateToWidth,
|
|
40
|
+
}),
|
|
41
|
+
styleSuggestion: text => surface.theme.fg("dim", text),
|
|
42
|
+
styleSuggestionCaret: caretCell,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
editor.setFocused?.(true);
|
|
46
|
+
return {
|
|
47
|
+
render(width) {
|
|
48
|
+
columns = width;
|
|
49
|
+
return editor.render(width);
|
|
50
|
+
},
|
|
51
|
+
handleInput: (data) => editor.handleInput?.(data),
|
|
52
|
+
handlePointer: (event) => editor.handlePointer(event),
|
|
53
|
+
getText: () => editor.getText(),
|
|
54
|
+
hasSelection: () => editor.hasSelection(),
|
|
55
|
+
ownsPointer: () => editor.ownsPointer(),
|
|
56
|
+
setFocused: (focused) => editor.setFocused?.(focused),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { OwnedUiApplicationPort, PresentationTerminalPort } from "../contracts/presentation/index.js";
|
|
2
|
+
import type { TabBridgeClient } from "../foundation/resident-tabs/bridge-client.js";
|
|
3
|
+
import type { ResidentTabRoute } from "../foundation/resident-tabs/routes.js";
|
|
4
|
+
import type { ReleaseNoteCatalog } from "../features/owned-ui/release-notes.js";
|
|
5
|
+
import type { UiRouteHost } from "../ui/apps/contracts.js";
|
|
6
|
+
import type { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
7
|
+
import { terminateOwnedUiProcess } from "../features/owned-ui/run.js";
|
|
8
|
+
export { terminateOwnedUiProcess };
|
|
9
|
+
export interface UtilityTabOptions {
|
|
10
|
+
readonly route: ResidentTabRoute;
|
|
11
|
+
readonly bridge: TabBridgeClient;
|
|
12
|
+
readonly cwd?: string;
|
|
13
|
+
readonly profileId?: string;
|
|
14
|
+
readonly terminal?: PresentationTerminalPort;
|
|
15
|
+
readonly agentDir?: string;
|
|
16
|
+
readonly settings?: OwnedSettingsManager;
|
|
17
|
+
readonly routeHost?: UiRouteHost;
|
|
18
|
+
readonly releaseNotes?: ReleaseNoteCatalog;
|
|
19
|
+
readonly onApplication?: (application: OwnedUiApplicationPort) => void;
|
|
20
|
+
}
|
|
21
|
+
export interface UtilityTabComposition {
|
|
22
|
+
readonly application: OwnedUiApplicationPort;
|
|
23
|
+
readonly settings: OwnedSettingsManager;
|
|
24
|
+
}
|
|
25
|
+
/** Runs one pinned Settings or Changelog screen without constructing an Agent engine or session. */
|
|
26
|
+
export declare function runUtilityTab(options: UtilityTabOptions): Promise<number>;
|
|
27
|
+
export declare function composeUtilityTab(options: UtilityTabOptions): Promise<UtilityTabComposition>;
|
|
28
|
+
export declare function utilityAgentDir(environment?: NodeJS.ProcessEnv): string;
|