@timurproko/a1 0.1.8-dev.512 → 0.1.8-dev.521
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 +64 -20
- package/dist/app/session-shell/index.d.ts +1 -1
- package/dist/app/session-shell/prompt-suggestion-controller.d.ts +2 -0
- package/dist/app/session-shell/prompt-suggestion-controller.js +12 -0
- package/dist/app/session-shell/session-shell-root.d.ts +10 -0
- package/dist/app/session-shell/session-shell-root.js +12 -2
- package/dist/app/session-shell/session-shell.d.ts +8 -1
- package/dist/app/session-shell/session-shell.js +217 -18
- package/dist/composition/index.d.ts +1 -1
- package/dist/composition/owned-ui.js +21 -3
- package/dist/composition/settings-route-host.d.ts +17 -4
- package/dist/composition/settings-route-host.js +47 -16
- package/dist/contracts/owned-ui/index.d.ts +1 -1
- package/dist/contracts/owned-ui/model.d.ts +1 -5
- package/dist/features/owned-ui/index.d.ts +3 -0
- package/dist/features/owned-ui/index.js +2 -0
- package/dist/features/owned-ui/reference-routes.d.ts +6 -0
- package/dist/features/owned-ui/reference-routes.js +6 -0
- package/dist/features/owned-ui/reference-screen-app.d.ts +37 -0
- package/dist/features/owned-ui/reference-screen-app.js +232 -0
- package/dist/features/owned-ui/settings-app.js +2 -7
- package/dist/integrations/pi/components/index.d.ts +4 -2
- package/dist/integrations/pi/components/index.js +2 -1
- package/dist/integrations/pi/components/models-dialog.d.ts +55 -0
- package/dist/integrations/pi/components/models-dialog.js +310 -0
- package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +10 -0
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +29 -5
- package/dist/integrations/pi/components/shell-footer-status.js +2 -1
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +10 -0
- package/dist/integrations/pi/components/shell-presenters-info.js +31 -11
- package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +11 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +13 -0
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +8 -0
- package/dist/integrations/pi/components/skills-command.d.ts +47 -0
- package/dist/integrations/pi/components/skills-command.js +118 -0
- package/dist/integrations/pi/components/skills-dialog.d.ts +9 -0
- package/dist/integrations/pi/components/skills-dialog.js +123 -0
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +8 -2
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +42 -7
- package/dist/integrations/pi/engine/adapter.d.ts +5 -1
- package/dist/integrations/pi/engine/adapter.js +13 -1
- package/dist/integrations/pi/engine/index.d.ts +2 -2
- package/dist/integrations/pi/engine/index.js +1 -1
- package/dist/integrations/pi/engine/resource-catalog.d.ts +2 -1
- package/dist/integrations/pi/engine/resource-catalog.js +19 -9
- package/dist/integrations/pi/engine/workflow-contexts.d.ts +8 -1
- package/dist/integrations/pi/engine/workflow-contexts.js +52 -8
- package/dist/integrations/pi/engine/workflow-runner.js +98 -74
- package/dist/integrations/pi/engine/workflows.d.ts +26 -2
- package/dist/integrations/pi/engine/workflows.js +8 -0
- 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/ui/apps/contracts.d.ts +9 -1
- package/dist/ui/apps/index.d.ts +1 -1
- package/dist/ui/settings/declarations.d.ts +15 -29
- package/dist/ui/settings/declarations.js +14 -25
- package/dist/ui/settings/index.d.ts +1 -1
- package/dist/ui/settings/index.js +1 -1
- package/dist/ui/settings/migrations.js +18 -0
- package/docs/architecture/prompt-suggestions.md +1 -1
- package/docs/architecture/ui-reference-provenance.md +1 -0
- package/docs/ci-release-runbook.md +31 -23
- package/docs/features/modal-content-interaction.md +3 -2
- package/package.json +1 -1
|
@@ -9,12 +9,14 @@ import { assertPromptImages, ImageAttachmentError } from "../../contracts/owned-
|
|
|
9
9
|
import { ContextualPromptSuggestionController } from "./prompt-suggestion-controller.js";
|
|
10
10
|
import { MOUSE_TRACKING_OFF, MOUSE_TRACKING_ON, parseMouseInput } from "../../ui/components/mouse.js";
|
|
11
11
|
import { readVisibleHyperlinks } from "../../ui/components/visible-hyperlinks.js";
|
|
12
|
-
import { PINNED_PI_HIDDEN_COMMAND_NAMES,
|
|
12
|
+
import { PINNED_PI_HIDDEN_COMMAND_NAMES, workflowCommandNames } from "../../integrations/pi/engine/workflows.js";
|
|
13
13
|
import { createPiExtensionUiBridge } from "../../integrations/pi/components/shell-extension-ui.js";
|
|
14
14
|
import { createPiShellEditor } from "../../integrations/pi/components/shell-editor-autocomplete.js";
|
|
15
|
+
import { SKILLS_COMMAND_NAME, findSkillByArgument, rewriteSkillsTunnelSubmission, skillPrompt, skillsFromCommands, } from "../../integrations/pi/components/skills-command.js";
|
|
15
16
|
import { createPiQueuedInputStatus, createPiShellFooter, createPiShellHeader, createPiShellLoadedResources, createPiShellStatus, } from "../../integrations/pi/components/shell-footer-status.js";
|
|
16
|
-
import { createPiShellArmin, createPiShellAuthProviderSelector, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellExtensionSelector, createPiShellLoginDialog, createPiShellModelSelector, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellThinkingSelector, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, } from "../../integrations/pi/components/shell-selectors-dialogs.js";
|
|
17
|
+
import { createPiShellArmin, createPiShellAuthProviderSelector, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellExtensionSelector, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellSkillsSelector, createPiShellThinkingSelector, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, } from "../../integrations/pi/components/shell-selectors-dialogs.js";
|
|
17
18
|
import { createPiShellChangelog, createPiShellHotkeys, createPiShellSessionInfo, renderPiShellStatusText, } from "../../integrations/pi/components/shell-presenters-info.js";
|
|
19
|
+
import { CHANGELOG_ROUTE } from "../../features/owned-ui/reference-routes.js";
|
|
18
20
|
import { createPiShellTranscriptComponent, renderPiShellPackageUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellTranscriptBlock, } from "../../integrations/pi/components/shell-presenters-transcript.js";
|
|
19
21
|
import { onPiThemeChange, piTheme } from "../../integrations/pi/components/upstream/theme/theme.js";
|
|
20
22
|
import { DamageAwareTerminalAdapter } from "../../integrations/pi/tui-runtime/damage-aware-terminal.js";
|
|
@@ -35,6 +37,9 @@ export class OwnedUiSessionShell {
|
|
|
35
37
|
#unsubscribe;
|
|
36
38
|
#unsubscribePromptSuggestions;
|
|
37
39
|
#promptSuggestions;
|
|
40
|
+
#skills;
|
|
41
|
+
#unsubscribeSkills;
|
|
42
|
+
#installedCommandSignature = "";
|
|
38
43
|
#promptHistory = null;
|
|
39
44
|
#promptHistoryImageSidecar;
|
|
40
45
|
#extensionBridge;
|
|
@@ -51,6 +56,8 @@ export class OwnedUiSessionShell {
|
|
|
51
56
|
#shutdownPromise;
|
|
52
57
|
#disposePromise;
|
|
53
58
|
#pointerReporting = false;
|
|
59
|
+
// Invariant: the startup release notes open at most once per shell, whatever the view does later.
|
|
60
|
+
#startupChangelogHandled = false;
|
|
54
61
|
#customViewport;
|
|
55
62
|
#responseCopy;
|
|
56
63
|
// Rationale: only an executor this shell created owns a spare copy helper worth warming and disposing.
|
|
@@ -96,6 +103,8 @@ export class OwnedUiSessionShell {
|
|
|
96
103
|
let streamPresentation;
|
|
97
104
|
let pendingClipboardWrite = Promise.resolve();
|
|
98
105
|
let promptSuggestionController = null;
|
|
106
|
+
// Invariant: the collapsed skills presentation is a bare-A1 replacement; comparison profiles keep the pinned list.
|
|
107
|
+
this.#skills = this.#customViewport ? options.skills ?? null : null;
|
|
99
108
|
const terminalCopy = terminal !== undefined || hasAsyncClipboardOutput();
|
|
100
109
|
this.#responseCopy = this.#customViewport ? new ResponseCopyCoordinator({
|
|
101
110
|
execute: responseCopy?.execute ?? (this.#copyExecutor = createResponseCopyExecutor({
|
|
@@ -160,7 +169,7 @@ export class OwnedUiSessionShell {
|
|
|
160
169
|
onInterrupt: () => { void this.interrupt(); },
|
|
161
170
|
onClear: () => { void this.clearOrExit(); },
|
|
162
171
|
onExit: () => { void this.shutdown(); },
|
|
163
|
-
onModelSelect: () => this.showModelSelector(),
|
|
172
|
+
onModelSelect: () => this.#customViewport ? this.showModelsDialog() : this.showModelSelector(),
|
|
164
173
|
onModelCycle: direction => { void this.cycleModel(direction); },
|
|
165
174
|
onThinkingCycle: () => { void this.cycleThinkingLevel(); },
|
|
166
175
|
onThinkingToggle: () => {
|
|
@@ -170,7 +179,7 @@ export class OwnedUiSessionShell {
|
|
|
170
179
|
onMessageCopy: () => { void this.runWorkflow({ command: "copy", argument: "" }); },
|
|
171
180
|
onFollowUp: () => { void this.queueFollowUp().catch(() => this.#reportSubmissionError()); },
|
|
172
181
|
onDequeue: () => this.restoreQueuedInput(),
|
|
173
|
-
onEditorChange: () => { this.#editorRevision++; promptSuggestionController?.
|
|
182
|
+
onEditorChange: () => { this.#editorRevision++; promptSuggestionController?.abortPending(); },
|
|
174
183
|
onPromptSuggestionAccepted: () => promptSuggestionController?.accept(),
|
|
175
184
|
onInputSurfaceChanged: () => {
|
|
176
185
|
promptSuggestionController?.invalidate();
|
|
@@ -207,6 +216,7 @@ export class OwnedUiSessionShell {
|
|
|
207
216
|
},
|
|
208
217
|
...(pasteDiagnostics === undefined ? {} : { pasteDiagnostics: pasteDiagnostics }),
|
|
209
218
|
...(pastePreparation === undefined ? {} : { pastePreparation }),
|
|
219
|
+
skillsPresentation: () => this.#skills?.presentation() ?? "expand",
|
|
210
220
|
}, {
|
|
211
221
|
...startup,
|
|
212
222
|
resources: startup?.resources ?? shellResourceEntries(this.backend),
|
|
@@ -287,6 +297,15 @@ export class OwnedUiSessionShell {
|
|
|
287
297
|
this.#unsubscribePromptSuggestions = promptSuggestionOptions === undefined
|
|
288
298
|
? () => { }
|
|
289
299
|
: promptSuggestionOptions.onChange(enabled => this.#promptSuggestions?.setEnabled(enabled));
|
|
300
|
+
// Rationale: the same listener refreshes the menu for the A1 presentation choice and for the engine's
|
|
301
|
+
// skill-command registration, both of which the owned settings manager reports through one change.
|
|
302
|
+
this.#unsubscribeSkills = this.#skills === null ? () => { } : this.#skills.onChange(() => {
|
|
303
|
+
// Invariant: reinstalling drops extension provider wrappers, so an unrelated setting change leaves the list alone.
|
|
304
|
+
if (this.#disposed || this.#commandListSignature() === this.#installedCommandSignature)
|
|
305
|
+
return;
|
|
306
|
+
this.#installAutocompleteCommands();
|
|
307
|
+
this.runtime.requestRender();
|
|
308
|
+
});
|
|
290
309
|
const initialPiSettings = this.backend.pinnedSettingsSnapshot();
|
|
291
310
|
this.runtime.setHardwareCursor(initialPiSettings.showHardwareCursor);
|
|
292
311
|
this.runtime.setClearOnShrink(initialPiSettings.clearOnShrink);
|
|
@@ -453,7 +472,7 @@ export class OwnedUiSessionShell {
|
|
|
453
472
|
},
|
|
454
473
|
finishLogin: () => this.#finishWorkflowLogin(),
|
|
455
474
|
});
|
|
456
|
-
this
|
|
475
|
+
this.#installAutocompleteCommands();
|
|
457
476
|
this.#unsubscribe = this.backend.onEvent(event => {
|
|
458
477
|
// Performance: a streamed chunk names one block, and touching only that block is what keeps the
|
|
459
478
|
// cost of a chunk the same in a long session as in a new one. Everything else
|
|
@@ -669,7 +688,7 @@ export class OwnedUiSessionShell {
|
|
|
669
688
|
}, displayInput);
|
|
670
689
|
}
|
|
671
690
|
async clearOrExit(now = Date.now()) {
|
|
672
|
-
this.#promptSuggestions?.
|
|
691
|
+
this.#promptSuggestions?.abortPending();
|
|
673
692
|
if (now - this.#lastClearTime < 500)
|
|
674
693
|
return this.shutdown();
|
|
675
694
|
this.root.editor.setText("");
|
|
@@ -834,6 +853,23 @@ export class OwnedUiSessionShell {
|
|
|
834
853
|
this.root.setInputSurface(component);
|
|
835
854
|
this.runtime.requestRender();
|
|
836
855
|
}
|
|
856
|
+
/** The Skills dialog: a replacement input like the model selector, applying the chosen skill through the prompt path. */
|
|
857
|
+
showSkillsSelector(skills = this.#skillSummaries()) {
|
|
858
|
+
const close = () => {
|
|
859
|
+
this.root.setInputSurface(null);
|
|
860
|
+
this.runtime.requestRender();
|
|
861
|
+
};
|
|
862
|
+
const component = createPiShellSkillsSelector({
|
|
863
|
+
skills,
|
|
864
|
+
onSelect: name => {
|
|
865
|
+
close();
|
|
866
|
+
void this.#submitSkillPrompt(skillPrompt(name), skillPrompt(name)).catch(() => this.#reportSubmissionError());
|
|
867
|
+
},
|
|
868
|
+
onCancel: close,
|
|
869
|
+
});
|
|
870
|
+
this.root.setInputSurface(component);
|
|
871
|
+
this.runtime.requestRender();
|
|
872
|
+
}
|
|
837
873
|
showModelSelector(initialSearchInput) {
|
|
838
874
|
const context = this.backend.pinnedModelSelectorContext();
|
|
839
875
|
const close = () => {
|
|
@@ -1139,6 +1175,10 @@ export class OwnedUiSessionShell {
|
|
|
1139
1175
|
this.showScopedModelsSelector();
|
|
1140
1176
|
return { outcome: "completed", diagnostic: null };
|
|
1141
1177
|
}
|
|
1178
|
+
if (request.command === "models" && request.selection === undefined) {
|
|
1179
|
+
this.showModelsDialog(request.argument.trim() || undefined);
|
|
1180
|
+
return { outcome: "completed", diagnostic: null };
|
|
1181
|
+
}
|
|
1142
1182
|
if (request.command === "model" && request.selection === undefined && request.confirmed === undefined && request.argument.trim().length === 0) {
|
|
1143
1183
|
this.showModelSelector();
|
|
1144
1184
|
return { outcome: "completed", diagnostic: null };
|
|
@@ -1247,10 +1287,10 @@ export class OwnedUiSessionShell {
|
|
|
1247
1287
|
if (request.command === "reload" && result.outcome === "completed") {
|
|
1248
1288
|
this.root.resetWorkflowPresentation();
|
|
1249
1289
|
this.root.editor.reloadKeybindings();
|
|
1250
|
-
this
|
|
1290
|
+
this.#installAutocompleteCommands();
|
|
1251
1291
|
}
|
|
1252
1292
|
this.root.appendWorkflowResult(result);
|
|
1253
|
-
if (request.command === "model" && result.outcome === "completed")
|
|
1293
|
+
if ((request.command === "model" || request.command === "models") && result.outcome === "completed")
|
|
1254
1294
|
this.#showDaxnutsForActiveModel();
|
|
1255
1295
|
this.runtime.requestRender();
|
|
1256
1296
|
return workflowAdapterResult(result);
|
|
@@ -1357,6 +1397,90 @@ export class OwnedUiSessionShell {
|
|
|
1357
1397
|
this.runtime.requestRender();
|
|
1358
1398
|
}).finally(() => clearTimeout(timeout));
|
|
1359
1399
|
}
|
|
1400
|
+
// Invariant: bare A1 routes `models`; the comparison profile keeps the pinned `model`/`scoped-models` pair. Hidden routes are shared.
|
|
1401
|
+
#isWorkflowRoute(value) {
|
|
1402
|
+
return workflowCommandNames(this.#customViewport ? "bare" : "comparison").includes(value)
|
|
1403
|
+
|| PINNED_PI_HIDDEN_COMMAND_NAMES.includes(value);
|
|
1404
|
+
}
|
|
1405
|
+
/** The bare-A1 unified Models dialog: switch on Enter, scope on Space, persist on Ctrl+S, all through the engine. */
|
|
1406
|
+
showModelsDialog(initialQuery) {
|
|
1407
|
+
const context = this.backend.modelsContext();
|
|
1408
|
+
const available = new Set(context.models.map(model => `${model.provider}/${model.id}`));
|
|
1409
|
+
const savedScopeIds = context.persistedScopeIds.filter(id => available.has(id));
|
|
1410
|
+
// Invariant: an explicit session scope wins; otherwise the dialog starts from what is persisted, never from "all rows scoped".
|
|
1411
|
+
const scopeIds = context.sessionScopeIds.length > 0 ? context.sessionScopeIds : savedScopeIds;
|
|
1412
|
+
let disposed = false;
|
|
1413
|
+
let timedOut = false;
|
|
1414
|
+
const controller = new AbortController();
|
|
1415
|
+
const timeout = setTimeout(() => {
|
|
1416
|
+
timedOut = true;
|
|
1417
|
+
controller.abort();
|
|
1418
|
+
}, 15_000);
|
|
1419
|
+
const close = () => {
|
|
1420
|
+
disposed = true;
|
|
1421
|
+
clearTimeout(timeout);
|
|
1422
|
+
controller.abort();
|
|
1423
|
+
this.root.setInputSurface(null);
|
|
1424
|
+
this.runtime.requestRender();
|
|
1425
|
+
};
|
|
1426
|
+
const dialog = createPiShellModelsDialog({
|
|
1427
|
+
models: context.models,
|
|
1428
|
+
activeModelId: context.activeModelId,
|
|
1429
|
+
scopeIds,
|
|
1430
|
+
savedScopeIds,
|
|
1431
|
+
...(initialQuery === undefined ? {} : { initialQuery }),
|
|
1432
|
+
refreshStatus: "Refreshing model catalogs…",
|
|
1433
|
+
requestRender: () => this.runtime.requestRender(),
|
|
1434
|
+
onSelect: modelId => {
|
|
1435
|
+
void this.runWorkflow({ command: "models", argument: "", selection: modelId }).then(result => {
|
|
1436
|
+
if (!disposed && result.outcome === "completed")
|
|
1437
|
+
close();
|
|
1438
|
+
});
|
|
1439
|
+
},
|
|
1440
|
+
onScopeChange: ids => {
|
|
1441
|
+
this.backend.setSessionModelScope(ids);
|
|
1442
|
+
this.runtime.requestRender();
|
|
1443
|
+
},
|
|
1444
|
+
onSave: ids => {
|
|
1445
|
+
try {
|
|
1446
|
+
this.backend.persistModelScope(ids);
|
|
1447
|
+
}
|
|
1448
|
+
catch (error) {
|
|
1449
|
+
this.root.appendWorkflowResult({ command: "models", outcome: "failed", message: error instanceof Error ? error.message : String(error) });
|
|
1450
|
+
this.runtime.requestRender();
|
|
1451
|
+
throw error;
|
|
1452
|
+
}
|
|
1453
|
+
this.root.appendWorkflowStatus("Model selection saved to settings");
|
|
1454
|
+
this.runtime.requestRender();
|
|
1455
|
+
},
|
|
1456
|
+
onCancel: close,
|
|
1457
|
+
});
|
|
1458
|
+
const component = {
|
|
1459
|
+
...dialog,
|
|
1460
|
+
dispose: () => {
|
|
1461
|
+
disposed = true;
|
|
1462
|
+
clearTimeout(timeout);
|
|
1463
|
+
controller.abort();
|
|
1464
|
+
dialog.dispose?.();
|
|
1465
|
+
},
|
|
1466
|
+
};
|
|
1467
|
+
this.root.setInputSurface(component);
|
|
1468
|
+
this.runtime.requestRender();
|
|
1469
|
+
void this.backend.refreshModels(controller.signal).then(refreshed => {
|
|
1470
|
+
if (disposed)
|
|
1471
|
+
return;
|
|
1472
|
+
component.updateModels(refreshed.models);
|
|
1473
|
+
component.setRefreshStatus(timedOut ? "Model refresh timed out; showing cached models." : refreshed.status, timedOut ? "warning" : refreshed.statusKind);
|
|
1474
|
+
this.runtime.requestRender();
|
|
1475
|
+
}).catch(error => {
|
|
1476
|
+
if (disposed)
|
|
1477
|
+
return;
|
|
1478
|
+
component.setRefreshStatus(timedOut
|
|
1479
|
+
? "Model refresh timed out; showing cached models."
|
|
1480
|
+
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
1481
|
+
this.runtime.requestRender();
|
|
1482
|
+
}).finally(() => clearTimeout(timeout));
|
|
1483
|
+
}
|
|
1360
1484
|
#showDaxnutsForActiveModel() {
|
|
1361
1485
|
const model = this.view().activeModel;
|
|
1362
1486
|
if (model?.providerId === "opencode" && model.modelId.toLowerCase().includes("kimi-k2.5")) {
|
|
@@ -1409,6 +1533,7 @@ export class OwnedUiSessionShell {
|
|
|
1409
1533
|
attempt(() => this.#streamPresentation.dispose());
|
|
1410
1534
|
attempt(() => this.#promptSuggestions?.dispose());
|
|
1411
1535
|
attempt(() => this.#unsubscribePromptSuggestions());
|
|
1536
|
+
attempt(() => this.#unsubscribeSkills());
|
|
1412
1537
|
attempt(() => this.#unsubscribeSettings());
|
|
1413
1538
|
let fullscreenExitText = "";
|
|
1414
1539
|
attempt(() => {
|
|
@@ -1453,11 +1578,13 @@ export class OwnedUiSessionShell {
|
|
|
1453
1578
|
if (!this.runtime.active || this.runtime.mode !== "fullscreen")
|
|
1454
1579
|
return null;
|
|
1455
1580
|
try {
|
|
1456
|
-
|
|
1457
|
-
if (!enabled)
|
|
1581
|
+
if (!outro.snapshot().enabled)
|
|
1458
1582
|
return null;
|
|
1459
1583
|
const viewport = this.runtime.viewport();
|
|
1460
|
-
return {
|
|
1584
|
+
return {
|
|
1585
|
+
rows: this.#damageTerminal.presentedRows(), columns: viewport.columns, height: viewport.rows,
|
|
1586
|
+
settings: { effect: QUIT_OUTRO_EFFECT, durationMs: QUIT_OUTRO_DURATION_MS },
|
|
1587
|
+
};
|
|
1461
1588
|
}
|
|
1462
1589
|
catch {
|
|
1463
1590
|
return null;
|
|
@@ -1550,13 +1677,31 @@ export class OwnedUiSessionShell {
|
|
|
1550
1677
|
}
|
|
1551
1678
|
this.root.update(view);
|
|
1552
1679
|
this.#syncDialog(view.dialog);
|
|
1680
|
+
this.#presentStartupChangelog(view);
|
|
1553
1681
|
this.runtime.requestRender();
|
|
1554
1682
|
for (const listener of this.#listeners)
|
|
1555
1683
|
listener(view);
|
|
1556
1684
|
return view;
|
|
1557
1685
|
}
|
|
1558
|
-
|
|
1559
|
-
|
|
1686
|
+
// Rationale: the engine has already stored the current version when the diagnostic arrives, so the
|
|
1687
|
+
// entries newer than the last acknowledged one exist only in its message; the screen shows exactly those.
|
|
1688
|
+
#presentStartupChangelog(view) {
|
|
1689
|
+
if (this.#startupChangelogHandled || !this.#customViewport || this.#routeHost === null)
|
|
1690
|
+
return;
|
|
1691
|
+
const diagnostic = view.diagnostics.find(candidate => candidate.code === "changelog-expanded");
|
|
1692
|
+
// Invariant: a view synchronized before the runtime starts is not the moment of arrival; start() replays it.
|
|
1693
|
+
if (diagnostic === undefined || !this.runtime.active)
|
|
1694
|
+
return;
|
|
1695
|
+
this.#startupChangelogHandled = true;
|
|
1696
|
+
// Invariant: a dialog, selector, or owned screen already up keeps the screen; the hint stays in the feed.
|
|
1697
|
+
if (this.#dialogHandle !== undefined || !this.root.usesDefaultInputSurface())
|
|
1698
|
+
return;
|
|
1699
|
+
if (!this.#routeHost.claims(CHANGELOG_ROUTE))
|
|
1700
|
+
return;
|
|
1701
|
+
this.#openOwnedRoute(CHANGELOG_ROUTE, { document: diagnostic.message });
|
|
1702
|
+
}
|
|
1703
|
+
#openOwnedRoute(route, input) {
|
|
1704
|
+
const surface = this.#routeHost?.open(route, input) ?? null;
|
|
1560
1705
|
if (surface === null)
|
|
1561
1706
|
return { outcome: "failed", diagnostic: `route is unavailable: ${route}` };
|
|
1562
1707
|
if (!this.runtime.active)
|
|
@@ -1683,6 +1828,9 @@ export class OwnedUiSessionShell {
|
|
|
1683
1828
|
});
|
|
1684
1829
|
this.#dialogId = dialog.id;
|
|
1685
1830
|
}
|
|
1831
|
+
hotkeysPresentation() {
|
|
1832
|
+
return this.root.hotkeysPresentation();
|
|
1833
|
+
}
|
|
1686
1834
|
async #slashCommand(text) {
|
|
1687
1835
|
const body = text.slice(1).trim();
|
|
1688
1836
|
const separator = body.search(/\s/);
|
|
@@ -1690,8 +1838,15 @@ export class OwnedUiSessionShell {
|
|
|
1690
1838
|
const argument = separator < 0 ? "" : body.slice(separator + 1).trimStart();
|
|
1691
1839
|
if (this.#routeHost?.claims(name))
|
|
1692
1840
|
return this.#openOwnedRoute(name);
|
|
1693
|
-
if (isWorkflowRoute(name))
|
|
1841
|
+
if (this.#isWorkflowRoute(name))
|
|
1694
1842
|
return this.runWorkflow({ command: name, argument });
|
|
1843
|
+
if (this.#skillsCollapsed()) {
|
|
1844
|
+
if (name === SKILLS_COMMAND_NAME)
|
|
1845
|
+
return this.#runSkillsCommand(text, argument);
|
|
1846
|
+
const rewritten = rewriteSkillsTunnelSubmission(text);
|
|
1847
|
+
if (rewritten !== text)
|
|
1848
|
+
return this.#submitSkillPrompt(rewritten, text);
|
|
1849
|
+
}
|
|
1695
1850
|
// Compatibility: unknown slash input, prompt templates, skills, and extension commands remain Pi prompt input.
|
|
1696
1851
|
this.#rememberInput(text, "slash");
|
|
1697
1852
|
this.root.resumeViewportFollowing();
|
|
@@ -1702,6 +1857,51 @@ export class OwnedUiSessionShell {
|
|
|
1702
1857
|
text,
|
|
1703
1858
|
});
|
|
1704
1859
|
}
|
|
1860
|
+
#installAutocompleteCommands() {
|
|
1861
|
+
this.root.editor.setAutocompleteCommands(this.backend.workflowAutocompleteCommands());
|
|
1862
|
+
this.#installedCommandSignature = this.#commandListSignature();
|
|
1863
|
+
}
|
|
1864
|
+
#commandListSignature() {
|
|
1865
|
+
return JSON.stringify([this.#skills?.presentation() ?? "expand", this.backend.disposed ? [] : this.backend.workflowAutocompleteCommands().map(command => command.name)]);
|
|
1866
|
+
}
|
|
1867
|
+
// Invariant: collapse applies only while the engine registers skill commands; otherwise there is nothing to collapse.
|
|
1868
|
+
#skillsCollapsed() {
|
|
1869
|
+
return this.#skills !== null && this.#skills.presentation() === "collapse"
|
|
1870
|
+
&& !this.backend.disposed && this.backend.pinnedSettingsSnapshot().enableSkillCommands;
|
|
1871
|
+
}
|
|
1872
|
+
#skillSummaries() {
|
|
1873
|
+
return skillsFromCommands(this.backend.workflowAutocompleteCommands());
|
|
1874
|
+
}
|
|
1875
|
+
// Protocol: bare "/skills" opens the dialog, "/skills <name> [args]" applies directly, and an unknown name is a command outcome.
|
|
1876
|
+
async #runSkillsCommand(text, argument) {
|
|
1877
|
+
const skills = this.#skillSummaries();
|
|
1878
|
+
const trimmed = argument.trim();
|
|
1879
|
+
if (trimmed.length === 0) {
|
|
1880
|
+
this.showSkillsSelector(skills);
|
|
1881
|
+
return { outcome: "completed", diagnostic: null };
|
|
1882
|
+
}
|
|
1883
|
+
const separator = trimmed.search(/\s/u);
|
|
1884
|
+
const token = separator < 0 ? trimmed : trimmed.slice(0, separator);
|
|
1885
|
+
const skill = findSkillByArgument(skills, token);
|
|
1886
|
+
if (skill === undefined) {
|
|
1887
|
+
const message = "Unknown skill: " + token;
|
|
1888
|
+
this.root.appendWorkflowMessage({ kind: "error", message });
|
|
1889
|
+
this.runtime.requestRender();
|
|
1890
|
+
return { outcome: "failed", diagnostic: message };
|
|
1891
|
+
}
|
|
1892
|
+
return this.#submitSkillPrompt(skillPrompt(skill.name, separator < 0 ? "" : trimmed.slice(separator + 1)), text);
|
|
1893
|
+
}
|
|
1894
|
+
// Rationale: the engine expands "/skill:<name> args" itself; history keeps the form the user typed so recall restores the invocation.
|
|
1895
|
+
#submitSkillPrompt(prompt, typed) {
|
|
1896
|
+
this.#rememberInput(typed, "slash");
|
|
1897
|
+
this.root.resumeViewportFollowing();
|
|
1898
|
+
return this.#execute({
|
|
1899
|
+
type: this.view().lifecycle === "busy" ? "steer" : "prompt",
|
|
1900
|
+
correlationId: this.#correlation("prompt-command"),
|
|
1901
|
+
sessionId: this.backend.sessionId,
|
|
1902
|
+
text: prompt,
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1705
1905
|
async #completeTreeSelection(entryId, skipSummaryPrompt) {
|
|
1706
1906
|
let summarize = false;
|
|
1707
1907
|
let customInstructions;
|
|
@@ -1911,7 +2111,6 @@ function workflowAdapterResult(result) {
|
|
|
1911
2111
|
const INTERRUPT = "\u0003";
|
|
1912
2112
|
const INTERRUPT_CHORD_MS = 1_500;
|
|
1913
2113
|
const RELOAD_SURFACE_MIN_VISIBLE_MS = 400;
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
}
|
|
2114
|
+
// Rationale: the outro is not configurable; the switch only decides whether this plan plays.
|
|
2115
|
+
const QUIT_OUTRO_EFFECT = "fall";
|
|
2116
|
+
const QUIT_OUTRO_DURATION_MS = 800;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { composeOwnedUi, composeOwnedUiApplication, type OwnedUiComposition, type OwnedUiCompositionOptions, } from "./owned-ui.js";
|
|
2
|
-
export { createOwnedRouteHost } from "./settings-route-host.js";
|
|
2
|
+
export { createOwnedRouteHost, type OwnedReferenceProviders, type OwnedReferenceRows } from "./settings-route-host.js";
|
|
@@ -12,6 +12,8 @@ import { OwnedUiSessionShell } from "../app/session-shell/session-shell.js";
|
|
|
12
12
|
import { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
13
13
|
import { createPiTerminalBridge } from "../integrations/pi/tui-runtime/presentation-adapter.js";
|
|
14
14
|
import { createOwnedRouteHost } from "./settings-route-host.js";
|
|
15
|
+
import { renderPiShellChangelogLines, renderPiShellHotkeysLines } from "../integrations/pi/components/shell-presenters-info.js";
|
|
16
|
+
import { readPinnedCommandChangelog } from "../integrations/pi/engine/changelog.js";
|
|
15
17
|
export async function composeOwnedUiApplication(options = {}) {
|
|
16
18
|
return (await composeOwnedUi(options)).application;
|
|
17
19
|
}
|
|
@@ -40,7 +42,19 @@ export async function composeOwnedUi(options = {}) {
|
|
|
40
42
|
// dark, regardless of terminal detection or a previously stored Pi theme. The
|
|
41
43
|
// comparison profile keeps Pi's configured theme behavior and settings surface.
|
|
42
44
|
applyConfiguredPiTheme(ownedSurfaces ? "dark" : adapter.configuredTheme());
|
|
43
|
-
|
|
45
|
+
// Rationale: the reference screens read the shell the composition is about to construct; a route
|
|
46
|
+
// cannot open before the shell exists, so the closure is settled by the time it runs.
|
|
47
|
+
const references = {
|
|
48
|
+
changelog: async (input) => {
|
|
49
|
+
const markdown = input?.document ?? await readPinnedCommandChangelog();
|
|
50
|
+
return width => renderPiShellChangelogLines(markdown, width);
|
|
51
|
+
},
|
|
52
|
+
hotkeys: async () => {
|
|
53
|
+
const presentation = shell.hotkeysPresentation();
|
|
54
|
+
return width => renderPiShellHotkeysLines(presentation, width);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
const routeHost = settings === null || !ownedSurfaces ? null : createOwnedRouteHost(settings, references);
|
|
44
58
|
const viewportSettings = settings === null || !ownedSurfaces ? null : {
|
|
45
59
|
snapshot: () => viewportSettingsSnapshot(settings),
|
|
46
60
|
onChange: listener => settings.onChange(() => listener(viewportSettingsSnapshot(settings))),
|
|
@@ -54,6 +68,11 @@ export async function composeOwnedUi(options = {}) {
|
|
|
54
68
|
enabled: () => settings.value("promptSuggestions"),
|
|
55
69
|
onChange: (listener) => settings.onChange(() => listener(settings.value("promptSuggestions"))),
|
|
56
70
|
};
|
|
71
|
+
const skills = settings === null || !ownedSurfaces ? null : {
|
|
72
|
+
presentation: () => settings.value("skillsPresentation"),
|
|
73
|
+
// Rationale: one listener covers both the A1 presentation choice and the engine skill-command toggle.
|
|
74
|
+
onChange: (listener) => settings.onChange(() => listener()),
|
|
75
|
+
};
|
|
57
76
|
const historyLimit = settings?.value("promptHistoryMaxItems");
|
|
58
77
|
const historyProfileLocation = settings === null || !ownedSurfaces || !settings.value("promptHistoryEnabled")
|
|
59
78
|
? null
|
|
@@ -92,6 +111,7 @@ export async function composeOwnedUi(options = {}) {
|
|
|
92
111
|
paste: event => clipboardDiagnostics.paste(event),
|
|
93
112
|
} }),
|
|
94
113
|
...(promptSuggestions === null ? {} : { suggestions: promptSuggestions }),
|
|
114
|
+
...(skills === null ? {} : { skills }),
|
|
95
115
|
...(promptHistory === null ? {} : { history: {
|
|
96
116
|
...promptHistory,
|
|
97
117
|
editor: await import("../integrations/pi/components/history-editor-loader.js").then(module => module.loadHistoryEditor()),
|
|
@@ -123,8 +143,6 @@ export async function composeOwnedUi(options = {}) {
|
|
|
123
143
|
function quitOutroSettingsSnapshot(settings) {
|
|
124
144
|
return {
|
|
125
145
|
enabled: settings.value("quitAnimation"),
|
|
126
|
-
effect: settings.value("quitEffect"),
|
|
127
|
-
durationMs: settings.value("quitEffectDurationMs"),
|
|
128
146
|
};
|
|
129
147
|
}
|
|
130
148
|
function viewportSettingsSnapshot(settings) {
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import type { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
2
|
-
import type { UiRouteHost } from "../ui/apps/contracts.js";
|
|
2
|
+
import type { UiRouteHost, UiRouteInput } from "../ui/apps/contracts.js";
|
|
3
|
+
/** Styled document rows for one content width. */
|
|
4
|
+
export type OwnedReferenceRows = (width: number) => readonly string[];
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
+
* The documents the reference routes present, supplied by the composition so the
|
|
7
|
+
* route host never reads the changelog or the shell's keybindings itself.
|
|
6
8
|
*/
|
|
7
|
-
export
|
|
9
|
+
export interface OwnedReferenceProviders {
|
|
10
|
+
/** The complete pinned changelog, or the supplied document when the route input carries one. */
|
|
11
|
+
changelog(input?: UiRouteInput): Promise<OwnedReferenceRows>;
|
|
12
|
+
/** The shell's keyboard shortcuts as they stand when the screen opens. */
|
|
13
|
+
hotkeys(): Promise<OwnedReferenceRows>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Declares the A1-owned settings route, and the changelog and hotkeys reference
|
|
17
|
+
* routes when their documents are supplied, without evaluating their presentation
|
|
18
|
+
* graphs during startup. Opening a route retains input while the optional module loads.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createOwnedRouteHost(settings: OwnedSettingsManager, references?: OwnedReferenceProviders): UiRouteHost;
|
|
@@ -1,24 +1,38 @@
|
|
|
1
|
+
import { CHANGELOG_APP_ID, CHANGELOG_ROUTE, CHANGELOG_TITLE, HOTKEYS_APP_ID, HOTKEYS_ROUTE, HOTKEYS_TITLE, } from "../features/owned-ui/reference-routes.js";
|
|
1
2
|
import { SETTINGS_APP_ID, SETTINGS_ROUTE } from "../features/owned-ui/settings-route.js";
|
|
2
3
|
import { piTheme } from "../integrations/pi/components/upstream/theme/theme.js";
|
|
3
4
|
import { faint } from "../ui/components/text.js";
|
|
4
5
|
/**
|
|
5
|
-
* Declares the A1-owned settings route
|
|
6
|
-
*
|
|
6
|
+
* Declares the A1-owned settings route, and the changelog and hotkeys reference
|
|
7
|
+
* routes when their documents are supplied, without evaluating their presentation
|
|
8
|
+
* graphs during startup. Opening a route retains input while the optional module loads.
|
|
7
9
|
*/
|
|
8
|
-
export function createOwnedRouteHost(settings) {
|
|
10
|
+
export function createOwnedRouteHost(settings, references) {
|
|
11
|
+
const routes = new Set([SETTINGS_ROUTE, ...(references === undefined ? [] : [CHANGELOG_ROUTE, HOTKEYS_ROUTE])]);
|
|
9
12
|
return {
|
|
10
|
-
claims: route => route
|
|
11
|
-
open: route
|
|
13
|
+
claims: route => routes.has(route),
|
|
14
|
+
open: (route, input) => {
|
|
15
|
+
if (!routes.has(route))
|
|
16
|
+
return null;
|
|
17
|
+
if (route === SETTINGS_ROUTE) {
|
|
18
|
+
return deferredSurface(SETTINGS_APP_ID, "settings", () => loadSettingsSurface(settings));
|
|
19
|
+
}
|
|
20
|
+
const changelog = route === CHANGELOG_ROUTE;
|
|
21
|
+
const id = changelog ? CHANGELOG_APP_ID : HOTKEYS_APP_ID;
|
|
22
|
+
const title = changelog ? CHANGELOG_TITLE : HOTKEYS_TITLE;
|
|
23
|
+
const document = changelog ? references.changelog(input) : references.hotkeys();
|
|
24
|
+
return deferredSurface(id, title, () => loadReferenceSurface(settings, id, route, title, document));
|
|
25
|
+
},
|
|
12
26
|
};
|
|
13
27
|
}
|
|
14
|
-
function
|
|
28
|
+
function deferredSurface(id, label, load) {
|
|
15
29
|
let delegate = null;
|
|
16
30
|
let closed = false;
|
|
17
31
|
let failure = null;
|
|
18
32
|
let onRender = () => undefined;
|
|
19
33
|
let onExit = () => undefined;
|
|
20
34
|
const pending = [];
|
|
21
|
-
void
|
|
35
|
+
void load().then(surface => {
|
|
22
36
|
if (closed) {
|
|
23
37
|
surface.close();
|
|
24
38
|
return;
|
|
@@ -30,7 +44,7 @@ function deferredSettingsSurface(settings) {
|
|
|
30
44
|
action(surface);
|
|
31
45
|
onRender();
|
|
32
46
|
}).catch(error => {
|
|
33
|
-
failure = `Could not load
|
|
47
|
+
failure = `Could not load ${label}: ${error instanceof Error ? error.message : String(error)}`;
|
|
34
48
|
onRender();
|
|
35
49
|
});
|
|
36
50
|
const defer = (action) => {
|
|
@@ -40,10 +54,9 @@ function deferredSettingsSurface(settings) {
|
|
|
40
54
|
pending.push(action);
|
|
41
55
|
};
|
|
42
56
|
return {
|
|
43
|
-
id
|
|
57
|
+
id,
|
|
44
58
|
render: (width, height) => delegate?.render(width, height)
|
|
45
|
-
??
|
|
46
|
-
.map(line => line.slice(0, Math.max(0, width))),
|
|
59
|
+
?? Array.from({ length: Math.max(0, height) }, (_, row) => row === 0 && failure !== null ? failure.slice(0, Math.max(0, width)) : ""),
|
|
47
60
|
handleInput: data => { defer(surface => surface.handleInput(data)); return true; },
|
|
48
61
|
handleMouse: event => { defer(surface => surface.handleMouse(event)); return true; },
|
|
49
62
|
isClosed: () => closed || delegate?.isClosed() === true,
|
|
@@ -53,13 +66,31 @@ function deferredSettingsSurface(settings) {
|
|
|
53
66
|
};
|
|
54
67
|
}
|
|
55
68
|
async function loadSettingsSurface(settings) {
|
|
56
|
-
const
|
|
57
|
-
|
|
69
|
+
const { SettingsApp } = await import("../features/owned-ui/settings-app.js");
|
|
70
|
+
return hostApp(SETTINGS_APP_ID, SETTINGS_ROUTE, () => new SettingsApp(settings));
|
|
71
|
+
}
|
|
72
|
+
async function loadReferenceSurface(settings, id, route, title, document) {
|
|
73
|
+
// Rationale: the app module and the document load together, so a document that fails
|
|
74
|
+
// to render is reported by the placeholder rather than by a screen that never fills.
|
|
75
|
+
const [{ ReferenceScreenApp }, rows] = await Promise.all([import("../features/owned-ui/reference-screen-app.js"), document]);
|
|
76
|
+
return hostApp(id, route, () => new ReferenceScreenApp({
|
|
77
|
+
id,
|
|
78
|
+
title,
|
|
79
|
+
document: { rows },
|
|
80
|
+
scrollSettings: () => ({
|
|
81
|
+
scrollbarAppearance: settings.value("scrollbarAppearance"),
|
|
82
|
+
scrollbarStyle: settings.value("scrollbarStyle"),
|
|
83
|
+
scrollbarSpeed: settings.value("scrollbarSpeed"),
|
|
84
|
+
}),
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
async function hostApp(id, route, create) {
|
|
88
|
+
const [{ UiAppHost }, { UiAppRegistry }] = await Promise.all([
|
|
58
89
|
import("../ui/apps/host.js"),
|
|
59
90
|
import("../ui/apps/registry.js"),
|
|
60
91
|
]);
|
|
61
92
|
const registry = new UiAppRegistry();
|
|
62
|
-
registry.register({ id
|
|
93
|
+
registry.register({ id, route, create });
|
|
63
94
|
let size = { width: 80, height: 24 };
|
|
64
95
|
let frame = [];
|
|
65
96
|
let closed = false;
|
|
@@ -81,9 +112,9 @@ async function loadSettingsSurface(settings) {
|
|
|
81
112
|
},
|
|
82
113
|
},
|
|
83
114
|
});
|
|
84
|
-
host.open(
|
|
115
|
+
host.open(id);
|
|
85
116
|
return {
|
|
86
|
-
id
|
|
117
|
+
id,
|
|
87
118
|
render: (width, height) => {
|
|
88
119
|
size = { width, height };
|
|
89
120
|
host.render();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { OWNED_UI_EXTENSION_CONTRACT_VERSION, OWNED_UI_EXTENSION_RENDER_CALLBACKS, OWNED_UI_EXTENSION_UI_CALLBACKS, OWNED_UI_EXTENSION_UI_PROPERTIES, assertOwnedUiExtensionUiPort, } from "./extension-ui.js";
|
|
2
2
|
export type { OwnedUiExtensionAutocompleteItem, OwnedUiExtensionAutocompleteProvider, OwnedUiExtensionAutocompleteProviderFactory, OwnedUiExtensionAutocompleteSuggestions, OwnedUiExtensionComponent, OwnedUiExtensionComponentFactory, OwnedUiExtensionComponentFactoryContext, OwnedUiExtensionCustomFactory, OwnedUiExtensionCustomOptions, OwnedUiExtensionDialogOptions, OwnedUiExtensionEditorComponent, OwnedUiExtensionEditorFactory, OwnedUiExtensionEditorThemePort, OwnedUiExtensionEntryRenderInput, OwnedUiExtensionFooterDataPort, OwnedUiExtensionFooterFactory, OwnedUiExtensionInputListener, OwnedUiExtensionKeybindingsPort, OwnedUiExtensionMessageRenderInput, OwnedUiExtensionNotificationSeverity, OwnedUiExtensionOverlayAnchor, OwnedUiExtensionOverlayHandle, OwnedUiExtensionOverlayMargin, OwnedUiExtensionOverlayOptions, OwnedUiExtensionRenderCallback, OwnedUiExtensionRendererPort, OwnedUiExtensionRuntimePort, OwnedUiExtensionSelectListThemePort, OwnedUiExtensionSizeValue, OwnedUiExtensionTerminalPort, OwnedUiExtensionThemeBackground, OwnedUiExtensionThemeColor, OwnedUiExtensionThemeInfo, OwnedUiExtensionThemePort, OwnedUiExtensionToolRenderContext, OwnedUiExtensionUiCallback, OwnedUiExtensionUiPort, OwnedUiExtensionUiProperty, OwnedUiExtensionWidgetOptions, OwnedUiExtensionWidgetPlacement, OwnedUiExtensionWorkingIndicatorOptions, } from "./extension-ui.js";
|
|
3
3
|
export { OWNED_UI_CONTRACT_VERSION } from "./model.js";
|
|
4
|
-
export type { OwnedUiBlockStatus, OwnedUiCommand, OwnedUiCommandOutcome, OwnedUiCorrelationId, OwnedUiCustomization, OwnedUiDiagnostics, OwnedUiDialog, OwnedUiEditorState, OwnedUiEntityId, OwnedUiEvent, OwnedUiFooterView, OwnedUiImageAttachment, OwnedUiLifecycle, OwnedUiModelInfo, OwnedUiOverlay, OwnedUiPromptSuggestionGeneratorPort, OwnedUiPromptSuggestionIdentity, OwnedUiPromptSuggestionReasoning, OwnedUiPromptSuggestionRequest, OwnedUiPromptSuggestionResult, OwnedUiPromptSuggestionState,
|
|
4
|
+
export type { OwnedUiBlockStatus, OwnedUiCommand, OwnedUiCommandOutcome, OwnedUiCorrelationId, OwnedUiCustomization, OwnedUiDiagnostics, OwnedUiDialog, OwnedUiEditorState, OwnedUiEntityId, OwnedUiEvent, OwnedUiFooterView, OwnedUiImageAttachment, OwnedUiLifecycle, OwnedUiModelInfo, OwnedUiOverlay, OwnedUiPromptSuggestionGeneratorPort, OwnedUiPromptSuggestionIdentity, OwnedUiPromptSuggestionReasoning, OwnedUiPromptSuggestionRequest, OwnedUiPromptSuggestionResult, OwnedUiPromptSuggestionState, OwnedUiQuitOutroSettings, OwnedUiQuitOutroSettingsPort, OwnedUiSessionId, OwnedUiSessionViewModel, OwnedUiSeverity, OwnedUiSlotId, OwnedUiSnapshot, OwnedUiStatusView, OwnedUiTerminalSurface, OwnedUiThinkingLevel, OwnedUiToolRendering, OwnedUiToolResultPart, OwnedUiToolState, OwnedUiTranscriptBlock, OwnedUiTranscriptBlockKind, OwnedUiTranscriptImageReference, OwnedUiUsageView, OwnedUiViewportSettings, OwnedUiViewportSettingsPort, } from "./model.js";
|
|
5
5
|
export { acceptsTranscriptUpdate, transcriptToolState } from "./transcript-lifecycle.js";
|
|
6
6
|
export { ImageAttachmentError, MAX_CLIPBOARD_TEXT_BYTES, MAX_IMAGE_DATA_BYTES, MAX_PROMPT_IMAGES, assertImageEncodedSize, assertPromptImages, } from "./image-attachments.js";
|
|
7
7
|
export { CONTEXTUAL_PROMPT_SUGGESTION_INSTRUCTION, normalizePromptSuggestionCandidate } from "./prompt-suggestions.js";
|
|
@@ -64,14 +64,10 @@ export interface OwnedUiViewportSettingsPort {
|
|
|
64
64
|
snapshot(): OwnedUiViewportSettings;
|
|
65
65
|
onChange(listener: (settings: OwnedUiViewportSettings) => void): () => void;
|
|
66
66
|
}
|
|
67
|
-
export type OwnedUiQuitEffect = "fall" | "dissolve" | "starburst" | "waves";
|
|
68
67
|
/** Profile-local quit outro choice, read at the moment bare A1 quits. */
|
|
69
68
|
export interface OwnedUiQuitOutroSettings {
|
|
70
|
-
/** False leaves the terminal immediately;
|
|
69
|
+
/** False leaves the terminal immediately; true plays the shell's fixed effect. */
|
|
71
70
|
readonly enabled: boolean;
|
|
72
|
-
readonly effect: OwnedUiQuitEffect;
|
|
73
|
-
/** Requested playback length; the player clamps it to its supported range. */
|
|
74
|
-
readonly durationMs: number;
|
|
75
71
|
}
|
|
76
72
|
export interface OwnedUiQuitOutroSettingsPort {
|
|
77
73
|
snapshot(): OwnedUiQuitOutroSettings;
|
|
@@ -4,3 +4,6 @@ export { createConsoleProjectTrustPrompt } from "./project-trust-prompt.js";
|
|
|
4
4
|
export type { ConsoleProjectTrustPromptOptions, OwnedProjectTrustPrompt, OwnedProjectTrustPromptRequest } from "./project-trust-prompt.js";
|
|
5
5
|
export { createConsoleSessionForkPrompt } from "./session-fork-prompt.js";
|
|
6
6
|
export { SETTINGS_APP_ID, SETTINGS_ROUTE, SETTINGS_SHORTCUTS, SettingsApp } from "./settings-app.js";
|
|
7
|
+
export { REFERENCE_SCREEN_SHORTCUTS, ReferenceScreenApp } from "./reference-screen-app.js";
|
|
8
|
+
export type { ReferenceDocumentProvider, ReferenceScreenOptions } from "./reference-screen-app.js";
|
|
9
|
+
export { CHANGELOG_APP_ID, CHANGELOG_ROUTE, CHANGELOG_TITLE, HOTKEYS_APP_ID, HOTKEYS_ROUTE, HOTKEYS_TITLE, } from "./reference-routes.js";
|
|
@@ -2,3 +2,5 @@ export { runOwnedUi, terminateOwnedUiProcess } from "./run.js";
|
|
|
2
2
|
export { createConsoleProjectTrustPrompt } from "./project-trust-prompt.js";
|
|
3
3
|
export { createConsoleSessionForkPrompt } from "./session-fork-prompt.js";
|
|
4
4
|
export { SETTINGS_APP_ID, SETTINGS_ROUTE, SETTINGS_SHORTCUTS, SettingsApp } from "./settings-app.js";
|
|
5
|
+
export { REFERENCE_SCREEN_SHORTCUTS, ReferenceScreenApp } from "./reference-screen-app.js";
|
|
6
|
+
export { CHANGELOG_APP_ID, CHANGELOG_ROUTE, CHANGELOG_TITLE, HOTKEYS_APP_ID, HOTKEYS_ROUTE, HOTKEYS_TITLE, } from "./reference-routes.js";
|