@timurproko/a1 0.2.6-dev.717 → 0.2.6-dev.734
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/clipboard-services.d.ts +19 -0
- package/dist/app/session-shell/clipboard-services.js +7 -0
- package/dist/app/session-shell/exit-notice.d.ts +9 -5
- package/dist/app/session-shell/exit-notice.js +5 -5
- package/dist/app/session-shell/index.d.ts +3 -1
- package/dist/app/session-shell/index.js +1 -0
- package/dist/app/session-shell/paste-preparation-client.d.ts +3 -0
- package/dist/app/session-shell/paste-preparation-client.js +5 -2
- package/dist/app/session-shell/path-chip-presentation.d.ts +10 -3
- package/dist/app/session-shell/path-chip-presentation.js +48 -6
- package/dist/app/session-shell/prompt-chips.js +30 -4
- 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/quit-outro.d.ts +3 -1
- package/dist/app/session-shell/quit-outro.js +23 -8
- package/dist/app/session-shell/response-copy-transport.d.ts +6 -1
- package/dist/app/session-shell/response-copy-transport.js +8 -2
- package/dist/app/session-shell/session-shell-root.d.ts +22 -11
- package/dist/app/session-shell/session-shell-root.js +19 -12
- package/dist/app/session-shell/session-shell.d.ts +19 -21
- package/dist/app/session-shell/session-shell.js +678 -840
- 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 +23 -2
- package/dist/composition/owned-ui.js +124 -33
- package/dist/composition/session-info-reference.d.ts +2 -2
- package/dist/composition/session-info-reference.js +2 -2
- package/dist/composition/settings-route-host.js +2 -1
- package/dist/contracts/agent-engine/capability-ports.d.ts +1 -85
- package/dist/contracts/agent-engine/capability-ports.js +1 -35
- package/dist/contracts/agent-engine/index.d.ts +1 -7
- package/dist/contracts/agent-engine/index.js +0 -4
- package/dist/contracts/owned-ui/index.d.ts +9 -3
- package/dist/contracts/owned-ui/index.js +2 -1
- package/dist/contracts/owned-ui/model.d.ts +10 -0
- package/dist/contracts/owned-ui/session-backend.d.ts +119 -0
- package/dist/contracts/owned-ui/session-presenters.d.ts +55 -0
- package/dist/contracts/owned-ui/session-presenters.js +1 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +342 -0
- package/dist/contracts/owned-ui/session-workflows.js +30 -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/settings-app.js +56 -54
- 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/bootstrap.js +1 -2
- package/dist/foundation/release/progress-palette.generated.d.ts +2 -2
- package/dist/foundation/release/progress-palette.generated.js +2 -2
- package/dist/foundation/release/release-gc.js +1 -1
- package/dist/foundation/release/update.js +0 -4
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/foundation/storage/control-store.js +0 -12
- package/dist/integrations/pi/components/components.js +2 -18
- package/dist/integrations/pi/components/index.d.ts +4 -4
- package/dist/integrations/pi/components/index.js +2 -2
- package/dist/integrations/pi/components/modal-frame.js +3 -4
- package/dist/integrations/pi/components/models-dialog.js +6 -35
- 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 +19 -16
- package/dist/integrations/pi/components/shell-extension-ui.d.ts +5 -3
- package/dist/integrations/pi/components/shell-extension-ui.js +26 -12
- 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 +13 -13
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -6
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +21 -1
- package/dist/integrations/pi/components/shell-shared-facade.js +19 -3
- 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 +9 -9
- 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/theme-controller.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.d.ts +22 -1
- package/dist/integrations/pi/components/upstream/theme/theme.js +225 -10
- package/dist/integrations/pi/engine/adapter.d.ts +44 -24
- package/dist/integrations/pi/engine/adapter.js +130 -22
- package/dist/integrations/pi/engine/command-dispatch.d.ts +2 -5
- package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -11
- package/dist/integrations/pi/engine/host-ports.d.ts +20 -0
- package/dist/integrations/pi/engine/host-ports.js +13 -0
- package/dist/integrations/pi/engine/host.d.ts +70 -0
- package/dist/integrations/pi/engine/host.js +147 -0
- package/dist/integrations/pi/engine/index.d.ts +8 -4
- package/dist/integrations/pi/engine/index.js +3 -1
- package/dist/integrations/pi/engine/pi-settings-metadata.json +1 -1
- package/dist/integrations/pi/engine/resource-catalog.d.ts +4 -23
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/runtime-integration.d.ts +8 -2
- package/dist/integrations/pi/engine/runtime-integration.js +12 -7
- package/dist/integrations/pi/engine/session-events.js +10 -2
- package/dist/integrations/pi/engine/session-integration.d.ts +3 -8
- package/dist/integrations/pi/engine/session-integration.js +0 -49
- package/dist/integrations/pi/engine/session-runtime.d.ts +18 -3
- package/dist/integrations/pi/engine/session-runtime.js +18 -7
- package/dist/integrations/pi/engine/settings-bridge.d.ts +2 -2
- package/dist/integrations/pi/engine/settings-bridge.js +0 -2
- package/dist/integrations/pi/engine/settings-port.d.ts +2 -0
- package/dist/integrations/pi/engine/settings-port.js +3 -5
- package/dist/integrations/pi/engine/transcript-projection.js +2 -1
- package/dist/integrations/pi/engine/workflows.d.ts +33 -260
- package/dist/integrations/pi/engine/workflows.js +6 -28
- package/dist/integrations/pi/session-presenters/index.d.ts +2 -0
- package/dist/integrations/pi/session-presenters/index.js +1 -0
- package/dist/integrations/pi/session-presenters/presenters.d.ts +16 -0
- package/dist/integrations/pi/session-presenters/presenters.js +341 -0
- 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 +2 -1
- package/dist/integrations/pi/tui-runtime/adapter.js +7 -2
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +3 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +8 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +67 -2
- package/dist/integrations/pi/tui-runtime/index.d.ts +1 -1
- package/dist/integrations/pi/tui-runtime/index.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 +38 -14
- package/dist/ui/settings/declarations.js +35 -11
- package/dist/ui/settings/migrations.js +23 -0
- package/docs/architecture/boundaries.md +9 -1
- package/docs/architecture/project-structure.md +7 -5
- package/docs/architecture/prompt-suggestions.md +14 -10
- package/docs/local-worktree-cleanup.md +11 -5
- package/docs/openspec-archive-automation.md +6 -5
- package/package.json +3 -3
- package/dist/contracts/agent-engine/model.d.ts +0 -78
- package/dist/contracts/agent-engine/model.js +0 -1
- package/dist/contracts/agent-engine/ports.d.ts +0 -18
- package/dist/contracts/agent-engine/serialization.d.ts +0 -7
- package/dist/contracts/agent-engine/serialization.js +0 -58
- package/dist/contracts/agent-engine/validation.d.ts +0 -5
- package/dist/contracts/agent-engine/validation.js +0 -128
- package/dist/integrations/pi/components/upstream/theme/system-theme.d.ts +0 -61
- package/dist/integrations/pi/components/upstream/theme/system-theme.js +0 -709
- /package/dist/contracts/{agent-engine/ports.js → owned-ui/session-backend.js} +0 -0
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { assertOwnedUiPromptSuggestionResult, normalizePromptSuggestionCandidate, } from "../../contracts/owned-ui/index.js";
|
|
2
|
-
|
|
2
|
+
const TRANSIENT_PRESENTATION_REASONS = new Set([
|
|
3
|
+
"not-ready", "not-focused", "autocomplete", "prompt-mode",
|
|
4
|
+
]);
|
|
5
|
+
const RETRYABLE_OUTCOMES = new Set([
|
|
6
|
+
"empty", "rejected", "provider-failure", "unavailable", "timeout",
|
|
7
|
+
]);
|
|
8
|
+
/** Prefetches one inert candidate and owns one bounded settlement/retry recovery lifecycle. */
|
|
3
9
|
export class ContextualPromptSuggestionController {
|
|
4
10
|
#state = { status: "idle" };
|
|
11
|
+
#lifecycle = null;
|
|
5
12
|
#request = null;
|
|
6
13
|
#lastConsidered = "";
|
|
14
|
+
#retiredIdentity = "";
|
|
7
15
|
#enabled;
|
|
8
16
|
#disposed = false;
|
|
9
17
|
#sessionKey = "";
|
|
@@ -27,6 +35,7 @@ export class ContextualPromptSuggestionController {
|
|
|
27
35
|
}
|
|
28
36
|
skip(identity, reason) {
|
|
29
37
|
this.invalidate();
|
|
38
|
+
this.#lastConsidered = decisionIdentityKey(identity);
|
|
30
39
|
this.#emit(this.#metadata(identity), "skipped", reason);
|
|
31
40
|
}
|
|
32
41
|
consider(identity, decision) {
|
|
@@ -34,51 +43,43 @@ export class ContextualPromptSuggestionController {
|
|
|
34
43
|
if (key === this.#lastConsidered)
|
|
35
44
|
return;
|
|
36
45
|
this.#lastConsidered = key;
|
|
37
|
-
this
|
|
38
|
-
const reason = this.#
|
|
39
|
-
: decision === false ? "ineligible" : decision === true ? null : decision;
|
|
46
|
+
this.#reset(true, true);
|
|
47
|
+
const reason = this.#decisionReason(decision);
|
|
40
48
|
if (reason !== null) {
|
|
41
49
|
this.#emit(this.#metadata(identity), "skipped", reason);
|
|
42
50
|
return;
|
|
43
51
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
catch { /* Security: isolate diagnostic metadata failure. */ }
|
|
49
|
-
const request = {
|
|
50
|
-
identity,
|
|
51
|
-
metadata: { ...this.#metadata(identity), request: ++this.#requestSequence, reasoning },
|
|
52
|
-
abort: new AbortController(), startedAt: this.#now(), terminal: false,
|
|
53
|
-
};
|
|
54
|
-
this.#request = request;
|
|
55
|
-
this.#state = { status: "generating", identity, settled: false };
|
|
56
|
-
this.#emit(request.metadata, "started");
|
|
57
|
-
request.timer = setTimeout(() => {
|
|
58
|
-
if (this.#request !== request || this.#state.status !== "generating")
|
|
59
|
-
return;
|
|
60
|
-
this.#finish(request, "timeout");
|
|
61
|
-
this.#state = { status: "idle" };
|
|
62
|
-
this.#request = null;
|
|
63
|
-
request.abort.abort();
|
|
64
|
-
}, this.#timeoutMs);
|
|
65
|
-
request.timer.unref?.();
|
|
66
|
-
try {
|
|
67
|
-
void this.options.generator.generate({ identity, signal: request.abort.signal })
|
|
68
|
-
.then(result => this.#receive(request, result), () => this.#failed(request))
|
|
69
|
-
.finally(() => clearTimeout(request.timer));
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
this.#failed(request);
|
|
73
|
-
}
|
|
52
|
+
this.#retiredIdentity = "";
|
|
53
|
+
this.#lifecycle = { identity, settled: false, attempts: 0, retryPending: false, presentationDeferred: false };
|
|
54
|
+
this.#startAttempt("prefetch");
|
|
74
55
|
}
|
|
75
|
-
|
|
76
|
-
|
|
56
|
+
/** Settles an existing prefetch or starts the first request when that eligible prefetch was missed. */
|
|
57
|
+
settle(identity, decision = null) {
|
|
58
|
+
if (this.#disposed || !this.#enabled || identityKey(identity) === this.#retiredIdentity)
|
|
77
59
|
return;
|
|
78
|
-
|
|
60
|
+
const reason = this.#decisionReason(decision);
|
|
61
|
+
const lifecycle = this.#lifecycle;
|
|
62
|
+
if (lifecycle !== null && !samePromptSuggestionIdentity(lifecycle.identity, identity)) {
|
|
79
63
|
if (this.#request)
|
|
80
64
|
this.#finish(this.#request, "stale-result", "stale-identity");
|
|
81
|
-
this
|
|
65
|
+
this.#reset(true, true);
|
|
66
|
+
}
|
|
67
|
+
if (reason !== null) {
|
|
68
|
+
if (this.#lifecycle !== null)
|
|
69
|
+
this.#reset(true, true);
|
|
70
|
+
else
|
|
71
|
+
this.#emit(this.#metadata(identity), "skipped", reason);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (this.#lifecycle === null) {
|
|
75
|
+
this.#retiredIdentity = "";
|
|
76
|
+
this.#lifecycle = { identity, settled: true, attempts: 0, retryPending: false, presentationDeferred: false };
|
|
77
|
+
this.#startAttempt("settlement");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.#lifecycle.settled = true;
|
|
81
|
+
if (this.#lifecycle.retryPending) {
|
|
82
|
+
this.#startAttempt("retry");
|
|
82
83
|
return;
|
|
83
84
|
}
|
|
84
85
|
if (this.#state.status === "generating")
|
|
@@ -86,23 +87,23 @@ export class ContextualPromptSuggestionController {
|
|
|
86
87
|
else if (this.#state.status === "prepared" && this.#request)
|
|
87
88
|
this.#show(this.#request, this.#state.text);
|
|
88
89
|
}
|
|
89
|
-
accept() { this.#
|
|
90
|
-
invalidate() { this.#
|
|
91
|
-
/** Retires
|
|
90
|
+
accept() { this.#reset(false, true); }
|
|
91
|
+
invalidate() { this.#reset(true, true); }
|
|
92
|
+
/** Retires generating or scheduled recovery; a prepared or available suggestion survives a draft edit. */
|
|
92
93
|
abortPending() {
|
|
93
|
-
if (this.#state.status !== "generating")
|
|
94
|
-
return;
|
|
95
|
-
const request = this.#request;
|
|
96
|
-
this.#request = null;
|
|
97
|
-
this.#state = { status: "idle" };
|
|
98
|
-
if (request === null)
|
|
94
|
+
if (this.#state.status !== "generating" && !(this.#state.status === "idle" && this.#lifecycle?.retryPending))
|
|
99
95
|
return;
|
|
100
|
-
this.#
|
|
101
|
-
request.abort.abort();
|
|
96
|
+
this.#reset(false, true);
|
|
102
97
|
}
|
|
103
|
-
/** Reasserts retained ghost text
|
|
98
|
+
/** Reasserts retained ghost text or retries a deferred presentation when the editor is eligible. */
|
|
104
99
|
restoreAvailable() {
|
|
105
|
-
if (this.#disposed || !this.#enabled
|
|
100
|
+
if (this.#disposed || !this.#enabled)
|
|
101
|
+
return;
|
|
102
|
+
if (this.#state.status === "prepared" && this.#lifecycle?.settled && this.#request) {
|
|
103
|
+
this.#show(this.#request, this.#state.text);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (this.#state.status !== "available")
|
|
106
107
|
return;
|
|
107
108
|
const reason = this.options.surface.presentationBlockReason?.(this.#state.identity)
|
|
108
109
|
?? (this.options.surface.canPresent(this.#state.identity) ? null : "presentation-unavailable");
|
|
@@ -114,16 +115,64 @@ export class ContextualPromptSuggestionController {
|
|
|
114
115
|
this.#disposed = true;
|
|
115
116
|
this.invalidate();
|
|
116
117
|
this.#lastConsidered = "";
|
|
118
|
+
this.#retiredIdentity = "";
|
|
117
119
|
this.#sessionKey = "";
|
|
118
120
|
}
|
|
119
|
-
#
|
|
121
|
+
#decisionReason(decision) {
|
|
122
|
+
return this.#disposed ? "disposed" : !this.#enabled ? "disabled"
|
|
123
|
+
: decision === false ? "ineligible" : decision === true ? null : decision;
|
|
124
|
+
}
|
|
125
|
+
#startAttempt(trigger) {
|
|
126
|
+
const lifecycle = this.#lifecycle;
|
|
127
|
+
if (lifecycle === null || this.#request !== null || lifecycle.attempts >= 2)
|
|
128
|
+
return;
|
|
129
|
+
lifecycle.retryPending = false;
|
|
130
|
+
lifecycle.presentationDeferred = false;
|
|
131
|
+
const attempt = ++lifecycle.attempts;
|
|
132
|
+
let reasoning = "unavailable";
|
|
133
|
+
try {
|
|
134
|
+
reasoning = this.options.generator.suggestionReasoningPolicy?.() ?? "unavailable";
|
|
135
|
+
}
|
|
136
|
+
catch { /* Security: isolate diagnostic metadata failure. */ }
|
|
137
|
+
const request = {
|
|
138
|
+
identity: lifecycle.identity,
|
|
139
|
+
metadata: { ...this.#metadata(lifecycle.identity), request: ++this.#requestSequence, reasoning, attempt, trigger },
|
|
140
|
+
abort: new AbortController(), startedAt: this.#now(), terminal: false,
|
|
141
|
+
};
|
|
142
|
+
this.#request = request;
|
|
143
|
+
this.#state = { status: "generating", identity: lifecycle.identity, settled: lifecycle.settled };
|
|
144
|
+
this.#emit(request.metadata, "started");
|
|
145
|
+
request.timer = setTimeout(() => {
|
|
146
|
+
if (this.#request !== request || this.#state.status !== "generating")
|
|
147
|
+
return;
|
|
148
|
+
this.#finish(request, "timeout");
|
|
149
|
+
this.#request = null;
|
|
150
|
+
this.#state = { status: "idle" };
|
|
151
|
+
request.abort.abort();
|
|
152
|
+
this.#completeNoCandidate(request, "timeout");
|
|
153
|
+
}, this.#timeoutMs);
|
|
154
|
+
request.timer.unref?.();
|
|
155
|
+
try {
|
|
156
|
+
void this.options.generator.generate({ identity: lifecycle.identity, signal: request.abort.signal })
|
|
157
|
+
.then(result => this.#receive(request, result), () => this.#failed(request))
|
|
158
|
+
.finally(() => clearTimeout(request.timer));
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
this.#failed(request);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
#reset(clearSurface, retire) {
|
|
120
165
|
const hadVisibleSuggestion = this.#state.status === "available";
|
|
166
|
+
const identity = this.#lifecycle?.identity ?? (this.#state.status === "idle" ? null : this.#state.identity);
|
|
121
167
|
const request = this.#request;
|
|
122
168
|
if (request)
|
|
123
169
|
this.#finish(request, "cancelled");
|
|
124
170
|
this.#request = null;
|
|
171
|
+
this.#lifecycle = null;
|
|
125
172
|
this.#state = { status: "idle" };
|
|
126
173
|
request?.abort.abort();
|
|
174
|
+
if (retire && identity !== null)
|
|
175
|
+
this.#retiredIdentity = identityKey(identity);
|
|
127
176
|
if (clearSurface && hadVisibleSuggestion) {
|
|
128
177
|
this.options.surface.clear();
|
|
129
178
|
this.options.surface.requestRender();
|
|
@@ -137,6 +186,7 @@ export class ContextualPromptSuggestionController {
|
|
|
137
186
|
this.#finish(request, "provider-failure");
|
|
138
187
|
this.#request = null;
|
|
139
188
|
this.#state = { status: "idle" };
|
|
189
|
+
this.#completeNoCandidate(request, "provider-failure");
|
|
140
190
|
}
|
|
141
191
|
#receive(request, result) {
|
|
142
192
|
if (this.#disposed || this.#request !== request || request.terminal || this.#state.status !== "generating") {
|
|
@@ -148,41 +198,76 @@ export class ContextualPromptSuggestionController {
|
|
|
148
198
|
}
|
|
149
199
|
catch {
|
|
150
200
|
this.#finish(request, "rejected");
|
|
151
|
-
this
|
|
201
|
+
this.#request = null;
|
|
202
|
+
this.#state = { status: "idle" };
|
|
203
|
+
this.#completeNoCandidate(request, "rejected");
|
|
152
204
|
return;
|
|
153
205
|
}
|
|
154
206
|
if (!samePromptSuggestionIdentity(request.identity, result.identity)) {
|
|
155
207
|
this.#finish(request, "stale-result", "stale-identity");
|
|
156
|
-
this
|
|
208
|
+
this.#reset(true, true);
|
|
157
209
|
return;
|
|
158
210
|
}
|
|
159
211
|
if (result.outcome !== "candidate") {
|
|
160
212
|
this.#finish(request, result.outcome);
|
|
161
|
-
this
|
|
213
|
+
this.#request = null;
|
|
214
|
+
this.#state = { status: "idle" };
|
|
215
|
+
if (RETRYABLE_OUTCOMES.has(result.outcome))
|
|
216
|
+
this.#completeNoCandidate(request, result.outcome);
|
|
217
|
+
else {
|
|
218
|
+
this.#retiredIdentity = identityKey(request.identity);
|
|
219
|
+
this.#lifecycle = null;
|
|
220
|
+
}
|
|
162
221
|
return;
|
|
163
222
|
}
|
|
164
223
|
const text = normalizePromptSuggestionCandidate(result.text);
|
|
165
224
|
if (text === null) {
|
|
166
225
|
this.#finish(request, "rejected");
|
|
167
|
-
this
|
|
226
|
+
this.#request = null;
|
|
227
|
+
this.#state = { status: "idle" };
|
|
228
|
+
this.#completeNoCandidate(request, "rejected");
|
|
168
229
|
return;
|
|
169
230
|
}
|
|
170
231
|
clearTimeout(request.timer);
|
|
171
|
-
if (this.#
|
|
232
|
+
if (this.#lifecycle?.settled)
|
|
172
233
|
this.#show(request, text);
|
|
173
234
|
else
|
|
174
235
|
this.#state = { status: "prepared", identity: request.identity, text };
|
|
175
236
|
}
|
|
237
|
+
#completeNoCandidate(request, outcome) {
|
|
238
|
+
const lifecycle = this.#lifecycle;
|
|
239
|
+
if (lifecycle === null || !samePromptSuggestionIdentity(lifecycle.identity, request.identity))
|
|
240
|
+
return;
|
|
241
|
+
if (lifecycle.attempts >= 2 || !RETRYABLE_OUTCOMES.has(outcome)) {
|
|
242
|
+
this.#emit({ ...request.metadata, elapsedMs: Math.max(0, this.#now() - request.startedAt) }, "retry-exhausted");
|
|
243
|
+
this.#retiredIdentity = identityKey(request.identity);
|
|
244
|
+
this.#lifecycle = null;
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
lifecycle.retryPending = true;
|
|
248
|
+
if (lifecycle.settled)
|
|
249
|
+
this.#startAttempt("retry");
|
|
250
|
+
}
|
|
176
251
|
#show(request, text) {
|
|
177
252
|
const reason = this.options.surface.presentationBlockReason?.(request.identity)
|
|
178
253
|
?? (this.options.surface.canPresent(request.identity) ? null : "presentation-unavailable");
|
|
254
|
+
if (reason !== null && TRANSIENT_PRESENTATION_REASONS.has(reason)) {
|
|
255
|
+
this.#state = { status: "prepared", identity: request.identity, text };
|
|
256
|
+
if (this.#lifecycle !== null && !this.#lifecycle.presentationDeferred) {
|
|
257
|
+
this.#lifecycle.presentationDeferred = true;
|
|
258
|
+
this.#emit({ ...request.metadata, elapsedMs: Math.max(0, this.#now() - request.startedAt) }, "presentation-deferred", reason);
|
|
259
|
+
}
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
179
262
|
if (reason !== null || !this.options.surface.present(text)) {
|
|
180
263
|
this.#finish(request, "presentation-blocked", reason ?? "presentation-unavailable");
|
|
181
|
-
this
|
|
264
|
+
this.#reset(true, true);
|
|
182
265
|
return;
|
|
183
266
|
}
|
|
184
267
|
this.#state = { status: "available", identity: request.identity, text };
|
|
185
268
|
this.#finish(request, "displayed");
|
|
269
|
+
if (this.#lifecycle !== null)
|
|
270
|
+
this.#lifecycle.presentationDeferred = false;
|
|
186
271
|
this.options.surface.requestRender();
|
|
187
272
|
}
|
|
188
273
|
#finish(request, event, reason) {
|
|
@@ -227,3 +312,8 @@ export function samePromptSuggestionIdentity(left, right) {
|
|
|
227
312
|
function identityKey(identity) {
|
|
228
313
|
return `${identity.sessionId}\0${identity.sessionGeneration}\0${identity.runSequence}\0${identity.responseSequence}\0${identity.model.providerId}\0${identity.model.modelId}`;
|
|
229
314
|
}
|
|
315
|
+
function decisionIdentityKey(identity) {
|
|
316
|
+
return identity.model === null
|
|
317
|
+
? `${identity.sessionId}\0${identity.sessionGeneration}\0${identity.runSequence}\0${identity.responseSequence}\0\0`
|
|
318
|
+
: identityKey(identity);
|
|
319
|
+
}
|
|
@@ -15,6 +15,8 @@ export interface QuitOutroPlayback {
|
|
|
15
15
|
sleep?(ms: number): Promise<void>;
|
|
16
16
|
/** Plan seed; defaults to a time- and geometry-derived value. */
|
|
17
17
|
readonly seed?: number;
|
|
18
|
+
/** Active bare-A1 canvas; omitted preserves transparent playback bytes. */
|
|
19
|
+
readonly canvasBackgroundAnsi?: string;
|
|
18
20
|
}
|
|
19
21
|
export declare const QUIT_OUTRO_MIN_MS = 300;
|
|
20
22
|
export declare const QUIT_OUTRO_MAX_MS = 2000;
|
|
@@ -29,7 +31,7 @@ export declare function clampQuitOutroDuration(durationMs: number): number;
|
|
|
29
31
|
*/
|
|
30
32
|
export declare function captureQuitOutroFrame(presented: readonly string[], columns: number, rows: number): QuitOutroFrame | null;
|
|
31
33
|
/** The clear-and-repaint block that seeds the animation surface with the captured frame. */
|
|
32
|
-
export declare function createQuitOutroSurfaceFrame(frame: QuitOutroFrame): string;
|
|
34
|
+
export declare function createQuitOutroSurfaceFrame(frame: QuitOutroFrame, canvasBackgroundAnsi?: string): string;
|
|
33
35
|
/**
|
|
34
36
|
* Plays the effect over the frame. Resolves true when the plan was played to
|
|
35
37
|
* completion or abandoned at its guard, false when there was nothing to play.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* terminal cannot delay restoration past the configured clamp.
|
|
7
7
|
*/
|
|
8
8
|
import { displayWidth, truncateToWidth } from "../../ui/components/index.js";
|
|
9
|
+
import { rebaseTerminalDefaultBackground } from "../../integrations/pi/tui-runtime/index.js";
|
|
9
10
|
import { createQuitOutroPlan } from "./quit-outro-effects.js";
|
|
10
11
|
export const QUIT_OUTRO_MIN_MS = 300;
|
|
11
12
|
export const QUIT_OUTRO_MAX_MS = 2000;
|
|
@@ -44,14 +45,25 @@ export function captureQuitOutroFrame(presented, columns, rows) {
|
|
|
44
45
|
return { lines, columns: width, rows: height, rowWidths };
|
|
45
46
|
}
|
|
46
47
|
/** The clear-and-repaint block that seeds the animation surface with the captured frame. */
|
|
47
|
-
export function createQuitOutroSurfaceFrame(frame) {
|
|
48
|
-
|
|
48
|
+
export function createQuitOutroSurfaceFrame(frame, canvasBackgroundAnsi) {
|
|
49
|
+
if (canvasBackgroundAnsi === undefined) {
|
|
50
|
+
let output = `${SYNC_BEGIN}${HIDE_CURSOR}${CLEAR_SCREEN}${HOME}${RESET}`;
|
|
51
|
+
for (let row = 0; row < frame.rows; row++) {
|
|
52
|
+
const line = frame.lines[row] ?? "";
|
|
53
|
+
if (frame.rowWidths[row] > 0)
|
|
54
|
+
output += `${cursorAt(row, 0)}${line}${RESET}`;
|
|
55
|
+
}
|
|
56
|
+
return `${output}${SYNC_END}`;
|
|
57
|
+
}
|
|
58
|
+
let output = `${SYNC_BEGIN}${HIDE_CURSOR}${RESET}${canvasBackgroundAnsi}${CLEAR_SCREEN}${HOME}`;
|
|
49
59
|
for (let row = 0; row < frame.rows; row++) {
|
|
50
60
|
const line = frame.lines[row] ?? "";
|
|
51
|
-
if (frame.rowWidths[row] > 0)
|
|
52
|
-
output += `${cursorAt(row, 0)}${
|
|
61
|
+
if (frame.rowWidths[row] > 0) {
|
|
62
|
+
output += `${cursorAt(row, 0)}${canvasBackgroundAnsi}`
|
|
63
|
+
+ `${rebaseTerminalDefaultBackground(line, canvasBackgroundAnsi)}${RESET}${canvasBackgroundAnsi}`;
|
|
64
|
+
}
|
|
53
65
|
}
|
|
54
|
-
return `${output}${SYNC_END}`;
|
|
66
|
+
return `${output}${RESET}${SYNC_END}`;
|
|
55
67
|
}
|
|
56
68
|
/**
|
|
57
69
|
* Plays the effect over the frame. Resolves true when the plan was played to
|
|
@@ -69,20 +81,23 @@ export async function playQuitOutro(frame, effect, durationMs, playback) {
|
|
|
69
81
|
let sparkleIndex = 0;
|
|
70
82
|
let clearIndex = 0;
|
|
71
83
|
let ticks = 0;
|
|
72
|
-
playback.
|
|
84
|
+
const canvas = playback.canvasBackgroundAnsi;
|
|
85
|
+
playback.write(createQuitOutroSurfaceFrame(frame, canvas));
|
|
73
86
|
const startedAt = now();
|
|
74
87
|
for (;;) {
|
|
75
88
|
ticks += 1;
|
|
76
89
|
const elapsed = now() - startedAt;
|
|
77
90
|
const progress = Math.min(1, elapsed / duration);
|
|
78
|
-
let output = `${SYNC_BEGIN}${RESET}`;
|
|
91
|
+
let output = canvas === undefined ? `${SYNC_BEGIN}${RESET}` : `${SYNC_BEGIN}${RESET}${canvas}`;
|
|
79
92
|
while (sparkleIndex < plan.sparkles.length && plan.sparkles[sparkleIndex].start <= progress) {
|
|
80
93
|
const cell = plan.sparkles[sparkleIndex++];
|
|
81
94
|
output += `${cursorAt(cell.row, cell.col)}${cell.color}${cell.glyph}`;
|
|
82
95
|
}
|
|
83
96
|
while (clearIndex < plan.clears.length && plan.clears[clearIndex].end <= progress) {
|
|
84
97
|
const cell = plan.clears[clearIndex++];
|
|
85
|
-
output +=
|
|
98
|
+
output += canvas === undefined
|
|
99
|
+
? `${cursorAt(cell.row, cell.col)}${RESET} `
|
|
100
|
+
: `${cursorAt(cell.row, cell.col)}${RESET}${canvas} `;
|
|
86
101
|
}
|
|
87
102
|
const finished = clearIndex >= plan.clears.length || progress >= 1
|
|
88
103
|
|| elapsed > duration + QUIT_OUTRO_GUARD_MS || ticks >= QUIT_OUTRO_MAX_TICKS;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HelperPool } from "./helper-pool.js";
|
|
1
2
|
import type { SelectionCopySnapshot } from "../../ui/components/selection-copy.js";
|
|
2
3
|
import { type CopyResult } from "./response-copy-protocol.js";
|
|
3
4
|
export interface ResponseCopyJob {
|
|
@@ -8,7 +9,7 @@ export interface ResponseCopyJob {
|
|
|
8
9
|
}
|
|
9
10
|
export type CopyPhaseObserver = (phase: "extracted" | "encoded" | "submitting", bytes: number, transport: "native" | "terminal" | "injected") => void;
|
|
10
11
|
export type ResponseCopyExecutor = (snapshot: SelectionCopySnapshot, phase: CopyPhaseObserver) => ResponseCopyJob;
|
|
11
|
-
/** The production executor also
|
|
12
|
+
/** The production executor also holds a spare helper; the owner warms it at start and disposes it at shutdown unless the pool is shared. */
|
|
12
13
|
export interface OwnedResponseCopyExecutor extends ResponseCopyExecutor {
|
|
13
14
|
warm(): void;
|
|
14
15
|
dispose(): void;
|
|
@@ -36,4 +37,8 @@ export declare function createResponseCopyExecutor(options?: {
|
|
|
36
37
|
readonly helper?: URL;
|
|
37
38
|
/** Idle bound for the spare helper; production keeps the default. */
|
|
38
39
|
readonly spareIdleMs?: number;
|
|
40
|
+
/** Process-wide spare pool shared across sessions; the executor warms it but never disposes it. */
|
|
41
|
+
readonly pool?: HelperPool;
|
|
39
42
|
}): OwnedResponseCopyExecutor;
|
|
43
|
+
/** A spare-of-one pool of copy helpers; `createResponseCopyExecutor` takes its child and warms the next one after each copy. */
|
|
44
|
+
export declare function createCopyHelperPool(helper?: URL, idleMs?: number): HelperPool;
|
|
@@ -23,7 +23,8 @@ export function hasAsyncClipboardOutput(platform = process.platform, stdout = pr
|
|
|
23
23
|
}
|
|
24
24
|
/** Isolates preparation and native clipboard access; only the owner may submit terminal controls. */
|
|
25
25
|
export function createResponseCopyExecutor(options = {}) {
|
|
26
|
-
const pool =
|
|
26
|
+
const pool = options.pool ?? createCopyHelperPool(options.helper, options.spareIdleMs);
|
|
27
|
+
const ownsPool = options.pool === undefined;
|
|
27
28
|
const execute = (snapshot, phase) => {
|
|
28
29
|
const controller = new AbortController();
|
|
29
30
|
let active;
|
|
@@ -70,10 +71,15 @@ export function createResponseCopyExecutor(options = {}) {
|
|
|
70
71
|
// Rationale: `Object.assign` would copy the getter's value once; the accessor must read the pool each time.
|
|
71
72
|
return Object.defineProperties(execute, {
|
|
72
73
|
warm: { value: () => pool.warm() },
|
|
73
|
-
dispose: { value: () =>
|
|
74
|
+
dispose: { value: () => { if (ownsPool)
|
|
75
|
+
pool.dispose(); } },
|
|
74
76
|
warmed: { get: () => pool.warmed },
|
|
75
77
|
});
|
|
76
78
|
}
|
|
79
|
+
/** A spare-of-one pool of copy helpers; `createResponseCopyExecutor` takes its child and warms the next one after each copy. */
|
|
80
|
+
export function createCopyHelperPool(helper, idleMs) {
|
|
81
|
+
return new HelperPool({ fork: () => forkCopyHelper(helper), stop: stopCopyHelper, ...(idleMs === undefined ? {} : { idleMs }) });
|
|
82
|
+
}
|
|
77
83
|
/** Forks one copy helper: bounded IPC only, no clipboard payload in argv or temp files, no inherited terminal descriptors. */
|
|
78
84
|
function forkCopyHelper(helper) {
|
|
79
85
|
const source = new URL(import.meta.url).pathname.endsWith(".ts");
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
|
|
2
|
-
import type { OwnedUiPromptSuggestionGeneratorPort, OwnedUiSessionViewModel, OwnedUiViewportSettings, OwnedUiViewportSettingsPort, OwnedUiQuitOutroSettingsPort, SuggestionDecision, SuggestionDiagnosticObserver } from "../../contracts/owned-ui/index.js";
|
|
2
|
+
import type { OwnedUiBackgroundSettingsPort, OwnedUiPromptSuggestionGeneratorPort, OwnedUiSessionBackend, OwnedUiSessionPresenters, OwnedUiSessionViewModel, OwnedUiTranscriptRendererPort, OwnedUiWorkflowMessage, OwnedUiWorkflowResult, OwnedUiViewportSettings, OwnedUiViewportSettingsPort, OwnedUiQuitOutroSettingsPort, SuggestionDecision, SuggestionDiagnosticObserver } from "../../contracts/owned-ui/index.js";
|
|
3
3
|
import type { PiTuiPointerSurface } from "../../integrations/pi/tui-runtime/contracts.js";
|
|
4
4
|
import type { UiRouteHost, UiRouteInput } from "../../ui/apps/contracts.js";
|
|
5
5
|
import type { TranscriptViewportFrame, TranscriptViewportFrameDescriptor } from "../../ui/components/transcript-viewport.js";
|
|
6
|
-
import type { PiEngineAdapter } from "../../integrations/pi/engine/adapter.js";
|
|
7
|
-
import type { PiWorkflowMessage, PiWorkflowResult } from "../../integrations/pi/engine/workflows.js";
|
|
8
6
|
import type { PiShellLazySelectorLoader } from "../../integrations/pi/components/lazy-selectors.js";
|
|
9
7
|
import { type PiShellHotkeysPresentation } from "../../integrations/pi/components/shell-presenters-info.js";
|
|
10
|
-
import { type PiShellClipboardContent, type PiShellComponentPort, type
|
|
8
|
+
import { type PiShellClipboardContent, type PiShellComponentPort, type PiKeybindingsHost, type PiShellEditorPort, type PiShellHeaderOptions, type PiShellHeaderPort, type PiShellImageAssetResolver, type PiShellLoadedResourcesPort, type PiShellResourceEntry, type PiShellTranscriptComponentPort } from "../../integrations/pi/components/shell-shared-facade.js";
|
|
11
9
|
import { type PiTuiInputCoordinationScheduler, type PiTuiInputSurfaceKind } from "../../integrations/pi/tui-runtime/input-presentation-coordinator.js";
|
|
12
10
|
import type { PiTuiComponentPort, PiTuiInputDiagnosticsEvent, PiTuiLayoutNode, PiTuiTerminalPort } from "../../integrations/pi/tui-runtime/contracts.js";
|
|
13
11
|
import { type PreparedPrompt } from "./prompt-chips.js";
|
|
14
12
|
import type { PastePreparationClientOptions } from "./paste-preparation-client.js";
|
|
13
|
+
import type { OwnedUiClipboardServices } from "./clipboard-services.js";
|
|
15
14
|
import { type SessionViewportInputResult } from "./session-viewport-controller.js";
|
|
16
15
|
import type { ResponseCopyExecutor } from "./response-copy-transport.js";
|
|
17
16
|
import type { ResponseCopyEvent } from "./response-copy-protocol.js";
|
|
18
17
|
import type { PasteEvent, PasteSource } from "./paste-protocol.js";
|
|
19
18
|
import type { StreamPresentationScheduler } from "./stream-presentation-coalescer.js";
|
|
20
|
-
export type OwnedUiBackendPort = PiEngineAdapter;
|
|
21
19
|
export type OwnedUiTerminalPort = PiTuiTerminalPort;
|
|
22
20
|
type OwnedUiStartupOptions = PiShellHeaderOptions;
|
|
23
21
|
export interface OwnedUiClipboardPort {
|
|
@@ -30,7 +28,7 @@ export interface OwnedUiClipboardPort {
|
|
|
30
28
|
}
|
|
31
29
|
/** The engine session the shell presents and the composition's decisions about it. */
|
|
32
30
|
export interface OwnedUiShellEngineOptions {
|
|
33
|
-
readonly backend:
|
|
31
|
+
readonly backend: OwnedUiSessionBackend;
|
|
34
32
|
readonly cwd: string;
|
|
35
33
|
/**
|
|
36
34
|
* Declared A1-owned routes. A route this host claims resolves to its app;
|
|
@@ -52,6 +50,8 @@ export interface OwnedUiShellPresentationOptions {
|
|
|
52
50
|
readonly startup?: OwnedUiStartupOptions;
|
|
53
51
|
/** Live profile-local settings, supplied only to the bare-A1 composition. */
|
|
54
52
|
readonly viewportSettings?: OwnedUiViewportSettingsPort;
|
|
53
|
+
/** Live fullscreen canvas choice, supplied only to the bare-A1 composition. */
|
|
54
|
+
readonly backgroundSettings?: OwnedUiBackgroundSettingsPort;
|
|
55
55
|
/** Deterministic scheduling seam for presentation-cadence tests. */
|
|
56
56
|
readonly stream?: {
|
|
57
57
|
readonly intervalMs?: number;
|
|
@@ -130,9 +130,17 @@ export interface OwnedUiShellSkillsOptions {
|
|
|
130
130
|
readonly presentation: () => "collapse" | "expand";
|
|
131
131
|
readonly onChange: (listener: () => void) => () => void;
|
|
132
132
|
}
|
|
133
|
+
/** Process-wide services composition creates once and every session shell borrows; absent, a shell keeps private ones. */
|
|
134
|
+
export interface OwnedUiShellSharedServices {
|
|
135
|
+
readonly clipboard?: OwnedUiClipboardServices;
|
|
136
|
+
/** Must match the shell's layout: the owned-input profile for the custom viewport, Pi's otherwise. */
|
|
137
|
+
readonly keybindings?: PiKeybindingsHost;
|
|
138
|
+
}
|
|
133
139
|
/** What composes an owned session shell, grouped by the collaborator that provides each part. */
|
|
134
140
|
export interface OwnedUiSessionShellOptions {
|
|
135
141
|
readonly engine: OwnedUiShellEngineOptions;
|
|
142
|
+
/** Opens the selectors and resolves the transcript renderers whose inputs are engine objects. */
|
|
143
|
+
readonly presenters: OwnedUiSessionPresenters;
|
|
136
144
|
readonly presentation?: OwnedUiShellPresentationOptions;
|
|
137
145
|
readonly history?: OwnedUiShellHistoryOptions;
|
|
138
146
|
readonly suggestions?: OwnedUiShellSuggestionOptions;
|
|
@@ -141,6 +149,7 @@ export interface OwnedUiSessionShellOptions {
|
|
|
141
149
|
/** Supplied only to the bare-A1 composition; absent keeps the pinned per-skill command list. */
|
|
142
150
|
readonly skills?: OwnedUiShellSkillsOptions;
|
|
143
151
|
readonly diagnostics?: OwnedUiShellDiagnosticOptions;
|
|
152
|
+
readonly shared?: OwnedUiShellSharedServices;
|
|
144
153
|
}
|
|
145
154
|
/** Composes backend session state into the owned transcript, viewport, editor, and dock presentation. */
|
|
146
155
|
export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
|
|
@@ -172,14 +181,16 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
|
|
|
172
181
|
readonly onEditorChange?: (text: string) => void;
|
|
173
182
|
readonly onPromptSuggestionAccepted?: (text: string) => void;
|
|
174
183
|
readonly onInputSurfaceChanged?: () => void;
|
|
184
|
+
readonly onPromptSuggestionEligibilityChanged?: () => void;
|
|
175
185
|
readonly onCopyText?: (text: string) => void;
|
|
176
186
|
readonly readClipboardContent?: (signal?: AbortSignal) => Promise<PiShellClipboardContent | null>;
|
|
177
187
|
readonly captureClipboardPaste?: () => PasteSource;
|
|
178
188
|
readonly pasteDiagnostics?: (event: PasteEvent) => void;
|
|
179
189
|
readonly pastePreparation?: Omit<PastePreparationClientOptions, "onEvent">;
|
|
190
|
+
readonly keybindings?: PiKeybindingsHost;
|
|
180
191
|
readonly promptImageLimit?: () => number;
|
|
181
192
|
readonly skillsPresentation?: () => "collapse" | "expand";
|
|
182
|
-
}, startup?: PiShellHeaderOptions, agentDir?: string, extensionRenderers?:
|
|
193
|
+
}, startup?: PiShellHeaderOptions, agentDir?: string, extensionRenderers?: OwnedUiTranscriptRendererPort, sessionLayout?: "pinned" | "custom-viewport", imageAssets?: PiShellImageAssetResolver);
|
|
183
194
|
setEditorPaddingX(padding: number): void;
|
|
184
195
|
setAutocompleteMaxVisible(maxVisible: number): void;
|
|
185
196
|
setOutputPad(padding: 0 | 1): void;
|
|
@@ -245,7 +256,7 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
|
|
|
245
256
|
maxScroll: number;
|
|
246
257
|
cause: "initial" | "steady" | "dock-input" | "follow-shift" | "detached" | "geometry-change" | null;
|
|
247
258
|
};
|
|
248
|
-
/** Visible non-
|
|
259
|
+
/** Visible non-persistent Steering, alignment, and Working rows, for rendering evidence. */
|
|
249
260
|
viewportTransientTailRowCount(): number;
|
|
250
261
|
hasActiveSelection(): boolean;
|
|
251
262
|
setViewportConfig(config: OwnedUiViewportSettings): void;
|
|
@@ -265,8 +276,8 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
|
|
|
265
276
|
transcriptComponent(id: string): PiShellTranscriptComponentPort | undefined;
|
|
266
277
|
exitTranscript(width: number): string;
|
|
267
278
|
appendWorkflowStatus(message: string): void;
|
|
268
|
-
appendWorkflowMessage(message:
|
|
269
|
-
appendWorkflowResult(result:
|
|
279
|
+
appendWorkflowMessage(message: OwnedUiWorkflowMessage, errorCode?: ImageAttachmentError["code"]): void;
|
|
280
|
+
appendWorkflowResult(result: OwnedUiWorkflowResult, errorCode?: ImageAttachmentError["code"]): void;
|
|
270
281
|
toggleThinkingVisibility(): void;
|
|
271
282
|
get toolsExpanded(): boolean;
|
|
272
283
|
setToolsExpanded(expanded: boolean): void;
|
|
@@ -295,5 +306,5 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
|
|
|
295
306
|
setFocused(focused: boolean): void;
|
|
296
307
|
dispose(): void;
|
|
297
308
|
}
|
|
298
|
-
export declare function shellResourceEntries(backend:
|
|
309
|
+
export declare function shellResourceEntries(backend: OwnedUiSessionBackend): readonly PiShellResourceEntry[];
|
|
299
310
|
export {};
|