@inhuman.tools/harness-tui 0.0.0-stage → 0.3.0
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/LICENSE.md +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/interpreter/ComputedExecBox.d.ts +12 -0
- package/dist/interpreter/ComputedExecBox.d.ts.map +1 -0
- package/dist/interpreter/ComputedExecBox.js +88 -0
- package/dist/interpreter/ComputedExecBox.js.map +1 -0
- package/dist/interpreter/imageCapability.d.ts +9 -0
- package/dist/interpreter/imageCapability.d.ts.map +1 -0
- package/dist/interpreter/imageCapability.js +49 -0
- package/dist/interpreter/imageCapability.js.map +1 -0
- package/dist/interpreter/rpcCapability.d.ts +11 -0
- package/dist/interpreter/rpcCapability.d.ts.map +1 -0
- package/dist/interpreter/rpcCapability.js +91 -0
- package/dist/interpreter/rpcCapability.js.map +1 -0
- package/dist/interpreter/uiCapability.d.ts +34 -0
- package/dist/interpreter/uiCapability.d.ts.map +1 -0
- package/dist/interpreter/uiCapability.js +207 -0
- package/dist/interpreter/uiCapability.js.map +1 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/worker-boot.d.ts +14 -0
- package/dist/schemas/worker-boot.d.ts.map +1 -0
- package/dist/schemas/worker-boot.js +15 -0
- package/dist/schemas/worker-boot.js.map +1 -0
- package/dist/tui/ack-prompt.d.ts +53 -0
- package/dist/tui/ack-prompt.d.ts.map +1 -0
- package/dist/tui/ack-prompt.js +61 -0
- package/dist/tui/ack-prompt.js.map +1 -0
- package/dist/tui/agents-drawer.d.ts +49 -0
- package/dist/tui/agents-drawer.d.ts.map +1 -0
- package/dist/tui/agents-drawer.js +318 -0
- package/dist/tui/agents-drawer.js.map +1 -0
- package/dist/tui/ask-shortcuts.d.ts +59 -0
- package/dist/tui/ask-shortcuts.d.ts.map +1 -0
- package/dist/tui/ask-shortcuts.js +96 -0
- package/dist/tui/ask-shortcuts.js.map +1 -0
- package/dist/tui/channel.d.ts +59 -0
- package/dist/tui/channel.d.ts.map +1 -0
- package/dist/tui/channel.js +27 -0
- package/dist/tui/channel.js.map +1 -0
- package/dist/tui/host-verbs.d.ts +7 -0
- package/dist/tui/host-verbs.d.ts.map +1 -0
- package/dist/tui/host-verbs.js +19 -0
- package/dist/tui/host-verbs.js.map +1 -0
- package/dist/tui/host.d.ts +25 -0
- package/dist/tui/host.d.ts.map +1 -0
- package/dist/tui/host.js +380 -0
- package/dist/tui/host.js.map +1 -0
- package/dist/tui/omnibox-seat.d.ts +132 -0
- package/dist/tui/omnibox-seat.d.ts.map +1 -0
- package/dist/tui/omnibox-seat.js +182 -0
- package/dist/tui/omnibox-seat.js.map +1 -0
- package/dist/tui/paint-controller.d.ts +170 -0
- package/dist/tui/paint-controller.d.ts.map +1 -0
- package/dist/tui/paint-controller.js +965 -0
- package/dist/tui/paint-controller.js.map +1 -0
- package/dist/tui/paint-dom.d.ts +335 -0
- package/dist/tui/paint-dom.d.ts.map +1 -0
- package/dist/tui/paint-dom.js +704 -0
- package/dist/tui/paint-dom.js.map +1 -0
- package/dist/tui/paint-source.d.ts +57 -0
- package/dist/tui/paint-source.d.ts.map +1 -0
- package/dist/tui/paint-source.js +570 -0
- package/dist/tui/paint-source.js.map +1 -0
- package/dist/tui/paint-transport.d.ts +42 -0
- package/dist/tui/paint-transport.d.ts.map +1 -0
- package/dist/tui/paint-transport.js +207 -0
- package/dist/tui/paint-transport.js.map +1 -0
- package/dist/tui/paint-types.d.ts +15 -0
- package/dist/tui/paint-types.d.ts.map +1 -0
- package/dist/tui/paint-types.js +6 -0
- package/dist/tui/paint-types.js.map +1 -0
- package/dist/tui/paint-widgets.d.ts +94 -0
- package/dist/tui/paint-widgets.d.ts.map +1 -0
- package/dist/tui/paint-widgets.js +877 -0
- package/dist/tui/paint-widgets.js.map +1 -0
- package/dist/tui/parse-args.d.ts +3 -0
- package/dist/tui/parse-args.d.ts.map +1 -0
- package/dist/tui/parse-args.js +13 -0
- package/dist/tui/parse-args.js.map +1 -0
- package/dist/tui/permissions-view.d.ts +93 -0
- package/dist/tui/permissions-view.d.ts.map +1 -0
- package/dist/tui/permissions-view.js +174 -0
- package/dist/tui/permissions-view.js.map +1 -0
- package/dist/tui/present-visual/approve.d.ts +10 -0
- package/dist/tui/present-visual/approve.d.ts.map +1 -0
- package/dist/tui/present-visual/approve.js +156 -0
- package/dist/tui/present-visual/approve.js.map +1 -0
- package/dist/tui/present-visual/dump.d.ts +47 -0
- package/dist/tui/present-visual/dump.d.ts.map +1 -0
- package/dist/tui/present-visual/dump.js +144 -0
- package/dist/tui/present-visual/dump.js.map +1 -0
- package/dist/tui/present-visual/journey-teardown.d.ts +3 -0
- package/dist/tui/present-visual/journey-teardown.d.ts.map +1 -0
- package/dist/tui/present-visual/journey-teardown.js +188 -0
- package/dist/tui/present-visual/journey-teardown.js.map +1 -0
- package/dist/tui/present-visual/journey.d.ts +15 -0
- package/dist/tui/present-visual/journey.d.ts.map +1 -0
- package/dist/tui/present-visual/journey.js +88 -0
- package/dist/tui/present-visual/journey.js.map +1 -0
- package/dist/tui/present-visual/raster.d.ts +3 -0
- package/dist/tui/present-visual/raster.d.ts.map +1 -0
- package/dist/tui/present-visual/raster.js +75 -0
- package/dist/tui/present-visual/raster.js.map +1 -0
- package/dist/tui/queue-shortcuts.d.ts +13 -0
- package/dist/tui/queue-shortcuts.d.ts.map +1 -0
- package/dist/tui/queue-shortcuts.js +23 -0
- package/dist/tui/queue-shortcuts.js.map +1 -0
- package/dist/tui/read-widen.d.ts +14 -0
- package/dist/tui/read-widen.d.ts.map +1 -0
- package/dist/tui/read-widen.js +45 -0
- package/dist/tui/read-widen.js.map +1 -0
- package/dist/tui/rewind-chrome.d.ts +29 -0
- package/dist/tui/rewind-chrome.d.ts.map +1 -0
- package/dist/tui/rewind-chrome.js +77 -0
- package/dist/tui/rewind-chrome.js.map +1 -0
- package/dist/tui/rust-present.d.ts +37 -0
- package/dist/tui/rust-present.d.ts.map +1 -0
- package/dist/tui/rust-present.js +205 -0
- package/dist/tui/rust-present.js.map +1 -0
- package/dist/tui/spinner-phase.d.ts +23 -0
- package/dist/tui/spinner-phase.d.ts.map +1 -0
- package/dist/tui/spinner-phase.js +25 -0
- package/dist/tui/spinner-phase.js.map +1 -0
- package/dist/tui/statusline-path.d.ts +10 -0
- package/dist/tui/statusline-path.d.ts.map +1 -0
- package/dist/tui/statusline-path.js +42 -0
- package/dist/tui/statusline-path.js.map +1 -0
- package/dist/tui/sugarcoat-paint.d.ts +14 -0
- package/dist/tui/sugarcoat-paint.d.ts.map +1 -0
- package/dist/tui/sugarcoat-paint.js +146 -0
- package/dist/tui/sugarcoat-paint.js.map +1 -0
- package/dist/tui/tape-spans.d.ts +64 -0
- package/dist/tui/tape-spans.d.ts.map +1 -0
- package/dist/tui/tape-spans.js +93 -0
- package/dist/tui/tape-spans.js.map +1 -0
- package/dist/tui/tea.d.ts +75 -0
- package/dist/tui/tea.d.ts.map +1 -0
- package/dist/tui/tea.js +2952 -0
- package/dist/tui/tea.js.map +1 -0
- package/dist/tui/vt-paint.d.ts +12 -0
- package/dist/tui/vt-paint.d.ts.map +1 -0
- package/dist/tui/vt-paint.js +123 -0
- package/dist/tui/vt-paint.js.map +1 -0
- package/dist/tui/wait-phrase.d.ts +31 -0
- package/dist/tui/wait-phrase.d.ts.map +1 -0
- package/dist/tui/wait-phrase.js +26 -0
- package/dist/tui/wait-phrase.js.map +1 -0
- package/dist/tui/widget-host.d.ts +34 -0
- package/dist/tui/widget-host.d.ts.map +1 -0
- package/dist/tui/widget-host.js +80 -0
- package/dist/tui/widget-host.js.map +1 -0
- package/dist/tui/work-cells.d.ts +47 -0
- package/dist/tui/work-cells.d.ts.map +1 -0
- package/dist/tui/work-cells.js +606 -0
- package/dist/tui/work-cells.js.map +1 -0
- package/dist/tui/worker-entry.d.ts +2 -0
- package/dist/tui/worker-entry.d.ts.map +1 -0
- package/dist/tui/worker-entry.js +98 -0
- package/dist/tui/worker-entry.js.map +1 -0
- package/package.json +83 -3
- package/README.md +0 -3
package/dist/tui/tea.js
ADDED
|
@@ -0,0 +1,2952 @@
|
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
5
|
+
}
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
8
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
+
var _, done = false;
|
|
14
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
+
var context = {};
|
|
16
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
+
if (kind === "accessor") {
|
|
21
|
+
if (result === void 0) continue;
|
|
22
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
26
|
+
}
|
|
27
|
+
else if (_ = accept(result)) {
|
|
28
|
+
if (kind === "field") initializers.unshift(_);
|
|
29
|
+
else descriptor[key] = _;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
+
done = true;
|
|
34
|
+
};
|
|
35
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
36
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
37
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Worker Tea. Posts paint_init / paint_patch. Catalog is CommandSpec plus
|
|
41
|
+
* host verbs — host-verbs.ts has no CommandSpec body; invoke locally.
|
|
42
|
+
*
|
|
43
|
+
* Omnibox winner lives in omnibox-seat.ts, CHANGE ONLY.
|
|
44
|
+
*/
|
|
45
|
+
import { exec } from "@here.build/arrival";
|
|
46
|
+
import { isUiForm } from "@inhuman.tools/harness-contract";
|
|
47
|
+
import { fail, step, trace } from "@inhuman.tools/harness-diagnostics";
|
|
48
|
+
import { CallJob, AgentMessageJob, otherSessionSeatCount, DEFAULT_CONTEXT_GLOW_REMAINING, STATUSLINE_NOTE_SEP, fileReadPreparedPath, mcpReadFloorDenies, parseCompactTrigger, parseSuperKey, PERMISSION_MODES, MCPToolJob, isAtTip, isRewindPin, onTipChain, previousPin, futurePins, pastPins, resolvedTip, reactChunks, tapeCompletion, layersOf, SessionTurn, sessionDisplayTitle, skillMatchesVerb, ToolCallJob, } from "@inhuman.tools/harness-model";
|
|
49
|
+
import { createBlobCache } from "@inhuman.tools/harness-peer";
|
|
50
|
+
import { flattenAgentDrawer, hostAskEscalateSessionId, mentionedAgentCall, projectAgentDrawer, projectRecentSessions, openExternalUrl, } from "@inhuman.tools/harness-sdk";
|
|
51
|
+
import { agentAskStackedBody, agentCoverPrompt, agentRecipeDescription, agentSpecKey, coverAskAnnotation, shellAskCommand, askPaintHead, emptyWaitChrome, formatMcpArgs, mcpConfirmViewport, } from "@inhuman.tools/harness-sdk/text";
|
|
52
|
+
import { CLASSES } from "@inhuman.tools/policy/floor";
|
|
53
|
+
import { applyDraftOp } from "@inhuman.tools/quickdraw/input";
|
|
54
|
+
import { eventMatchesChord } from "@inhuman.tools/quickdraw/layout";
|
|
55
|
+
import { agentsRowKeyFromHit, keyEventToDraftOp, maybeVisualMotion, receiveSubmit, rootInnerWidth, sessionIdFromAgentsKey, } from "@inhuman.tools/quickdraw/runtime";
|
|
56
|
+
import { catalogKey, COMPOSER_COMMAND_MAX_VISIBLE, matchComposerCommand, peekScroll, reconcileSelectedKey, } from "@inhuman.tools/quickdraw/widgets";
|
|
57
|
+
import { action, comparer, computed, observable, reaction, runInAction, when } from "mobx";
|
|
58
|
+
import invariant from "tiny-invariant";
|
|
59
|
+
import { ackAnnotation, ackPromptModel, ackVariant, cycleAck, } from "./ack-prompt.js";
|
|
60
|
+
import { agentsPaintFace } from "./agents-drawer.js";
|
|
61
|
+
import { HOTKEY_EVENT } from "./ask-shortcuts.js";
|
|
62
|
+
import { isHostVerb } from "./host-verbs.js";
|
|
63
|
+
import { omniboxSeat, omniboxStackPanel, paintOmnibox, } from "./omnibox-seat.js";
|
|
64
|
+
import { createPaintController, isCompletionCutoff, trackEqual, trackTurn, } from "./paint-controller.js";
|
|
65
|
+
import { parseProbe, permissionsSurface, permissionsView, } from "./permissions-view.js";
|
|
66
|
+
import { fileReadWiden } from "./read-widen.js";
|
|
67
|
+
import { rewindNeighborSlots } from "./rewind-chrome.js";
|
|
68
|
+
import { cwdParts } from "./statusline-path.js";
|
|
69
|
+
import { waitPhrase } from "./wait-phrase.js";
|
|
70
|
+
import { askPinFace, askPinWorthPainting } from "./work-cells.js";
|
|
71
|
+
import { ComputedExecBox } from "../interpreter/ComputedExecBox.js";
|
|
72
|
+
import { imageCapability } from "../interpreter/imageCapability.js";
|
|
73
|
+
import { rpcCapability } from "../interpreter/rpcCapability.js";
|
|
74
|
+
import { uiCapability, UiNode } from "../interpreter/uiCapability.js";
|
|
75
|
+
const COMMAND_CAPABILITIES = [imageCapability, uiCapability, rpcCapability];
|
|
76
|
+
/** Mash after cancel must not peel into history. Tea-local; the turn must also be idle. */
|
|
77
|
+
const REWIND_GRACE_MS = 1000;
|
|
78
|
+
export function bootComposerDraft(draft, connections) {
|
|
79
|
+
if (draft != null && draft !== "")
|
|
80
|
+
return draft;
|
|
81
|
+
for (const spec of connections) {
|
|
82
|
+
if (spec.driver?.abilityClaim.includes("completion"))
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return "/connect";
|
|
86
|
+
}
|
|
87
|
+
let Tea = (() => {
|
|
88
|
+
var _a, _b, _c, _d, _e, _f;
|
|
89
|
+
let _instanceExtraInitializers = [];
|
|
90
|
+
let _draft_decorators;
|
|
91
|
+
let _draft_initializers = [];
|
|
92
|
+
let _draft_extraInitializers = [];
|
|
93
|
+
let _submission_decorators;
|
|
94
|
+
let _submission_initializers = [];
|
|
95
|
+
let _submission_extraInitializers = [];
|
|
96
|
+
let _selectedCommandKey_decorators;
|
|
97
|
+
let _selectedCommandKey_initializers = [];
|
|
98
|
+
let _selectedCommandKey_extraInitializers = [];
|
|
99
|
+
let _scrollOffset_decorators;
|
|
100
|
+
let _scrollOffset_initializers = [];
|
|
101
|
+
let _scrollOffset_extraInitializers = [];
|
|
102
|
+
let _escClearArmed_decorators;
|
|
103
|
+
let _escClearArmed_initializers = [];
|
|
104
|
+
let _escClearArmed_extraInitializers = [];
|
|
105
|
+
let _cols_decorators;
|
|
106
|
+
let _cols_initializers = [];
|
|
107
|
+
let _cols_extraInitializers = [];
|
|
108
|
+
let _rows_decorators;
|
|
109
|
+
let _rows_initializers = [];
|
|
110
|
+
let _rows_extraInitializers = [];
|
|
111
|
+
let _private_busy_decorators;
|
|
112
|
+
let _private_busy_initializers = [];
|
|
113
|
+
let _private_busy_extraInitializers = [];
|
|
114
|
+
let _private_busy_descriptor;
|
|
115
|
+
let _private_callback_decorators;
|
|
116
|
+
let _private_callback_initializers = [];
|
|
117
|
+
let _private_callback_extraInitializers = [];
|
|
118
|
+
let _private_callback_descriptor;
|
|
119
|
+
let _private_focus_decorators;
|
|
120
|
+
let _private_focus_initializers = [];
|
|
121
|
+
let _private_focus_extraInitializers = [];
|
|
122
|
+
let _private_focus_descriptor;
|
|
123
|
+
let _private_oauthWaiting_decorators;
|
|
124
|
+
let _private_oauthWaiting_initializers = [];
|
|
125
|
+
let _private_oauthWaiting_extraInitializers = [];
|
|
126
|
+
let _private_oauthWaiting_descriptor;
|
|
127
|
+
let _private_processing_decorators;
|
|
128
|
+
let _private_processing_initializers = [];
|
|
129
|
+
let _private_processing_extraInitializers = [];
|
|
130
|
+
let _private_processing_descriptor;
|
|
131
|
+
let _private_coverDraft_decorators;
|
|
132
|
+
let _private_coverDraft_initializers = [];
|
|
133
|
+
let _private_coverDraft_extraInitializers = [];
|
|
134
|
+
let _private_coverDraft_descriptor;
|
|
135
|
+
let _private_coverThrottle_decorators;
|
|
136
|
+
let _private_coverThrottle_initializers = [];
|
|
137
|
+
let _private_coverThrottle_extraInitializers = [];
|
|
138
|
+
let _private_coverThrottle_descriptor;
|
|
139
|
+
let _private_coverConfirmLive_decorators;
|
|
140
|
+
let _private_coverConfirmLive_initializers = [];
|
|
141
|
+
let _private_coverConfirmLive_extraInitializers = [];
|
|
142
|
+
let _private_coverConfirmLive_descriptor;
|
|
143
|
+
let _private_ackPick_decorators;
|
|
144
|
+
let _private_ackPick_initializers = [];
|
|
145
|
+
let _private_ackPick_extraInitializers = [];
|
|
146
|
+
let _private_ackPick_descriptor;
|
|
147
|
+
let _private_askHold_decorators;
|
|
148
|
+
let _private_askHold_initializers = [];
|
|
149
|
+
let _private_askHold_extraInitializers = [];
|
|
150
|
+
let _private_askHold_descriptor;
|
|
151
|
+
let _private_drainAsk_decorators;
|
|
152
|
+
let _private_drainAsk_initializers = [];
|
|
153
|
+
let _private_drainAsk_extraInitializers = [];
|
|
154
|
+
let _private_drainAsk_descriptor;
|
|
155
|
+
let _private_agentsOpen_decorators;
|
|
156
|
+
let _private_agentsOpen_initializers = [];
|
|
157
|
+
let _private_agentsOpen_extraInitializers = [];
|
|
158
|
+
let _private_agentsOpen_descriptor;
|
|
159
|
+
let _private_agentsFocus_decorators;
|
|
160
|
+
let _private_agentsFocus_initializers = [];
|
|
161
|
+
let _private_agentsFocus_extraInitializers = [];
|
|
162
|
+
let _private_agentsFocus_descriptor;
|
|
163
|
+
let _private_agentsHover_decorators;
|
|
164
|
+
let _private_agentsHover_initializers = [];
|
|
165
|
+
let _private_agentsHover_extraInitializers = [];
|
|
166
|
+
let _private_agentsHover_descriptor;
|
|
167
|
+
let _private_agentsScroll_decorators;
|
|
168
|
+
let _private_agentsScroll_initializers = [];
|
|
169
|
+
let _private_agentsScroll_extraInitializers = [];
|
|
170
|
+
let _private_agentsScroll_descriptor;
|
|
171
|
+
let _private_agentsPreview_decorators;
|
|
172
|
+
let _private_agentsPreview_initializers = [];
|
|
173
|
+
let _private_agentsPreview_extraInitializers = [];
|
|
174
|
+
let _private_agentsPreview_descriptor;
|
|
175
|
+
let _private_peekPlexus_decorators;
|
|
176
|
+
let _private_peekPlexus_initializers = [];
|
|
177
|
+
let _private_peekPlexus_extraInitializers = [];
|
|
178
|
+
let _private_peekPlexus_descriptor;
|
|
179
|
+
let _private_askPlexus_decorators;
|
|
180
|
+
let _private_askPlexus_initializers = [];
|
|
181
|
+
let _private_askPlexus_extraInitializers = [];
|
|
182
|
+
let _private_askPlexus_descriptor;
|
|
183
|
+
let _private_viewPin_decorators;
|
|
184
|
+
let _private_viewPin_initializers = [];
|
|
185
|
+
let _private_viewPin_extraInitializers = [];
|
|
186
|
+
let _private_viewPin_descriptor;
|
|
187
|
+
let _private_historyNav_decorators;
|
|
188
|
+
let _private_historyNav_initializers = [];
|
|
189
|
+
let _private_historyNav_extraInitializers = [];
|
|
190
|
+
let _private_historyNav_descriptor;
|
|
191
|
+
let _private_restoredDraft_decorators;
|
|
192
|
+
let _private_restoredDraft_initializers = [];
|
|
193
|
+
let _private_restoredDraft_extraInitializers = [];
|
|
194
|
+
let _private_restoredDraft_descriptor;
|
|
195
|
+
let _private_get_agentDrawerRows_decorators;
|
|
196
|
+
let _private_get_agentDrawerRows_descriptor;
|
|
197
|
+
let _private_get_sessionTitle_decorators;
|
|
198
|
+
let _private_get_sessionTitle_descriptor;
|
|
199
|
+
let _private_get_isHeadAtTip_decorators;
|
|
200
|
+
let _private_get_isHeadAtTip_descriptor;
|
|
201
|
+
let _private_get_askHead_decorators;
|
|
202
|
+
let _private_get_askHead_descriptor;
|
|
203
|
+
let _private_get_ackPrompt_decorators;
|
|
204
|
+
let _private_get_ackPrompt_descriptor;
|
|
205
|
+
let _private_get_coverAskAgentSpec_decorators;
|
|
206
|
+
let _private_get_coverAskAgentSpec_descriptor;
|
|
207
|
+
let _private_get_askHome_decorators;
|
|
208
|
+
let _private_get_askHome_descriptor;
|
|
209
|
+
let _private_get_readWiden_decorators;
|
|
210
|
+
let _private_get_readWiden_descriptor;
|
|
211
|
+
let _private_get_omniboxValue_decorators;
|
|
212
|
+
let _private_get_omniboxValue_descriptor;
|
|
213
|
+
let _private_get_contextRail_decorators;
|
|
214
|
+
let _private_get_contextRail_descriptor;
|
|
215
|
+
let _private_get_omnibox_decorators;
|
|
216
|
+
let _private_get_omnibox_descriptor;
|
|
217
|
+
let _private_get_askIsolated_decorators;
|
|
218
|
+
let _private_get_askIsolated_descriptor;
|
|
219
|
+
let _private_get_admissionDeckText_decorators;
|
|
220
|
+
let _private_get_admissionDeckText_descriptor;
|
|
221
|
+
let _private_get_waitChrome_decorators;
|
|
222
|
+
let _private_get_waitChrome_descriptor;
|
|
223
|
+
let _private_get_commands_decorators;
|
|
224
|
+
let _private_get_commands_descriptor;
|
|
225
|
+
let _private_get_parentNode_decorators;
|
|
226
|
+
let _private_get_parentNode_descriptor;
|
|
227
|
+
let _private_get_inCommand_decorators;
|
|
228
|
+
let _private_get_inCommand_descriptor;
|
|
229
|
+
let _private_get_atCatalog_decorators;
|
|
230
|
+
let _private_get_atCatalog_descriptor;
|
|
231
|
+
let _private_get_pickerRows_decorators;
|
|
232
|
+
let _private_get_pickerRows_descriptor;
|
|
233
|
+
let _private_get_catalogNodes_decorators;
|
|
234
|
+
let _private_get_catalogNodes_descriptor;
|
|
235
|
+
let _private_get_commandChoices_decorators;
|
|
236
|
+
let _private_get_commandChoices_descriptor;
|
|
237
|
+
let _get_effectiveKey_decorators;
|
|
238
|
+
let _private_get_commandAction_decorators;
|
|
239
|
+
let _private_get_commandAction_descriptor;
|
|
240
|
+
let _private_get_commandSurface_decorators;
|
|
241
|
+
let _private_get_commandSurface_descriptor;
|
|
242
|
+
let _private_get_selectedIndex_decorators;
|
|
243
|
+
let _private_get_selectedIndex_descriptor;
|
|
244
|
+
let _focusAt_decorators;
|
|
245
|
+
let _handle_decorators;
|
|
246
|
+
let _private_get_activeConnection_decorators;
|
|
247
|
+
let _private_get_activeConnection_descriptor;
|
|
248
|
+
let _private_get_quotaWindows_decorators;
|
|
249
|
+
let _private_get_quotaWindows_descriptor;
|
|
250
|
+
let _private_get_statusItems_decorators;
|
|
251
|
+
let _private_get_statusItems_descriptor;
|
|
252
|
+
let _private_stepCoverThrottle_decorators;
|
|
253
|
+
let _private_stepCoverThrottle_descriptor;
|
|
254
|
+
let _private_get_attentionSubjects_decorators;
|
|
255
|
+
let _private_get_attentionSubjects_descriptor;
|
|
256
|
+
return class Tea {
|
|
257
|
+
static {
|
|
258
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
259
|
+
__esDecorate(this, null, _draft_decorators, { kind: "accessor", name: "draft", static: false, private: false, access: { has: obj => "draft" in obj, get: obj => obj.draft, set: (obj, value) => { obj.draft = value; } }, metadata: _metadata }, _draft_initializers, _draft_extraInitializers);
|
|
260
|
+
__esDecorate(this, null, _submission_decorators, { kind: "accessor", name: "submission", static: false, private: false, access: { has: obj => "submission" in obj, get: obj => obj.submission, set: (obj, value) => { obj.submission = value; } }, metadata: _metadata }, _submission_initializers, _submission_extraInitializers);
|
|
261
|
+
__esDecorate(this, null, _selectedCommandKey_decorators, { kind: "accessor", name: "selectedCommandKey", static: false, private: false, access: { has: obj => "selectedCommandKey" in obj, get: obj => obj.selectedCommandKey, set: (obj, value) => { obj.selectedCommandKey = value; } }, metadata: _metadata }, _selectedCommandKey_initializers, _selectedCommandKey_extraInitializers);
|
|
262
|
+
__esDecorate(this, null, _scrollOffset_decorators, { kind: "accessor", name: "scrollOffset", static: false, private: false, access: { has: obj => "scrollOffset" in obj, get: obj => obj.scrollOffset, set: (obj, value) => { obj.scrollOffset = value; } }, metadata: _metadata }, _scrollOffset_initializers, _scrollOffset_extraInitializers);
|
|
263
|
+
__esDecorate(this, null, _escClearArmed_decorators, { kind: "accessor", name: "escClearArmed", static: false, private: false, access: { has: obj => "escClearArmed" in obj, get: obj => obj.escClearArmed, set: (obj, value) => { obj.escClearArmed = value; } }, metadata: _metadata }, _escClearArmed_initializers, _escClearArmed_extraInitializers);
|
|
264
|
+
__esDecorate(this, null, _cols_decorators, { kind: "accessor", name: "cols", static: false, private: false, access: { has: obj => "cols" in obj, get: obj => obj.cols, set: (obj, value) => { obj.cols = value; } }, metadata: _metadata }, _cols_initializers, _cols_extraInitializers);
|
|
265
|
+
__esDecorate(this, null, _rows_decorators, { kind: "accessor", name: "rows", static: false, private: false, access: { has: obj => "rows" in obj, get: obj => obj.rows, set: (obj, value) => { obj.rows = value; } }, metadata: _metadata }, _rows_initializers, _rows_extraInitializers);
|
|
266
|
+
__esDecorate(this, _private_busy_descriptor = { get: __setFunctionName(function () { return this.#busy_accessor_storage; }, "#busy", "get"), set: __setFunctionName(function (value) { this.#busy_accessor_storage = value; }, "#busy", "set") }, _private_busy_decorators, { kind: "accessor", name: "#busy", static: false, private: true, access: { has: obj => #busy in obj, get: obj => obj.#busy, set: (obj, value) => { obj.#busy = value; } }, metadata: _metadata }, _private_busy_initializers, _private_busy_extraInitializers);
|
|
267
|
+
__esDecorate(this, _private_callback_descriptor = { get: __setFunctionName(function () { return this.#callback_accessor_storage; }, "#callback", "get"), set: __setFunctionName(function (value) { this.#callback_accessor_storage = value; }, "#callback", "set") }, _private_callback_decorators, { kind: "accessor", name: "#callback", static: false, private: true, access: { has: obj => #callback in obj, get: obj => obj.#callback, set: (obj, value) => { obj.#callback = value; } }, metadata: _metadata }, _private_callback_initializers, _private_callback_extraInitializers);
|
|
268
|
+
__esDecorate(this, _private_focus_descriptor = { get: __setFunctionName(function () { return this.#focus_accessor_storage; }, "#focus", "get"), set: __setFunctionName(function (value) { this.#focus_accessor_storage = value; }, "#focus", "set") }, _private_focus_decorators, { kind: "accessor", name: "#focus", static: false, private: true, access: { has: obj => #focus in obj, get: obj => obj.#focus, set: (obj, value) => { obj.#focus = value; } }, metadata: _metadata }, _private_focus_initializers, _private_focus_extraInitializers);
|
|
269
|
+
__esDecorate(this, _private_oauthWaiting_descriptor = { get: __setFunctionName(function () { return this.#oauthWaiting_accessor_storage; }, "#oauthWaiting", "get"), set: __setFunctionName(function (value) { this.#oauthWaiting_accessor_storage = value; }, "#oauthWaiting", "set") }, _private_oauthWaiting_decorators, { kind: "accessor", name: "#oauthWaiting", static: false, private: true, access: { has: obj => #oauthWaiting in obj, get: obj => obj.#oauthWaiting, set: (obj, value) => { obj.#oauthWaiting = value; } }, metadata: _metadata }, _private_oauthWaiting_initializers, _private_oauthWaiting_extraInitializers);
|
|
270
|
+
__esDecorate(this, _private_processing_descriptor = { get: __setFunctionName(function () { return this.#processing_accessor_storage; }, "#processing", "get"), set: __setFunctionName(function (value) { this.#processing_accessor_storage = value; }, "#processing", "set") }, _private_processing_decorators, { kind: "accessor", name: "#processing", static: false, private: true, access: { has: obj => #processing in obj, get: obj => obj.#processing, set: (obj, value) => { obj.#processing = value; } }, metadata: _metadata }, _private_processing_initializers, _private_processing_extraInitializers);
|
|
271
|
+
__esDecorate(this, _private_coverDraft_descriptor = { get: __setFunctionName(function () { return this.#coverDraft_accessor_storage; }, "#coverDraft", "get"), set: __setFunctionName(function (value) { this.#coverDraft_accessor_storage = value; }, "#coverDraft", "set") }, _private_coverDraft_decorators, { kind: "accessor", name: "#coverDraft", static: false, private: true, access: { has: obj => #coverDraft in obj, get: obj => obj.#coverDraft, set: (obj, value) => { obj.#coverDraft = value; } }, metadata: _metadata }, _private_coverDraft_initializers, _private_coverDraft_extraInitializers);
|
|
272
|
+
__esDecorate(this, _private_coverThrottle_descriptor = { get: __setFunctionName(function () { return this.#coverThrottle_accessor_storage; }, "#coverThrottle", "get"), set: __setFunctionName(function (value) { this.#coverThrottle_accessor_storage = value; }, "#coverThrottle", "set") }, _private_coverThrottle_decorators, { kind: "accessor", name: "#coverThrottle", static: false, private: true, access: { has: obj => #coverThrottle in obj, get: obj => obj.#coverThrottle, set: (obj, value) => { obj.#coverThrottle = value; } }, metadata: _metadata }, _private_coverThrottle_initializers, _private_coverThrottle_extraInitializers);
|
|
273
|
+
__esDecorate(this, _private_coverConfirmLive_descriptor = { get: __setFunctionName(function () { return this.#coverConfirmLive_accessor_storage; }, "#coverConfirmLive", "get"), set: __setFunctionName(function (value) { this.#coverConfirmLive_accessor_storage = value; }, "#coverConfirmLive", "set") }, _private_coverConfirmLive_decorators, { kind: "accessor", name: "#coverConfirmLive", static: false, private: true, access: { has: obj => #coverConfirmLive in obj, get: obj => obj.#coverConfirmLive, set: (obj, value) => { obj.#coverConfirmLive = value; } }, metadata: _metadata }, _private_coverConfirmLive_initializers, _private_coverConfirmLive_extraInitializers);
|
|
274
|
+
__esDecorate(this, _private_ackPick_descriptor = { get: __setFunctionName(function () { return this.#ackPick_accessor_storage; }, "#ackPick", "get"), set: __setFunctionName(function (value) { this.#ackPick_accessor_storage = value; }, "#ackPick", "set") }, _private_ackPick_decorators, { kind: "accessor", name: "#ackPick", static: false, private: true, access: { has: obj => #ackPick in obj, get: obj => obj.#ackPick, set: (obj, value) => { obj.#ackPick = value; } }, metadata: _metadata }, _private_ackPick_initializers, _private_ackPick_extraInitializers);
|
|
275
|
+
__esDecorate(this, _private_askHold_descriptor = { get: __setFunctionName(function () { return this.#askHold_accessor_storage; }, "#askHold", "get"), set: __setFunctionName(function (value) { this.#askHold_accessor_storage = value; }, "#askHold", "set") }, _private_askHold_decorators, { kind: "accessor", name: "#askHold", static: false, private: true, access: { has: obj => #askHold in obj, get: obj => obj.#askHold, set: (obj, value) => { obj.#askHold = value; } }, metadata: _metadata }, _private_askHold_initializers, _private_askHold_extraInitializers);
|
|
276
|
+
__esDecorate(this, _private_drainAsk_descriptor = { get: __setFunctionName(function () { return this.#drainAsk_accessor_storage; }, "#drainAsk", "get"), set: __setFunctionName(function (value) { this.#drainAsk_accessor_storage = value; }, "#drainAsk", "set") }, _private_drainAsk_decorators, { kind: "accessor", name: "#drainAsk", static: false, private: true, access: { has: obj => #drainAsk in obj, get: obj => obj.#drainAsk, set: (obj, value) => { obj.#drainAsk = value; } }, metadata: _metadata }, _private_drainAsk_initializers, _private_drainAsk_extraInitializers);
|
|
277
|
+
__esDecorate(this, _private_agentsOpen_descriptor = { get: __setFunctionName(function () { return this.#agentsOpen_accessor_storage; }, "#agentsOpen", "get"), set: __setFunctionName(function (value) { this.#agentsOpen_accessor_storage = value; }, "#agentsOpen", "set") }, _private_agentsOpen_decorators, { kind: "accessor", name: "#agentsOpen", static: false, private: true, access: { has: obj => #agentsOpen in obj, get: obj => obj.#agentsOpen, set: (obj, value) => { obj.#agentsOpen = value; } }, metadata: _metadata }, _private_agentsOpen_initializers, _private_agentsOpen_extraInitializers);
|
|
278
|
+
__esDecorate(this, _private_agentsFocus_descriptor = { get: __setFunctionName(function () { return this.#agentsFocus_accessor_storage; }, "#agentsFocus", "get"), set: __setFunctionName(function (value) { this.#agentsFocus_accessor_storage = value; }, "#agentsFocus", "set") }, _private_agentsFocus_decorators, { kind: "accessor", name: "#agentsFocus", static: false, private: true, access: { has: obj => #agentsFocus in obj, get: obj => obj.#agentsFocus, set: (obj, value) => { obj.#agentsFocus = value; } }, metadata: _metadata }, _private_agentsFocus_initializers, _private_agentsFocus_extraInitializers);
|
|
279
|
+
__esDecorate(this, _private_agentsHover_descriptor = { get: __setFunctionName(function () { return this.#agentsHover_accessor_storage; }, "#agentsHover", "get"), set: __setFunctionName(function (value) { this.#agentsHover_accessor_storage = value; }, "#agentsHover", "set") }, _private_agentsHover_decorators, { kind: "accessor", name: "#agentsHover", static: false, private: true, access: { has: obj => #agentsHover in obj, get: obj => obj.#agentsHover, set: (obj, value) => { obj.#agentsHover = value; } }, metadata: _metadata }, _private_agentsHover_initializers, _private_agentsHover_extraInitializers);
|
|
280
|
+
__esDecorate(this, _private_agentsScroll_descriptor = { get: __setFunctionName(function () { return this.#agentsScroll_accessor_storage; }, "#agentsScroll", "get"), set: __setFunctionName(function (value) { this.#agentsScroll_accessor_storage = value; }, "#agentsScroll", "set") }, _private_agentsScroll_decorators, { kind: "accessor", name: "#agentsScroll", static: false, private: true, access: { has: obj => #agentsScroll in obj, get: obj => obj.#agentsScroll, set: (obj, value) => { obj.#agentsScroll = value; } }, metadata: _metadata }, _private_agentsScroll_initializers, _private_agentsScroll_extraInitializers);
|
|
281
|
+
__esDecorate(this, _private_agentsPreview_descriptor = { get: __setFunctionName(function () { return this.#agentsPreview_accessor_storage; }, "#agentsPreview", "get"), set: __setFunctionName(function (value) { this.#agentsPreview_accessor_storage = value; }, "#agentsPreview", "set") }, _private_agentsPreview_decorators, { kind: "accessor", name: "#agentsPreview", static: false, private: true, access: { has: obj => #agentsPreview in obj, get: obj => obj.#agentsPreview, set: (obj, value) => { obj.#agentsPreview = value; } }, metadata: _metadata }, _private_agentsPreview_initializers, _private_agentsPreview_extraInitializers);
|
|
282
|
+
__esDecorate(this, _private_peekPlexus_descriptor = { get: __setFunctionName(function () { return this.#peekPlexus_accessor_storage; }, "#peekPlexus", "get"), set: __setFunctionName(function (value) { this.#peekPlexus_accessor_storage = value; }, "#peekPlexus", "set") }, _private_peekPlexus_decorators, { kind: "accessor", name: "#peekPlexus", static: false, private: true, access: { has: obj => #peekPlexus in obj, get: obj => obj.#peekPlexus, set: (obj, value) => { obj.#peekPlexus = value; } }, metadata: _metadata }, _private_peekPlexus_initializers, _private_peekPlexus_extraInitializers);
|
|
283
|
+
__esDecorate(this, _private_askPlexus_descriptor = { get: __setFunctionName(function () { return this.#askPlexus_accessor_storage; }, "#askPlexus", "get"), set: __setFunctionName(function (value) { this.#askPlexus_accessor_storage = value; }, "#askPlexus", "set") }, _private_askPlexus_decorators, { kind: "accessor", name: "#askPlexus", static: false, private: true, access: { has: obj => #askPlexus in obj, get: obj => obj.#askPlexus, set: (obj, value) => { obj.#askPlexus = value; } }, metadata: _metadata }, _private_askPlexus_initializers, _private_askPlexus_extraInitializers);
|
|
284
|
+
__esDecorate(this, _private_viewPin_descriptor = { get: __setFunctionName(function () { return this.#viewPin_accessor_storage; }, "#viewPin", "get"), set: __setFunctionName(function (value) { this.#viewPin_accessor_storage = value; }, "#viewPin", "set") }, _private_viewPin_decorators, { kind: "accessor", name: "#viewPin", static: false, private: true, access: { has: obj => #viewPin in obj, get: obj => obj.#viewPin, set: (obj, value) => { obj.#viewPin = value; } }, metadata: _metadata }, _private_viewPin_initializers, _private_viewPin_extraInitializers);
|
|
285
|
+
__esDecorate(this, _private_historyNav_descriptor = { get: __setFunctionName(function () { return this.#historyNav_accessor_storage; }, "#historyNav", "get"), set: __setFunctionName(function (value) { this.#historyNav_accessor_storage = value; }, "#historyNav", "set") }, _private_historyNav_decorators, { kind: "accessor", name: "#historyNav", static: false, private: true, access: { has: obj => #historyNav in obj, get: obj => obj.#historyNav, set: (obj, value) => { obj.#historyNav = value; } }, metadata: _metadata }, _private_historyNav_initializers, _private_historyNav_extraInitializers);
|
|
286
|
+
__esDecorate(this, _private_restoredDraft_descriptor = { get: __setFunctionName(function () { return this.#restoredDraft_accessor_storage; }, "#restoredDraft", "get"), set: __setFunctionName(function (value) { this.#restoredDraft_accessor_storage = value; }, "#restoredDraft", "set") }, _private_restoredDraft_decorators, { kind: "accessor", name: "#restoredDraft", static: false, private: true, access: { has: obj => #restoredDraft in obj, get: obj => obj.#restoredDraft, set: (obj, value) => { obj.#restoredDraft = value; } }, metadata: _metadata }, _private_restoredDraft_initializers, _private_restoredDraft_extraInitializers);
|
|
287
|
+
__esDecorate(this, _private_get_agentDrawerRows_descriptor = { get: __setFunctionName(function () {
|
|
288
|
+
return flattenAgentDrawer(projectAgentDrawer(this.client));
|
|
289
|
+
}, "#agentDrawerRows", "get") }, _private_get_agentDrawerRows_decorators, { kind: "getter", name: "#agentDrawerRows", static: false, private: true, access: { has: obj => #agentDrawerRows in obj, get: obj => obj.#agentDrawerRows }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
290
|
+
__esDecorate(this, _private_get_sessionTitle_descriptor = { get: __setFunctionName(function () {
|
|
291
|
+
return (this.client.sessionRoot.manualTitle.trim() ||
|
|
292
|
+
resolvedTip(this.client.sessionRoot.head, this.client.sessionRoot.tip)?.metadata?.title ||
|
|
293
|
+
"");
|
|
294
|
+
}, "#sessionTitle", "get") }, _private_get_sessionTitle_decorators, { kind: "getter", name: "#sessionTitle", static: false, private: true, access: { has: obj => #sessionTitle in obj, get: obj => obj.#sessionTitle }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
295
|
+
__esDecorate(this, _private_get_isHeadAtTip_descriptor = { get: __setFunctionName(function () {
|
|
296
|
+
return isAtTip(this.client.sessionRoot.head, this.client.sessionRoot.tip);
|
|
297
|
+
}, "#isHeadAtTip", "get") }, _private_get_isHeadAtTip_decorators, { kind: "getter", name: "#isHeadAtTip", static: false, private: true, access: { has: obj => #isHeadAtTip in obj, get: obj => obj.#isHeadAtTip }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
298
|
+
__esDecorate(this, _private_get_askHead_descriptor = { get: __setFunctionName(function () {
|
|
299
|
+
const host = this.client.sessionRoot.findRunningTurn()?.approvalHead ?? null;
|
|
300
|
+
if (host != null)
|
|
301
|
+
return host;
|
|
302
|
+
const id = hostAskEscalateSessionId(this.client);
|
|
303
|
+
if (id == null || this.#askPlexus?.root.sessionId !== id)
|
|
304
|
+
return null;
|
|
305
|
+
return this.#askPlexus.root.findRunningTurn()?.approvalHead ?? null;
|
|
306
|
+
}, "#askHead", "get") }, _private_get_askHead_decorators, { kind: "getter", name: "#askHead", static: false, private: true, access: { has: obj => #askHead in obj, get: obj => obj.#askHead }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
307
|
+
__esDecorate(this, _private_get_ackPrompt_descriptor = { get: __setFunctionName(function () {
|
|
308
|
+
const leaf = this.#askHead;
|
|
309
|
+
if (leaf == null)
|
|
310
|
+
return null;
|
|
311
|
+
const variant = ackVariant({
|
|
312
|
+
ackPending: leaf.ackPending,
|
|
313
|
+
policyResult: leaf.policyResult,
|
|
314
|
+
baseDecision: leaf.baseLicenseDetail.decision,
|
|
315
|
+
});
|
|
316
|
+
if (variant === null)
|
|
317
|
+
return null;
|
|
318
|
+
return ackPromptModel({
|
|
319
|
+
variant,
|
|
320
|
+
flags: leaf.ackFlags,
|
|
321
|
+
options: leaf.ackOptions,
|
|
322
|
+
bot: this.#askHome.agent.spec.name.trim() !== "",
|
|
323
|
+
});
|
|
324
|
+
}, "#ackPrompt", "get") }, _private_get_ackPrompt_decorators, { kind: "getter", name: "#ackPrompt", static: false, private: true, access: { has: obj => #ackPrompt in obj, get: obj => obj.#ackPrompt }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
325
|
+
__esDecorate(this, _private_get_coverAskAgentSpec_descriptor = { get: __setFunctionName(function () {
|
|
326
|
+
const leaf = this.#askHead;
|
|
327
|
+
if (leaf == null)
|
|
328
|
+
return undefined;
|
|
329
|
+
if (this.client.sessionRoot.findRunningTurn()?.approvalHead === leaf)
|
|
330
|
+
return undefined;
|
|
331
|
+
const id = hostAskEscalateSessionId(this.client);
|
|
332
|
+
if (id == null)
|
|
333
|
+
return undefined;
|
|
334
|
+
for (const agent of this.client.agents) {
|
|
335
|
+
if (agent.sessionId === id)
|
|
336
|
+
return agent.specName;
|
|
337
|
+
}
|
|
338
|
+
return "";
|
|
339
|
+
}, "#coverAskAgentSpec", "get") }, _private_get_coverAskAgentSpec_decorators, { kind: "getter", name: "#coverAskAgentSpec", static: false, private: true, access: { has: obj => #coverAskAgentSpec in obj, get: obj => obj.#coverAskAgentSpec }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
340
|
+
__esDecorate(this, _private_get_askHome_descriptor = { get: __setFunctionName(function () {
|
|
341
|
+
const host = this.client.sessionRoot;
|
|
342
|
+
if (host.findRunningTurn()?.approvalHead != null)
|
|
343
|
+
return host;
|
|
344
|
+
const id = hostAskEscalateSessionId(this.client);
|
|
345
|
+
if (id != null && this.#askPlexus?.root.sessionId === id)
|
|
346
|
+
return this.#askPlexus.root;
|
|
347
|
+
return host;
|
|
348
|
+
}, "#askHome", "get") }, _private_get_askHome_decorators, { kind: "getter", name: "#askHome", static: false, private: true, access: { has: obj => #askHome in obj, get: obj => obj.#askHome }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
349
|
+
__esDecorate(this, _private_get_readWiden_descriptor = { get: __setFunctionName(function () {
|
|
350
|
+
const leaf = this.#askHead;
|
|
351
|
+
if (!(leaf instanceof ToolCallJob))
|
|
352
|
+
return undefined;
|
|
353
|
+
const root = this.#askHome;
|
|
354
|
+
const prepared = fileReadPreparedPath(root.path, leaf.name, leaf.args);
|
|
355
|
+
if (prepared === undefined)
|
|
356
|
+
return undefined;
|
|
357
|
+
// Evidence is another outside read in flight, or a folder already treated as part of this session.
|
|
358
|
+
const observed = Object.keys(root.readRoots);
|
|
359
|
+
const turn = root.findRunningTurn();
|
|
360
|
+
for (const job of turn?.approvalLeaves ?? []) {
|
|
361
|
+
if (!(job instanceof ToolCallJob) || job === leaf)
|
|
362
|
+
continue;
|
|
363
|
+
const path = fileReadPreparedPath(root.path, job.name, job.args);
|
|
364
|
+
if (path !== undefined)
|
|
365
|
+
observed.push(path);
|
|
366
|
+
}
|
|
367
|
+
return fileReadWiden(root.path, prepared, observed);
|
|
368
|
+
}, "#readWiden", "get") }, _private_get_readWiden_decorators, { kind: "getter", name: "#readWiden", static: false, private: true, access: { has: obj => #readWiden in obj, get: obj => obj.#readWiden }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
369
|
+
__esDecorate(this, _private_get_omniboxValue_descriptor = { get: __setFunctionName(function () {
|
|
370
|
+
const overlay = this.#callback?.surface;
|
|
371
|
+
const leaf = this.#askHead;
|
|
372
|
+
const running = this.client.sessionRoot.findRunningTurn();
|
|
373
|
+
let overlayBag = null;
|
|
374
|
+
if (overlay !== undefined) {
|
|
375
|
+
const message = overlay.description === "" ? overlay.name : overlay.description;
|
|
376
|
+
const url = urlFrom(overlay);
|
|
377
|
+
const overlayText = url === undefined || message.includes(url) ? message : message === "" ? url : `${message}\n${url}`;
|
|
378
|
+
const overlayAsBody = !hasInputHole(overlay) && url === undefined;
|
|
379
|
+
const instructional = this.#inputting && (url !== undefined || overlay.description.trim() !== "");
|
|
380
|
+
overlayBag = {
|
|
381
|
+
body: overlayAsBody ? overlayText : undefined,
|
|
382
|
+
placeholder: overlayAsBody || this.#oauthWaiting || instructional ? undefined : overlayText,
|
|
383
|
+
secret: overlay.secret === true,
|
|
384
|
+
inputting: this.#inputting,
|
|
385
|
+
processing: this.#processing,
|
|
386
|
+
commandChoices: this.#commandChoices,
|
|
387
|
+
commandAction: this.#commandAction,
|
|
388
|
+
selectedCommandKey: this.effectiveKey,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
const slash = overlay !== undefined || this.#pickerRows === undefined
|
|
392
|
+
? null
|
|
393
|
+
: {
|
|
394
|
+
commandChoices: this.#commandChoices,
|
|
395
|
+
commandAction: this.#commandAction,
|
|
396
|
+
selectedCommandKey: this.effectiveKey,
|
|
397
|
+
};
|
|
398
|
+
const widen = this.#readWiden;
|
|
399
|
+
const model = nonempty(this.client.sessionRoot.kvs.model);
|
|
400
|
+
const asked = coverAskAnnotation(leaf, {
|
|
401
|
+
model,
|
|
402
|
+
kernel: this.client.kernelRoot,
|
|
403
|
+
agentSpec: this.#coverAskAgentSpec,
|
|
404
|
+
});
|
|
405
|
+
const mcpDeny = leaf instanceof MCPToolJob && mcpReadFloorDenies(leaf.serverToolName);
|
|
406
|
+
const ack = this.#ackPrompt;
|
|
407
|
+
const ackChoice = ack?.choices[this.#ackIndex];
|
|
408
|
+
const ask = leaf === null
|
|
409
|
+
? null
|
|
410
|
+
: {
|
|
411
|
+
armed: this.#coverConfirmLive,
|
|
412
|
+
// The daemon's offer for this exact call: a family for an ask, nothing for a soft-deny.
|
|
413
|
+
...(leaf.grantOptions.length === 0 ? {} : { remember: leaf.grantOptions[0].label }),
|
|
414
|
+
persistDeny: mcpDeny,
|
|
415
|
+
caution: leaf.policyResult === "deny",
|
|
416
|
+
tier: leaf.policyResult === "deny" ? "Soft-deny" : "Ask",
|
|
417
|
+
classLabels: leaf.policyClasses.map((id) => CLASSES[id].label),
|
|
418
|
+
...(leaf.judgeReason == null || leaf.classifierResult === null
|
|
419
|
+
? {}
|
|
420
|
+
: { judgeLine: `Judge: ${leaf.judgeReason}` }),
|
|
421
|
+
widen: widen?.label,
|
|
422
|
+
...(ack === null
|
|
423
|
+
? {}
|
|
424
|
+
: {
|
|
425
|
+
ack: {
|
|
426
|
+
variant: ack.variant,
|
|
427
|
+
...(ackChoice === undefined ? {} : { choice: ackChoice.text }),
|
|
428
|
+
cycle: ack.choices.length > 1,
|
|
429
|
+
},
|
|
430
|
+
}),
|
|
431
|
+
annotation: askAnnotation(leaf, asked, widen, ack ?? undefined),
|
|
432
|
+
...askStack(leaf, this.rows, this.client.kernelRoot.bots),
|
|
433
|
+
};
|
|
434
|
+
return {
|
|
435
|
+
draft: {
|
|
436
|
+
draft: this.draft.draft,
|
|
437
|
+
cursor: this.draft.cursor,
|
|
438
|
+
mark: this.draft.mark,
|
|
439
|
+
},
|
|
440
|
+
cover: {
|
|
441
|
+
draft: this.#coverDraft.draft,
|
|
442
|
+
cursor: this.#coverDraft.cursor,
|
|
443
|
+
mark: this.#coverDraft.mark,
|
|
444
|
+
},
|
|
445
|
+
ask,
|
|
446
|
+
slash,
|
|
447
|
+
overlay: overlayBag,
|
|
448
|
+
auth: this.#oauthWaiting ? { waiting: true } : null,
|
|
449
|
+
queue: running == null
|
|
450
|
+
? null
|
|
451
|
+
: {
|
|
452
|
+
stackedBody: this.#admissionDeckText,
|
|
453
|
+
queued: this.client.sessionRoot.promptQueue.length,
|
|
454
|
+
running: true,
|
|
455
|
+
},
|
|
456
|
+
busy: this.#busy,
|
|
457
|
+
escClearArmed: this.escClearArmed,
|
|
458
|
+
lastTurnIncomplete: this.client.sessionRoot.lastTurnIncomplete,
|
|
459
|
+
atTip: !this.#browsing() && this.#isHeadAtTip,
|
|
460
|
+
restoredDraft: this.#untouchedRestoredDraft,
|
|
461
|
+
retainedHistory: !this.#browsing() && !this.#isHeadAtTip,
|
|
462
|
+
sessionTitle: this.#sessionTitle,
|
|
463
|
+
retrying: isRetrying(running, this.#now()),
|
|
464
|
+
superKey: this.#superKey,
|
|
465
|
+
errorAnnotation: this.#errorAnnotation() ?? null,
|
|
466
|
+
statusItems: this.#statusItems,
|
|
467
|
+
quotaWindows: this.#quotaWindows,
|
|
468
|
+
...this.#contextRail,
|
|
469
|
+
scrollOffset: this.scrollOffset,
|
|
470
|
+
};
|
|
471
|
+
}, "#omniboxValue", "get") }, _private_get_omniboxValue_decorators, { kind: "getter", name: "#omniboxValue", static: false, private: true, access: { has: obj => #omniboxValue in obj, get: obj => obj.#omniboxValue }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
472
|
+
__esDecorate(this, _private_get_contextRail_descriptor = { get: __setFunctionName(function () {
|
|
473
|
+
const glowAt = parseCompactTrigger(this.client.kernelRoot.contextGlowRemaining) ??
|
|
474
|
+
parseCompactTrigger(DEFAULT_CONTEXT_GLOW_REMAINING) ??
|
|
475
|
+
0.75;
|
|
476
|
+
const liveModel = nonempty(this.client.sessionRoot.kvs.model);
|
|
477
|
+
const catalogLimit = catalogContextLimit(this.#activeConnection, liveModel);
|
|
478
|
+
const head = this.client.sessionRoot.head;
|
|
479
|
+
if (head instanceof SessionTurn) {
|
|
480
|
+
// A model switch moves the window before the next round reports it —
|
|
481
|
+
// the tape still carries the prior model's stamp (empty until a round
|
|
482
|
+
// names one). Re-base on the live model's catalog window so the rail
|
|
483
|
+
// follows the switch immediately; the tape's own stamp takes over again
|
|
484
|
+
// once a round re-measures it. A stale window beats none.
|
|
485
|
+
const switched = liveModel !== "" && head.contextModel !== liveModel;
|
|
486
|
+
const limit = switched ? catalogLimit || head.contextLimit : head.contextLimit;
|
|
487
|
+
return {
|
|
488
|
+
progress: head.contextRemainingProgress(this.client.kernelRoot.compactTriggers.soft, limit) ?? 0,
|
|
489
|
+
progressGlowAt: glowAt,
|
|
490
|
+
contextUsed: head.contextUsed,
|
|
491
|
+
contextLimit: limit,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
return {
|
|
495
|
+
progress: 0,
|
|
496
|
+
progressGlowAt: glowAt,
|
|
497
|
+
contextUsed: 0,
|
|
498
|
+
contextLimit: catalogLimit,
|
|
499
|
+
};
|
|
500
|
+
}, "#contextRail", "get") }, _private_get_contextRail_decorators, { kind: "getter", name: "#contextRail", static: false, private: true, access: { has: obj => #contextRail in obj, get: obj => obj.#contextRail }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
501
|
+
__esDecorate(this, _private_get_omnibox_descriptor = { get: __setFunctionName(function () {
|
|
502
|
+
return omniboxSeat(this.#omniboxValue);
|
|
503
|
+
}, "#omnibox", "get") }, _private_get_omnibox_decorators, { kind: "getter", name: "#omnibox", static: false, private: true, access: { has: obj => #omnibox in obj, get: obj => obj.#omnibox }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
504
|
+
__esDecorate(this, _private_get_askIsolated_descriptor = { get: __setFunctionName(function () {
|
|
505
|
+
return this.#omnibox.input === "ask";
|
|
506
|
+
}, "#askIsolated", "get") }, _private_get_askIsolated_decorators, { kind: "getter", name: "#askIsolated", static: false, private: true, access: { has: obj => #askIsolated in obj, get: obj => obj.#askIsolated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
507
|
+
__esDecorate(this, _private_get_admissionDeckText_descriptor = { get: __setFunctionName(function () {
|
|
508
|
+
const lines = [];
|
|
509
|
+
for (const row of this.client.sessionRoot.promptQueue) {
|
|
510
|
+
const text = row.text.trim();
|
|
511
|
+
if (text !== "")
|
|
512
|
+
lines.push(text);
|
|
513
|
+
}
|
|
514
|
+
return lines.join("\n");
|
|
515
|
+
}, "#admissionDeckText", "get") }, _private_get_admissionDeckText_decorators, { kind: "getter", name: "#admissionDeckText", static: false, private: true, access: { has: obj => #admissionDeckText in obj, get: obj => obj.#admissionDeckText }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
516
|
+
__esDecorate(this, _private_get_waitChrome_descriptor = { get: __setFunctionName(function () {
|
|
517
|
+
return waitPhrase({
|
|
518
|
+
seat: () => this.#omnibox.render,
|
|
519
|
+
historyHides: () => this.#historyHidesOmnibox,
|
|
520
|
+
ask: () => this.#askPinFace() != null,
|
|
521
|
+
occupancy: () => {
|
|
522
|
+
const head = this.client.sessionRoot.head;
|
|
523
|
+
return head instanceof SessionTurn && !this.#cancelAsked.has(head) ? emptyWaitChrome(head) : null;
|
|
524
|
+
},
|
|
525
|
+
cancel: () => this.#processing && this.client.sessionRoot.findRunningTurn() != null,
|
|
526
|
+
catalog: () => {
|
|
527
|
+
const connectionId = (this.client.sessionRoot.kvs.connection ?? "").trim();
|
|
528
|
+
const spec = connectionId === "" ? undefined : this.client.kernelRoot.connections[connectionId];
|
|
529
|
+
const models = spec == null ? [] : Array.isArray(spec.live.models) ? spec.live.models : [];
|
|
530
|
+
return { connectionId, readyState: spec?.readyState ?? null, modelCount: models.length };
|
|
531
|
+
},
|
|
532
|
+
slash: () => slashVerb(this.draft.draft),
|
|
533
|
+
error: () => this.#errorAnnotation()?.message ?? "",
|
|
534
|
+
});
|
|
535
|
+
}, "#waitChrome", "get") }, _private_get_waitChrome_decorators, { kind: "getter", name: "#waitChrome", static: false, private: true, access: { has: obj => #waitChrome in obj, get: obj => obj.#waitChrome }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
536
|
+
__esDecorate(this, _private_get_commands_descriptor = { get: __setFunctionName(function () {
|
|
537
|
+
const byVerb = new Map();
|
|
538
|
+
for (const spec of Object.values(this.client.kernelRoot.commands)) {
|
|
539
|
+
if (spec.verb === "" || isHostVerb(spec.verb))
|
|
540
|
+
continue;
|
|
541
|
+
byVerb.set(spec.verb, {
|
|
542
|
+
name: spec.verb,
|
|
543
|
+
description: spec.description === "" ? undefined : spec.description,
|
|
544
|
+
aliases: spec.aliases,
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
const compact = this.client.kernelRoot.commands.compact;
|
|
548
|
+
byVerb.set("compact", {
|
|
549
|
+
name: "compact",
|
|
550
|
+
description: compact?.description !== undefined && compact.description !== ""
|
|
551
|
+
? compact.description
|
|
552
|
+
: "Compact conversation context",
|
|
553
|
+
aliases: compact?.aliases,
|
|
554
|
+
});
|
|
555
|
+
const rename = this.client.kernelRoot.commands.rename;
|
|
556
|
+
byVerb.set("rename", {
|
|
557
|
+
name: "rename",
|
|
558
|
+
description: rename?.description !== undefined && rename.description !== ""
|
|
559
|
+
? rename.description
|
|
560
|
+
: "Set or clear the session title",
|
|
561
|
+
aliases: rename?.aliases,
|
|
562
|
+
});
|
|
563
|
+
const minted = this.client.kernelRoot.commands.new;
|
|
564
|
+
byVerb.set("new", {
|
|
565
|
+
name: "new",
|
|
566
|
+
description: minted?.description !== undefined && minted.description !== "" ? minted.description : "Mint a new session",
|
|
567
|
+
aliases: minted?.aliases,
|
|
568
|
+
});
|
|
569
|
+
const quit = this.client.kernelRoot.commands.quit;
|
|
570
|
+
byVerb.set("quit", {
|
|
571
|
+
name: "quit",
|
|
572
|
+
description: quit?.description !== undefined && quit.description !== "" ? quit.description : "Leave the TUI",
|
|
573
|
+
aliases: quit?.aliases,
|
|
574
|
+
});
|
|
575
|
+
const agentic = this.client.kernelRoot.commands.agentic;
|
|
576
|
+
byVerb.set("agentic", {
|
|
577
|
+
name: "agentic",
|
|
578
|
+
description: agentic?.description !== undefined && agentic.description !== ""
|
|
579
|
+
? agentic.description
|
|
580
|
+
: "Keep the session running without a client",
|
|
581
|
+
aliases: agentic?.aliases,
|
|
582
|
+
});
|
|
583
|
+
const background = this.client.kernelRoot.commands.background;
|
|
584
|
+
byVerb.set("background", {
|
|
585
|
+
name: "background",
|
|
586
|
+
description: background?.description !== undefined && background.description !== ""
|
|
587
|
+
? background.description
|
|
588
|
+
: "Keep the session running and leave the TUI",
|
|
589
|
+
aliases: background?.aliases,
|
|
590
|
+
});
|
|
591
|
+
const rewind = this.client.kernelRoot.commands.rewind;
|
|
592
|
+
byVerb.set("rewind", {
|
|
593
|
+
name: "rewind",
|
|
594
|
+
description: rewind?.description !== undefined && rewind.description !== ""
|
|
595
|
+
? rewind.description
|
|
596
|
+
: "Rewind conversation one step; files stay",
|
|
597
|
+
aliases: rewind?.aliases ?? ["undo"],
|
|
598
|
+
});
|
|
599
|
+
const permissions = this.client.kernelRoot.commands.permissions;
|
|
600
|
+
byVerb.set("permissions", {
|
|
601
|
+
name: "permissions",
|
|
602
|
+
description: permissions?.description !== undefined && permissions.description !== ""
|
|
603
|
+
? permissions.description
|
|
604
|
+
: "Mode, grants, acknowledgements; explain a call",
|
|
605
|
+
aliases: permissions?.aliases,
|
|
606
|
+
});
|
|
607
|
+
const skillEscape = new Set();
|
|
608
|
+
for (const skill of this.client.sessionRoot.skills) {
|
|
609
|
+
const verb = skill.invoke === "" ? skill.name : skill.invoke;
|
|
610
|
+
if (verb !== "" && !isHostVerb(verb) && !byVerb.has(verb)) {
|
|
611
|
+
byVerb.set(verb, {
|
|
612
|
+
name: verb,
|
|
613
|
+
description: skill.description === "" ? undefined : skill.description,
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
if (skillEscape.has(skill.name))
|
|
617
|
+
continue;
|
|
618
|
+
skillEscape.add(skill.name);
|
|
619
|
+
const escape = `skill:${skill.name}`;
|
|
620
|
+
if (escape === "" || isHostVerb(escape) || byVerb.has(escape))
|
|
621
|
+
continue;
|
|
622
|
+
byVerb.set(escape, {
|
|
623
|
+
name: escape,
|
|
624
|
+
description: skill.description === "" ? undefined : skill.description,
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
return [...byVerb.values()];
|
|
628
|
+
}, "#commands", "get") }, _private_get_commands_decorators, { kind: "getter", name: "#commands", static: false, private: true, access: { has: obj => #commands in obj, get: obj => obj.#commands }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
629
|
+
__esDecorate(this, _private_get_parentNode_descriptor = { get: __setFunctionName(function () {
|
|
630
|
+
if (this.#callback !== undefined)
|
|
631
|
+
return this.#callback.surface;
|
|
632
|
+
if (this.#focus !== undefined)
|
|
633
|
+
return this.#focus;
|
|
634
|
+
return this.#commandSurface;
|
|
635
|
+
}, "#parentNode", "get") }, _private_get_parentNode_decorators, { kind: "getter", name: "#parentNode", static: false, private: true, access: { has: obj => #parentNode in obj, get: obj => obj.#parentNode }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
636
|
+
__esDecorate(this, _private_get_inCommand_descriptor = { get: __setFunctionName(function () {
|
|
637
|
+
const verb = slashVerb(this.draft.draft);
|
|
638
|
+
if (verb === null)
|
|
639
|
+
return false;
|
|
640
|
+
if (isHostVerb(verb))
|
|
641
|
+
return true;
|
|
642
|
+
if (this.client.kernelRoot.commands[verb] !== undefined)
|
|
643
|
+
return true;
|
|
644
|
+
return this.#skillVerb(verb);
|
|
645
|
+
}, "#inCommand", "get") }, _private_get_inCommand_decorators, { kind: "getter", name: "#inCommand", static: false, private: true, access: { has: obj => #inCommand in obj, get: obj => obj.#inCommand }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
646
|
+
__esDecorate(this, _private_get_atCatalog_descriptor = { get: __setFunctionName(function () {
|
|
647
|
+
if (this.#parentNode !== undefined)
|
|
648
|
+
return false;
|
|
649
|
+
if (this.#inCommand)
|
|
650
|
+
return false;
|
|
651
|
+
return (this.draft.draft.split("\n")[0] ?? "").trim().startsWith("/");
|
|
652
|
+
}, "#atCatalog", "get") }, _private_get_atCatalog_decorators, { kind: "getter", name: "#atCatalog", static: false, private: true, access: { has: obj => #atCatalog in obj, get: obj => obj.#atCatalog }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
653
|
+
__esDecorate(this, _private_get_pickerRows_descriptor = { get: __setFunctionName(function () {
|
|
654
|
+
if (this.#focus !== undefined) {
|
|
655
|
+
return this.#focus.choices.filter((child) => child.name !== "");
|
|
656
|
+
}
|
|
657
|
+
const parent = this.#parentNode;
|
|
658
|
+
if (parent !== undefined) {
|
|
659
|
+
const verb = slashVerb(this.draft.draft) ?? "";
|
|
660
|
+
const needle = (this.draft.draft.split("\n")[0] ?? "")
|
|
661
|
+
.trim()
|
|
662
|
+
.slice(verb.length + 1)
|
|
663
|
+
.trim()
|
|
664
|
+
.toLowerCase();
|
|
665
|
+
const named = parent.choices.filter((child) => child.name !== "");
|
|
666
|
+
const exact = named.some((child) => child.name.toLowerCase() === needle);
|
|
667
|
+
return named.filter((child) => {
|
|
668
|
+
if (needle === "" || exact)
|
|
669
|
+
return true;
|
|
670
|
+
const hay = [child.name, child.annotation, child.description, child.healthAnnotation, ...child.aliases]
|
|
671
|
+
.join(" ")
|
|
672
|
+
.toLowerCase();
|
|
673
|
+
return hay.includes(needle);
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
if (this.#atCatalog)
|
|
677
|
+
return this.#catalogNodes;
|
|
678
|
+
if (this.#inCommand)
|
|
679
|
+
return [];
|
|
680
|
+
return undefined;
|
|
681
|
+
}, "#pickerRows", "get") }, _private_get_pickerRows_decorators, { kind: "getter", name: "#pickerRows", static: false, private: true, access: { has: obj => #pickerRows in obj, get: obj => obj.#pickerRows }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
682
|
+
__esDecorate(this, _private_get_catalogNodes_descriptor = { get: __setFunctionName(function () {
|
|
683
|
+
return matchComposerCommand(this.draft.draft, this.#commands).matches.map((cmd) => new UiNode(cmd.name.replace(/^\//, ""), cmd.description ?? "", cmd.aliases ?? [], "ok", "", undefined, [], [], [], null, {}));
|
|
684
|
+
}, "#catalogNodes", "get") }, _private_get_catalogNodes_decorators, { kind: "getter", name: "#catalogNodes", static: false, private: true, access: { has: obj => #catalogNodes in obj, get: obj => obj.#catalogNodes }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
685
|
+
__esDecorate(this, _private_get_commandChoices_descriptor = { get: __setFunctionName(function () {
|
|
686
|
+
const rows = this.#pickerRows;
|
|
687
|
+
if (rows === undefined)
|
|
688
|
+
return undefined;
|
|
689
|
+
const catalog = this.#atCatalog;
|
|
690
|
+
const parent = this.#focus === undefined ? this.#parentNode : this.#focus;
|
|
691
|
+
const named = parent === undefined ? undefined : parent.choices.filter((child) => child.name !== "");
|
|
692
|
+
return rows.map((node) => {
|
|
693
|
+
const unfilteredIndex = named === undefined ? -1 : named.indexOf(node);
|
|
694
|
+
const name = catalog && !node.name.startsWith("/") ? `/${node.name}` : node.name;
|
|
695
|
+
const annotation = node.annotation.trim();
|
|
696
|
+
const description = node.description.trim();
|
|
697
|
+
const healthAnnotation = node.healthAnnotation.trim();
|
|
698
|
+
return {
|
|
699
|
+
key: catalog ? catalogKey(node.name) : `choice:${unfilteredIndex}:${node.name}`,
|
|
700
|
+
name,
|
|
701
|
+
description: description || healthAnnotation || undefined,
|
|
702
|
+
annotation: annotation === "" ? undefined : annotation,
|
|
703
|
+
status: node.health === "ok" ? undefined : node.health,
|
|
704
|
+
actionDisplayName: primaryDisplayName(node) ?? (isActivatable(node, catalog) ? "select" : undefined),
|
|
705
|
+
actions: pickerActions(node, catalog),
|
|
706
|
+
};
|
|
707
|
+
});
|
|
708
|
+
}, "#commandChoices", "get") }, _private_get_commandChoices_decorators, { kind: "getter", name: "#commandChoices", static: false, private: true, access: { has: obj => #commandChoices in obj, get: obj => obj.#commandChoices }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
709
|
+
__esDecorate(this, null, _get_effectiveKey_decorators, { kind: "getter", name: "effectiveKey", static: false, private: false, access: { has: obj => "effectiveKey" in obj, get: obj => obj.effectiveKey }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
710
|
+
__esDecorate(this, _private_get_commandAction_descriptor = { get: __setFunctionName(function () {
|
|
711
|
+
const surface = this.#parentNode;
|
|
712
|
+
if (surface === undefined)
|
|
713
|
+
return undefined;
|
|
714
|
+
const row = surface.description.trim() === ""
|
|
715
|
+
? (primaryDisplayName(surface) ??
|
|
716
|
+
(surface.action[0]?.name === "" ? "select" : (surface.action[0]?.name ?? surface.name)))
|
|
717
|
+
: surface.description;
|
|
718
|
+
if (this.#processing) {
|
|
719
|
+
return { name: row, displayName: row, actions: [], href: urlFrom(surface) };
|
|
720
|
+
}
|
|
721
|
+
const actions = this.#oauthWaiting
|
|
722
|
+
? pickerActions(surface).filter((item) => item.hotkey?.toLowerCase() === "escape")
|
|
723
|
+
: pickerActions(surface);
|
|
724
|
+
if (actions.length === 0)
|
|
725
|
+
return undefined;
|
|
726
|
+
return {
|
|
727
|
+
name: row,
|
|
728
|
+
displayName: row,
|
|
729
|
+
actions,
|
|
730
|
+
href: urlFrom(surface),
|
|
731
|
+
};
|
|
732
|
+
}, "#commandAction", "get") }, _private_get_commandAction_decorators, { kind: "getter", name: "#commandAction", static: false, private: true, access: { has: obj => #commandAction in obj, get: obj => obj.#commandAction }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
733
|
+
__esDecorate(this, _private_get_commandSurface_descriptor = { get: __setFunctionName(function () {
|
|
734
|
+
if (this.#callback !== undefined)
|
|
735
|
+
return this.#callback.surface;
|
|
736
|
+
const verb = slashVerb(this.draft.draft);
|
|
737
|
+
if (verb === null)
|
|
738
|
+
return undefined;
|
|
739
|
+
const body = this.client.kernelRoot.commands[verb]?.body;
|
|
740
|
+
if (body === undefined || body === "")
|
|
741
|
+
return undefined;
|
|
742
|
+
const surface = this.#execFor(verb, body, this.client.kernelRoot).get();
|
|
743
|
+
if (verb === "model")
|
|
744
|
+
this.#noteModelEval(surface);
|
|
745
|
+
return surface instanceof UiNode ? surface : undefined;
|
|
746
|
+
}, "#commandSurface", "get") }, _private_get_commandSurface_decorators, { kind: "getter", name: "#commandSurface", static: false, private: true, access: { has: obj => #commandSurface in obj, get: obj => obj.#commandSurface }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
747
|
+
__esDecorate(this, _private_get_selectedIndex_descriptor = { get: __setFunctionName(function () {
|
|
748
|
+
const keyed = this.#commandChoices;
|
|
749
|
+
if (keyed === undefined || keyed.length === 0)
|
|
750
|
+
return 0;
|
|
751
|
+
const i = keyed.findIndex((row) => row.key === this.effectiveKey);
|
|
752
|
+
return Math.max(i, 0);
|
|
753
|
+
}, "#selectedIndex", "get") }, _private_get_selectedIndex_decorators, { kind: "getter", name: "#selectedIndex", static: false, private: true, access: { has: obj => #selectedIndex in obj, get: obj => obj.#selectedIndex }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
754
|
+
__esDecorate(this, null, _focusAt_decorators, { kind: "method", name: "focusAt", static: false, private: false, access: { has: obj => "focusAt" in obj, get: obj => obj.focusAt }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
755
|
+
__esDecorate(this, null, _handle_decorators, { kind: "method", name: "handle", static: false, private: false, access: { has: obj => "handle" in obj, get: obj => obj.handle }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
756
|
+
__esDecorate(this, _private_get_activeConnection_descriptor = { get: __setFunctionName(function () {
|
|
757
|
+
const connectionId = (this.client.sessionRoot.kvs.connection ?? "").trim();
|
|
758
|
+
return connectionId === "" ? undefined : this.client.kernelRoot.connections[connectionId];
|
|
759
|
+
}, "#activeConnection", "get") }, _private_get_activeConnection_decorators, { kind: "getter", name: "#activeConnection", static: false, private: true, access: { has: obj => #activeConnection in obj, get: obj => obj.#activeConnection }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
760
|
+
__esDecorate(this, _private_get_quotaWindows_descriptor = { get: __setFunctionName(function () {
|
|
761
|
+
return quotaWindowsOf(this.#activeConnection);
|
|
762
|
+
}, "#quotaWindows", "get") }, _private_get_quotaWindows_decorators, { kind: "getter", name: "#quotaWindows", static: false, private: true, access: { has: obj => #quotaWindows in obj, get: obj => obj.#quotaWindows }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
763
|
+
__esDecorate(this, _private_get_statusItems_descriptor = { get: __setFunctionName(function () {
|
|
764
|
+
const session = this.client.sessionRoot;
|
|
765
|
+
const kvs = session.kvs;
|
|
766
|
+
const model = (kvs.model ?? "").trim();
|
|
767
|
+
const connectionId = (kvs.connection ?? "").trim();
|
|
768
|
+
const connection = this.#activeConnection;
|
|
769
|
+
const provider = nonempty(typeof connection?.live?.catalogName === "string" ? connection.live.catalogName.trim() : "") ||
|
|
770
|
+
nonempty(connection?.name) ||
|
|
771
|
+
nonempty(connection?.driver?.name) ||
|
|
772
|
+
connectionId;
|
|
773
|
+
const items = [];
|
|
774
|
+
if (model !== "")
|
|
775
|
+
items.push(model);
|
|
776
|
+
if (provider !== "")
|
|
777
|
+
items.push(provider);
|
|
778
|
+
const chip = policyChip(session);
|
|
779
|
+
if (chip !== null)
|
|
780
|
+
items.push(chip);
|
|
781
|
+
return items.length > 0 ? items : undefined;
|
|
782
|
+
}, "#statusItems", "get") }, _private_get_statusItems_decorators, { kind: "getter", name: "#statusItems", static: false, private: true, access: { has: obj => #statusItems in obj, get: obj => obj.#statusItems }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
783
|
+
__esDecorate(this, _private_stepCoverThrottle_descriptor = { value: __setFunctionName(function () {
|
|
784
|
+
const leaf = this.#askHead;
|
|
785
|
+
const pendingLeafId = askLeafId(leaf);
|
|
786
|
+
const now = this.#now();
|
|
787
|
+
if (pendingLeafId === null) {
|
|
788
|
+
if (!this.#askHold && !this.#drainAsk) {
|
|
789
|
+
this.#coverThrottle = { episodeFrom: null, armedUntil: 0 };
|
|
790
|
+
}
|
|
791
|
+
this.#coverConfirmLive = false;
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
if (this.#coverThrottle.episodeFrom === null) {
|
|
795
|
+
const throttleMs = Math.max(0, this.client.kernelRoot.approvalAskThrottleMs);
|
|
796
|
+
this.#coverThrottle = {
|
|
797
|
+
episodeFrom: pendingLeafId,
|
|
798
|
+
armedUntil: this.draft.draft.trim() !== "" && throttleMs > 0 ? now + throttleMs : 0,
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
this.#coverConfirmLive = now >= this.#coverThrottle.armedUntil;
|
|
802
|
+
}
|
|
803
|
+
if (this.#coverTimer !== undefined) {
|
|
804
|
+
clearTimeout(this.#coverTimer);
|
|
805
|
+
this.#coverTimer = undefined;
|
|
806
|
+
}
|
|
807
|
+
if (leaf === null) {
|
|
808
|
+
this.#coverDraft = { draft: "", cursor: 0, mark: null };
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if (!this.#coverConfirmLive && this.#coverThrottle.armedUntil > this.#now()) {
|
|
812
|
+
const wait = this.#coverThrottle.armedUntil - this.#now();
|
|
813
|
+
this.#coverTimer = setTimeout(() => {
|
|
814
|
+
runInAction(() => this.#stepCoverThrottle());
|
|
815
|
+
}, wait);
|
|
816
|
+
}
|
|
817
|
+
}, "#stepCoverThrottle") }, _private_stepCoverThrottle_decorators, { kind: "method", name: "#stepCoverThrottle", static: false, private: true, access: { has: obj => #stepCoverThrottle in obj, get: obj => obj.#stepCoverThrottle }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
818
|
+
__esDecorate(this, _private_get_attentionSubjects_descriptor = { get: __setFunctionName(function () {
|
|
819
|
+
const rows = this.#pickerRows;
|
|
820
|
+
if (rows === undefined)
|
|
821
|
+
return [];
|
|
822
|
+
const { connections, drivers } = this.client.kernelRoot;
|
|
823
|
+
const out = new Set();
|
|
824
|
+
for (const node of rows) {
|
|
825
|
+
for (const leaf of node.action) {
|
|
826
|
+
const spec = leaf.op === "kv/set" && leaf.params.key === "connection"
|
|
827
|
+
? connections[paramString(leaf.params.value)]
|
|
828
|
+
: leaf.op === "connect/adopt"
|
|
829
|
+
? drivers[paramString(leaf.params.driver)]
|
|
830
|
+
: undefined;
|
|
831
|
+
if (spec === undefined)
|
|
832
|
+
continue;
|
|
833
|
+
out.add(spec);
|
|
834
|
+
break;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
return [...out];
|
|
838
|
+
}, "#attentionSubjects", "get") }, _private_get_attentionSubjects_decorators, { kind: "getter", name: "#attentionSubjects", static: false, private: true, access: { has: obj => #attentionSubjects in obj, get: obj => obj.#attentionSubjects }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
839
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
840
|
+
}
|
|
841
|
+
client = __runInitializers(this, _instanceExtraInitializers);
|
|
842
|
+
post;
|
|
843
|
+
#draft_accessor_storage = __runInitializers(this, _draft_initializers, { draft: "", cursor: 0, mark: null });
|
|
844
|
+
get draft() { return this.#draft_accessor_storage; }
|
|
845
|
+
set draft(value) { this.#draft_accessor_storage = value; }
|
|
846
|
+
#submission_accessor_storage = (__runInitializers(this, _draft_extraInitializers), __runInitializers(this, _submission_initializers, null));
|
|
847
|
+
/** Last honest submit. Parts and command stay apart; the string draft is typing only. */
|
|
848
|
+
get submission() { return this.#submission_accessor_storage; }
|
|
849
|
+
set submission(value) { this.#submission_accessor_storage = value; }
|
|
850
|
+
#selectedCommandKey_accessor_storage = (__runInitializers(this, _submission_extraInitializers), __runInitializers(this, _selectedCommandKey_initializers, null));
|
|
851
|
+
get selectedCommandKey() { return this.#selectedCommandKey_accessor_storage; }
|
|
852
|
+
set selectedCommandKey(value) { this.#selectedCommandKey_accessor_storage = value; }
|
|
853
|
+
#scrollOffset_accessor_storage = (__runInitializers(this, _selectedCommandKey_extraInitializers), __runInitializers(this, _scrollOffset_initializers, 0));
|
|
854
|
+
get scrollOffset() { return this.#scrollOffset_accessor_storage; }
|
|
855
|
+
set scrollOffset(value) { this.#scrollOffset_accessor_storage = value; }
|
|
856
|
+
#escClearArmed_accessor_storage = (__runInitializers(this, _scrollOffset_extraInitializers), __runInitializers(this, _escClearArmed_initializers, false));
|
|
857
|
+
get escClearArmed() { return this.#escClearArmed_accessor_storage; }
|
|
858
|
+
set escClearArmed(value) { this.#escClearArmed_accessor_storage = value; }
|
|
859
|
+
#cols_accessor_storage = (__runInitializers(this, _escClearArmed_extraInitializers), __runInitializers(this, _cols_initializers, 80));
|
|
860
|
+
get cols() { return this.#cols_accessor_storage; }
|
|
861
|
+
set cols(value) { this.#cols_accessor_storage = value; }
|
|
862
|
+
#rows_accessor_storage = (__runInitializers(this, _cols_extraInitializers), __runInitializers(this, _rows_initializers, 24));
|
|
863
|
+
get rows() { return this.#rows_accessor_storage; }
|
|
864
|
+
set rows(value) { this.#rows_accessor_storage = value; }
|
|
865
|
+
#busy_accessor_storage = (__runInitializers(this, _rows_extraInitializers), __runInitializers(this, _private_busy_initializers, false));
|
|
866
|
+
get #busy() { return _private_busy_descriptor.get.call(this); }
|
|
867
|
+
set #busy(value) { return _private_busy_descriptor.set.call(this, value); }
|
|
868
|
+
#callback_accessor_storage = (__runInitializers(this, _private_busy_extraInitializers), __runInitializers(this, _private_callback_initializers, undefined));
|
|
869
|
+
get #callback() { return _private_callback_descriptor.get.call(this); }
|
|
870
|
+
set #callback(value) { return _private_callback_descriptor.set.call(this, value); }
|
|
871
|
+
#focus_accessor_storage = (__runInitializers(this, _private_callback_extraInitializers), __runInitializers(this, _private_focus_initializers, undefined));
|
|
872
|
+
get #focus() { return _private_focus_descriptor.get.call(this); }
|
|
873
|
+
set #focus(value) { return _private_focus_descriptor.set.call(this, value); }
|
|
874
|
+
#oauthWaiting_accessor_storage = (__runInitializers(this, _private_focus_extraInitializers), __runInitializers(this, _private_oauthWaiting_initializers, false));
|
|
875
|
+
get #oauthWaiting() { return _private_oauthWaiting_descriptor.get.call(this); }
|
|
876
|
+
set #oauthWaiting(value) { return _private_oauthWaiting_descriptor.set.call(this, value); }
|
|
877
|
+
#processing_accessor_storage = (__runInitializers(this, _private_oauthWaiting_extraInitializers), __runInitializers(this, _private_processing_initializers, false));
|
|
878
|
+
/** Overlay action fired; ui/resolve (or the next park) has not landed yet. */
|
|
879
|
+
get #processing() { return _private_processing_descriptor.get.call(this); }
|
|
880
|
+
set #processing(value) { return _private_processing_descriptor.set.call(this, value); }
|
|
881
|
+
#coverDraft_accessor_storage = (__runInitializers(this, _private_processing_extraInitializers), __runInitializers(this, _private_coverDraft_initializers, { draft: "", cursor: 0, mark: null }));
|
|
882
|
+
get #coverDraft() { return _private_coverDraft_descriptor.get.call(this); }
|
|
883
|
+
set #coverDraft(value) { return _private_coverDraft_descriptor.set.call(this, value); }
|
|
884
|
+
#coverThrottle_accessor_storage = (__runInitializers(this, _private_coverDraft_extraInitializers), __runInitializers(this, _private_coverThrottle_initializers, { episodeFrom: null, armedUntil: 0 }));
|
|
885
|
+
get #coverThrottle() { return _private_coverThrottle_descriptor.get.call(this); }
|
|
886
|
+
set #coverThrottle(value) { return _private_coverThrottle_descriptor.set.call(this, value); }
|
|
887
|
+
#coverConfirmLive_accessor_storage = (__runInitializers(this, _private_coverThrottle_extraInitializers), __runInitializers(this, _private_coverConfirmLive_initializers, false));
|
|
888
|
+
get #coverConfirmLive() { return _private_coverConfirmLive_descriptor.get.call(this); }
|
|
889
|
+
set #coverConfirmLive(value) { return _private_coverConfirmLive_descriptor.set.call(this, value); }
|
|
890
|
+
#ackPick_accessor_storage = (__runInitializers(this, _private_coverConfirmLive_extraInitializers), __runInitializers(this, _private_ackPick_initializers, { id: "", index: 0 }));
|
|
891
|
+
/** see omnibox-seat.ts, CHANGE ONLY. */
|
|
892
|
+
/** Which remember option of the acknowledgement prompt is picked (reset when another call asks). */
|
|
893
|
+
get #ackPick() { return _private_ackPick_descriptor.get.call(this); }
|
|
894
|
+
set #ackPick(value) { return _private_ackPick_descriptor.set.call(this, value); }
|
|
895
|
+
#askHold_accessor_storage = (__runInitializers(this, _private_ackPick_extraInitializers), __runInitializers(this, _private_askHold_initializers, false));
|
|
896
|
+
get #askHold() { return _private_askHold_descriptor.get.call(this); }
|
|
897
|
+
set #askHold(value) { return _private_askHold_descriptor.set.call(this, value); }
|
|
898
|
+
#drainAsk_accessor_storage = (__runInitializers(this, _private_askHold_extraInitializers), __runInitializers(this, _private_drainAsk_initializers, false));
|
|
899
|
+
get #drainAsk() { return _private_drainAsk_descriptor.get.call(this); }
|
|
900
|
+
set #drainAsk(value) { return _private_drainAsk_descriptor.set.call(this, value); }
|
|
901
|
+
#agentsOpen_accessor_storage = (__runInitializers(this, _private_drainAsk_extraInitializers), __runInitializers(this, _private_agentsOpen_initializers, false));
|
|
902
|
+
get #agentsOpen() { return _private_agentsOpen_descriptor.get.call(this); }
|
|
903
|
+
set #agentsOpen(value) { return _private_agentsOpen_descriptor.set.call(this, value); }
|
|
904
|
+
#agentsFocus_accessor_storage = (__runInitializers(this, _private_agentsOpen_extraInitializers), __runInitializers(this, _private_agentsFocus_initializers, null));
|
|
905
|
+
get #agentsFocus() { return _private_agentsFocus_descriptor.get.call(this); }
|
|
906
|
+
set #agentsFocus(value) { return _private_agentsFocus_descriptor.set.call(this, value); }
|
|
907
|
+
#agentsHover_accessor_storage = (__runInitializers(this, _private_agentsFocus_extraInitializers), __runInitializers(this, _private_agentsHover_initializers, null));
|
|
908
|
+
get #agentsHover() { return _private_agentsHover_descriptor.get.call(this); }
|
|
909
|
+
set #agentsHover(value) { return _private_agentsHover_descriptor.set.call(this, value); }
|
|
910
|
+
#agentsScroll_accessor_storage = (__runInitializers(this, _private_agentsHover_extraInitializers), __runInitializers(this, _private_agentsScroll_initializers, 0));
|
|
911
|
+
get #agentsScroll() { return _private_agentsScroll_descriptor.get.call(this); }
|
|
912
|
+
set #agentsScroll(value) { return _private_agentsScroll_descriptor.set.call(this, value); }
|
|
913
|
+
#agentsPreview_accessor_storage = (__runInitializers(this, _private_agentsScroll_extraInitializers), __runInitializers(this, _private_agentsPreview_initializers, null));
|
|
914
|
+
get #agentsPreview() { return _private_agentsPreview_descriptor.get.call(this); }
|
|
915
|
+
set #agentsPreview(value) { return _private_agentsPreview_descriptor.set.call(this, value); }
|
|
916
|
+
#peekPlexus_accessor_storage = (__runInitializers(this, _private_agentsPreview_extraInitializers), __runInitializers(this, _private_peekPlexus_initializers, null));
|
|
917
|
+
get #peekPlexus() { return _private_peekPlexus_descriptor.get.call(this); }
|
|
918
|
+
set #peekPlexus(value) { return _private_peekPlexus_descriptor.set.call(this, value); }
|
|
919
|
+
#askPlexus_accessor_storage = (__runInitializers(this, _private_peekPlexus_extraInitializers), __runInitializers(this, _private_askPlexus_initializers, null));
|
|
920
|
+
get #askPlexus() { return _private_askPlexus_descriptor.get.call(this); }
|
|
921
|
+
set #askPlexus(value) { return _private_askPlexus_descriptor.set.call(this, value); }
|
|
922
|
+
/** Turns this client asked the daemon to cancel; only `turn/cancel` writes `cancelRequested`. */
|
|
923
|
+
#cancelAsked = (__runInitializers(this, _private_askPlexus_extraInitializers), observable.set([], { deep: false }));
|
|
924
|
+
#askedPolicy = null;
|
|
925
|
+
#viewPin_accessor_storage = __runInitializers(this, _private_viewPin_initializers, null);
|
|
926
|
+
/** Local tape selection. Null follows `head`. Enter commits via `turn/rewind`. */
|
|
927
|
+
get #viewPin() { return _private_viewPin_descriptor.get.call(this); }
|
|
928
|
+
set #viewPin(value) { return _private_viewPin_descriptor.set.call(this, value); }
|
|
929
|
+
#historyNav_accessor_storage = (__runInitializers(this, _private_viewPin_extraInitializers), __runInitializers(this, _private_historyNav_initializers, false));
|
|
930
|
+
/** Double-Esc on empty. Arrows move the view; Esc / Enter leave. */
|
|
931
|
+
get #historyNav() { return _private_historyNav_descriptor.get.call(this); }
|
|
932
|
+
set #historyNav(value) { return _private_historyNav_descriptor.set.call(this, value); }
|
|
933
|
+
#restoredDraft_accessor_storage = (__runInitializers(this, _private_historyNav_extraInitializers), __runInitializers(this, _private_restoredDraft_initializers, null));
|
|
934
|
+
get #restoredDraft() { return _private_restoredDraft_descriptor.get.call(this); }
|
|
935
|
+
set #restoredDraft(value) { return _private_restoredDraft_descriptor.set.call(this, value); }
|
|
936
|
+
#rewindPending = (__runInitializers(this, _private_restoredDraft_extraInitializers), false);
|
|
937
|
+
#askBindGen = 0;
|
|
938
|
+
#paint;
|
|
939
|
+
/** Blob text the document names, fetched on demand. Peeks are MobX reads: a landing repaints what peeked. */
|
|
940
|
+
#blobs;
|
|
941
|
+
#disposers = [];
|
|
942
|
+
#execs = new Map();
|
|
943
|
+
#lastModelEvalLog = "";
|
|
944
|
+
#resolveWaiter;
|
|
945
|
+
#savedDraft;
|
|
946
|
+
#agentsParked;
|
|
947
|
+
/** The pending whose `opened` answer is in flight; Esc sends it a cancel. */
|
|
948
|
+
#waitingPending;
|
|
949
|
+
#coverTimer;
|
|
950
|
+
#rewindGraceUntil = 0;
|
|
951
|
+
#open;
|
|
952
|
+
#now;
|
|
953
|
+
#title;
|
|
954
|
+
#quit;
|
|
955
|
+
#resident;
|
|
956
|
+
#replaceSession;
|
|
957
|
+
get #superKey() {
|
|
958
|
+
return parseSuperKey(this.client.kernelRoot.superKey);
|
|
959
|
+
}
|
|
960
|
+
constructor(client, post, options = {}) {
|
|
961
|
+
this.client = client;
|
|
962
|
+
this.post = post;
|
|
963
|
+
this.cols = options.cols ?? 80;
|
|
964
|
+
this.rows = options.rows ?? 24;
|
|
965
|
+
this.#open = options.open ?? openExternalUrl;
|
|
966
|
+
this.#now = options.now ?? Date.now;
|
|
967
|
+
this.#title = options.title;
|
|
968
|
+
this.#quit = options.quit;
|
|
969
|
+
this.#resident = options.resident;
|
|
970
|
+
this.#replaceSession = options.replaceSession;
|
|
971
|
+
if (options.draft != null && options.draft !== "") {
|
|
972
|
+
this.draft = { draft: options.draft, cursor: options.draft.length, mark: null };
|
|
973
|
+
}
|
|
974
|
+
// A landing is a write keyed by hash, so only what peeked that blob re-runs: the same path a document change takes.
|
|
975
|
+
const landed = observable.map([], { deep: false });
|
|
976
|
+
const blobCache = createBlobCache((method, params) => this.client.request(method, params), (sha256) => runInAction(() => landed.set(sha256, (landed.get(sha256) ?? 0) + 1)));
|
|
977
|
+
this.#blobs = {
|
|
978
|
+
peek: (sha256) => {
|
|
979
|
+
landed.get(sha256);
|
|
980
|
+
return blobCache.peek(sha256);
|
|
981
|
+
},
|
|
982
|
+
want: (sha256) => blobCache.want(sha256),
|
|
983
|
+
};
|
|
984
|
+
this.#paint = createPaintController((message) => this.post([message]), "paint", {
|
|
985
|
+
agentGlance: (job) => agentTapeGlance(job, this.client.kernelRoot, this.client.sessionRoot.kvs.model),
|
|
986
|
+
kernel: this.client.kernelRoot,
|
|
987
|
+
cancelAsked: (turn) => this.#cancelAsked.has(turn),
|
|
988
|
+
blobs: this.#blobs,
|
|
989
|
+
});
|
|
990
|
+
this.client.setComputedAttention(() => this.#attentionSubjects);
|
|
991
|
+
this.client.setComputedAttentionFocus(() => this.#activeConnection ?? null);
|
|
992
|
+
this.#disposers.push(reaction(() => sessionDisplayTitle(this.client.sessionRoot), (title) => this.#title?.(title), { fireImmediately: true }), reaction(() => this.client.sessionRoot.agent.spec.resident, (on) => this.#resident?.(on), { fireImmediately: true }), reaction(() => askLeafId(this.#askHead), () => this.#stepCoverThrottle(), { fireImmediately: true }), reaction(() => this.#paintComposerFace(), (face) => this.#paint.projectComposer(face), { fireImmediately: true }), reaction(() => this.#askPinFace(), (face) => this.#paint.projectAsk(face), { fireImmediately: true }), reaction(() => this.#waitChrome, (chrome) => this.#paint.projectWait(chrome), { fireImmediately: true }), reaction(() => [this.client.sessionRoot.path, this.client.sessionRoot.statuslineLeft], ([path, left]) => {
|
|
993
|
+
const parts = cwdParts(path);
|
|
994
|
+
const cut = left.indexOf(STATUSLINE_NOTE_SEP);
|
|
995
|
+
this.#paint.projectStatusline({
|
|
996
|
+
cwd: `${parts.root}${parts.rest}`,
|
|
997
|
+
cwdRoot: parts.root,
|
|
998
|
+
left: cut === -1 ? left : left.slice(0, cut),
|
|
999
|
+
note: cut === -1 ? "" : left.slice(cut + STATUSLINE_NOTE_SEP.length),
|
|
1000
|
+
});
|
|
1001
|
+
}, { fireImmediately: true }), reaction(() => this.#paintTrackSpine(), () => {
|
|
1002
|
+
this.#paint.syncSpine(this.#paintSpineTurns(), this.client.sessionRoot.steerQueue);
|
|
1003
|
+
this.#applyPinRecap();
|
|
1004
|
+
}, { fireImmediately: true, equals: trackEqual }), reaction(() => this.#rewindPaintTrack(), () => this.#syncRewindPaint(), { fireImmediately: true }), reaction(() => this.#previewPaintTrack(), () => this.#paint.syncPreviewSpine(this.#agentsPreview === null ? null : this.#previewSpineTurns(), this.#peekPlexus?.root.kvs.model), { fireImmediately: true, equals: trackEqual }), reaction(() => this.#agentsPaintFace(), (face) => this.#paint.projectAgents(face), { fireImmediately: true }), reaction(() => hostAskEscalateSessionId(this.client), (id) => {
|
|
1005
|
+
void this.#bindAskEscalate(id);
|
|
1006
|
+
}, { fireImmediately: true }));
|
|
1007
|
+
this.#paint.attach();
|
|
1008
|
+
}
|
|
1009
|
+
/** Write tree. Cadence / visual present read the host replica, not this. */
|
|
1010
|
+
get paintRoot() {
|
|
1011
|
+
return this.#paint.root;
|
|
1012
|
+
}
|
|
1013
|
+
flushPaint() {
|
|
1014
|
+
this.#paint.flush();
|
|
1015
|
+
}
|
|
1016
|
+
#paintComposerFace() {
|
|
1017
|
+
const face = paintOmnibox(this.#omniboxValue);
|
|
1018
|
+
return this.#agentsOpen || this.#agentsPreview !== null ? { ...face, interactive: false } : face;
|
|
1019
|
+
}
|
|
1020
|
+
#agentsPaintFace() {
|
|
1021
|
+
const keys = this.#agentsRowKeys();
|
|
1022
|
+
if (this.#agentsHover !== null && !keys.includes(this.#agentsHover)) {
|
|
1023
|
+
runInAction(() => {
|
|
1024
|
+
this.#agentsHover = null;
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
if (this.#agentsPreview !== null &&
|
|
1028
|
+
!keys.includes(this.#agentsPreview) &&
|
|
1029
|
+
mentionedAgentCall(this.client, this.#agentsPreview) == null) {
|
|
1030
|
+
runInAction(() => {
|
|
1031
|
+
this.#closeAgentsPreview();
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
return agentsPaintFace(this.client, {
|
|
1035
|
+
open: this.#agentsOpen,
|
|
1036
|
+
focusKey: this.#agentsHover ?? this.#agentsFocus,
|
|
1037
|
+
scroll: this.#agentsScroll,
|
|
1038
|
+
previewKey: this.#agentsPreview,
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
get #agentDrawerRows() { return _private_get_agentDrawerRows_descriptor.get.call(this); }
|
|
1042
|
+
#agentsRowKeys() {
|
|
1043
|
+
return this.#agentDrawerRows.map((row) => row.key);
|
|
1044
|
+
}
|
|
1045
|
+
#openAgents() {
|
|
1046
|
+
this.#agentsParked = { draft: this.draft.draft, cursor: this.draft.cursor, mark: this.draft.mark };
|
|
1047
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
1048
|
+
this.#resetSelection();
|
|
1049
|
+
this.#agentsOpen = true;
|
|
1050
|
+
this.#agentsScroll = 0;
|
|
1051
|
+
this.#agentsFocus = this.#agentsRowKeys()[0] ?? null;
|
|
1052
|
+
this.#agentsHover = null;
|
|
1053
|
+
}
|
|
1054
|
+
#closeAgents() {
|
|
1055
|
+
this.#closeAgentsPreview();
|
|
1056
|
+
const parked = this.#agentsParked;
|
|
1057
|
+
this.#agentsParked = undefined;
|
|
1058
|
+
this.#agentsOpen = false;
|
|
1059
|
+
this.#agentsFocus = null;
|
|
1060
|
+
this.#agentsHover = null;
|
|
1061
|
+
this.#agentsScroll = 0;
|
|
1062
|
+
if (parked !== undefined)
|
|
1063
|
+
Object.assign(this.draft, parked);
|
|
1064
|
+
}
|
|
1065
|
+
#moveAgentsFocus(delta) {
|
|
1066
|
+
const keys = this.#agentsRowKeys();
|
|
1067
|
+
if (keys.length === 0)
|
|
1068
|
+
return;
|
|
1069
|
+
if (this.#agentsHover !== null) {
|
|
1070
|
+
this.#agentsFocus = this.#agentsHover;
|
|
1071
|
+
this.#agentsHover = null;
|
|
1072
|
+
}
|
|
1073
|
+
const i = Math.max(0, keys.indexOf(this.#agentsFocus ?? ""));
|
|
1074
|
+
const next = Math.min(keys.length - 1, Math.max(0, i + delta));
|
|
1075
|
+
this.#agentsFocus = keys[next];
|
|
1076
|
+
this.#agentsScroll = Math.max(0, next);
|
|
1077
|
+
}
|
|
1078
|
+
#handleAgentsChord(event, seat) {
|
|
1079
|
+
const chord = event.ctrl === true || event.meta === true || event.alt === true;
|
|
1080
|
+
if (this.#omniboxValue.ask !== null)
|
|
1081
|
+
return false;
|
|
1082
|
+
if (this.#agentsPreviewConsumes(event))
|
|
1083
|
+
return true;
|
|
1084
|
+
if (!this.#agentsOpen) {
|
|
1085
|
+
if (chord || event.key !== "ArrowLeft" || this.draft.draft !== "")
|
|
1086
|
+
return false;
|
|
1087
|
+
if (seat.input === "overlay" || seat.input === "auth")
|
|
1088
|
+
return false;
|
|
1089
|
+
this.#openAgents();
|
|
1090
|
+
return true;
|
|
1091
|
+
}
|
|
1092
|
+
return this.#agentsDrawerConsumes(event);
|
|
1093
|
+
}
|
|
1094
|
+
#agentsPreviewConsumes(event) {
|
|
1095
|
+
if (this.#agentsPreview === null)
|
|
1096
|
+
return false;
|
|
1097
|
+
if (event.key === "Escape")
|
|
1098
|
+
this.#closeAgentsPreview();
|
|
1099
|
+
return true;
|
|
1100
|
+
}
|
|
1101
|
+
#agentsDrawerConsumes(event) {
|
|
1102
|
+
if (event.ctrl === true || event.meta === true || event.alt === true)
|
|
1103
|
+
return true;
|
|
1104
|
+
if (event.key === "j" || event.key === "ArrowDown") {
|
|
1105
|
+
this.#moveAgentsFocus(1);
|
|
1106
|
+
return true;
|
|
1107
|
+
}
|
|
1108
|
+
if (event.key === "k" || event.key === "ArrowUp") {
|
|
1109
|
+
this.#moveAgentsFocus(-1);
|
|
1110
|
+
return true;
|
|
1111
|
+
}
|
|
1112
|
+
if (event.key === "ArrowRight" || event.key === "Escape") {
|
|
1113
|
+
this.#closeAgents();
|
|
1114
|
+
return true;
|
|
1115
|
+
}
|
|
1116
|
+
if (event.key === "Enter") {
|
|
1117
|
+
this.#activateAgentsKey(this.#agentsHover ?? this.#agentsFocus);
|
|
1118
|
+
return true;
|
|
1119
|
+
}
|
|
1120
|
+
return true;
|
|
1121
|
+
}
|
|
1122
|
+
#focusAgentsKey(key) {
|
|
1123
|
+
const row = agentsRowKeyFromHit(key) ?? key;
|
|
1124
|
+
const keys = this.#agentsRowKeys();
|
|
1125
|
+
const i = keys.indexOf(row);
|
|
1126
|
+
if (i === -1)
|
|
1127
|
+
return;
|
|
1128
|
+
this.#agentsFocus = keys[i];
|
|
1129
|
+
this.#agentsScroll = Math.max(0, i);
|
|
1130
|
+
}
|
|
1131
|
+
#activateAgentsKey(key) {
|
|
1132
|
+
if (key == null)
|
|
1133
|
+
return;
|
|
1134
|
+
const rowKey = agentsRowKeyFromHit(key) ?? key;
|
|
1135
|
+
const row = this.#agentDrawerRows.find((item) => item.key === rowKey);
|
|
1136
|
+
if (row?.kind === "call") {
|
|
1137
|
+
this.#openAgentsPreview(row.key, row.sessionId);
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
const sessionId = sessionIdFromAgentsKey(key);
|
|
1141
|
+
if (sessionId == null)
|
|
1142
|
+
return;
|
|
1143
|
+
this.#switchSession(sessionId);
|
|
1144
|
+
}
|
|
1145
|
+
#openAgentsPreview(key, sessionId) {
|
|
1146
|
+
this.#agentsPreview = key;
|
|
1147
|
+
if (this.client.peekPlexus?.root.sessionId === sessionId) {
|
|
1148
|
+
this.#peekPlexus = this.client.peekPlexus;
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
this.#peekPlexus = null;
|
|
1152
|
+
this.client.releasePeek();
|
|
1153
|
+
if (sessionId === "")
|
|
1154
|
+
return;
|
|
1155
|
+
const token = key;
|
|
1156
|
+
void this.client
|
|
1157
|
+
.watchPeek(sessionId)
|
|
1158
|
+
.then(() => {
|
|
1159
|
+
return runInAction(() => {
|
|
1160
|
+
if (this.#agentsPreview !== token)
|
|
1161
|
+
return;
|
|
1162
|
+
this.#peekPlexus = this.client.peekPlexus;
|
|
1163
|
+
});
|
|
1164
|
+
})
|
|
1165
|
+
.catch(() => undefined);
|
|
1166
|
+
}
|
|
1167
|
+
#closeAgentsPreview() {
|
|
1168
|
+
this.#agentsPreview = null;
|
|
1169
|
+
this.#peekPlexus = null;
|
|
1170
|
+
this.client.releasePeek();
|
|
1171
|
+
}
|
|
1172
|
+
async #bindAskEscalate(id) {
|
|
1173
|
+
const gen = ++this.#askBindGen;
|
|
1174
|
+
if (id == null) {
|
|
1175
|
+
runInAction(() => {
|
|
1176
|
+
this.#askPlexus = null;
|
|
1177
|
+
});
|
|
1178
|
+
this.client.releaseAsk();
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
if (this.client.askPlexus?.root.sessionId === id) {
|
|
1182
|
+
runInAction(() => {
|
|
1183
|
+
this.#askPlexus = this.client.askPlexus;
|
|
1184
|
+
});
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
try {
|
|
1188
|
+
await this.client.watchAsk(id);
|
|
1189
|
+
}
|
|
1190
|
+
catch {
|
|
1191
|
+
// TODO: swallowed — glance says awaiting, so no cover mounts until the
|
|
1192
|
+
// ask interns. Same shape as watchPeek. Surface or log, do not silently
|
|
1193
|
+
// retry (the ask still lives on the host queue).
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
if (gen !== this.#askBindGen)
|
|
1197
|
+
return;
|
|
1198
|
+
runInAction(() => {
|
|
1199
|
+
if (hostAskEscalateSessionId(this.client) !== id)
|
|
1200
|
+
return;
|
|
1201
|
+
this.#askPlexus = this.client.askPlexus;
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
#switchSession(sessionId) {
|
|
1205
|
+
if (sessionId === this.client.sessionId) {
|
|
1206
|
+
this.#closeAgents();
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
if (!projectRecentSessions(this.client).some((row) => row.sessionId === sessionId)) {
|
|
1210
|
+
this.#closeAgents();
|
|
1211
|
+
void this.#showNotice("session not found");
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
if (this.#replaceSession === undefined)
|
|
1215
|
+
return;
|
|
1216
|
+
this.#replaceSession({ path: this.client.sessionRoot.path, sessionId });
|
|
1217
|
+
}
|
|
1218
|
+
#paintSpineTurns() {
|
|
1219
|
+
const root = this.client.sessionRoot;
|
|
1220
|
+
return tapeSpine(this.#historyNav ? resolvedTip(root.head, root.tip) : root.head);
|
|
1221
|
+
}
|
|
1222
|
+
get #sessionTitle() { return _private_get_sessionTitle_descriptor.get.call(this); }
|
|
1223
|
+
get #isHeadAtTip() { return _private_get_isHeadAtTip_descriptor.get.call(this); }
|
|
1224
|
+
#viewTurn() {
|
|
1225
|
+
const head = this.client.sessionRoot.head;
|
|
1226
|
+
const tip = resolvedTip(head, this.client.sessionRoot.tip);
|
|
1227
|
+
const view = this.#viewPin;
|
|
1228
|
+
if (view instanceof SessionTurn && onTipChain(view, tip, head))
|
|
1229
|
+
return view;
|
|
1230
|
+
return head instanceof SessionTurn ? head : null;
|
|
1231
|
+
}
|
|
1232
|
+
get #untouchedRestoredDraft() {
|
|
1233
|
+
return (this.#restoredDraft != null &&
|
|
1234
|
+
this.#restoredDraft.turnId === this.client.sessionRoot.head?.uuid &&
|
|
1235
|
+
this.#restoredDraft.prompt === this.draft.draft);
|
|
1236
|
+
}
|
|
1237
|
+
#browsing() {
|
|
1238
|
+
return this.#historyNav;
|
|
1239
|
+
}
|
|
1240
|
+
#enterHistory() {
|
|
1241
|
+
if (this.#viewTurn() == null)
|
|
1242
|
+
return;
|
|
1243
|
+
if (this.client.sessionRoot.findRunningTurn() != null)
|
|
1244
|
+
return;
|
|
1245
|
+
const head = this.client.sessionRoot.head;
|
|
1246
|
+
if (head instanceof SessionTurn && head.openWork)
|
|
1247
|
+
return;
|
|
1248
|
+
this.#historyNav = true;
|
|
1249
|
+
// A promptless suffix (continue, empty compact) is not a message. Land
|
|
1250
|
+
// on the latest prompt so Enter rolls that suffix back instead of
|
|
1251
|
+
// prefilling an empty draft over a head that never moves.
|
|
1252
|
+
if (head instanceof SessionTurn && !isRewindPin(head)) {
|
|
1253
|
+
const pin = previousPin(head);
|
|
1254
|
+
if (pin != null)
|
|
1255
|
+
this.#viewPin = pin;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
#leaveHistory() {
|
|
1259
|
+
this.#historyNav = false;
|
|
1260
|
+
this.#viewPin = null;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Turns newer than `view`, oldest first. Pins, then the episode ceiling
|
|
1264
|
+
* when it is not already that last pin — a promptless continue, or the
|
|
1265
|
+
* last message once `futurePins` has stopped short of it.
|
|
1266
|
+
*/
|
|
1267
|
+
#aheadOf(view) {
|
|
1268
|
+
const tip = this.client.sessionRoot.tip;
|
|
1269
|
+
const ahead = futurePins(view, tip);
|
|
1270
|
+
const ceiling = resolvedTip(view, tip);
|
|
1271
|
+
if (ceiling != null && ceiling !== view && ahead.at(-1) !== ceiling)
|
|
1272
|
+
ahead.push(ceiling);
|
|
1273
|
+
return ahead;
|
|
1274
|
+
}
|
|
1275
|
+
#moveView(turn) {
|
|
1276
|
+
// Keep the pin even when it is `head`. Rewind cuts *before* the selected
|
|
1277
|
+
// message, so head is the turn we just left — ArrowDown has to be able
|
|
1278
|
+
// to land back on it.
|
|
1279
|
+
this.#viewPin = turn;
|
|
1280
|
+
this.#historyNav = true;
|
|
1281
|
+
}
|
|
1282
|
+
#pinById(id) {
|
|
1283
|
+
const head = this.client.sessionRoot.head;
|
|
1284
|
+
const tip = resolvedTip(head, this.client.sessionRoot.tip);
|
|
1285
|
+
let unit = tip;
|
|
1286
|
+
const seen = new Set();
|
|
1287
|
+
while (unit instanceof SessionTurn) {
|
|
1288
|
+
if (seen.has(unit))
|
|
1289
|
+
break;
|
|
1290
|
+
seen.add(unit);
|
|
1291
|
+
if (unit.uuid === id && (isRewindPin(unit) || unit === tip))
|
|
1292
|
+
return unit;
|
|
1293
|
+
unit = unit.turnTail;
|
|
1294
|
+
}
|
|
1295
|
+
return null;
|
|
1296
|
+
}
|
|
1297
|
+
#applyPinRecap() {
|
|
1298
|
+
const view = this.#viewTurn();
|
|
1299
|
+
const running = this.client.sessionRoot.findRunningTurn() != null;
|
|
1300
|
+
if (running || view == null || !this.#historyNav || this.#callback !== undefined) {
|
|
1301
|
+
this.#paint.projectPinRecap(null);
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
this.#paint.projectPinRecap(view, this.#sessionTitle, [
|
|
1305
|
+
{ key: "Enter", action: "Rollback here" },
|
|
1306
|
+
{ key: "Esc", action: "Back" },
|
|
1307
|
+
...(previousPin(view) == null ? [] : [{ key: "↑", action: "Previous message" }]),
|
|
1308
|
+
...(this.#aheadOf(view).length === 0 ? [] : [{ key: "↓", action: "Next message" }]),
|
|
1309
|
+
]);
|
|
1310
|
+
}
|
|
1311
|
+
#rewindPaintTrack() {
|
|
1312
|
+
const head = this.client.sessionRoot.head;
|
|
1313
|
+
const tip = this.client.sessionRoot.tip;
|
|
1314
|
+
return [
|
|
1315
|
+
head?.uuid ?? "",
|
|
1316
|
+
tip?.uuid ?? "",
|
|
1317
|
+
this.#viewPin?.uuid ?? "",
|
|
1318
|
+
this.#historyNav,
|
|
1319
|
+
this.client.sessionRoot.findRunningTurn()?.uuid ?? "",
|
|
1320
|
+
this.#sessionTitle,
|
|
1321
|
+
this.#callback?.surface.name ?? "",
|
|
1322
|
+
];
|
|
1323
|
+
}
|
|
1324
|
+
#syncRewindPaint() {
|
|
1325
|
+
const tip = this.client.sessionRoot.tip;
|
|
1326
|
+
const view = this.#viewTurn();
|
|
1327
|
+
const running = this.client.sessionRoot.findRunningTurn() != null;
|
|
1328
|
+
const rewindChromeCollapsed = running || !this.#historyNav || view == null || this.#callback !== undefined;
|
|
1329
|
+
// LATEST_PLACE: the view is the episode ceiling, so there is no newer
|
|
1330
|
+
// message and the ahead stack drops. The composer stays hidden either
|
|
1331
|
+
// way — the recap block is the input while history navigation is open.
|
|
1332
|
+
const latestPlace = !rewindChromeCollapsed && view != null && isAtTip(view, tip);
|
|
1333
|
+
const pastAll = rewindChromeCollapsed ? [] : pastPins(view);
|
|
1334
|
+
const futureAll = rewindChromeCollapsed || latestPlace || view == null ? [] : this.#aheadOf(view);
|
|
1335
|
+
const slots = rewindNeighborSlots(futureAll.length, pastAll.length);
|
|
1336
|
+
const past = pastAll
|
|
1337
|
+
.slice(0, slots.behind)
|
|
1338
|
+
.toReversed()
|
|
1339
|
+
.map((turn) => ({ key: turn.uuid, text: turn.prompt }));
|
|
1340
|
+
const future = futureAll
|
|
1341
|
+
.slice(0, slots.ahead)
|
|
1342
|
+
.map((turn) => ({ key: turn.uuid, text: turn.prompt || "Latest conversation" }));
|
|
1343
|
+
const steal = this.#omnibox.render === "ask" || this.#omnibox.render === "overlay" || this.#omnibox.render === "auth";
|
|
1344
|
+
this.#paint.projectRewind({
|
|
1345
|
+
// atTip is "not browsing". The ceiling still browses: it dims the
|
|
1346
|
+
// tape and scrolls to the block. Follow-tail is only for the live view.
|
|
1347
|
+
atTip: rewindChromeCollapsed,
|
|
1348
|
+
seatRim: steal || !this.#browsing(),
|
|
1349
|
+
past,
|
|
1350
|
+
future,
|
|
1351
|
+
pastTotal: pastAll.length,
|
|
1352
|
+
futureTotal: futureAll.length,
|
|
1353
|
+
});
|
|
1354
|
+
this.#applyPinRecap();
|
|
1355
|
+
}
|
|
1356
|
+
#previewSpineTurns() {
|
|
1357
|
+
if (this.#agentsPreview == null)
|
|
1358
|
+
return [];
|
|
1359
|
+
return tapeSpine(this.#peekPlexus?.root.head ?? null);
|
|
1360
|
+
}
|
|
1361
|
+
#paintTrackSpine() {
|
|
1362
|
+
const tip = resolvedTip(this.client.sessionRoot.head, this.client.sessionRoot.tip);
|
|
1363
|
+
return [
|
|
1364
|
+
this.client.kernelRoot.hideFloorTools,
|
|
1365
|
+
this.#trackSpine(this.#paintSpineTurns()),
|
|
1366
|
+
this.client.sessionRoot.steerQueue.map((row) => [row, row.text]),
|
|
1367
|
+
tip?.uuid ?? "",
|
|
1368
|
+
this.client.sessionRoot.findRunningTurn()?.uuid ?? "",
|
|
1369
|
+
];
|
|
1370
|
+
}
|
|
1371
|
+
#previewPaintTrack() {
|
|
1372
|
+
return [
|
|
1373
|
+
this.#agentsPreview,
|
|
1374
|
+
this.client.kernelRoot.hideFloorTools,
|
|
1375
|
+
this.#peekPlexus?.root.kvs.model ?? "",
|
|
1376
|
+
this.#trackSpine(this.#previewSpineTurns()),
|
|
1377
|
+
];
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Structure only — turn/chunk identity, cutoff, ask pin, hidden tools.
|
|
1381
|
+
* PEW field values belong to per-cell reactions in PaintController.
|
|
1382
|
+
*/
|
|
1383
|
+
#trackSpine(turns) {
|
|
1384
|
+
return turns.map((turn) => [trackTurn(turn), this.#cancelAsked.has(turn)]);
|
|
1385
|
+
}
|
|
1386
|
+
get #askHead() { return _private_get_askHead_descriptor.get.call(this); }
|
|
1387
|
+
/** The acknowledgement the asked call carries, when a flag still waits on a person. */
|
|
1388
|
+
get #ackPrompt() { return _private_get_ackPrompt_descriptor.get.call(this); }
|
|
1389
|
+
get #ackIndex() {
|
|
1390
|
+
const leaf = this.#askHead;
|
|
1391
|
+
const model = this.#ackPrompt;
|
|
1392
|
+
if (leaf == null || model == null || this.#ackPick.id !== leaf.uuid)
|
|
1393
|
+
return 0;
|
|
1394
|
+
return Math.min(this.#ackPick.index, Math.max(0, model.choices.length - 1));
|
|
1395
|
+
}
|
|
1396
|
+
get #coverAskAgentSpec() { return _private_get_coverAskAgentSpec_descriptor.get.call(this); }
|
|
1397
|
+
get #askHome() { return _private_get_askHome_descriptor.get.call(this); }
|
|
1398
|
+
get #readWiden() { return _private_get_readWiden_descriptor.get.call(this); }
|
|
1399
|
+
get #omniboxValue() { return _private_get_omniboxValue_descriptor.get.call(this); }
|
|
1400
|
+
get #contextRail() { return _private_get_contextRail_descriptor.get.call(this); }
|
|
1401
|
+
get #omnibox() { return _private_get_omnibox_descriptor.get.call(this); }
|
|
1402
|
+
get #askIsolated() { return _private_get_askIsolated_descriptor.get.call(this); }
|
|
1403
|
+
get #historyHidesOmnibox() {
|
|
1404
|
+
if (!this.#browsing())
|
|
1405
|
+
return false;
|
|
1406
|
+
const render = this.#omnibox.render;
|
|
1407
|
+
return render !== "ask" && render !== "overlay" && render !== "auth";
|
|
1408
|
+
}
|
|
1409
|
+
/** Next-turn rows only. A sitting steer paints as an upcoming user prompt. */
|
|
1410
|
+
get #admissionDeckText() { return _private_get_admissionDeckText_descriptor.get.call(this); }
|
|
1411
|
+
#askPinFace() {
|
|
1412
|
+
const seat = this.#omnibox;
|
|
1413
|
+
if (seat.render === "overlay" || seat.render === "auth")
|
|
1414
|
+
return null;
|
|
1415
|
+
const host = this.client.sessionRoot.findRunningTurn();
|
|
1416
|
+
const turn = host?.approvalHead == null ? this.#askHome.findRunningTurn() : host;
|
|
1417
|
+
const head = turn == null ? null : askPaintHead(turn);
|
|
1418
|
+
if (head instanceof ToolCallJob) {
|
|
1419
|
+
const face = askPinFace(head, this.client.kernelRoot, this.#blobs);
|
|
1420
|
+
return askPinWorthPainting(face) ? face : null;
|
|
1421
|
+
}
|
|
1422
|
+
return null;
|
|
1423
|
+
}
|
|
1424
|
+
/**
|
|
1425
|
+
* Plexus facts for the pin. The paint tree is MST, so the constructor
|
|
1426
|
+
* reaction stamps this through `projectWait`.
|
|
1427
|
+
*/
|
|
1428
|
+
get #waitChrome() { return _private_get_waitChrome_descriptor.get.call(this); }
|
|
1429
|
+
get #inputting() {
|
|
1430
|
+
return (this.#callback !== undefined && hasInputHole(this.#callback.surface) && !this.#oauthWaiting && !this.#processing);
|
|
1431
|
+
}
|
|
1432
|
+
get #commands() { return _private_get_commands_descriptor.get.call(this); }
|
|
1433
|
+
#skillVerb(verb) {
|
|
1434
|
+
if (isHostVerb(verb) || this.client.kernelRoot.commands[verb] !== undefined)
|
|
1435
|
+
return false;
|
|
1436
|
+
return this.client.sessionRoot.skills.some((skill) => skillMatchesVerb(skill, verb));
|
|
1437
|
+
}
|
|
1438
|
+
get #parentNode() { return _private_get_parentNode_descriptor.get.call(this); }
|
|
1439
|
+
get #inCommand() { return _private_get_inCommand_descriptor.get.call(this); }
|
|
1440
|
+
get #atCatalog() { return _private_get_atCatalog_descriptor.get.call(this); }
|
|
1441
|
+
get #pickerRows() { return _private_get_pickerRows_descriptor.get.call(this); }
|
|
1442
|
+
get #catalogNodes() { return _private_get_catalogNodes_descriptor.get.call(this); }
|
|
1443
|
+
get #commandChoices() { return _private_get_commandChoices_descriptor.get.call(this); }
|
|
1444
|
+
get effectiveKey() {
|
|
1445
|
+
return reconcileSelectedKey(this.selectedCommandKey, this.#commandChoices ?? []);
|
|
1446
|
+
}
|
|
1447
|
+
get #commandAction() { return _private_get_commandAction_descriptor.get.call(this); }
|
|
1448
|
+
/** Picker rows. Logic reads this; paint is not the catalog. */
|
|
1449
|
+
get commandChoices() {
|
|
1450
|
+
return this.#commandChoices;
|
|
1451
|
+
}
|
|
1452
|
+
/** Composer title. Manual title wins; otherwise the latest metadata claim. */
|
|
1453
|
+
get sessionTitle() {
|
|
1454
|
+
return this.#sessionTitle;
|
|
1455
|
+
}
|
|
1456
|
+
/** Quota windows Tea hands to paint. Paint spells the remaining label. */
|
|
1457
|
+
get quotaWindows() {
|
|
1458
|
+
return this.#quotaWindows ?? [];
|
|
1459
|
+
}
|
|
1460
|
+
/** Parked confirm / oauth surface. Null when the composer owns the draft. */
|
|
1461
|
+
get callbackSurface() {
|
|
1462
|
+
return this.#callback?.surface ?? null;
|
|
1463
|
+
}
|
|
1464
|
+
// COMMAND_SURFACE_KEEPALIVE: isolated-ask paint skips this surface for a
|
|
1465
|
+
// tick. Without keepAlive, onBecomeUnobserved runs exec.get() and aborts
|
|
1466
|
+
// the command-body eval.
|
|
1467
|
+
get #commandSurface() { return _private_get_commandSurface_descriptor.get.call(this); }
|
|
1468
|
+
#noteModelEval(surface) {
|
|
1469
|
+
const kernel = this.client.kernelRoot;
|
|
1470
|
+
const session = this.client.sessionRoot;
|
|
1471
|
+
const connections = Object.values(kernel.connections).map((spec) => {
|
|
1472
|
+
const models = Array.isArray(spec.live.models) ? spec.live.models.map(String) : [];
|
|
1473
|
+
const can = spec.driver?.abilityClaim ?? [];
|
|
1474
|
+
return `${spec.id} can=${can.join(",") || "(none)"} ready=${spec.readyState} models=${models.length}`;
|
|
1475
|
+
});
|
|
1476
|
+
const choices = surface instanceof UiNode ? surface.choices.filter((child) => child.name !== "").length : "no-surface";
|
|
1477
|
+
const replica = this.client.kernelPlexus.doc;
|
|
1478
|
+
const line = `command evaluation: current connection=${session.kvs.connection ?? ""} model=${session.kvs.model ?? ""} surface=${choices} replica=guid=${replica.guid} client=${replica.clientID} ${connections.join("; ") || "connections=(none)"}`;
|
|
1479
|
+
if (line === this.#lastModelEvalLog)
|
|
1480
|
+
return;
|
|
1481
|
+
this.#lastModelEvalLog = line;
|
|
1482
|
+
step(line);
|
|
1483
|
+
}
|
|
1484
|
+
#commandConfig(extra = {}) {
|
|
1485
|
+
return {
|
|
1486
|
+
kernel: this.client.kernelRoot,
|
|
1487
|
+
session: this.client.sessionRoot,
|
|
1488
|
+
rpc: (method, params) => this.client.request(method, params),
|
|
1489
|
+
...extra,
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
#execFor(verb, body, kernel) {
|
|
1493
|
+
const hit = this.#execs.get(verb);
|
|
1494
|
+
if (hit !== undefined && hit.body === body)
|
|
1495
|
+
return hit.exec;
|
|
1496
|
+
const box = new ComputedExecBox(body, {
|
|
1497
|
+
capabilities: COMMAND_CAPABILITIES,
|
|
1498
|
+
config: this.#commandConfig({ kernel }),
|
|
1499
|
+
});
|
|
1500
|
+
this.#execs.set(verb, { body, exec: box });
|
|
1501
|
+
return box;
|
|
1502
|
+
}
|
|
1503
|
+
get #selectedIndex() { return _private_get_selectedIndex_descriptor.get.call(this); }
|
|
1504
|
+
focusAt(index) {
|
|
1505
|
+
const keyed = this.#commandChoices;
|
|
1506
|
+
if (keyed === undefined || keyed.length === 0)
|
|
1507
|
+
return;
|
|
1508
|
+
const i = ((index % keyed.length) + keyed.length) % keyed.length;
|
|
1509
|
+
this.selectedCommandKey = keyed[i].key ?? null;
|
|
1510
|
+
const sel = keyed.findIndex((row) => row.key === this.selectedCommandKey);
|
|
1511
|
+
this.scrollOffset = peekScroll(sel, keyed.length, COMPOSER_COMMAND_MAX_VISIBLE, this.scrollOffset);
|
|
1512
|
+
}
|
|
1513
|
+
#draftFromKey(state, event) {
|
|
1514
|
+
const op = keyEventToDraftOp(event);
|
|
1515
|
+
if (op === null || op === "clear")
|
|
1516
|
+
return null;
|
|
1517
|
+
return applyDraftOp(state, maybeVisualMotion(op, state, rootInnerWidth(this.cols)));
|
|
1518
|
+
}
|
|
1519
|
+
#peekSelection() {
|
|
1520
|
+
const keyed = this.#commandChoices;
|
|
1521
|
+
if (keyed === undefined || keyed.length === 0) {
|
|
1522
|
+
if (omniboxStackPanel(this.#omniboxValue).body === "")
|
|
1523
|
+
this.scrollOffset = 0;
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
const sel = keyed.findIndex((row) => row.key === this.effectiveKey);
|
|
1527
|
+
this.scrollOffset = peekScroll(sel, keyed.length, COMPOSER_COMMAND_MAX_VISIBLE, this.scrollOffset);
|
|
1528
|
+
}
|
|
1529
|
+
#resetSelection() {
|
|
1530
|
+
this.selectedCommandKey = null;
|
|
1531
|
+
this.#peekSelection();
|
|
1532
|
+
}
|
|
1533
|
+
handle(message) {
|
|
1534
|
+
switch (message.kind) {
|
|
1535
|
+
case "resize":
|
|
1536
|
+
this.cols = message.cols;
|
|
1537
|
+
this.rows = message.rows;
|
|
1538
|
+
return;
|
|
1539
|
+
case "input_events": {
|
|
1540
|
+
this.#stepCoverThrottle();
|
|
1541
|
+
if (this.#askHead != null || this.#drainAsk)
|
|
1542
|
+
this.#askHold = true;
|
|
1543
|
+
if (this.#agentsOpen && this.#omniboxValue.ask !== null)
|
|
1544
|
+
this.#closeAgents();
|
|
1545
|
+
let draftChanged = false;
|
|
1546
|
+
for (const event of message.events) {
|
|
1547
|
+
if (this.escClearArmed && event.key !== "Escape")
|
|
1548
|
+
this.escClearArmed = false;
|
|
1549
|
+
if (this.#handleHotkey(event))
|
|
1550
|
+
continue;
|
|
1551
|
+
if (this.#askIsolated) {
|
|
1552
|
+
const next = this.#draftFromKey(this.#coverDraft, event);
|
|
1553
|
+
if (next === null)
|
|
1554
|
+
continue;
|
|
1555
|
+
Object.assign(this.#coverDraft, next);
|
|
1556
|
+
continue;
|
|
1557
|
+
}
|
|
1558
|
+
if (this.#historyHidesOmnibox)
|
|
1559
|
+
continue;
|
|
1560
|
+
if (this.#busy && !this.#inputting)
|
|
1561
|
+
continue;
|
|
1562
|
+
const prevVerb = slashVerb(this.draft.draft);
|
|
1563
|
+
const prevInCommand = this.#inCommand;
|
|
1564
|
+
const prevText = this.draft.draft;
|
|
1565
|
+
const next = this.#draftFromKey(this.draft, event);
|
|
1566
|
+
if (next === null)
|
|
1567
|
+
continue;
|
|
1568
|
+
if (next.draft !== this.draft.draft) {
|
|
1569
|
+
draftChanged = true;
|
|
1570
|
+
if (slashVerb(next.draft) !== prevVerb)
|
|
1571
|
+
this.#focus = undefined;
|
|
1572
|
+
}
|
|
1573
|
+
Object.assign(this.draft, next);
|
|
1574
|
+
if (next.draft !== prevText) {
|
|
1575
|
+
this.#askHold = false;
|
|
1576
|
+
this.#drainAsk = false;
|
|
1577
|
+
}
|
|
1578
|
+
// see COMMAND_SURFACE_KEEPALIVE.
|
|
1579
|
+
if (this.#inCommand !== prevInCommand || (this.#inCommand && slashVerb(this.draft.draft) !== prevVerb)) {
|
|
1580
|
+
this.selectedCommandKey = null;
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
if (this.#askHead == null && !this.#drainAsk)
|
|
1584
|
+
this.#askHold = false;
|
|
1585
|
+
if (draftChanged)
|
|
1586
|
+
this.#peekSelection();
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
case "picker_activate": {
|
|
1590
|
+
const keyed = this.#commandChoices;
|
|
1591
|
+
const nodes = this.#pickerRows;
|
|
1592
|
+
if (keyed === undefined || nodes === undefined)
|
|
1593
|
+
return;
|
|
1594
|
+
const i = keyed.findIndex((row) => row.key === message.key);
|
|
1595
|
+
if (i !== -1)
|
|
1596
|
+
this.#pick(nodes[i], true);
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
case "picker_scroll": {
|
|
1600
|
+
const panel = omniboxStackPanel(this.#omniboxValue);
|
|
1601
|
+
if (panel.body !== "") {
|
|
1602
|
+
const n = panel.body.split("\n").length;
|
|
1603
|
+
const viewport = panel.viewport ?? n;
|
|
1604
|
+
const maxS = Math.max(0, n - viewport);
|
|
1605
|
+
this.scrollOffset = Math.min(maxS, Math.max(0, this.scrollOffset + message.delta));
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1608
|
+
const n = this.#commandChoices?.length ?? 0;
|
|
1609
|
+
const maxS = Math.max(0, n - COMPOSER_COMMAND_MAX_VISIBLE);
|
|
1610
|
+
this.scrollOffset = Math.min(maxS, Math.max(0, this.scrollOffset + message.delta));
|
|
1611
|
+
return;
|
|
1612
|
+
}
|
|
1613
|
+
case "agents_scroll":
|
|
1614
|
+
if (!this.#agentsOpen || this.#agentsPreview !== null)
|
|
1615
|
+
return;
|
|
1616
|
+
this.#agentsScroll = Math.max(0, this.#agentsScroll + message.delta);
|
|
1617
|
+
return;
|
|
1618
|
+
case "agents_focus":
|
|
1619
|
+
if (!this.#agentsOpen || this.#agentsPreview !== null)
|
|
1620
|
+
return;
|
|
1621
|
+
this.#focusAgentsKey(message.key);
|
|
1622
|
+
return;
|
|
1623
|
+
case "agents_hover": {
|
|
1624
|
+
if (!this.#agentsOpen || this.#agentsPreview !== null)
|
|
1625
|
+
return;
|
|
1626
|
+
if (message.key == null) {
|
|
1627
|
+
this.#agentsHover = null;
|
|
1628
|
+
return;
|
|
1629
|
+
}
|
|
1630
|
+
const row = agentsRowKeyFromHit(message.key) ?? message.key;
|
|
1631
|
+
this.#agentsHover = this.#agentsRowKeys().includes(row) ? row : null;
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
case "submit": {
|
|
1635
|
+
const received = receiveSubmit(message);
|
|
1636
|
+
if (received !== null)
|
|
1637
|
+
this.submission = received;
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
case "activate":
|
|
1641
|
+
if (this.#agentsPreview !== null) {
|
|
1642
|
+
if (message.key.endsWith(":backdrop"))
|
|
1643
|
+
this.#closeAgentsPreview();
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
if (message.key.startsWith("mention:")) {
|
|
1647
|
+
const call = mentionedAgentCall(this.client, `call:${message.key.slice("mention:".length)}`);
|
|
1648
|
+
if (call != null) {
|
|
1649
|
+
this.#openAgentsPreview(call.key, call.sessionId);
|
|
1650
|
+
return;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
if (this.#agentsOpen) {
|
|
1654
|
+
if (message.key.endsWith(":backdrop")) {
|
|
1655
|
+
this.#closeAgents();
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1658
|
+
this.#activateAgentsKey(message.key);
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
{
|
|
1662
|
+
const pin = this.#pinById(message.key);
|
|
1663
|
+
if (pin != null)
|
|
1664
|
+
this.#moveView(pin);
|
|
1665
|
+
}
|
|
1666
|
+
return;
|
|
1667
|
+
default:
|
|
1668
|
+
return;
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
/**
|
|
1672
|
+
* Honest submit wins. Text parts join into the prompt. Picture bytes ride
|
|
1673
|
+
* beside it. The command stays out of both. With no submission, the typed
|
|
1674
|
+
* string goes as before.
|
|
1675
|
+
*/
|
|
1676
|
+
#submitTurn(kind) {
|
|
1677
|
+
const typed = this.draft.draft.trim();
|
|
1678
|
+
const honest = this.submission;
|
|
1679
|
+
const joined = honest !== null && honest.parts.length > 0 ? promptFromParts(honest.parts) : null;
|
|
1680
|
+
const prompt = joined === null ? typed : joined.text;
|
|
1681
|
+
const visuals = joined?.visuals ?? [];
|
|
1682
|
+
if (prompt.trim() === "" && visuals.length === 0)
|
|
1683
|
+
return false;
|
|
1684
|
+
const params = { prompt };
|
|
1685
|
+
if (kind !== undefined)
|
|
1686
|
+
params.kind = kind;
|
|
1687
|
+
if (visuals.length > 0)
|
|
1688
|
+
params.visuals = visuals;
|
|
1689
|
+
trace("harness:turn", `submit chars=${prompt.trim().length}`);
|
|
1690
|
+
this.#fire([new UiNode("turn", "", [], "ok", "", undefined, [], [], [], "turn", params)], true);
|
|
1691
|
+
this.submission = null;
|
|
1692
|
+
return true;
|
|
1693
|
+
}
|
|
1694
|
+
#fire(leaves, dismiss = false) {
|
|
1695
|
+
if (leaves === undefined || leaves.length === 0)
|
|
1696
|
+
return;
|
|
1697
|
+
if (this.#resolveWaiter !== undefined) {
|
|
1698
|
+
const leaf = leaves.find((item) => item.op === "ui/resolve") ?? leaves[0];
|
|
1699
|
+
if (leaf?.op === "ui/resolve") {
|
|
1700
|
+
this.#completeCallback(fillParams(jsonParams(leaf.params), this.#remainder));
|
|
1701
|
+
}
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
if (this.#busy)
|
|
1705
|
+
return;
|
|
1706
|
+
void this.#run(leaves, dismiss);
|
|
1707
|
+
}
|
|
1708
|
+
/** One named RPC at a time. A `{ form: "ui" }` result parks in the omnibox. */
|
|
1709
|
+
async #run(leaves, dismiss = false) {
|
|
1710
|
+
const saved = dismiss ? { draft: this.draft.draft, cursor: this.draft.cursor, mark: this.draft.mark } : null;
|
|
1711
|
+
runInAction(() => {
|
|
1712
|
+
if (dismiss) {
|
|
1713
|
+
this.#savedDraft = saved ?? undefined;
|
|
1714
|
+
this.#focus = undefined;
|
|
1715
|
+
this.escClearArmed = false;
|
|
1716
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
1717
|
+
this.#resetSelection();
|
|
1718
|
+
}
|
|
1719
|
+
this.#busy = true;
|
|
1720
|
+
});
|
|
1721
|
+
try {
|
|
1722
|
+
for (const leaf of leaves) {
|
|
1723
|
+
if (leaf.op == null)
|
|
1724
|
+
continue;
|
|
1725
|
+
const params = fillParams(jsonParams(leaf.params), this.#remainder);
|
|
1726
|
+
let log = `tea ${leaf.op}`;
|
|
1727
|
+
if (leaf.op === "kv/set" || leaf.op === "kv/clear") {
|
|
1728
|
+
const key = typeof params.key === "string" ? params.key : "";
|
|
1729
|
+
if (key !== "") {
|
|
1730
|
+
const scope = params.scope === "kernel" || params.scope === "project" ? params.scope : "session";
|
|
1731
|
+
if (leaf.op === "kv/clear") {
|
|
1732
|
+
log += ` ${scope} ${key}`;
|
|
1733
|
+
}
|
|
1734
|
+
else {
|
|
1735
|
+
const value = typeof params.value === "string" ? params.value : "";
|
|
1736
|
+
log += ` ${scope} ${key}=${value}`;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
step(log);
|
|
1741
|
+
let result = await this.client.request(leaf.op, params);
|
|
1742
|
+
while (isUiForm(result)) {
|
|
1743
|
+
result = await this.#awaitCallback(result);
|
|
1744
|
+
}
|
|
1745
|
+
const refused = refusalOf(result);
|
|
1746
|
+
if (refused !== undefined)
|
|
1747
|
+
throw new Error(refused);
|
|
1748
|
+
if (leaf.op === "connect/adopt") {
|
|
1749
|
+
const value = typeof result === "object" && result !== null ? result.id : undefined;
|
|
1750
|
+
const id = typeof value === "string" && value.trim() !== "" ? value.trim() : undefined;
|
|
1751
|
+
if (id !== undefined) {
|
|
1752
|
+
const connection = { key: "connection", value: id };
|
|
1753
|
+
step(`tea kv/set session connection=${id}`);
|
|
1754
|
+
await this.client.request("kv/set", connection);
|
|
1755
|
+
runInAction(() => {
|
|
1756
|
+
this.#savedDraft = undefined;
|
|
1757
|
+
this.draft = { draft: "/model", cursor: 6, mark: null };
|
|
1758
|
+
this.#resetSelection();
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
const kvs = this.client.sessionRoot.kvs;
|
|
1764
|
+
step(`tea replica model=${kvs.model ?? ""} connection=${kvs.connection ?? ""}`);
|
|
1765
|
+
}
|
|
1766
|
+
catch (error) {
|
|
1767
|
+
if (saved !== null) {
|
|
1768
|
+
runInAction(() => {
|
|
1769
|
+
Object.assign(this.draft, saved);
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
fail("tea run", error);
|
|
1773
|
+
await this.#showNotice(error instanceof Error ? error.message : String(error));
|
|
1774
|
+
}
|
|
1775
|
+
finally {
|
|
1776
|
+
runInAction(() => {
|
|
1777
|
+
this.#busy = false;
|
|
1778
|
+
this.#processing = false;
|
|
1779
|
+
this.#callback = undefined;
|
|
1780
|
+
this.#focus = undefined;
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
async #showNotice(message) {
|
|
1785
|
+
const surface = new UiNode(message, "", [], "ok", "", undefined, [new UiNode("Dismiss", "", [], "ok", "", undefined, [], [], [], "ui/resolve", { pending: "", kind: "dismiss" })], [new UiNode("Dismiss", "", [], "ok", "", "escape", [], [], [], "ui/resolve", { pending: "", kind: "dismiss" })], [], null, {});
|
|
1786
|
+
await this.#parkSurface(surface);
|
|
1787
|
+
}
|
|
1788
|
+
/** Park a surface in the omnibox until one of its `ui/resolve` leaves fires; the draft comes back after. */
|
|
1789
|
+
async #parkSurface(surface) {
|
|
1790
|
+
const saved = { ...this.draft };
|
|
1791
|
+
this.#savedDraft = saved;
|
|
1792
|
+
runInAction(() => {
|
|
1793
|
+
this.#callback = { pending: "", surface };
|
|
1794
|
+
this.#focus = undefined;
|
|
1795
|
+
this.draft = { draft: "", cursor: 0, mark: null };
|
|
1796
|
+
this.#resetSelection();
|
|
1797
|
+
this.escClearArmed = false;
|
|
1798
|
+
});
|
|
1799
|
+
try {
|
|
1800
|
+
return await new Promise((resolve) => {
|
|
1801
|
+
this.#resolveWaiter = resolve;
|
|
1802
|
+
});
|
|
1803
|
+
}
|
|
1804
|
+
finally {
|
|
1805
|
+
this.#resolveWaiter = undefined;
|
|
1806
|
+
runInAction(() => {
|
|
1807
|
+
this.#callback = undefined;
|
|
1808
|
+
this.#processing = false;
|
|
1809
|
+
Object.assign(this.draft, this.#savedDraft ?? saved);
|
|
1810
|
+
this.#savedDraft = undefined;
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
/** `/permissions [probe]`: the view, then Enter on a stored row revokes it and the view reloads. */
|
|
1815
|
+
async #showPermissions(probe) {
|
|
1816
|
+
const root = this.client.sessionRoot;
|
|
1817
|
+
let explain;
|
|
1818
|
+
const parsed = parseProbe(probe);
|
|
1819
|
+
for (;;) {
|
|
1820
|
+
if (parsed !== null) {
|
|
1821
|
+
explain = await this.client.request("policy/explain", { probe: parsed }).then((outcome) => ({ probe, outcome: outcome }), (error) => ({
|
|
1822
|
+
probe,
|
|
1823
|
+
outcome: null,
|
|
1824
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1825
|
+
}));
|
|
1826
|
+
}
|
|
1827
|
+
const listing = { sessionId: root.sessionId, projectPath: root.path };
|
|
1828
|
+
const rows = async (method) => this.client.request(method, listing).then((out) => out.rows, (error) => {
|
|
1829
|
+
fail(method, error);
|
|
1830
|
+
return [];
|
|
1831
|
+
});
|
|
1832
|
+
const view = permissionsView({
|
|
1833
|
+
mode: root.permissionMode,
|
|
1834
|
+
layers: layersOf({
|
|
1835
|
+
user: root.authorizationUserJson,
|
|
1836
|
+
project: root.authorizationProjectJson,
|
|
1837
|
+
session: root.authorizationOverlayJson,
|
|
1838
|
+
}),
|
|
1839
|
+
grants: await rows("grant/list"),
|
|
1840
|
+
acks: await rows("ack/list"),
|
|
1841
|
+
nowMs: this.#now(),
|
|
1842
|
+
...(explain === undefined ? {} : { explain }),
|
|
1843
|
+
});
|
|
1844
|
+
const answer = await this.#parkSurface(permissionsSurface(view));
|
|
1845
|
+
const picked = answer.kind === "revoke" && typeof answer.index === "number" ? view.revocable[answer.index] : undefined;
|
|
1846
|
+
if (picked === undefined)
|
|
1847
|
+
return;
|
|
1848
|
+
await this.client
|
|
1849
|
+
.request(picked.revoke.method, picked.revoke.params)
|
|
1850
|
+
.catch((error) => fail(picked.revoke.method, error));
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
async #awaitCallback(form) {
|
|
1854
|
+
const values = await exec(form.body, {
|
|
1855
|
+
capabilities: COMMAND_CAPABILITIES,
|
|
1856
|
+
config: this.#commandConfig({ pending: form.pending }),
|
|
1857
|
+
});
|
|
1858
|
+
const surface = values.at(-1);
|
|
1859
|
+
invariant(surface instanceof UiNode, "ui form body did not eval to a UiNode");
|
|
1860
|
+
const saved = this.#savedDraft ?? {
|
|
1861
|
+
draft: this.draft.draft,
|
|
1862
|
+
cursor: this.draft.cursor,
|
|
1863
|
+
mark: this.draft.mark,
|
|
1864
|
+
};
|
|
1865
|
+
this.#savedDraft = saved;
|
|
1866
|
+
runInAction(() => {
|
|
1867
|
+
this.#callback = { pending: form.pending, surface };
|
|
1868
|
+
this.#processing = false;
|
|
1869
|
+
this.#focus = undefined;
|
|
1870
|
+
this.draft = { draft: "", cursor: 0, mark: null };
|
|
1871
|
+
this.#resetSelection();
|
|
1872
|
+
this.escClearArmed = false;
|
|
1873
|
+
});
|
|
1874
|
+
const answerPromise = new Promise((resolve) => {
|
|
1875
|
+
this.#resolveWaiter = resolve;
|
|
1876
|
+
});
|
|
1877
|
+
const url = urlFrom(surface);
|
|
1878
|
+
// No field to type in (Nous): the link opens now and Enter means "continue".
|
|
1879
|
+
if (url !== undefined && !hasInputHole(surface))
|
|
1880
|
+
this.#openUrl(url);
|
|
1881
|
+
try {
|
|
1882
|
+
let answer = await answerPromise;
|
|
1883
|
+
step(`oauth resolve keys=${Object.keys(answer).sort().join(",")}`);
|
|
1884
|
+
// An empty field on a link park is "open it": the daemon owns the callback and waits for it.
|
|
1885
|
+
if (url !== undefined && answer.kind === "text" && answer.input === "") {
|
|
1886
|
+
this.#openUrl(url);
|
|
1887
|
+
answer = { kind: "opened", url };
|
|
1888
|
+
}
|
|
1889
|
+
if (answer.kind === "opened") {
|
|
1890
|
+
this.#waitingPending = form.pending;
|
|
1891
|
+
runInAction(() => {
|
|
1892
|
+
this.#oauthWaiting = true;
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
return await this.client.request("ui/resolve", { pending: form.pending, ...answer });
|
|
1896
|
+
}
|
|
1897
|
+
finally {
|
|
1898
|
+
this.#waitingPending = undefined;
|
|
1899
|
+
this.#resolveWaiter = undefined;
|
|
1900
|
+
runInAction(() => {
|
|
1901
|
+
this.#oauthWaiting = false;
|
|
1902
|
+
this.#processing = false;
|
|
1903
|
+
this.#callback = undefined;
|
|
1904
|
+
Object.assign(this.draft, this.#savedDraft ?? saved);
|
|
1905
|
+
this.#savedDraft = undefined;
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
#openUrl(url) {
|
|
1910
|
+
let host;
|
|
1911
|
+
try {
|
|
1912
|
+
host = new URL(url).host;
|
|
1913
|
+
}
|
|
1914
|
+
catch {
|
|
1915
|
+
host = "invalid";
|
|
1916
|
+
}
|
|
1917
|
+
step(`oauth open ${host}`);
|
|
1918
|
+
this.#open(url);
|
|
1919
|
+
}
|
|
1920
|
+
/** Esc on "Waiting for the browser…": abort the daemon's wait; the `opened` request then settles. */
|
|
1921
|
+
#cancelWaiting() {
|
|
1922
|
+
const pending = this.#waitingPending;
|
|
1923
|
+
if (pending === undefined)
|
|
1924
|
+
return;
|
|
1925
|
+
this.#waitingPending = undefined;
|
|
1926
|
+
this.client.request("ui/resolve", { pending, kind: "cancel" }).catch((error) => {
|
|
1927
|
+
fail("oauth cancel", error);
|
|
1928
|
+
});
|
|
1929
|
+
}
|
|
1930
|
+
#completeCallback(params) {
|
|
1931
|
+
const waiter = this.#resolveWaiter;
|
|
1932
|
+
this.#resolveWaiter = undefined;
|
|
1933
|
+
if (params.kind !== "cancel") {
|
|
1934
|
+
runInAction(() => {
|
|
1935
|
+
this.#processing = true;
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1938
|
+
waiter?.(params);
|
|
1939
|
+
}
|
|
1940
|
+
get #activeConnection() { return _private_get_activeConnection_descriptor.get.call(this); }
|
|
1941
|
+
/** Top-right omnibox annotation: failed head, else the selected wire's sticky error. */
|
|
1942
|
+
#errorAnnotation() {
|
|
1943
|
+
const head = this.client.sessionRoot.head;
|
|
1944
|
+
if (head instanceof SessionTurn && !isRetrying(head, this.#now())) {
|
|
1945
|
+
const chunks = reactChunks(head);
|
|
1946
|
+
for (let i = chunks.length - 1; i >= 0; i -= 1) {
|
|
1947
|
+
const pew = tapeCompletion(chunks[i]);
|
|
1948
|
+
if (pew == null || pew.outcome !== "failed")
|
|
1949
|
+
continue;
|
|
1950
|
+
if (isCompletionCutoff(pew))
|
|
1951
|
+
continue;
|
|
1952
|
+
const picked = pew.endDetail ?? pew.failReason;
|
|
1953
|
+
return { level: "error", message: picked == null ? "turn failed" : picked.trim() };
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
const connection = this.#activeConnection;
|
|
1957
|
+
if (connection != null) {
|
|
1958
|
+
const message = nonempty(connection.error);
|
|
1959
|
+
const failed = connection.readyState === "failed";
|
|
1960
|
+
const authLine = failed && authStatusLine(message);
|
|
1961
|
+
if (authLine)
|
|
1962
|
+
return { level: "error", message: "The key was refused. Reconnect." };
|
|
1963
|
+
if (failed && message !== "")
|
|
1964
|
+
return { level: "error", message };
|
|
1965
|
+
if (connection.live.auth === "needs-auth") {
|
|
1966
|
+
const id = connection.id.trim();
|
|
1967
|
+
const who = id === "" ? "connection" : `connection ${id}`;
|
|
1968
|
+
return { level: "error", message: `${who} needs auth — reconnect` };
|
|
1969
|
+
}
|
|
1970
|
+
if (failed)
|
|
1971
|
+
return { level: "error", message: "connection failed" };
|
|
1972
|
+
}
|
|
1973
|
+
return this.#pluginAnnotation();
|
|
1974
|
+
}
|
|
1975
|
+
/** The session's plugin behavior problem, else the first installed plugin that failed to load. */
|
|
1976
|
+
#pluginAnnotation() {
|
|
1977
|
+
const session = nonempty(this.client.sessionRoot.pluginProblem);
|
|
1978
|
+
if (session !== "")
|
|
1979
|
+
return { level: "warning", message: session };
|
|
1980
|
+
for (const plugin of Object.values(this.client.kernelRoot.plugins ?? {})) {
|
|
1981
|
+
const problem = plugin.enabled ? nonempty(plugin.problem) : "";
|
|
1982
|
+
if (problem !== "")
|
|
1983
|
+
return { level: "warning", message: `${plugin.pluginName}: ${problem}` };
|
|
1984
|
+
}
|
|
1985
|
+
return undefined;
|
|
1986
|
+
}
|
|
1987
|
+
/** Persist-mod overlay data. Paint spells remaining from resetAt; Tea does not. */
|
|
1988
|
+
get #quotaWindows() { return _private_get_quotaWindows_descriptor.get.call(this); }
|
|
1989
|
+
/** Bottom-right omnibox chips: model, wire name, then auto / always approve. Manual is blank. */
|
|
1990
|
+
get #statusItems() { return _private_get_statusItems_descriptor.get.call(this); }
|
|
1991
|
+
get #remainder() {
|
|
1992
|
+
const line = (this.draft.draft.split("\n")[0] ?? "").trim();
|
|
1993
|
+
if (this.#callback !== undefined)
|
|
1994
|
+
return line;
|
|
1995
|
+
const verb = slashVerb(this.draft.draft);
|
|
1996
|
+
if (verb === null)
|
|
1997
|
+
return line;
|
|
1998
|
+
return line.slice(verb.length + 1).trim();
|
|
1999
|
+
}
|
|
2000
|
+
get #stepCoverThrottle() { return _private_stepCoverThrottle_descriptor.value; }
|
|
2001
|
+
#fireHotkeyEvent(event) {
|
|
2002
|
+
switch (event) {
|
|
2003
|
+
case HOTKEY_EVENT.allow:
|
|
2004
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2005
|
+
return true;
|
|
2006
|
+
this.#answerAsk(true);
|
|
2007
|
+
return true;
|
|
2008
|
+
case HOTKEY_EVENT.allowSession:
|
|
2009
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2010
|
+
return true;
|
|
2011
|
+
this.#answerAsk(true, { remember: "session" });
|
|
2012
|
+
return true;
|
|
2013
|
+
case HOTKEY_EVENT.allowAlways:
|
|
2014
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2015
|
+
return true;
|
|
2016
|
+
this.#answerAsk(true, { remember: "project" });
|
|
2017
|
+
return true;
|
|
2018
|
+
case HOTKEY_EVENT.ackRemember: {
|
|
2019
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2020
|
+
return true;
|
|
2021
|
+
const choice = this.#ackPrompt?.choices[this.#ackIndex];
|
|
2022
|
+
if (choice !== undefined)
|
|
2023
|
+
this.#answerAsk(true, { ackChoice: choice });
|
|
2024
|
+
return true;
|
|
2025
|
+
}
|
|
2026
|
+
case HOTKEY_EVENT.ackNext:
|
|
2027
|
+
case HOTKEY_EVENT.ackPrev: {
|
|
2028
|
+
const leaf = this.#askHead;
|
|
2029
|
+
const size = this.#ackPrompt?.choices.length ?? 0;
|
|
2030
|
+
if (leaf == null || size === 0)
|
|
2031
|
+
return true;
|
|
2032
|
+
this.#ackPick = {
|
|
2033
|
+
id: leaf.uuid,
|
|
2034
|
+
index: cycleAck(this.#ackIndex, size, event === HOTKEY_EVENT.ackNext ? 1 : -1),
|
|
2035
|
+
};
|
|
2036
|
+
return true;
|
|
2037
|
+
}
|
|
2038
|
+
case HOTKEY_EVENT.allowWiden: {
|
|
2039
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2040
|
+
return true;
|
|
2041
|
+
const widen = this.#readWiden;
|
|
2042
|
+
this.#answerAsk(true, { widen: widen?.path });
|
|
2043
|
+
return true;
|
|
2044
|
+
}
|
|
2045
|
+
case HOTKEY_EVENT.deny:
|
|
2046
|
+
if (this.#processing)
|
|
2047
|
+
return true;
|
|
2048
|
+
this.#answerAsk(false);
|
|
2049
|
+
return true;
|
|
2050
|
+
case HOTKEY_EVENT.denySession:
|
|
2051
|
+
if (this.#processing)
|
|
2052
|
+
return true;
|
|
2053
|
+
this.#answerAsk(false, { persist: "session" });
|
|
2054
|
+
return true;
|
|
2055
|
+
case HOTKEY_EVENT.denyAlways:
|
|
2056
|
+
if (this.#processing)
|
|
2057
|
+
return true;
|
|
2058
|
+
this.#answerAsk(false, { persist: "always" });
|
|
2059
|
+
return true;
|
|
2060
|
+
case HOTKEY_EVENT.retry:
|
|
2061
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2062
|
+
return true;
|
|
2063
|
+
this.#fire([new UiNode("turn/retry", "", [], "ok", "", undefined, [], [], [], "turn/retry", {})], true);
|
|
2064
|
+
return true;
|
|
2065
|
+
case HOTKEY_EVENT.queueMessage: {
|
|
2066
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2067
|
+
return true;
|
|
2068
|
+
if (!this.#submitTurn("queue"))
|
|
2069
|
+
return true;
|
|
2070
|
+
return true;
|
|
2071
|
+
}
|
|
2072
|
+
case HOTKEY_EVENT.steerFirst:
|
|
2073
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2074
|
+
return true;
|
|
2075
|
+
this.#queueMove("queue/steer-first", this.client.sessionRoot.promptQueue[0]);
|
|
2076
|
+
return true;
|
|
2077
|
+
case HOTKEY_EVENT.continue: {
|
|
2078
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2079
|
+
return true;
|
|
2080
|
+
const head = this.client.sessionRoot.head;
|
|
2081
|
+
if (head instanceof SessionTurn && head.lastTurnIncomplete && isAtTip(head, this.client.sessionRoot.tip)) {
|
|
2082
|
+
this.#fire([
|
|
2083
|
+
new UiNode("turn", "", [], "ok", "", undefined, [], [], [], "turn", {
|
|
2084
|
+
prompt: "",
|
|
2085
|
+
kind: "continue",
|
|
2086
|
+
}),
|
|
2087
|
+
], true);
|
|
2088
|
+
}
|
|
2089
|
+
return true;
|
|
2090
|
+
}
|
|
2091
|
+
case HOTKEY_EVENT.clear:
|
|
2092
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2093
|
+
this.escClearArmed = false;
|
|
2094
|
+
this.#resetSelection();
|
|
2095
|
+
return true;
|
|
2096
|
+
case HOTKEY_EVENT.cancelTurn: {
|
|
2097
|
+
const running = this.client.sessionRoot.findRunningTurn();
|
|
2098
|
+
this.escClearArmed = false;
|
|
2099
|
+
this.#drainAsk = false;
|
|
2100
|
+
this.#askHold = false;
|
|
2101
|
+
if (running != null)
|
|
2102
|
+
this.#requestTurnCancel(running);
|
|
2103
|
+
return true;
|
|
2104
|
+
}
|
|
2105
|
+
default:
|
|
2106
|
+
return true;
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* One human answer. `remember` stores the family the daemon offered for this exact call (an ask;
|
|
2111
|
+
* a soft-deny offers none). `widen` says yes to "Treat <folder> as part of this session?".
|
|
2112
|
+
* `persist` hides a refused MCP look-up. The daemon checks all three; a refusal here is a no-op.
|
|
2113
|
+
*/
|
|
2114
|
+
#answerAsk(allow, opts = {}) {
|
|
2115
|
+
const leaf = this.#askHead;
|
|
2116
|
+
if (leaf === null || leaf.humanApprove !== null)
|
|
2117
|
+
return;
|
|
2118
|
+
const comment = this.#coverDraft.draft.trim();
|
|
2119
|
+
const desk = this.client.sessionRoot;
|
|
2120
|
+
const ack = this.#ackPrompt;
|
|
2121
|
+
let combinedAckStore;
|
|
2122
|
+
if (ack !== null) {
|
|
2123
|
+
const picked = ack.choices[this.#ackIndex];
|
|
2124
|
+
const ackStore = !allow || comment !== ""
|
|
2125
|
+
? undefined
|
|
2126
|
+
: opts.ackChoice !== undefined
|
|
2127
|
+
? { scope: opts.ackChoice.scope, subject: opts.ackChoice.subject }
|
|
2128
|
+
: opts.remember !== undefined && picked !== undefined
|
|
2129
|
+
? { scope: opts.remember, subject: picked.subject }
|
|
2130
|
+
: undefined;
|
|
2131
|
+
const own = desk.findRunningTurn()?.approvalHead === leaf;
|
|
2132
|
+
const sessionId = own ? desk.sessionId : (this.#askPlexus?.root.sessionId ?? desk.sessionId);
|
|
2133
|
+
if (ack.variant === "ack") {
|
|
2134
|
+
// Allowed by policy; only the acknowledgement is asked.
|
|
2135
|
+
void this.client
|
|
2136
|
+
.request("ack/answer", {
|
|
2137
|
+
sessionId,
|
|
2138
|
+
jobId: leaf.uuid,
|
|
2139
|
+
ackId: leaf.uuid,
|
|
2140
|
+
accept: allow,
|
|
2141
|
+
...(ackStore === undefined ? {} : { store: ackStore }),
|
|
2142
|
+
...(comment === "" ? {} : { comment }),
|
|
2143
|
+
})
|
|
2144
|
+
.catch((error) => fail("ack/answer", error));
|
|
2145
|
+
this.#drainAsk = true;
|
|
2146
|
+
this.#askHold = true;
|
|
2147
|
+
this.#coverDraft = { draft: "", cursor: 0, mark: null };
|
|
2148
|
+
this.#stepCoverThrottle();
|
|
2149
|
+
return;
|
|
2150
|
+
}
|
|
2151
|
+
// A combined prompt: the human yes settles both; remembering the flag rides as `ackStore`.
|
|
2152
|
+
combinedAckStore = ackStore;
|
|
2153
|
+
}
|
|
2154
|
+
// A kernel-wide "never this tool" is a kernel RPC; everything on the session is the daemon's answer.
|
|
2155
|
+
if (opts.persist === "always" &&
|
|
2156
|
+
comment === "" &&
|
|
2157
|
+
!allow &&
|
|
2158
|
+
leaf instanceof MCPToolJob &&
|
|
2159
|
+
mcpReadFloorDenies(leaf.serverToolName))
|
|
2160
|
+
this.#persistGlobal(leaf, false);
|
|
2161
|
+
const subject = leaf.grantOptions[0]?.subject;
|
|
2162
|
+
const store = allow && comment === "" && opts.remember !== undefined && subject !== undefined
|
|
2163
|
+
? { scope: opts.remember, subject }
|
|
2164
|
+
: undefined;
|
|
2165
|
+
const own = desk.findRunningTurn()?.approvalHead === leaf;
|
|
2166
|
+
void this.client
|
|
2167
|
+
.request("ask/answer", {
|
|
2168
|
+
sessionId: own ? desk.sessionId : (this.#askPlexus?.root.sessionId ?? desk.sessionId),
|
|
2169
|
+
jobId: leaf.uuid,
|
|
2170
|
+
allow,
|
|
2171
|
+
...(comment === "" ? {} : { comment }),
|
|
2172
|
+
...(opts.widen === undefined || opts.widen === "" ? {} : { widen: opts.widen }),
|
|
2173
|
+
...(store === undefined ? {} : { store }),
|
|
2174
|
+
...(combinedAckStore === undefined ? {} : { ackStore: combinedAckStore }),
|
|
2175
|
+
...(opts.persist === undefined || allow ? {} : { persist: opts.persist }),
|
|
2176
|
+
})
|
|
2177
|
+
.catch((error) => fail("ask/answer", error));
|
|
2178
|
+
this.#drainAsk = true;
|
|
2179
|
+
this.#askHold = true;
|
|
2180
|
+
this.#coverDraft = { draft: "", cursor: 0, mark: null };
|
|
2181
|
+
this.#stepCoverThrottle();
|
|
2182
|
+
}
|
|
2183
|
+
#setResident(resident) {
|
|
2184
|
+
return this.client.request("resident/set", { resident }).catch((error) => fail("resident/set", error));
|
|
2185
|
+
}
|
|
2186
|
+
/** The daemon moves the row; a local shift would merge with its turn-close drain. */
|
|
2187
|
+
#queueMove(op, row) {
|
|
2188
|
+
if (row == null)
|
|
2189
|
+
return;
|
|
2190
|
+
this.#fire([new UiNode(op, "", [], "ok", "", undefined, [], [], [], op, { id: row.uuid })]);
|
|
2191
|
+
}
|
|
2192
|
+
/** Paint the cancel before the daemon stamps it; the turn's flag stays the daemon's to write. */
|
|
2193
|
+
#askCancel(turn) {
|
|
2194
|
+
runInAction(() => this.#cancelAsked.add(turn));
|
|
2195
|
+
this.#disposers.push(when(() => turn.cutOff || !turn.inLoop, () => runInAction(() => this.#cancelAsked.delete(turn))));
|
|
2196
|
+
}
|
|
2197
|
+
#requestTurnCancel(turn) {
|
|
2198
|
+
this.#askCancel(turn);
|
|
2199
|
+
this.#rewindGraceUntil = this.#now() + REWIND_GRACE_MS;
|
|
2200
|
+
this.#fire([
|
|
2201
|
+
new UiNode("turn/cancel", "", [], "ok", "", undefined, [], [], [], "turn/cancel", {
|
|
2202
|
+
turnId: turn.uuid,
|
|
2203
|
+
}),
|
|
2204
|
+
], true);
|
|
2205
|
+
}
|
|
2206
|
+
#handleEscapeUnwind(seat) {
|
|
2207
|
+
if (this.#oauthWaiting) {
|
|
2208
|
+
this.#cancelWaiting();
|
|
2209
|
+
return true;
|
|
2210
|
+
}
|
|
2211
|
+
if (this.#processing)
|
|
2212
|
+
return true;
|
|
2213
|
+
if (seat.input === "overlay" || seat.input === "auth" || this.#callback !== undefined) {
|
|
2214
|
+
this.#completeCallback({ kind: "cancel" });
|
|
2215
|
+
return true;
|
|
2216
|
+
}
|
|
2217
|
+
if (this.#focus !== undefined) {
|
|
2218
|
+
this.#focus = undefined;
|
|
2219
|
+
this.#resetSelection();
|
|
2220
|
+
this.escClearArmed = false;
|
|
2221
|
+
return true;
|
|
2222
|
+
}
|
|
2223
|
+
if (this.draft.draft.length > 0 && !this.#historyNav) {
|
|
2224
|
+
if (this.escClearArmed) {
|
|
2225
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2226
|
+
this.escClearArmed = false;
|
|
2227
|
+
this.#resetSelection();
|
|
2228
|
+
}
|
|
2229
|
+
else {
|
|
2230
|
+
this.escClearArmed = true;
|
|
2231
|
+
}
|
|
2232
|
+
return true;
|
|
2233
|
+
}
|
|
2234
|
+
// see omnibox-seat.ts, CHANGE ONLY.
|
|
2235
|
+
if (this.client.sessionRoot.promptQueue.length > 0 && !this.#drainAsk && !this.#askHold) {
|
|
2236
|
+
this.#queueMove("queue/retract-last", this.client.sessionRoot.promptQueue.at(-1));
|
|
2237
|
+
this.escClearArmed = false;
|
|
2238
|
+
return true;
|
|
2239
|
+
}
|
|
2240
|
+
const running = this.client.sessionRoot.findRunningTurn();
|
|
2241
|
+
if (running != null) {
|
|
2242
|
+
if (this.escClearArmed) {
|
|
2243
|
+
this.escClearArmed = false;
|
|
2244
|
+
this.#drainAsk = false;
|
|
2245
|
+
this.#askHold = false;
|
|
2246
|
+
this.#requestTurnCancel(running);
|
|
2247
|
+
}
|
|
2248
|
+
else {
|
|
2249
|
+
this.escClearArmed = true;
|
|
2250
|
+
}
|
|
2251
|
+
return true;
|
|
2252
|
+
}
|
|
2253
|
+
if (this.#historyNav) {
|
|
2254
|
+
this.#leaveHistory();
|
|
2255
|
+
this.escClearArmed = false;
|
|
2256
|
+
return true;
|
|
2257
|
+
}
|
|
2258
|
+
if (this.#rewindGraceActive()) {
|
|
2259
|
+
this.escClearArmed = false;
|
|
2260
|
+
return true;
|
|
2261
|
+
}
|
|
2262
|
+
if (this.#viewTurn() == null) {
|
|
2263
|
+
this.escClearArmed = false;
|
|
2264
|
+
return true;
|
|
2265
|
+
}
|
|
2266
|
+
if (this.escClearArmed) {
|
|
2267
|
+
this.escClearArmed = false;
|
|
2268
|
+
this.#enterHistory();
|
|
2269
|
+
}
|
|
2270
|
+
else {
|
|
2271
|
+
this.escClearArmed = true;
|
|
2272
|
+
}
|
|
2273
|
+
return true;
|
|
2274
|
+
}
|
|
2275
|
+
#rewindGraceActive() {
|
|
2276
|
+
if (this.client.sessionRoot.findRunningTurn() != null)
|
|
2277
|
+
return false;
|
|
2278
|
+
return this.#now() < this.#rewindGraceUntil;
|
|
2279
|
+
}
|
|
2280
|
+
#handleRewindArrows(event, chord) {
|
|
2281
|
+
if (this.#callback !== undefined)
|
|
2282
|
+
return false;
|
|
2283
|
+
if (chord || event.shift === true)
|
|
2284
|
+
return false;
|
|
2285
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown")
|
|
2286
|
+
return false;
|
|
2287
|
+
if (!this.#browsing())
|
|
2288
|
+
return false;
|
|
2289
|
+
if (this.client.sessionRoot.findRunningTurn() != null)
|
|
2290
|
+
return false;
|
|
2291
|
+
const view = this.#viewTurn();
|
|
2292
|
+
const target = event.key === "ArrowUp" ? previousPin(view) : view ? (this.#aheadOf(view)[0] ?? null) : null;
|
|
2293
|
+
if (target != null)
|
|
2294
|
+
this.#moveView(target);
|
|
2295
|
+
return true;
|
|
2296
|
+
}
|
|
2297
|
+
#hostRewind() {
|
|
2298
|
+
if (this.#remainder.trim() !== "") {
|
|
2299
|
+
void this.#showNotice("usage: /rewind");
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
const pin = previousPin(this.#viewTurn());
|
|
2303
|
+
if (pin == null) {
|
|
2304
|
+
void this.#showNotice("nothing to rewind");
|
|
2305
|
+
return;
|
|
2306
|
+
}
|
|
2307
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2308
|
+
this.#resetSelection();
|
|
2309
|
+
this.#moveView(pin);
|
|
2310
|
+
}
|
|
2311
|
+
#confirmHistory() {
|
|
2312
|
+
if (this.#rewindPending)
|
|
2313
|
+
return;
|
|
2314
|
+
const target = this.#viewTurn();
|
|
2315
|
+
if (target == null)
|
|
2316
|
+
return;
|
|
2317
|
+
if (target.visuals.length > 0) {
|
|
2318
|
+
void this.#showNotice("pictures on this turn can be edited in the web or mobile app");
|
|
2319
|
+
return;
|
|
2320
|
+
}
|
|
2321
|
+
const head = this.client.sessionRoot.head;
|
|
2322
|
+
const tip = resolvedTip(head, this.client.sessionRoot.tip);
|
|
2323
|
+
// The selected message is what the operator is about to resend, so it
|
|
2324
|
+
// leaves the tape. Head lands on the previous user message. The immediate
|
|
2325
|
+
// tail is often a promptless continue or compact, and the daemon refuses
|
|
2326
|
+
// those (`not-a-pin`). Nothing before the first message is a prefill.
|
|
2327
|
+
const before = previousPin(target);
|
|
2328
|
+
const ceiling = target === head && isAtTip(head, tip);
|
|
2329
|
+
if (before == null || (ceiling && target.prompt.trim() === "")) {
|
|
2330
|
+
// First message, or a promptless ceiling: there is no pin to cut to.
|
|
2331
|
+
// Prefilling "" and closing navigation lets the same Enter fall through
|
|
2332
|
+
// into `kind: "continue"`. A real first-message prompt is the resend.
|
|
2333
|
+
const prefill = ceiling && target.prompt.trim() === "" ? "" : target.prompt;
|
|
2334
|
+
this.#restoredDraft = prefill === "" ? null : { turnId: target.uuid, prompt: prefill };
|
|
2335
|
+
Object.assign(this.draft, { draft: prefill, cursor: prefill.length, mark: null });
|
|
2336
|
+
this.#resetSelection();
|
|
2337
|
+
this.#leaveHistory();
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
void this.#requestRewind(before.uuid, target.prompt);
|
|
2341
|
+
}
|
|
2342
|
+
async #requestRewind(turnId, draft) {
|
|
2343
|
+
if (this.#rewindPending)
|
|
2344
|
+
return;
|
|
2345
|
+
this.#rewindPending = true;
|
|
2346
|
+
try {
|
|
2347
|
+
const result = await this.client.request("turn/rewind", { turnId });
|
|
2348
|
+
if (typeof result === "object" &&
|
|
2349
|
+
result !== null &&
|
|
2350
|
+
"ok" in result &&
|
|
2351
|
+
result.ok === false) {
|
|
2352
|
+
await this.#showNotice("nothing to rewind");
|
|
2353
|
+
return;
|
|
2354
|
+
}
|
|
2355
|
+
runInAction(() => {
|
|
2356
|
+
this.#restoredDraft = draft === "" ? null : { turnId, prompt: draft };
|
|
2357
|
+
Object.assign(this.draft, { draft, cursor: draft.length, mark: null });
|
|
2358
|
+
this.#resetSelection();
|
|
2359
|
+
this.#leaveHistory();
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2362
|
+
catch (error) {
|
|
2363
|
+
await this.#showNotice(error instanceof Error ? error.message : String(error));
|
|
2364
|
+
}
|
|
2365
|
+
finally {
|
|
2366
|
+
this.#rewindPending = false;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
#hostNew() {
|
|
2370
|
+
const remainder = this.#remainder;
|
|
2371
|
+
const path = this.client.sessionRoot.path;
|
|
2372
|
+
// The turn is shared. Cancel only when this window is the last seat —
|
|
2373
|
+
// another open window is still watching the loop.
|
|
2374
|
+
const running = otherSessionSeatCount(this.client.kernelPlexus.awareness, this.client.sessionId) === 0
|
|
2375
|
+
? this.client.sessionRoot.findRunningTurn()
|
|
2376
|
+
: null;
|
|
2377
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2378
|
+
this.#resetSelection();
|
|
2379
|
+
if (this.#replaceSession === undefined)
|
|
2380
|
+
return;
|
|
2381
|
+
const fire = () => {
|
|
2382
|
+
this.#replaceSession?.({ path, ...(remainder === "" ? {} : { draft: remainder }) });
|
|
2383
|
+
};
|
|
2384
|
+
if (running == null) {
|
|
2385
|
+
fire();
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
this.#processing = true;
|
|
2389
|
+
this.#askCancel(running);
|
|
2390
|
+
void this.client
|
|
2391
|
+
.request("turn/cancel", { turnId: running.uuid })
|
|
2392
|
+
.catch((error) => fail("turn/cancel", error))
|
|
2393
|
+
.finally(() => {
|
|
2394
|
+
this.#processing = false;
|
|
2395
|
+
fire();
|
|
2396
|
+
});
|
|
2397
|
+
}
|
|
2398
|
+
#persistGlobal(leaf, allow) {
|
|
2399
|
+
const method = allow ? "connect/always-allow" : "connect/exclude-tool";
|
|
2400
|
+
void this.client.request(method, { id: leaf.connectionKey, tool: leaf.serverToolName }).catch((error) => {
|
|
2401
|
+
fail(method, error);
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
#handleHotkey(event) {
|
|
2405
|
+
const seat = this.#omnibox;
|
|
2406
|
+
const rows = this.#pickerRows;
|
|
2407
|
+
const i = this.#selectedIndex;
|
|
2408
|
+
const selected = rows?.[i];
|
|
2409
|
+
const chord = event.ctrl === true || event.meta === true || event.alt === true;
|
|
2410
|
+
if (this.#handleAgentsChord(event, seat))
|
|
2411
|
+
return true;
|
|
2412
|
+
if (event.key === "Tab" && event.shift === true && !chord) {
|
|
2413
|
+
const ids = PERMISSION_MODES;
|
|
2414
|
+
const current = this.#askedPolicy ?? this.client.sessionRoot.permissionMode;
|
|
2415
|
+
const next = ids[(ids.indexOf(current) + 1) % ids.length];
|
|
2416
|
+
// The daemon writes the mode; cycle from what was asked until the replica shows it.
|
|
2417
|
+
this.#askedPolicy = next;
|
|
2418
|
+
void this.client
|
|
2419
|
+
.request("policy/set", { policy: next })
|
|
2420
|
+
.catch((error) => {
|
|
2421
|
+
fail("policy/set", error);
|
|
2422
|
+
})
|
|
2423
|
+
.finally(() => {
|
|
2424
|
+
if (this.#askedPolicy === next)
|
|
2425
|
+
this.#askedPolicy = null;
|
|
2426
|
+
});
|
|
2427
|
+
return true;
|
|
2428
|
+
}
|
|
2429
|
+
if (this.#browsing() &&
|
|
2430
|
+
this.#callback === undefined &&
|
|
2431
|
+
!chord &&
|
|
2432
|
+
event.shift !== true &&
|
|
2433
|
+
(event.key === "Enter" || event.key === "Escape")) {
|
|
2434
|
+
if (event.key === "Escape") {
|
|
2435
|
+
if (!this.#rewindPending)
|
|
2436
|
+
this.#leaveHistory();
|
|
2437
|
+
return true;
|
|
2438
|
+
}
|
|
2439
|
+
this.#confirmHistory();
|
|
2440
|
+
return true;
|
|
2441
|
+
}
|
|
2442
|
+
if (this.#historyHidesOmnibox && !chord && event.shift !== true && this.#handleRewindArrows(event, chord))
|
|
2443
|
+
return true;
|
|
2444
|
+
if (event.key === "Escape" && !chord) {
|
|
2445
|
+
const target = this.#askIsolated ? this.#coverDraft : this.draft;
|
|
2446
|
+
if (target.mark !== null && target.mark !== target.cursor) {
|
|
2447
|
+
Object.assign(target, { draft: target.draft, cursor: target.cursor, mark: null });
|
|
2448
|
+
return true;
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
const painted = this.#paintComposerFace().hotkeys;
|
|
2452
|
+
const hit = painted?.find((hotkey) => hotkey.event !== undefined && eventMatchesChord(event, hotkey.key));
|
|
2453
|
+
if (hit?.event !== undefined) {
|
|
2454
|
+
if (seat.askChords === "inert")
|
|
2455
|
+
return true;
|
|
2456
|
+
// see omnibox-seat.ts, CHANGE ONLY.
|
|
2457
|
+
if ((this.#drainAsk || this.#askHold) && seat.askChords === "off" && event.key === "Enter") {
|
|
2458
|
+
return true;
|
|
2459
|
+
}
|
|
2460
|
+
return this.#fireHotkeyEvent(hit.event);
|
|
2461
|
+
}
|
|
2462
|
+
if (seat.askChords !== "off" && (event.key === "Enter" || event.key === "Escape")) {
|
|
2463
|
+
return true;
|
|
2464
|
+
}
|
|
2465
|
+
if ((this.#drainAsk || this.#askHold) && event.key === "Enter") {
|
|
2466
|
+
return true;
|
|
2467
|
+
}
|
|
2468
|
+
if (seat.input === "ask")
|
|
2469
|
+
return false;
|
|
2470
|
+
if (event.key === "Enter" && !chord && event.shift !== true) {
|
|
2471
|
+
if (this.#processing || this.#oauthWaiting)
|
|
2472
|
+
return true;
|
|
2473
|
+
if (selected !== undefined) {
|
|
2474
|
+
this.#pick(selected, true);
|
|
2475
|
+
return true;
|
|
2476
|
+
}
|
|
2477
|
+
if (seat.input === "overlay" || this.#callback !== undefined) {
|
|
2478
|
+
this.#fire(this.#parentNode?.action, true);
|
|
2479
|
+
return true;
|
|
2480
|
+
}
|
|
2481
|
+
if (this.#historyNav) {
|
|
2482
|
+
this.#confirmHistory();
|
|
2483
|
+
return true;
|
|
2484
|
+
}
|
|
2485
|
+
const verb = slashVerb(this.draft.draft);
|
|
2486
|
+
if (verb === "compact") {
|
|
2487
|
+
const focus = this.#remainder;
|
|
2488
|
+
this.#fire([new UiNode("compact", "", [], "ok", "", undefined, [], [], [], "compact", focus === "" ? {} : { focus })], true);
|
|
2489
|
+
return true;
|
|
2490
|
+
}
|
|
2491
|
+
if (verb === "rename") {
|
|
2492
|
+
const rest = this.#remainder;
|
|
2493
|
+
this.#fire([
|
|
2494
|
+
new UiNode("rename", "", [], "ok", "", undefined, [], [], [], "rename", {
|
|
2495
|
+
title: rest === "--auto" ? "" : rest,
|
|
2496
|
+
}),
|
|
2497
|
+
], true);
|
|
2498
|
+
return true;
|
|
2499
|
+
}
|
|
2500
|
+
if (verb !== null && isHostVerb(verb) && verb !== "compact" && verb !== "rename") {
|
|
2501
|
+
this.#invokeHostVerb(verb);
|
|
2502
|
+
return true;
|
|
2503
|
+
}
|
|
2504
|
+
if (verb !== null && this.#skillVerb(verb)) {
|
|
2505
|
+
this.#submitTurn(seat.input === "queue" ? "queue" : undefined);
|
|
2506
|
+
return true;
|
|
2507
|
+
}
|
|
2508
|
+
if (seat.input === "slash" || verb !== null) {
|
|
2509
|
+
this.#fire(this.#parentNode?.action, true);
|
|
2510
|
+
return true;
|
|
2511
|
+
}
|
|
2512
|
+
if (seat.input === "queue") {
|
|
2513
|
+
if (this.#submitTurn("queue"))
|
|
2514
|
+
return true;
|
|
2515
|
+
this.#queueMove("queue/steer-first", this.client.sessionRoot.promptQueue[0]);
|
|
2516
|
+
return true;
|
|
2517
|
+
}
|
|
2518
|
+
if (this.#submitTurn())
|
|
2519
|
+
return true;
|
|
2520
|
+
const head = this.client.sessionRoot.head;
|
|
2521
|
+
if (!isAtTip(head, this.client.sessionRoot.tip))
|
|
2522
|
+
return true;
|
|
2523
|
+
if (head instanceof SessionTurn && head.lastTurnIncomplete) {
|
|
2524
|
+
this.#fire([
|
|
2525
|
+
new UiNode("turn", "", [], "ok", "", undefined, [], [], [], "turn", {
|
|
2526
|
+
prompt: "",
|
|
2527
|
+
kind: "continue",
|
|
2528
|
+
}),
|
|
2529
|
+
], true);
|
|
2530
|
+
return true;
|
|
2531
|
+
}
|
|
2532
|
+
this.#fire(this.#parentNode?.action, true);
|
|
2533
|
+
return true;
|
|
2534
|
+
}
|
|
2535
|
+
if (event.key === "Escape" && !chord) {
|
|
2536
|
+
return this.#handleEscapeUnwind(seat);
|
|
2537
|
+
}
|
|
2538
|
+
if (rows !== undefined && rows.length > 0 && selected !== undefined && !chord && event.shift !== true) {
|
|
2539
|
+
if (event.key === "ArrowUp") {
|
|
2540
|
+
this.focusAt(i - 1);
|
|
2541
|
+
return true;
|
|
2542
|
+
}
|
|
2543
|
+
if (event.key === "ArrowDown") {
|
|
2544
|
+
this.focusAt(i + 1);
|
|
2545
|
+
return true;
|
|
2546
|
+
}
|
|
2547
|
+
if (event.key === "Tab") {
|
|
2548
|
+
this.#pick(selected, false);
|
|
2549
|
+
return true;
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
if (this.#handleRewindArrows(event, chord))
|
|
2553
|
+
return true;
|
|
2554
|
+
const alt = selected?.alternateActions.find((item) => eventMatchesChord(event, item.hotkey ?? "")) ??
|
|
2555
|
+
this.#parentNode?.alternateActions.find((item) => eventMatchesChord(event, item.hotkey ?? ""));
|
|
2556
|
+
if (alt !== undefined) {
|
|
2557
|
+
this.#fire([alt]);
|
|
2558
|
+
return true;
|
|
2559
|
+
}
|
|
2560
|
+
return false;
|
|
2561
|
+
}
|
|
2562
|
+
#pick(node, invoke) {
|
|
2563
|
+
if (this.#atCatalog || node.choices.length > 0) {
|
|
2564
|
+
if (invoke && this.#atCatalog) {
|
|
2565
|
+
const verb = node.name.replace(/^\//, "");
|
|
2566
|
+
if (isHostVerb(verb) && verb !== "compact" && verb !== "rename") {
|
|
2567
|
+
this.#completeName(node);
|
|
2568
|
+
this.#resetSelection();
|
|
2569
|
+
this.#invokeHostVerb(verb);
|
|
2570
|
+
return;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
if (!this.#atCatalog)
|
|
2574
|
+
this.#focus = node;
|
|
2575
|
+
this.#completeName(node);
|
|
2576
|
+
this.#resetSelection();
|
|
2577
|
+
return;
|
|
2578
|
+
}
|
|
2579
|
+
this.#completeName(node);
|
|
2580
|
+
if (invoke && node.action.length > 0)
|
|
2581
|
+
this.#fire(node.action, true);
|
|
2582
|
+
}
|
|
2583
|
+
/** Catalog Enter on a host verb that has no CommandSpec body. */
|
|
2584
|
+
#invokeHostVerb(verb) {
|
|
2585
|
+
if (verb === "quit") {
|
|
2586
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2587
|
+
this.#resetSelection();
|
|
2588
|
+
this.#quit?.();
|
|
2589
|
+
return;
|
|
2590
|
+
}
|
|
2591
|
+
if (verb === "new") {
|
|
2592
|
+
this.#hostNew();
|
|
2593
|
+
return;
|
|
2594
|
+
}
|
|
2595
|
+
if (verb === "agentic") {
|
|
2596
|
+
const rest = this.#remainder.trim().toLowerCase();
|
|
2597
|
+
const flag = rest === "true" ? true : rest === "false" ? false : null;
|
|
2598
|
+
if (flag === null)
|
|
2599
|
+
return;
|
|
2600
|
+
void this.#setResident(flag);
|
|
2601
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2602
|
+
this.#resetSelection();
|
|
2603
|
+
return;
|
|
2604
|
+
}
|
|
2605
|
+
if (verb === "background") {
|
|
2606
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2607
|
+
this.#resetSelection();
|
|
2608
|
+
// Leave only after the daemon holds the bit; a replica write could die with this process.
|
|
2609
|
+
void this.#setResident(true).finally(() => this.#quit?.());
|
|
2610
|
+
return;
|
|
2611
|
+
}
|
|
2612
|
+
if (verb === "rewind" || verb === "undo") {
|
|
2613
|
+
this.#hostRewind();
|
|
2614
|
+
return;
|
|
2615
|
+
}
|
|
2616
|
+
if (verb === "permissions") {
|
|
2617
|
+
if (this.#callback !== undefined)
|
|
2618
|
+
return;
|
|
2619
|
+
const probe = this.#remainder.trim();
|
|
2620
|
+
Object.assign(this.draft, { draft: "", cursor: 0, mark: null });
|
|
2621
|
+
this.#resetSelection();
|
|
2622
|
+
void this.#showPermissions(probe);
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
#completeName(node) {
|
|
2626
|
+
if (this.#atCatalog) {
|
|
2627
|
+
const draft = this.draft.draft;
|
|
2628
|
+
const nl = draft.indexOf("\n");
|
|
2629
|
+
const first = nl === -1 ? draft : draft.slice(0, nl);
|
|
2630
|
+
const rest = nl === -1 ? "" : draft.slice(nl);
|
|
2631
|
+
const lead = first.match(/^\s*/)?.[0] ?? "";
|
|
2632
|
+
const after = first.slice(lead.length);
|
|
2633
|
+
if (!after.startsWith("/")) {
|
|
2634
|
+
Object.assign(this.draft, { draft, cursor: draft.length, mark: null });
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
const sp = after.search(/\s/);
|
|
2638
|
+
const args = sp < 0 ? " " : after.slice(sp);
|
|
2639
|
+
const verb = node.name.replace(/^\//, "");
|
|
2640
|
+
const nextFirst = `${lead}/${verb}${args}`;
|
|
2641
|
+
Object.assign(this.draft, {
|
|
2642
|
+
draft: `${nextFirst}${rest}`,
|
|
2643
|
+
cursor: nextFirst.length,
|
|
2644
|
+
mark: null,
|
|
2645
|
+
});
|
|
2646
|
+
return;
|
|
2647
|
+
}
|
|
2648
|
+
const verb = slashVerb(this.draft.draft);
|
|
2649
|
+
if (verb === null)
|
|
2650
|
+
return;
|
|
2651
|
+
const draft = this.draft.draft;
|
|
2652
|
+
const nl = draft.indexOf("\n");
|
|
2653
|
+
const rest = nl === -1 ? "" : draft.slice(nl);
|
|
2654
|
+
const lead = (nl === -1 ? draft : draft.slice(0, nl)).match(/^\s*/)?.[0] ?? "";
|
|
2655
|
+
const nextFirst = `${lead}/${verb} ${node.name}`;
|
|
2656
|
+
Object.assign(this.draft, {
|
|
2657
|
+
draft: `${nextFirst}${rest}`,
|
|
2658
|
+
cursor: nextFirst.length,
|
|
2659
|
+
mark: null,
|
|
2660
|
+
});
|
|
2661
|
+
}
|
|
2662
|
+
/**
|
|
2663
|
+
* What the open picker looks at: the connections it lists, and the drivers
|
|
2664
|
+
* whose adopt doors it lists (so a driver can keep its offers fresh).
|
|
2665
|
+
*/
|
|
2666
|
+
get #attentionSubjects() { return _private_get_attentionSubjects_descriptor.get.call(this); }
|
|
2667
|
+
[(_draft_decorators = [observable], _submission_decorators = [observable], _selectedCommandKey_decorators = [observable], _scrollOffset_decorators = [observable], _escClearArmed_decorators = [observable], _cols_decorators = [observable], _rows_decorators = [observable], _private_busy_decorators = [observable], _private_callback_decorators = [observable], _private_focus_decorators = [observable], _private_oauthWaiting_decorators = [observable], _private_processing_decorators = [observable], _private_coverDraft_decorators = [observable], _private_coverThrottle_decorators = [(_a = observable).ref.bind(_a)], _private_coverConfirmLive_decorators = [observable], _private_ackPick_decorators = [observable], _private_askHold_decorators = [observable], _private_drainAsk_decorators = [observable], _private_agentsOpen_decorators = [observable], _private_agentsFocus_decorators = [observable], _private_agentsHover_decorators = [observable], _private_agentsScroll_decorators = [observable], _private_agentsPreview_decorators = [observable], _private_peekPlexus_decorators = [(_b = observable).ref.bind(_b)], _private_askPlexus_decorators = [(_c = observable).ref.bind(_c)], _private_viewPin_decorators = [(_d = observable).ref.bind(_d)], _private_historyNav_decorators = [observable], _private_restoredDraft_decorators = [(_e = observable).ref.bind(_e)], _private_get_agentDrawerRows_decorators = [computed], _private_get_sessionTitle_decorators = [computed], _private_get_isHeadAtTip_decorators = [computed], _private_get_askHead_decorators = [computed], _private_get_ackPrompt_decorators = [computed], _private_get_coverAskAgentSpec_decorators = [computed], _private_get_askHome_decorators = [computed], _private_get_readWiden_decorators = [computed], _private_get_omniboxValue_decorators = [computed], _private_get_contextRail_decorators = [computed({ equals: comparer.structural })], _private_get_omnibox_decorators = [computed], _private_get_askIsolated_decorators = [computed], _private_get_admissionDeckText_decorators = [computed], _private_get_waitChrome_decorators = [(_f = computed).struct.bind(_f)], _private_get_commands_decorators = [computed], _private_get_parentNode_decorators = [computed], _private_get_inCommand_decorators = [computed], _private_get_atCatalog_decorators = [computed], _private_get_pickerRows_decorators = [computed], _private_get_catalogNodes_decorators = [computed], _private_get_commandChoices_decorators = [computed], _get_effectiveKey_decorators = [computed], _private_get_commandAction_decorators = [computed], _private_get_commandSurface_decorators = [computed({ keepAlive: true })], _private_get_selectedIndex_decorators = [computed], _focusAt_decorators = [action], _handle_decorators = [action], _private_get_activeConnection_decorators = [computed], _private_get_quotaWindows_decorators = [computed({ equals: comparer.structural })], _private_get_statusItems_decorators = [computed({ equals: comparer.structural })], _private_stepCoverThrottle_decorators = [action], _private_get_attentionSubjects_decorators = [computed], Symbol.dispose)]() {
|
|
2668
|
+
if (this.#coverTimer !== undefined) {
|
|
2669
|
+
clearTimeout(this.#coverTimer);
|
|
2670
|
+
this.#coverTimer = undefined;
|
|
2671
|
+
}
|
|
2672
|
+
this.client.releasePeek();
|
|
2673
|
+
this.client.releaseAsk();
|
|
2674
|
+
this.client.setComputedAttention(() => []);
|
|
2675
|
+
this.client.setComputedAttentionFocus(() => null);
|
|
2676
|
+
this.#cancelWaiting();
|
|
2677
|
+
this.#completeCallback({ kind: "cancel" });
|
|
2678
|
+
for (const dispose of this.#disposers.splice(0))
|
|
2679
|
+
dispose();
|
|
2680
|
+
this.#paint[Symbol.dispose]();
|
|
2681
|
+
}
|
|
2682
|
+
};
|
|
2683
|
+
})();
|
|
2684
|
+
export { Tea };
|
|
2685
|
+
function primaryDisplayName(node) {
|
|
2686
|
+
const first = node.action[0];
|
|
2687
|
+
if (first === undefined)
|
|
2688
|
+
return undefined;
|
|
2689
|
+
const label = first.name.trim();
|
|
2690
|
+
if (label !== "" && label !== (first.op ?? ""))
|
|
2691
|
+
return label;
|
|
2692
|
+
return "select";
|
|
2693
|
+
}
|
|
2694
|
+
function isActivatable(node, catalog) {
|
|
2695
|
+
return catalog || node.choices.length > 0 || node.action.length > 0;
|
|
2696
|
+
}
|
|
2697
|
+
function pickerActions(node, catalog = false) {
|
|
2698
|
+
const first = node.action[0];
|
|
2699
|
+
const head = isActivatable(node, catalog)
|
|
2700
|
+
? [
|
|
2701
|
+
{
|
|
2702
|
+
name: first?.op ?? first?.name ?? node.name,
|
|
2703
|
+
displayName: primaryDisplayName(node) ?? "select",
|
|
2704
|
+
hotkey: "Enter",
|
|
2705
|
+
},
|
|
2706
|
+
]
|
|
2707
|
+
: [];
|
|
2708
|
+
const alts = node.alternateActions.map((alt) => ({
|
|
2709
|
+
name: alt.op ?? alt.name,
|
|
2710
|
+
displayName: alt.name,
|
|
2711
|
+
hotkey: alt.hotkey,
|
|
2712
|
+
}));
|
|
2713
|
+
return [...head, ...alts];
|
|
2714
|
+
}
|
|
2715
|
+
function urlFrom(node) {
|
|
2716
|
+
for (const item of [node, ...node.action, ...node.alternateActions]) {
|
|
2717
|
+
const url = item.params.url;
|
|
2718
|
+
if (typeof url === "string" && /^https?:\/\//i.test(url.trim()))
|
|
2719
|
+
return url.trim();
|
|
2720
|
+
}
|
|
2721
|
+
return undefined;
|
|
2722
|
+
}
|
|
2723
|
+
/** `{ ok: false, error }` is how a host verb such as `plugin/method` refuses without throwing. */
|
|
2724
|
+
function refusalOf(result) {
|
|
2725
|
+
if (result === null || typeof result !== "object")
|
|
2726
|
+
return undefined;
|
|
2727
|
+
const record = result;
|
|
2728
|
+
return record.ok === false && typeof record.error === "string" ? record.error : undefined;
|
|
2729
|
+
}
|
|
2730
|
+
/** A scheme-built param is a bare string, a boxed `{ __string__ }`, or a spec with an `id`. */
|
|
2731
|
+
function paramString(value) {
|
|
2732
|
+
if (typeof value === "string")
|
|
2733
|
+
return value;
|
|
2734
|
+
if (typeof value !== "object" || value === null)
|
|
2735
|
+
return "";
|
|
2736
|
+
const rec = value;
|
|
2737
|
+
if (typeof rec.__string__ === "string")
|
|
2738
|
+
return rec.__string__;
|
|
2739
|
+
return typeof rec.id === "string" ? rec.id : "";
|
|
2740
|
+
}
|
|
2741
|
+
function fillParams(params, remainder) {
|
|
2742
|
+
if (remainder === "")
|
|
2743
|
+
return params;
|
|
2744
|
+
let next = params;
|
|
2745
|
+
if (Object.prototype.hasOwnProperty.call(params, "input") && (params.input === undefined || params.input === "")) {
|
|
2746
|
+
next = { ...next, input: remainder };
|
|
2747
|
+
}
|
|
2748
|
+
if (Object.prototype.hasOwnProperty.call(params, "value") && params.value === "") {
|
|
2749
|
+
next = { ...next, value: remainder };
|
|
2750
|
+
}
|
|
2751
|
+
return next;
|
|
2752
|
+
}
|
|
2753
|
+
function hasInputHole(node) {
|
|
2754
|
+
const walk = [node, ...node.action, ...node.alternateActions, ...node.choices];
|
|
2755
|
+
return walk.some((item) => item.op != null &&
|
|
2756
|
+
Object.prototype.hasOwnProperty.call(item.params, "input") &&
|
|
2757
|
+
(item.params.input === undefined || item.params.input === ""));
|
|
2758
|
+
}
|
|
2759
|
+
/** Text parts join in order. Picture bytes are standard base64 beside the prompt. */
|
|
2760
|
+
function promptFromParts(parts) {
|
|
2761
|
+
const visuals = [];
|
|
2762
|
+
let text = "";
|
|
2763
|
+
for (const part of parts) {
|
|
2764
|
+
const image = part.image;
|
|
2765
|
+
if (image !== undefined) {
|
|
2766
|
+
visuals.push({ mime: image.mime, bytesBase64: Buffer.from(image.bytes).toString("base64") });
|
|
2767
|
+
}
|
|
2768
|
+
if (typeof part.text === "string")
|
|
2769
|
+
text += part.text;
|
|
2770
|
+
}
|
|
2771
|
+
return { text, visuals };
|
|
2772
|
+
}
|
|
2773
|
+
function jsonParams(params) {
|
|
2774
|
+
try {
|
|
2775
|
+
return JSON.parse(JSON.stringify(params, (_key, value) => {
|
|
2776
|
+
if (typeof value === "boolean")
|
|
2777
|
+
return value;
|
|
2778
|
+
if (typeof value !== "object" || value === null)
|
|
2779
|
+
return value;
|
|
2780
|
+
const rec = value;
|
|
2781
|
+
if (typeof rec.__boolean__ === "boolean")
|
|
2782
|
+
return rec.__boolean__;
|
|
2783
|
+
if (typeof rec.__string__ === "string")
|
|
2784
|
+
return rec.__string__;
|
|
2785
|
+
if (typeof rec.id === "string" && rec.id.length > 0 && "configuration" in rec)
|
|
2786
|
+
return rec.id;
|
|
2787
|
+
if (typeof rec.name === "string" && "importPath" in rec)
|
|
2788
|
+
return rec.name;
|
|
2789
|
+
return value;
|
|
2790
|
+
}));
|
|
2791
|
+
}
|
|
2792
|
+
catch {
|
|
2793
|
+
return {};
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
function nonempty(value) {
|
|
2797
|
+
return (value ?? "").trim();
|
|
2798
|
+
}
|
|
2799
|
+
/** 401 or 403 as a status, not a digit inside a longer number. Same test as connect.scm `auth-line?`. */
|
|
2800
|
+
function authStatusLine(line) {
|
|
2801
|
+
return /(?:^|\D)40[13](?:\D|$)/.test(line);
|
|
2802
|
+
}
|
|
2803
|
+
function askStack(leaf, rows, bots = {}) {
|
|
2804
|
+
if (leaf instanceof CallJob || leaf instanceof AgentMessageJob) {
|
|
2805
|
+
const description = agentRecipeDescription(bots, agentSpecKey(leaf));
|
|
2806
|
+
let body = nonempty(agentAskStackedBody(agentCoverPrompt(leaf), description));
|
|
2807
|
+
if (body === "" && leaf instanceof CallJob) {
|
|
2808
|
+
const args = { ...(leaf.args ?? {}) };
|
|
2809
|
+
delete args.spec;
|
|
2810
|
+
body = nonempty(formatMcpArgs(args));
|
|
2811
|
+
}
|
|
2812
|
+
if (body === "")
|
|
2813
|
+
return {};
|
|
2814
|
+
return { stackedBody: body, stackedViewport: mcpConfirmViewport(rows) };
|
|
2815
|
+
}
|
|
2816
|
+
if (leaf instanceof MCPToolJob) {
|
|
2817
|
+
const body = nonempty(formatMcpArgs(leaf.args));
|
|
2818
|
+
if (body === "")
|
|
2819
|
+
return {};
|
|
2820
|
+
return { stackedBody: body, stackedViewport: mcpConfirmViewport(rows) };
|
|
2821
|
+
}
|
|
2822
|
+
const command = shellAskCommand(leaf);
|
|
2823
|
+
if (command === undefined)
|
|
2824
|
+
return {};
|
|
2825
|
+
return {
|
|
2826
|
+
stackedBody: command,
|
|
2827
|
+
stackedViewport: mcpConfirmViewport(rows),
|
|
2828
|
+
stackedLang: "bash",
|
|
2829
|
+
};
|
|
2830
|
+
}
|
|
2831
|
+
function policyChip(session) {
|
|
2832
|
+
if (session.permissionMode === "yolo")
|
|
2833
|
+
return { text: "always approve", role: "attention" };
|
|
2834
|
+
if (session.permissionMode !== "auto")
|
|
2835
|
+
return null;
|
|
2836
|
+
return { text: "auto", role: "auto" };
|
|
2837
|
+
}
|
|
2838
|
+
/**
|
|
2839
|
+
* The line over an approval: what kind of question this is and why the floor asked, the judge's
|
|
2840
|
+
* reason when it weighed in, what the call is, and the folder question when one is suggested.
|
|
2841
|
+
*/
|
|
2842
|
+
export function askAnnotation(leaf, asked, widen, ack) {
|
|
2843
|
+
// An allowed call that only waits for an acknowledgement is not an ask: its own header leads.
|
|
2844
|
+
if (ack?.variant === "ack") {
|
|
2845
|
+
return [ackAnnotation(ack), asked].filter((part) => part !== undefined && part !== "").join(" · ");
|
|
2846
|
+
}
|
|
2847
|
+
const tier = leaf.policyResult === "deny" ? "Soft-deny" : "Ask";
|
|
2848
|
+
const why = leaf.policyClasses.map((id) => CLASSES[id].label).join(", ");
|
|
2849
|
+
const parts = [
|
|
2850
|
+
why === "" ? tier : `${tier} · ${why}`,
|
|
2851
|
+
leaf.policyResult === "deny" ? "licensed every time, nothing is remembered" : undefined,
|
|
2852
|
+
leaf.classifierResult !== null && leaf.judgeReason ? `Judge: ${leaf.judgeReason}` : undefined,
|
|
2853
|
+
ack === undefined ? undefined : ackAnnotation(ack),
|
|
2854
|
+
asked,
|
|
2855
|
+
widen === undefined ? undefined : `Treat ${widen.label} as part of this session?`,
|
|
2856
|
+
].filter((part) => part !== undefined && part !== "");
|
|
2857
|
+
return parts.length === 0 ? undefined : parts.join(" · ");
|
|
2858
|
+
}
|
|
2859
|
+
function catalogContextLimit(connection, model) {
|
|
2860
|
+
const windows = connection?.live?.windows;
|
|
2861
|
+
if (typeof windows !== "object" || windows === null)
|
|
2862
|
+
return 0;
|
|
2863
|
+
const id = (model ?? "").trim();
|
|
2864
|
+
const raw = id === "" ? undefined : windows[id];
|
|
2865
|
+
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : 0;
|
|
2866
|
+
}
|
|
2867
|
+
function quotaWindowsOf(connection) {
|
|
2868
|
+
const account = connection?.live?.account;
|
|
2869
|
+
if (typeof account !== "object" || account === null)
|
|
2870
|
+
return undefined;
|
|
2871
|
+
const detail = account.balanceDetail;
|
|
2872
|
+
if (typeof detail !== "object" || detail === null)
|
|
2873
|
+
return undefined;
|
|
2874
|
+
const rows = detail.windows;
|
|
2875
|
+
if (!Array.isArray(rows))
|
|
2876
|
+
return undefined;
|
|
2877
|
+
const out = [];
|
|
2878
|
+
for (const row of rows) {
|
|
2879
|
+
if (typeof row !== "object" || row === null)
|
|
2880
|
+
continue;
|
|
2881
|
+
const rec = row;
|
|
2882
|
+
const remaining = numberOf(rec.remainingPercent);
|
|
2883
|
+
if (remaining === undefined)
|
|
2884
|
+
continue;
|
|
2885
|
+
const remainingPercent = Math.round(Math.min(100, Math.max(0, remaining)));
|
|
2886
|
+
const resetAtRaw = numberOf(rec.resetAt);
|
|
2887
|
+
const resetAt = resetAtRaw === undefined ? undefined : Math.trunc(resetAtRaw);
|
|
2888
|
+
out.push(resetAt === undefined ? { remainingPercent } : { remainingPercent, resetAt });
|
|
2889
|
+
}
|
|
2890
|
+
return out.length > 0 ? out : undefined;
|
|
2891
|
+
}
|
|
2892
|
+
function numberOf(value) {
|
|
2893
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
2894
|
+
return value;
|
|
2895
|
+
if (typeof value !== "string")
|
|
2896
|
+
return undefined;
|
|
2897
|
+
const n = Number(value.trim());
|
|
2898
|
+
return Number.isFinite(n) ? n : undefined;
|
|
2899
|
+
}
|
|
2900
|
+
function askLeafId(leaf) {
|
|
2901
|
+
if (leaf === null)
|
|
2902
|
+
return null;
|
|
2903
|
+
if (leaf instanceof ToolCallJob && leaf.toolCallId !== "")
|
|
2904
|
+
return leaf.toolCallId;
|
|
2905
|
+
if (leaf instanceof ToolCallJob && leaf.name !== "")
|
|
2906
|
+
return leaf.name;
|
|
2907
|
+
return "ask";
|
|
2908
|
+
}
|
|
2909
|
+
function agentTapeGlance(job, kernel, parentModel) {
|
|
2910
|
+
const id = job.workerSessionId.trim();
|
|
2911
|
+
const glance = id === "" ? undefined : kernel.sessions[id];
|
|
2912
|
+
const recap = (glance?.status ?? "").replaceAll(/\s+/g, " ").trim();
|
|
2913
|
+
const live = !job.completed || glance?.midMotion === true;
|
|
2914
|
+
const status = recap === "" ? (glance?.asking === true ? "blocked" : live ? "active" : "") : recap;
|
|
2915
|
+
const model = (glance?.model.trim() || parentModel?.trim() || "").trim();
|
|
2916
|
+
return { status, model };
|
|
2917
|
+
}
|
|
2918
|
+
function tapeSpine(head) {
|
|
2919
|
+
const spine = [];
|
|
2920
|
+
const seen = new Set();
|
|
2921
|
+
let cell = head;
|
|
2922
|
+
while (cell !== null && !seen.has(cell)) {
|
|
2923
|
+
seen.add(cell);
|
|
2924
|
+
if (cell instanceof SessionTurn)
|
|
2925
|
+
spine.push(cell);
|
|
2926
|
+
cell = cell.turnTail;
|
|
2927
|
+
}
|
|
2928
|
+
spine.reverse();
|
|
2929
|
+
return spine;
|
|
2930
|
+
}
|
|
2931
|
+
function slashVerb(draft) {
|
|
2932
|
+
const token = (draft.split("\n")[0] ?? "").trim().split(/\s/)[0] ?? "";
|
|
2933
|
+
if (!token.startsWith("/") || token.length < 2)
|
|
2934
|
+
return null;
|
|
2935
|
+
return token.slice(1);
|
|
2936
|
+
}
|
|
2937
|
+
function isRetrying(turn, now) {
|
|
2938
|
+
if (turn == null)
|
|
2939
|
+
return false;
|
|
2940
|
+
const chunks = reactChunks(turn);
|
|
2941
|
+
for (let i = chunks.length - 1; i >= 0; i -= 1) {
|
|
2942
|
+
const pew = tapeCompletion(chunks[i]);
|
|
2943
|
+
if (pew == null)
|
|
2944
|
+
continue;
|
|
2945
|
+
if (pew.outcome != null)
|
|
2946
|
+
return false;
|
|
2947
|
+
const retryUntilMs = pew.report?.retryUntilMs;
|
|
2948
|
+
return typeof retryUntilMs === "number" && retryUntilMs > now;
|
|
2949
|
+
}
|
|
2950
|
+
return false;
|
|
2951
|
+
}
|
|
2952
|
+
//# sourceMappingURL=tea.js.map
|