open-multi-agent-kit 0.96.2 → 0.97.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/CHANGELOG.md +16 -0
- package/README.md +4 -2
- package/dist/core/agent-session.d.ts +9 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +84 -7
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/attachment-store.d.ts +39 -0
- package/dist/core/attachment-store.d.ts.map +1 -0
- package/dist/core/attachment-store.js +81 -0
- package/dist/core/attachment-store.js.map +1 -0
- package/dist/core/command-safety.d.ts +8 -0
- package/dist/core/command-safety.d.ts.map +1 -1
- package/dist/core/command-safety.js +140 -14
- package/dist/core/command-safety.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +6 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +35 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context-budget-governor-v2.d.ts +1 -1
- package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
- package/dist/core/context-budget-governor-v2.js +1 -1
- package/dist/core/context-budget-governor-v2.js.map +1 -1
- package/dist/core/context-budget-v2-cache-keys.d.ts +3 -0
- package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-cache-keys.js +2 -0
- package/dist/core/context-budget-v2-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.js +3 -0
- package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +2 -1
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-scoring.d.ts +17 -0
- package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
- package/dist/core/context-budget-v2-scoring.js +25 -8
- package/dist/core/context-budget-v2-scoring.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +2 -2
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +18 -1
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +17 -0
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js +15 -0
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.d.ts +3 -1
- package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.js +7 -0
- package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
- package/dist/core/extensions/types.d.ts +12 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +8 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +71 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-doctor-source-scan.d.ts +9 -0
- package/dist/core/package-doctor-source-scan.d.ts.map +1 -1
- package/dist/core/package-doctor-source-scan.js +77 -4
- package/dist/core/package-doctor-source-scan.js.map +1 -1
- package/dist/core/prompt-attachment.d.ts +51 -0
- package/dist/core/prompt-attachment.d.ts.map +1 -0
- package/dist/core/prompt-attachment.js +186 -0
- package/dist/core/prompt-attachment.js.map +1 -0
- package/dist/core/provider-resilience.d.ts +28 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +50 -0
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/provider-retry.d.ts +1 -1
- package/dist/core/provider-retry.d.ts.map +1 -1
- package/dist/core/provider-retry.js +1 -1
- package/dist/core/provider-retry.js.map +1 -1
- package/dist/core/provider-usage.d.ts.map +1 -1
- package/dist/core/provider-usage.js +68 -2
- package/dist/core/provider-usage.js.map +1 -1
- package/dist/core/reasoning-router-promotion.d.ts +84 -0
- package/dist/core/reasoning-router-promotion.d.ts.map +1 -0
- package/dist/core/reasoning-router-promotion.js +92 -0
- package/dist/core/reasoning-router-promotion.js.map +1 -0
- package/dist/core/session-bash-service.d.ts.map +1 -1
- package/dist/core/session-bash-service.js +4 -3
- package/dist/core/session-bash-service.js.map +1 -1
- package/dist/core/session-termination.d.ts +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +11 -2
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +13 -48
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -34
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/attachment-strip.d.ts +21 -0
- package/dist/modes/interactive/components/attachment-strip.d.ts.map +1 -0
- package/dist/modes/interactive/components/attachment-strip.js +136 -0
- package/dist/modes/interactive/components/attachment-strip.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +6 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +26 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.js +12 -1
- package/dist/modes/interactive/components/status-sidebar.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +23 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +174 -53
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/compaction.md +1 -1
- package/docs/extensions.md +12 -3
- package/docs/index.md +4 -1
- package/docs/metrics.md +74 -2
- package/docs/provider-resilience.md +11 -0
- package/docs/usage.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +7 -7
- package/dist/core/tools/omp-pure-seams.d.ts +0 -41
- package/dist/core/tools/omp-pure-seams.d.ts.map +0 -1
- package/dist/core/tools/omp-pure-seams.js +0 -142
- package/dist/core/tools/omp-pure-seams.js.map +0 -1
- package/dist/core/tools/omp-seam-runtime.d.ts +0 -100
- package/dist/core/tools/omp-seam-runtime.d.ts.map +0 -1
- package/dist/core/tools/omp-seam-runtime.js +0 -40
- package/dist/core/tools/omp-seam-runtime.js.map +0 -1
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* allow: SIZE_OK - legacy TUI coordinator; this change only adds a two-line CONTROL status bridge.
|
|
4
4
|
* Handles TUI rendering and user interaction, delegating business logic to AgentSession.
|
|
5
5
|
*/
|
|
6
|
-
import * as crypto from "node:crypto";
|
|
7
6
|
import * as fs from "node:fs";
|
|
8
7
|
import * as os from "node:os";
|
|
9
8
|
import * as path from "node:path";
|
|
10
9
|
import { spawn, spawnSync } from "child_process";
|
|
11
10
|
import { getProviders, } from "omk-ai";
|
|
11
|
+
import { AttachmentStore } from "../../core/attachment-store.js";
|
|
12
|
+
import { describePromptImageAttachment } from "../../core/prompt-attachment.js";
|
|
13
|
+
import { createAttachmentStrip } from "./components/attachment-strip.js";
|
|
12
14
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Loader, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, visibleWidth, } from "omk-tui";
|
|
13
15
|
import { APP_NAME, APP_TITLE, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
14
16
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
@@ -33,7 +35,7 @@ import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
|
33
35
|
import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
|
|
34
36
|
import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
|
|
35
37
|
import { copyToClipboard } from "../../utils/clipboard.js";
|
|
36
|
-
import {
|
|
38
|
+
import { readClipboardImage } from "../../utils/clipboard-image.js";
|
|
37
39
|
import { parseGitUrl } from "../../utils/git.js";
|
|
38
40
|
import { openBrowser } from "../../utils/open-browser.js";
|
|
39
41
|
import { getCwdRelativePath } from "../../utils/paths.js";
|
|
@@ -219,7 +221,11 @@ export class InteractiveMode {
|
|
|
219
221
|
version;
|
|
220
222
|
isInitialized = false;
|
|
221
223
|
onInputCallback;
|
|
222
|
-
|
|
224
|
+
pendingPromptPayloads = [];
|
|
225
|
+
attachmentStore = new AttachmentStore();
|
|
226
|
+
draftAttachmentIds = [];
|
|
227
|
+
attachmentStripContainer = new Container();
|
|
228
|
+
interactiveLoopActive = true;
|
|
223
229
|
loadingAnimation = undefined;
|
|
224
230
|
// Wall-clock start of the current agent turn, for the working loader elapsed suffix
|
|
225
231
|
workingStartedAt = undefined;
|
|
@@ -652,6 +658,7 @@ export class InteractiveMode {
|
|
|
652
658
|
this.ui.addChild(this.statusContainer);
|
|
653
659
|
this.renderWidgets(); // Initialize with default spacer
|
|
654
660
|
this.ui.addChild(this.widgetContainerAbove);
|
|
661
|
+
this.ui.addChild(this.attachmentStripContainer);
|
|
655
662
|
this.ui.addChild(this.editorContainer);
|
|
656
663
|
this.ui.addChild(this.widgetContainerBelow);
|
|
657
664
|
this.ui.addChild(this.noticeContainer);
|
|
@@ -780,13 +787,17 @@ export class InteractiveMode {
|
|
|
780
787
|
}
|
|
781
788
|
}
|
|
782
789
|
// Main interactive loop
|
|
783
|
-
while (
|
|
784
|
-
const
|
|
790
|
+
while (this.interactiveLoopActive) {
|
|
791
|
+
const payload = await this.getUserInput();
|
|
785
792
|
const previousTermination = this.session.lastTermination;
|
|
786
793
|
try {
|
|
787
|
-
await this.session.prompt(
|
|
794
|
+
await this.session.prompt(payload.text, payload.images ? { images: payload.images } : undefined);
|
|
795
|
+
// Acceptance: release exactly the attachments that were sent.
|
|
796
|
+
if (payload.imageIds && payload.imageIds.length > 0)
|
|
797
|
+
this.consumeDraftAttachments(payload.imageIds);
|
|
788
798
|
}
|
|
789
799
|
catch (error) {
|
|
800
|
+
// Preflight/model failure: attachments stay attached for retry.
|
|
790
801
|
this.showPromptError(error, previousTermination);
|
|
791
802
|
}
|
|
792
803
|
}
|
|
@@ -1234,9 +1245,10 @@ export class InteractiveMode {
|
|
|
1234
1245
|
const body = visibleLabels.length > 0 ? `${visibleLabels.join(", ")}${suffix}` : "(none)";
|
|
1235
1246
|
return theme.fg("dim", ` ${body}`);
|
|
1236
1247
|
};
|
|
1237
|
-
const addLoadedSection = (name, collapsedBody, expandedBody
|
|
1248
|
+
const addLoadedSection = (name, collapsedBody, expandedBody, color = "mdHeading") => {
|
|
1249
|
+
const resolvedExpandedBody = expandedBody ?? collapsedBody;
|
|
1238
1250
|
const getCollapsedBody = typeof collapsedBody === "function" ? collapsedBody : () => collapsedBody;
|
|
1239
|
-
const getExpandedBody = typeof
|
|
1251
|
+
const getExpandedBody = typeof resolvedExpandedBody === "function" ? resolvedExpandedBody : () => resolvedExpandedBody;
|
|
1240
1252
|
const section = new ExpandableText(() => `${sectionHeader(name, color)}\n${getCollapsedBody()}`, () => `${sectionHeader(name, color)}\n${getExpandedBody()}`, this.getStartupExpansionState(), 0, 0);
|
|
1241
1253
|
this.chatContainer.addChild(section);
|
|
1242
1254
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -2216,18 +2228,98 @@ export class InteractiveMode {
|
|
|
2216
2228
|
if (!image) {
|
|
2217
2229
|
return;
|
|
2218
2230
|
}
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
this.
|
|
2231
|
+
let attachment;
|
|
2232
|
+
try {
|
|
2233
|
+
attachment = this.attachmentStore.put(new Uint8Array(image.bytes), "clipboard");
|
|
2234
|
+
}
|
|
2235
|
+
catch (error) {
|
|
2236
|
+
this.showWarning(error instanceof Error ? error.message : String(error));
|
|
2237
|
+
return;
|
|
2238
|
+
}
|
|
2239
|
+
this.draftAttachmentIds.push(attachment.id);
|
|
2240
|
+
this.refreshAttachmentStrip();
|
|
2228
2241
|
}
|
|
2229
|
-
catch {
|
|
2230
|
-
|
|
2242
|
+
catch (error) {
|
|
2243
|
+
this.showWarning(`Clipboard paste failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
/** Rebuild the preview strip above the editor from the current draft ids. */
|
|
2247
|
+
refreshAttachmentStrip() {
|
|
2248
|
+
this.attachmentStripContainer.clear();
|
|
2249
|
+
const items = this.draftAttachmentIds
|
|
2250
|
+
.map((id) => this.attachmentStore.get(id))
|
|
2251
|
+
.filter((item) => item !== undefined);
|
|
2252
|
+
if (items.length > 0) {
|
|
2253
|
+
this.attachmentStripContainer.addChild(createAttachmentStrip(items, (id) => this.attachmentStore.getBytes(id)));
|
|
2254
|
+
}
|
|
2255
|
+
this.ui.requestRender();
|
|
2256
|
+
}
|
|
2257
|
+
materializeDraftImages(ids) {
|
|
2258
|
+
return this.attachmentStore.materializeImages(ids);
|
|
2259
|
+
}
|
|
2260
|
+
/** Release exactly the attachments that were accepted with a sent prompt. */
|
|
2261
|
+
consumeDraftAttachments(ids) {
|
|
2262
|
+
for (const id of ids) {
|
|
2263
|
+
this.attachmentStore.remove(id);
|
|
2264
|
+
const index = this.draftAttachmentIds.indexOf(id);
|
|
2265
|
+
if (index >= 0)
|
|
2266
|
+
this.draftAttachmentIds.splice(index, 1);
|
|
2267
|
+
}
|
|
2268
|
+
this.refreshAttachmentStrip();
|
|
2269
|
+
}
|
|
2270
|
+
clearDraftAttachments() {
|
|
2271
|
+
this.draftAttachmentIds = [];
|
|
2272
|
+
this.attachmentStore.clear();
|
|
2273
|
+
this.refreshAttachmentStrip();
|
|
2274
|
+
}
|
|
2275
|
+
removeLastDraftAttachment() {
|
|
2276
|
+
const id = this.draftAttachmentIds.pop();
|
|
2277
|
+
if (id)
|
|
2278
|
+
this.attachmentStore.remove(id);
|
|
2279
|
+
this.refreshAttachmentStrip();
|
|
2280
|
+
}
|
|
2281
|
+
isVisionCapable() {
|
|
2282
|
+
const model = this.session.model;
|
|
2283
|
+
return Array.isArray(model?.input) ? model.input.includes("image") : true;
|
|
2284
|
+
}
|
|
2285
|
+
handleAttachCommand(argument) {
|
|
2286
|
+
const [verb, rest] = argument.split(/\s+/);
|
|
2287
|
+
switch (verb ?? "") {
|
|
2288
|
+
case "":
|
|
2289
|
+
case "list": {
|
|
2290
|
+
const items = this.draftAttachmentIds
|
|
2291
|
+
.map((id) => this.attachmentStore.get(id))
|
|
2292
|
+
.filter((item) => item !== undefined);
|
|
2293
|
+
if (items.length === 0) {
|
|
2294
|
+
this.showStatus("No image attachments.");
|
|
2295
|
+
}
|
|
2296
|
+
else {
|
|
2297
|
+
this.showStatus(items.map((item, index) => `${index + 1}. ${describePromptImageAttachment(item)}`).join(" · "));
|
|
2298
|
+
}
|
|
2299
|
+
break;
|
|
2300
|
+
}
|
|
2301
|
+
case "clear":
|
|
2302
|
+
this.clearDraftAttachments();
|
|
2303
|
+
this.showStatus("Image attachments cleared.");
|
|
2304
|
+
break;
|
|
2305
|
+
case "remove":
|
|
2306
|
+
case "rm": {
|
|
2307
|
+
const position = Number.parseInt(rest ?? "", 10);
|
|
2308
|
+
if (Number.isFinite(position) && position >= 1 && position <= this.draftAttachmentIds.length) {
|
|
2309
|
+
const id = this.draftAttachmentIds.splice(position - 1, 1)[0];
|
|
2310
|
+
if (id)
|
|
2311
|
+
this.attachmentStore.remove(id);
|
|
2312
|
+
}
|
|
2313
|
+
else {
|
|
2314
|
+
this.removeLastDraftAttachment();
|
|
2315
|
+
}
|
|
2316
|
+
this.refreshAttachmentStrip();
|
|
2317
|
+
this.showStatus("Image attachment removed.");
|
|
2318
|
+
break;
|
|
2319
|
+
}
|
|
2320
|
+
default:
|
|
2321
|
+
this.showStatus("Usage: /attach [list|clear|remove [n]]");
|
|
2322
|
+
break;
|
|
2231
2323
|
}
|
|
2232
2324
|
}
|
|
2233
2325
|
parseBangInput(text) {
|
|
@@ -2245,9 +2337,16 @@ export class InteractiveMode {
|
|
|
2245
2337
|
setupEditorSubmitHandler() {
|
|
2246
2338
|
this.defaultEditor.onSubmit = async (text) => {
|
|
2247
2339
|
text = text.trim();
|
|
2248
|
-
|
|
2340
|
+
const draftImageIds = [...(this.draftAttachmentIds ?? [])];
|
|
2341
|
+
const hasAttachments = draftImageIds.length > 0;
|
|
2342
|
+
if (!text && !hasAttachments)
|
|
2249
2343
|
return;
|
|
2250
2344
|
// Handle commands
|
|
2345
|
+
if (text === "/attach" || text.startsWith("/attach ")) {
|
|
2346
|
+
this.editor.setText("");
|
|
2347
|
+
this.handleAttachCommand(text.slice("/attach".length).trim());
|
|
2348
|
+
return;
|
|
2349
|
+
}
|
|
2251
2350
|
if (text === "/settings") {
|
|
2252
2351
|
this.showSettingsSelector();
|
|
2253
2352
|
this.editor.setText("");
|
|
@@ -2409,8 +2508,26 @@ export class InteractiveMode {
|
|
|
2409
2508
|
return;
|
|
2410
2509
|
}
|
|
2411
2510
|
}
|
|
2511
|
+
let draftImages;
|
|
2512
|
+
if (hasAttachments) {
|
|
2513
|
+
try {
|
|
2514
|
+
draftImages = this.materializeDraftImages(draftImageIds);
|
|
2515
|
+
}
|
|
2516
|
+
catch (error) {
|
|
2517
|
+
this.showWarning(error instanceof Error ? error.message : String(error));
|
|
2518
|
+
return;
|
|
2519
|
+
}
|
|
2520
|
+
if (!this.isVisionCapable()) {
|
|
2521
|
+
this.showWarning("The selected model cannot accept images. Switch model (/model) or run /attach clear.");
|
|
2522
|
+
return;
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2412
2525
|
// Queue input during compaction (extension commands execute immediately)
|
|
2413
2526
|
if (this.session.isCompacting) {
|
|
2527
|
+
if (hasAttachments) {
|
|
2528
|
+
this.showWarning("Attachments are held while compaction finishes — resubmit after it completes.");
|
|
2529
|
+
return;
|
|
2530
|
+
}
|
|
2414
2531
|
if (this.isExtensionCommand(text)) {
|
|
2415
2532
|
this.editor.addToHistory?.(text);
|
|
2416
2533
|
this.editor.setText("");
|
|
@@ -2426,7 +2543,10 @@ export class InteractiveMode {
|
|
|
2426
2543
|
if (this.session.isStreaming) {
|
|
2427
2544
|
this.editor.addToHistory?.(text);
|
|
2428
2545
|
this.editor.setText("");
|
|
2429
|
-
await this.session.prompt(text, { streamingBehavior: "steer" });
|
|
2546
|
+
await this.session.prompt(text, draftImages ? { images: draftImages, streamingBehavior: "steer" } : { streamingBehavior: "steer" });
|
|
2547
|
+
// Queued without throwing: acceptance — release exactly what was sent.
|
|
2548
|
+
if (draftImageIds.length > 0)
|
|
2549
|
+
this.consumeDraftAttachments(draftImageIds);
|
|
2430
2550
|
this.updatePendingMessagesDisplay();
|
|
2431
2551
|
this.ui.requestRender();
|
|
2432
2552
|
return;
|
|
@@ -2434,11 +2554,14 @@ export class InteractiveMode {
|
|
|
2434
2554
|
// Normal message submission
|
|
2435
2555
|
// First, move any pending bash components to chat
|
|
2436
2556
|
this.flushPendingBashComponents();
|
|
2557
|
+
const payload = draftImages
|
|
2558
|
+
? { text, images: draftImages, imageIds: draftImageIds }
|
|
2559
|
+
: { text };
|
|
2437
2560
|
if (this.onInputCallback) {
|
|
2438
|
-
this.onInputCallback(
|
|
2561
|
+
this.onInputCallback(payload);
|
|
2439
2562
|
}
|
|
2440
2563
|
else {
|
|
2441
|
-
this.
|
|
2564
|
+
this.pendingPromptPayloads.push(payload);
|
|
2442
2565
|
}
|
|
2443
2566
|
this.editor.addToHistory?.(text);
|
|
2444
2567
|
};
|
|
@@ -2978,14 +3101,14 @@ export class InteractiveMode {
|
|
|
2978
3101
|
}
|
|
2979
3102
|
}
|
|
2980
3103
|
async getUserInput() {
|
|
2981
|
-
const
|
|
2982
|
-
if (
|
|
2983
|
-
return
|
|
3104
|
+
const queuedPayload = this.pendingPromptPayloads.shift();
|
|
3105
|
+
if (queuedPayload !== undefined) {
|
|
3106
|
+
return queuedPayload;
|
|
2984
3107
|
}
|
|
2985
3108
|
return new Promise((resolve) => {
|
|
2986
|
-
this.onInputCallback = (
|
|
3109
|
+
this.onInputCallback = (payload) => {
|
|
2987
3110
|
this.onInputCallback = undefined;
|
|
2988
|
-
resolve(
|
|
3111
|
+
resolve(payload);
|
|
2989
3112
|
};
|
|
2990
3113
|
});
|
|
2991
3114
|
}
|
|
@@ -3028,6 +3151,7 @@ export class InteractiveMode {
|
|
|
3028
3151
|
*/
|
|
3029
3152
|
isShuttingDown = false;
|
|
3030
3153
|
async shutdown(options) {
|
|
3154
|
+
this.interactiveLoopActive = false;
|
|
3031
3155
|
if (this.isShuttingDown)
|
|
3032
3156
|
return;
|
|
3033
3157
|
this.isShuttingDown = true;
|
|
@@ -5022,34 +5146,31 @@ export class InteractiveMode {
|
|
|
5022
5146
|
/**
|
|
5023
5147
|
* Get capitalized display string for an editor keybinding action.
|
|
5024
5148
|
*/
|
|
5025
|
-
getEditorKeyDisplay(action) {
|
|
5026
|
-
return keyDisplayText(action);
|
|
5027
|
-
}
|
|
5028
5149
|
handleHotkeysCommand() {
|
|
5029
5150
|
// Navigation keybindings
|
|
5030
|
-
const cursorUp =
|
|
5031
|
-
const cursorDown =
|
|
5032
|
-
const cursorLeft =
|
|
5033
|
-
const cursorRight =
|
|
5034
|
-
const cursorWordLeft =
|
|
5035
|
-
const cursorWordRight =
|
|
5036
|
-
const cursorLineStart =
|
|
5037
|
-
const cursorLineEnd =
|
|
5038
|
-
const jumpForward =
|
|
5039
|
-
const jumpBackward =
|
|
5040
|
-
const pageUp =
|
|
5041
|
-
const pageDown =
|
|
5151
|
+
const cursorUp = keyDisplayText("tui.editor.cursorUp");
|
|
5152
|
+
const cursorDown = keyDisplayText("tui.editor.cursorDown");
|
|
5153
|
+
const cursorLeft = keyDisplayText("tui.editor.cursorLeft");
|
|
5154
|
+
const cursorRight = keyDisplayText("tui.editor.cursorRight");
|
|
5155
|
+
const cursorWordLeft = keyDisplayText("tui.editor.cursorWordLeft");
|
|
5156
|
+
const cursorWordRight = keyDisplayText("tui.editor.cursorWordRight");
|
|
5157
|
+
const cursorLineStart = keyDisplayText("tui.editor.cursorLineStart");
|
|
5158
|
+
const cursorLineEnd = keyDisplayText("tui.editor.cursorLineEnd");
|
|
5159
|
+
const jumpForward = keyDisplayText("tui.editor.jumpForward");
|
|
5160
|
+
const jumpBackward = keyDisplayText("tui.editor.jumpBackward");
|
|
5161
|
+
const pageUp = keyDisplayText("tui.editor.pageUp");
|
|
5162
|
+
const pageDown = keyDisplayText("tui.editor.pageDown");
|
|
5042
5163
|
// Editing keybindings
|
|
5043
|
-
const submit =
|
|
5044
|
-
const newLine =
|
|
5045
|
-
const deleteWordBackward =
|
|
5046
|
-
const deleteWordForward =
|
|
5047
|
-
const deleteToLineStart =
|
|
5048
|
-
const deleteToLineEnd =
|
|
5049
|
-
const yank =
|
|
5050
|
-
const yankPop =
|
|
5051
|
-
const undo =
|
|
5052
|
-
const tab =
|
|
5164
|
+
const submit = keyDisplayText("tui.input.submit");
|
|
5165
|
+
const newLine = keyDisplayText("tui.input.newLine");
|
|
5166
|
+
const deleteWordBackward = keyDisplayText("tui.editor.deleteWordBackward");
|
|
5167
|
+
const deleteWordForward = keyDisplayText("tui.editor.deleteWordForward");
|
|
5168
|
+
const deleteToLineStart = keyDisplayText("tui.editor.deleteToLineStart");
|
|
5169
|
+
const deleteToLineEnd = keyDisplayText("tui.editor.deleteToLineEnd");
|
|
5170
|
+
const yank = keyDisplayText("tui.editor.yank");
|
|
5171
|
+
const yankPop = keyDisplayText("tui.editor.yankPop");
|
|
5172
|
+
const undo = keyDisplayText("tui.editor.undo");
|
|
5173
|
+
const tab = keyDisplayText("tui.input.tab");
|
|
5053
5174
|
// App keybindings
|
|
5054
5175
|
const interrupt = this.getAppKeyDisplay("app.interrupt");
|
|
5055
5176
|
const clear = this.getAppKeyDisplay("app.clear");
|