tabminal 3.0.8 → 3.0.9
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/package.json +1 -1
- package/public/app.js +574 -43
- package/src/acp-manager.mjs +422 -80
- package/src/server.mjs +87 -0
package/public/app.js
CHANGED
|
@@ -375,6 +375,11 @@ function persistRuntimeBootId(bootId) {
|
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
function getLoadedRuntimeAssetKey() {
|
|
379
|
+
const assetKey = window.__tabminalRuntimeAssetKey;
|
|
380
|
+
return typeof assetKey === 'string' ? assetKey : '';
|
|
381
|
+
}
|
|
382
|
+
|
|
378
383
|
function handlePrimaryRuntimeVersion(data) {
|
|
379
384
|
const runtime = data?.runtime;
|
|
380
385
|
const bootIdRaw = runtime?.bootId;
|
|
@@ -382,16 +387,20 @@ function handlePrimaryRuntimeVersion(data) {
|
|
|
382
387
|
const bootId = String(bootIdRaw);
|
|
383
388
|
if (!bootId) return;
|
|
384
389
|
const storedBootId = readRuntimeBootId();
|
|
390
|
+
const loadedAssetKey = getLoadedRuntimeAssetKey();
|
|
391
|
+
const needsShellReload = loadedAssetKey !== bootId;
|
|
385
392
|
|
|
386
393
|
if (!primaryServerBootId) {
|
|
387
394
|
primaryServerBootId = bootId;
|
|
388
|
-
if (storedBootId === bootId) {
|
|
395
|
+
if (storedBootId === bootId && !needsShellReload) {
|
|
389
396
|
return;
|
|
390
397
|
}
|
|
391
398
|
const persisted = persistRuntimeBootId(bootId);
|
|
392
|
-
if (
|
|
399
|
+
if (persisted && needsShellReload && !runtimeReloadScheduled) {
|
|
393
400
|
runtimeReloadScheduled = true;
|
|
394
|
-
console.info(
|
|
401
|
+
console.info(
|
|
402
|
+
'[Runtime] Syncing app shell cache key with server boot id.'
|
|
403
|
+
);
|
|
395
404
|
window.location.reload();
|
|
396
405
|
}
|
|
397
406
|
return;
|
|
@@ -400,6 +409,13 @@ function handlePrimaryRuntimeVersion(data) {
|
|
|
400
409
|
if (storedBootId !== bootId) {
|
|
401
410
|
persistRuntimeBootId(bootId);
|
|
402
411
|
}
|
|
412
|
+
if (needsShellReload && !runtimeReloadScheduled) {
|
|
413
|
+
runtimeReloadScheduled = true;
|
|
414
|
+
console.info(
|
|
415
|
+
'[Runtime] Reloading app shell to match server boot id.'
|
|
416
|
+
);
|
|
417
|
+
window.location.reload();
|
|
418
|
+
}
|
|
403
419
|
return;
|
|
404
420
|
}
|
|
405
421
|
if (runtimeReloadScheduled) return;
|
|
@@ -703,6 +719,8 @@ class EditorManager {
|
|
|
703
719
|
this.agentCommandMenu = null;
|
|
704
720
|
this.agentCommandSuggestions = [];
|
|
705
721
|
this.agentCommandIndex = 0;
|
|
722
|
+
this.agentCommandMenuStateKey = '';
|
|
723
|
+
this.agentCommandMenuToken = 0;
|
|
706
724
|
this.isApplyingAgentPromptState = false;
|
|
707
725
|
this.suppressAgentCommandMenu = false;
|
|
708
726
|
this.agentEmbeddedEditors = [];
|
|
@@ -1106,6 +1124,14 @@ class EditorManager {
|
|
|
1106
1124
|
});
|
|
1107
1125
|
this.agentPrompt.addEventListener('blur', () => {
|
|
1108
1126
|
setTimeout(() => {
|
|
1127
|
+
if (
|
|
1128
|
+
document.activeElement?.classList?.contains(
|
|
1129
|
+
'xterm-helper-textarea'
|
|
1130
|
+
)
|
|
1131
|
+
&& this.agentCommandSuggestions.length > 0
|
|
1132
|
+
) {
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1109
1135
|
this.hideAgentCommandMenu();
|
|
1110
1136
|
}, 120);
|
|
1111
1137
|
});
|
|
@@ -1134,14 +1160,24 @@ class EditorManager {
|
|
|
1134
1160
|
? state.agentTabs.get(activeTabKey)
|
|
1135
1161
|
: null;
|
|
1136
1162
|
|
|
1163
|
+
if (
|
|
1164
|
+
agentTab
|
|
1165
|
+
&& this.agentCommandSuggestions.length > 0
|
|
1166
|
+
&& Number.isInteger(agentTab.promptHistoryIndex)
|
|
1167
|
+
) {
|
|
1168
|
+
this.exitAgentPromptHistoryBrowsing(agentTab);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1137
1171
|
if (this.agentCommandSuggestions.length > 0) {
|
|
1138
1172
|
if (event.key === 'ArrowDown') {
|
|
1139
1173
|
event.preventDefault();
|
|
1174
|
+
event.stopImmediatePropagation();
|
|
1140
1175
|
this.moveAgentCommandSelection(1);
|
|
1141
1176
|
return;
|
|
1142
1177
|
}
|
|
1143
1178
|
if (event.key === 'ArrowUp') {
|
|
1144
1179
|
event.preventDefault();
|
|
1180
|
+
event.stopImmediatePropagation();
|
|
1145
1181
|
this.moveAgentCommandSelection(-1);
|
|
1146
1182
|
return;
|
|
1147
1183
|
}
|
|
@@ -1156,11 +1192,13 @@ class EditorManager {
|
|
|
1156
1192
|
)
|
|
1157
1193
|
) {
|
|
1158
1194
|
event.preventDefault();
|
|
1159
|
-
|
|
1195
|
+
event.stopImmediatePropagation();
|
|
1196
|
+
void this.applyAgentCommandSuggestion();
|
|
1160
1197
|
return;
|
|
1161
1198
|
}
|
|
1162
1199
|
if (event.key === 'Escape') {
|
|
1163
1200
|
event.preventDefault();
|
|
1201
|
+
event.stopImmediatePropagation();
|
|
1164
1202
|
this.hideAgentCommandMenu();
|
|
1165
1203
|
return;
|
|
1166
1204
|
}
|
|
@@ -1556,9 +1594,7 @@ class EditorManager {
|
|
|
1556
1594
|
const hasAgentTabs = getAgentTabsForSession(this.currentSession).length > 0;
|
|
1557
1595
|
const compact = this.hasCompactWorkspaceTabs(this.currentSession);
|
|
1558
1596
|
const hasTabs = compact || hasOpenFiles || hasAgentTabs;
|
|
1559
|
-
const shouldShow =
|
|
1560
|
-
? true
|
|
1561
|
-
: state.isVisible || hasOpenFiles || hasAgentTabs;
|
|
1597
|
+
const shouldShow = hasTabs;
|
|
1562
1598
|
|
|
1563
1599
|
this.tabsContainer.style.display = hasTabs ? 'flex' : 'none';
|
|
1564
1600
|
this.pane.style.display = shouldShow ? 'flex' : 'none';
|
|
@@ -1644,8 +1680,7 @@ class EditorManager {
|
|
|
1644
1680
|
const state = session.editorState;
|
|
1645
1681
|
|
|
1646
1682
|
// Only render tabs and content, file tree is persistent in sidebar
|
|
1647
|
-
const shouldShowWorkspace =
|
|
1648
|
-
|| this.hasVisibleWorkspaceTabs(session);
|
|
1683
|
+
const shouldShowWorkspace = this.hasVisibleWorkspaceTabs(session);
|
|
1649
1684
|
if (shouldShowWorkspace) {
|
|
1650
1685
|
if (state.isVisible) {
|
|
1651
1686
|
this.refreshSessionTree(session);
|
|
@@ -1654,8 +1689,6 @@ class EditorManager {
|
|
|
1654
1689
|
const activeKey = this.getActiveWorkspaceTabKey(session);
|
|
1655
1690
|
if (activeKey) {
|
|
1656
1691
|
this.activateWorkspaceTab(activeKey, true);
|
|
1657
|
-
} else {
|
|
1658
|
-
this.showEmptyState();
|
|
1659
1692
|
}
|
|
1660
1693
|
}
|
|
1661
1694
|
|
|
@@ -3155,6 +3188,17 @@ class EditorManager {
|
|
|
3155
3188
|
const attachments = Array.isArray(agentTab.pendingAttachments)
|
|
3156
3189
|
? [...agentTab.pendingAttachments]
|
|
3157
3190
|
: [];
|
|
3191
|
+
const promptIntent = getAgentPromptIntent(
|
|
3192
|
+
agentTab,
|
|
3193
|
+
this.agentPrompt.value || ''
|
|
3194
|
+
);
|
|
3195
|
+
if (promptIntent.kind === 'resume') {
|
|
3196
|
+
alert('Select a previous session from the /resume menu.', {
|
|
3197
|
+
type: 'warning',
|
|
3198
|
+
title: getAgentBaseName(agentTab)
|
|
3199
|
+
});
|
|
3200
|
+
return;
|
|
3201
|
+
}
|
|
3158
3202
|
if (!text && attachments.length === 0) {
|
|
3159
3203
|
if (canAutostartQueuedAgentPrompt(agentTab)) {
|
|
3160
3204
|
await drainQueuedAgentPrompt(agentTab);
|
|
@@ -3329,7 +3373,21 @@ class EditorManager {
|
|
|
3329
3373
|
if (this.suppressAgentCommandMenu) {
|
|
3330
3374
|
this.hideAgentCommandMenu();
|
|
3331
3375
|
} else {
|
|
3332
|
-
this.
|
|
3376
|
+
const promptValue = this.agentPrompt?.value || '';
|
|
3377
|
+
const promptIntent = getAgentPromptIntent(
|
|
3378
|
+
activeAgentTab,
|
|
3379
|
+
promptValue
|
|
3380
|
+
);
|
|
3381
|
+
const nextMenuStateKey = [
|
|
3382
|
+
activeAgentTab?.key || '',
|
|
3383
|
+
promptIntent.kind,
|
|
3384
|
+
promptValue
|
|
3385
|
+
].join('::');
|
|
3386
|
+
const menuVisible = this.agentCommandMenu
|
|
3387
|
+
&& this.agentCommandMenu.style.display !== 'none';
|
|
3388
|
+
if (!menuVisible || this.agentCommandMenuStateKey !== nextMenuStateKey) {
|
|
3389
|
+
this.renderAgentCommandMenu(activeAgentTab);
|
|
3390
|
+
}
|
|
3333
3391
|
}
|
|
3334
3392
|
if (
|
|
3335
3393
|
activeAgentTab
|
|
@@ -3500,12 +3558,7 @@ class EditorManager {
|
|
|
3500
3558
|
this.agentScrollBottomButton.style.display = shouldShow ? '' : 'none';
|
|
3501
3559
|
}
|
|
3502
3560
|
|
|
3503
|
-
|
|
3504
|
-
if (!this.agentCommandMenu) return;
|
|
3505
|
-
const suggestions = getAgentCommandSuggestions(
|
|
3506
|
-
agentTab,
|
|
3507
|
-
this.agentPrompt?.value || ''
|
|
3508
|
-
);
|
|
3561
|
+
#renderAgentCommandSuggestions(suggestions) {
|
|
3509
3562
|
this.agentCommandSuggestions = suggestions;
|
|
3510
3563
|
if (suggestions.length === 0) {
|
|
3511
3564
|
this.hideAgentCommandMenu();
|
|
@@ -3527,7 +3580,11 @@ class EditorManager {
|
|
|
3527
3580
|
}
|
|
3528
3581
|
const name = document.createElement('span');
|
|
3529
3582
|
name.className = 'agent-command-option-name';
|
|
3530
|
-
name.textContent =
|
|
3583
|
+
name.textContent = command.kind === 'resume_session'
|
|
3584
|
+
? command.displayName || command.title || command.sessionId
|
|
3585
|
+
: command.kind === 'info'
|
|
3586
|
+
? command.label || ''
|
|
3587
|
+
: `/${command.name}`;
|
|
3531
3588
|
button.appendChild(name);
|
|
3532
3589
|
if (command.description) {
|
|
3533
3590
|
const meta = document.createElement('span');
|
|
@@ -3535,12 +3592,16 @@ class EditorManager {
|
|
|
3535
3592
|
meta.textContent = command.description;
|
|
3536
3593
|
button.appendChild(meta);
|
|
3537
3594
|
}
|
|
3595
|
+
if (command.kind === 'info') {
|
|
3596
|
+
button.disabled = true;
|
|
3597
|
+
}
|
|
3538
3598
|
button.addEventListener('mousedown', (event) => {
|
|
3539
3599
|
event.preventDefault();
|
|
3540
3600
|
});
|
|
3541
3601
|
button.addEventListener('click', () => {
|
|
3602
|
+
if (command.kind === 'info') return;
|
|
3542
3603
|
this.agentCommandIndex = index;
|
|
3543
|
-
this.applyAgentCommandSuggestion();
|
|
3604
|
+
void this.applyAgentCommandSuggestion();
|
|
3544
3605
|
});
|
|
3545
3606
|
this.agentCommandMenu.appendChild(button);
|
|
3546
3607
|
}
|
|
@@ -3554,10 +3615,95 @@ class EditorManager {
|
|
|
3554
3615
|
}
|
|
3555
3616
|
}
|
|
3556
3617
|
|
|
3618
|
+
async renderAgentCommandMenu(agentTab = null) {
|
|
3619
|
+
if (!this.agentCommandMenu) return;
|
|
3620
|
+
const promptValue = this.agentPrompt?.value || '';
|
|
3621
|
+
const token = this.agentCommandMenuToken + 1;
|
|
3622
|
+
this.agentCommandMenuToken = token;
|
|
3623
|
+
const intent = getAgentPromptIntent(agentTab, promptValue);
|
|
3624
|
+
const menuStateKey = [
|
|
3625
|
+
agentTab?.key || '',
|
|
3626
|
+
intent.kind,
|
|
3627
|
+
promptValue
|
|
3628
|
+
].join('::');
|
|
3629
|
+
|
|
3630
|
+
if (!agentTab || intent.kind === 'none' || intent.kind === 'other') {
|
|
3631
|
+
this.hideAgentCommandMenu();
|
|
3632
|
+
return;
|
|
3633
|
+
}
|
|
3634
|
+
|
|
3635
|
+
if (Number.isInteger(agentTab.promptHistoryIndex)) {
|
|
3636
|
+
this.exitAgentPromptHistoryBrowsing(agentTab);
|
|
3637
|
+
}
|
|
3638
|
+
|
|
3639
|
+
if (intent.kind === 'resume') {
|
|
3640
|
+
const hasLoadedResumeSuggestions = (
|
|
3641
|
+
this.agentCommandMenuStateKey === menuStateKey
|
|
3642
|
+
&& this.agentCommandSuggestions.length > 0
|
|
3643
|
+
&& !(
|
|
3644
|
+
this.agentCommandSuggestions.length === 1
|
|
3645
|
+
&& this.agentCommandSuggestions[0]?.kind === 'info'
|
|
3646
|
+
&& /loading previous sessions/i.test(
|
|
3647
|
+
this.agentCommandSuggestions[0]?.label || ''
|
|
3648
|
+
)
|
|
3649
|
+
)
|
|
3650
|
+
);
|
|
3651
|
+
if (hasLoadedResumeSuggestions) {
|
|
3652
|
+
this.#renderAgentCommandSuggestions(
|
|
3653
|
+
this.agentCommandSuggestions
|
|
3654
|
+
);
|
|
3655
|
+
return;
|
|
3656
|
+
}
|
|
3657
|
+
this.agentCommandMenuStateKey = menuStateKey;
|
|
3658
|
+
this.#renderAgentCommandSuggestions([{
|
|
3659
|
+
kind: 'info',
|
|
3660
|
+
label: 'Loading previous sessions…',
|
|
3661
|
+
description: ''
|
|
3662
|
+
}]);
|
|
3663
|
+
try {
|
|
3664
|
+
const sessions = await agentTab.listResumeSessions();
|
|
3665
|
+
if (this.agentCommandMenuToken !== token) {
|
|
3666
|
+
return;
|
|
3667
|
+
}
|
|
3668
|
+
const suggestions = getAgentResumeSuggestions(
|
|
3669
|
+
agentTab,
|
|
3670
|
+
promptValue,
|
|
3671
|
+
sessions
|
|
3672
|
+
);
|
|
3673
|
+
if (suggestions.length === 0) {
|
|
3674
|
+
this.#renderAgentCommandSuggestions([{
|
|
3675
|
+
kind: 'info',
|
|
3676
|
+
label: 'No previous sessions found',
|
|
3677
|
+
description: ''
|
|
3678
|
+
}]);
|
|
3679
|
+
return;
|
|
3680
|
+
}
|
|
3681
|
+
this.#renderAgentCommandSuggestions(suggestions);
|
|
3682
|
+
} catch (error) {
|
|
3683
|
+
if (this.agentCommandMenuToken !== token) {
|
|
3684
|
+
return;
|
|
3685
|
+
}
|
|
3686
|
+
this.#renderAgentCommandSuggestions([{
|
|
3687
|
+
kind: 'info',
|
|
3688
|
+
label: 'Unable to load previous sessions',
|
|
3689
|
+
description: error?.message || ''
|
|
3690
|
+
}]);
|
|
3691
|
+
}
|
|
3692
|
+
return;
|
|
3693
|
+
}
|
|
3694
|
+
|
|
3695
|
+
this.agentCommandMenuStateKey = menuStateKey;
|
|
3696
|
+
this.#renderAgentCommandSuggestions(
|
|
3697
|
+
getAgentCommandSuggestions(agentTab, promptValue)
|
|
3698
|
+
);
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3557
3701
|
hideAgentCommandMenu() {
|
|
3558
3702
|
if (!this.agentCommandMenu) return;
|
|
3703
|
+
this.agentCommandMenuToken += 1;
|
|
3559
3704
|
this.agentCommandSuggestions = [];
|
|
3560
3705
|
this.agentCommandIndex = 0;
|
|
3706
|
+
this.agentCommandMenuStateKey = '';
|
|
3561
3707
|
this.agentCommandMenu.style.display = 'none';
|
|
3562
3708
|
this.agentCommandMenu.innerHTML = '';
|
|
3563
3709
|
}
|
|
@@ -3568,7 +3714,7 @@ class EditorManager {
|
|
|
3568
3714
|
this.agentCommandIndex = nextIndex < 0
|
|
3569
3715
|
? this.agentCommandSuggestions.length - 1
|
|
3570
3716
|
: nextIndex % this.agentCommandSuggestions.length;
|
|
3571
|
-
this.
|
|
3717
|
+
this.#renderAgentCommandSuggestions(this.agentCommandSuggestions);
|
|
3572
3718
|
}
|
|
3573
3719
|
|
|
3574
3720
|
setAgentPromptValue(value, agentTab = null, options = {}) {
|
|
@@ -3739,9 +3885,40 @@ class EditorManager {
|
|
|
3739
3885
|
agentTab.promptDraft = this.agentPrompt?.value || '';
|
|
3740
3886
|
}
|
|
3741
3887
|
|
|
3742
|
-
applyAgentCommandSuggestion() {
|
|
3888
|
+
async applyAgentCommandSuggestion() {
|
|
3743
3889
|
const command = this.agentCommandSuggestions[this.agentCommandIndex];
|
|
3744
3890
|
if (!command) return;
|
|
3891
|
+
if (command.kind === 'info') {
|
|
3892
|
+
return;
|
|
3893
|
+
}
|
|
3894
|
+
if (command.kind === 'resume_session') {
|
|
3895
|
+
const agentTab = getActiveAgentTab();
|
|
3896
|
+
if (!agentTab) return;
|
|
3897
|
+
const session = agentTab.getLinkedSession();
|
|
3898
|
+
if (!session) return;
|
|
3899
|
+
try {
|
|
3900
|
+
if (command.openTabKey) {
|
|
3901
|
+
const existingTab = state.agentTabs.get(command.openTabKey);
|
|
3902
|
+
const existingSession = existingTab?.getLinkedSession() || null;
|
|
3903
|
+
if (existingTab && existingSession) {
|
|
3904
|
+
await activateAgentTab(existingSession, existingTab, {
|
|
3905
|
+
switchSession: true
|
|
3906
|
+
});
|
|
3907
|
+
} else {
|
|
3908
|
+
await resumeAgentTabFromHistory(session, agentTab, command);
|
|
3909
|
+
}
|
|
3910
|
+
} else {
|
|
3911
|
+
await resumeAgentTabFromHistory(session, agentTab, command);
|
|
3912
|
+
}
|
|
3913
|
+
this.hideAgentCommandMenu();
|
|
3914
|
+
} catch (error) {
|
|
3915
|
+
alert(error.message, {
|
|
3916
|
+
type: 'error',
|
|
3917
|
+
title: getAgentBaseName(agentTab)
|
|
3918
|
+
});
|
|
3919
|
+
}
|
|
3920
|
+
return;
|
|
3921
|
+
}
|
|
3745
3922
|
const suffix = command.inputHint
|
|
3746
3923
|
? ` ${command.inputHint}`
|
|
3747
3924
|
: ' ';
|
|
@@ -5205,6 +5382,9 @@ class AgentTab {
|
|
|
5205
5382
|
this.scrollToBottomOnNextRender = true;
|
|
5206
5383
|
this.busySyncTimer = null;
|
|
5207
5384
|
this.planHistory = [];
|
|
5385
|
+
this.resumeSessions = [];
|
|
5386
|
+
this.resumeSessionsLoadedAt = 0;
|
|
5387
|
+
this.resumeSessionsPromise = null;
|
|
5208
5388
|
this.update(data);
|
|
5209
5389
|
this.connect();
|
|
5210
5390
|
}
|
|
@@ -5224,6 +5404,7 @@ class AgentTab {
|
|
|
5224
5404
|
}
|
|
5225
5405
|
|
|
5226
5406
|
update(data) {
|
|
5407
|
+
const previousResumeCacheKey = `${this.agentId || ''}:${this.cwd || ''}`;
|
|
5227
5408
|
this.runtimeId = data.runtimeId || '';
|
|
5228
5409
|
this.runtimeKey = data.runtimeKey || '';
|
|
5229
5410
|
this.acpSessionId = data.acpSessionId || '';
|
|
@@ -5244,9 +5425,17 @@ class AgentTab {
|
|
|
5244
5425
|
this.availableCommands = Array.isArray(data.availableCommands)
|
|
5245
5426
|
? data.availableCommands
|
|
5246
5427
|
: [];
|
|
5428
|
+
this.sessionCapabilities = normalizeAgentSessionCapabilities(
|
|
5429
|
+
data.sessionCapabilities || this.sessionCapabilities
|
|
5430
|
+
);
|
|
5247
5431
|
this.configOptions = Array.isArray(data.configOptions)
|
|
5248
5432
|
? data.configOptions
|
|
5249
5433
|
: [];
|
|
5434
|
+
const nextResumeCacheKey = `${this.agentId || ''}:${this.cwd || ''}`;
|
|
5435
|
+
if (previousResumeCacheKey !== nextResumeCacheKey) {
|
|
5436
|
+
this.resumeSessions = [];
|
|
5437
|
+
this.resumeSessionsLoadedAt = 0;
|
|
5438
|
+
}
|
|
5250
5439
|
const nextPlan = Array.isArray(data.plan)
|
|
5251
5440
|
? data.plan.map((entry) => this.#normalizePlanEntry(entry))
|
|
5252
5441
|
: [];
|
|
@@ -5314,6 +5503,49 @@ class AgentTab {
|
|
|
5314
5503
|
this.#syncBusyWatchdog();
|
|
5315
5504
|
}
|
|
5316
5505
|
|
|
5506
|
+
async listResumeSessions({ force = false } = {}) {
|
|
5507
|
+
if (!supportsAgentResumeCommand(this)) {
|
|
5508
|
+
return [];
|
|
5509
|
+
}
|
|
5510
|
+
if (
|
|
5511
|
+
!force
|
|
5512
|
+
&& this.resumeSessionsLoadedAt > 0
|
|
5513
|
+
&& (Date.now() - this.resumeSessionsLoadedAt) < 30 * 1000
|
|
5514
|
+
) {
|
|
5515
|
+
return this.resumeSessions;
|
|
5516
|
+
}
|
|
5517
|
+
if (this.resumeSessionsPromise) {
|
|
5518
|
+
return this.resumeSessionsPromise;
|
|
5519
|
+
}
|
|
5520
|
+
|
|
5521
|
+
this.resumeSessionsPromise = (async () => {
|
|
5522
|
+
const cwd = this.cwd || this.getLinkedSession()?.cwd || '';
|
|
5523
|
+
const params = new URLSearchParams({
|
|
5524
|
+
agentId: this.agentId,
|
|
5525
|
+
cwd
|
|
5526
|
+
});
|
|
5527
|
+
const response = await this.server.fetch(
|
|
5528
|
+
`/api/agents/sessions?${params.toString()}`
|
|
5529
|
+
);
|
|
5530
|
+
if (!response.ok) {
|
|
5531
|
+
await throwResponseError(
|
|
5532
|
+
response,
|
|
5533
|
+
'Failed to load previous sessions'
|
|
5534
|
+
);
|
|
5535
|
+
}
|
|
5536
|
+
const data = await response.json();
|
|
5537
|
+
this.resumeSessions = normalizeListedAgentSessions(data.sessions);
|
|
5538
|
+
this.resumeSessionsLoadedAt = Date.now();
|
|
5539
|
+
return this.resumeSessions;
|
|
5540
|
+
})();
|
|
5541
|
+
|
|
5542
|
+
try {
|
|
5543
|
+
return await this.resumeSessionsPromise;
|
|
5544
|
+
} finally {
|
|
5545
|
+
this.resumeSessionsPromise = null;
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
|
|
5317
5549
|
connect() {
|
|
5318
5550
|
if (!this.server.isAuthenticated) return;
|
|
5319
5551
|
if (
|
|
@@ -5887,6 +6119,23 @@ class AgentTab {
|
|
|
5887
6119
|
|
|
5888
6120
|
applyInventory(data) {
|
|
5889
6121
|
const previousSession = this.getLinkedSession();
|
|
6122
|
+
const previousSnapshot = JSON.stringify({
|
|
6123
|
+
runtimeId: this.runtimeId || '',
|
|
6124
|
+
runtimeKey: this.runtimeKey || '',
|
|
6125
|
+
acpSessionId: this.acpSessionId || '',
|
|
6126
|
+
agentId: this.agentId || '',
|
|
6127
|
+
agentLabel: this.agentLabel || '',
|
|
6128
|
+
title: this.title || '',
|
|
6129
|
+
commandLabel: this.commandLabel || '',
|
|
6130
|
+
terminalSessionId: this.terminalSessionId || '',
|
|
6131
|
+
cwd: this.cwd || '',
|
|
6132
|
+
createdAt: this.createdAt || '',
|
|
6133
|
+
status: this.status || 'ready',
|
|
6134
|
+
busy: !!this.busy,
|
|
6135
|
+
errorMessage: this.errorMessage || '',
|
|
6136
|
+
currentModeId: this.currentModeId || '',
|
|
6137
|
+
sessionCapabilities: this.sessionCapabilities || null
|
|
6138
|
+
});
|
|
5890
6139
|
this.runtimeId = data.runtimeId || this.runtimeId || '';
|
|
5891
6140
|
this.runtimeKey = data.runtimeKey || this.runtimeKey || '';
|
|
5892
6141
|
this.acpSessionId = data.acpSessionId || this.acpSessionId || '';
|
|
@@ -5901,7 +6150,32 @@ class AgentTab {
|
|
|
5901
6150
|
this.busy = typeof data.busy === 'boolean' ? data.busy : this.busy;
|
|
5902
6151
|
this.errorMessage = data.errorMessage || this.errorMessage || '';
|
|
5903
6152
|
this.currentModeId = data.currentModeId || this.currentModeId || '';
|
|
6153
|
+
this.sessionCapabilities = normalizeAgentSessionCapabilities(
|
|
6154
|
+
data.sessionCapabilities || this.sessionCapabilities
|
|
6155
|
+
);
|
|
5904
6156
|
const nextSession = this.getLinkedSession();
|
|
6157
|
+
const nextSnapshot = JSON.stringify({
|
|
6158
|
+
runtimeId: this.runtimeId || '',
|
|
6159
|
+
runtimeKey: this.runtimeKey || '',
|
|
6160
|
+
acpSessionId: this.acpSessionId || '',
|
|
6161
|
+
agentId: this.agentId || '',
|
|
6162
|
+
agentLabel: this.agentLabel || '',
|
|
6163
|
+
title: this.title || '',
|
|
6164
|
+
commandLabel: this.commandLabel || '',
|
|
6165
|
+
terminalSessionId: this.terminalSessionId || '',
|
|
6166
|
+
cwd: this.cwd || '',
|
|
6167
|
+
createdAt: this.createdAt || '',
|
|
6168
|
+
status: this.status || 'ready',
|
|
6169
|
+
busy: !!this.busy,
|
|
6170
|
+
errorMessage: this.errorMessage || '',
|
|
6171
|
+
currentModeId: this.currentModeId || '',
|
|
6172
|
+
sessionCapabilities: this.sessionCapabilities || null
|
|
6173
|
+
});
|
|
6174
|
+
const changed = previousSnapshot !== nextSnapshot
|
|
6175
|
+
|| previousSession?.key !== nextSession?.key;
|
|
6176
|
+
if (!changed) {
|
|
6177
|
+
return false;
|
|
6178
|
+
}
|
|
5905
6179
|
previousSession?.updateTabUI();
|
|
5906
6180
|
if (nextSession && nextSession !== previousSession) {
|
|
5907
6181
|
nextSession.updateTabUI();
|
|
@@ -5909,6 +6183,7 @@ class AgentTab {
|
|
|
5909
6183
|
if (nextSession) {
|
|
5910
6184
|
refreshWorkspaceIfSessionActive(nextSession);
|
|
5911
6185
|
}
|
|
6186
|
+
return true;
|
|
5912
6187
|
}
|
|
5913
6188
|
|
|
5914
6189
|
async #waitForSettled(timeoutMs = 5000) {
|
|
@@ -6455,6 +6730,27 @@ function normalizeAgentConfigOptionOptions(options) {
|
|
|
6455
6730
|
return flattened;
|
|
6456
6731
|
}
|
|
6457
6732
|
|
|
6733
|
+
function normalizeAgentSessionCapabilities(sessionCapabilities) {
|
|
6734
|
+
const source = (
|
|
6735
|
+
sessionCapabilities && typeof sessionCapabilities === 'object'
|
|
6736
|
+
)
|
|
6737
|
+
? sessionCapabilities
|
|
6738
|
+
: {};
|
|
6739
|
+
return {
|
|
6740
|
+
load: !!source.load,
|
|
6741
|
+
list: !!source.list,
|
|
6742
|
+
resume: !!source.resume,
|
|
6743
|
+
fork: !!source.fork
|
|
6744
|
+
};
|
|
6745
|
+
}
|
|
6746
|
+
|
|
6747
|
+
function supportsAgentResumeCommand(agentTab) {
|
|
6748
|
+
const capabilities = normalizeAgentSessionCapabilities(
|
|
6749
|
+
agentTab?.sessionCapabilities
|
|
6750
|
+
);
|
|
6751
|
+
return !!(capabilities.load && capabilities.list);
|
|
6752
|
+
}
|
|
6753
|
+
|
|
6458
6754
|
function getAgentConfigOptionById(agentTab, configId) {
|
|
6459
6755
|
return normalizeAgentConfigOptions(agentTab?.configOptions).find(
|
|
6460
6756
|
(option) => option.id === configId
|
|
@@ -6555,6 +6851,7 @@ function normalizeAgentCommands(commands) {
|
|
|
6555
6851
|
: '';
|
|
6556
6852
|
if (!name) return null;
|
|
6557
6853
|
return {
|
|
6854
|
+
kind: 'command',
|
|
6558
6855
|
name,
|
|
6559
6856
|
description: command?.description || '',
|
|
6560
6857
|
inputHint: command?.input?.hint || ''
|
|
@@ -6563,6 +6860,107 @@ function normalizeAgentCommands(commands) {
|
|
|
6563
6860
|
.filter(Boolean);
|
|
6564
6861
|
}
|
|
6565
6862
|
|
|
6863
|
+
function normalizeListedAgentSessions(sessions) {
|
|
6864
|
+
if (!Array.isArray(sessions)) return [];
|
|
6865
|
+
const normalized = sessions
|
|
6866
|
+
.map((session, index) => {
|
|
6867
|
+
const sessionId = String(session?.sessionId || '').trim();
|
|
6868
|
+
const cwd = String(session?.cwd || '').trim();
|
|
6869
|
+
if (!sessionId || !cwd) return null;
|
|
6870
|
+
return {
|
|
6871
|
+
kind: 'resume_session',
|
|
6872
|
+
sortIndex: index,
|
|
6873
|
+
sessionId,
|
|
6874
|
+
cwd,
|
|
6875
|
+
title: typeof session?.title === 'string'
|
|
6876
|
+
? session.title
|
|
6877
|
+
: '',
|
|
6878
|
+
updatedAt: typeof session?.updatedAt === 'string'
|
|
6879
|
+
? session.updatedAt
|
|
6880
|
+
: '',
|
|
6881
|
+
relativeUpdatedAt: typeof session?.relativeUpdatedAt === 'string'
|
|
6882
|
+
? session.relativeUpdatedAt
|
|
6883
|
+
: ''
|
|
6884
|
+
};
|
|
6885
|
+
})
|
|
6886
|
+
.filter(Boolean);
|
|
6887
|
+
normalized.sort((left, right) => {
|
|
6888
|
+
const leftTime = Date.parse(left.updatedAt || '') || 0;
|
|
6889
|
+
const rightTime = Date.parse(right.updatedAt || '') || 0;
|
|
6890
|
+
if (leftTime !== rightTime) {
|
|
6891
|
+
return rightTime - leftTime;
|
|
6892
|
+
}
|
|
6893
|
+
return left.sortIndex - right.sortIndex;
|
|
6894
|
+
});
|
|
6895
|
+
return normalized;
|
|
6896
|
+
}
|
|
6897
|
+
|
|
6898
|
+
function getOpenAgentSessionsForServer(serverId, agentId = '') {
|
|
6899
|
+
const entries = Array.from(state.agentTabs.values())
|
|
6900
|
+
.filter((tab) => (
|
|
6901
|
+
tab.serverId === serverId
|
|
6902
|
+
&& (!agentId || tab.agentId === agentId)
|
|
6903
|
+
))
|
|
6904
|
+
.map((tab) => [String(tab.acpSessionId || '').trim(), tab])
|
|
6905
|
+
.filter(([sessionId]) => !!sessionId);
|
|
6906
|
+
return new Map(entries);
|
|
6907
|
+
}
|
|
6908
|
+
|
|
6909
|
+
function buildAgentResumeSessionMeta(sessionInfo) {
|
|
6910
|
+
const parts = [];
|
|
6911
|
+
const relativeUpdatedAt = String(
|
|
6912
|
+
sessionInfo?.relativeUpdatedAt || ''
|
|
6913
|
+
).trim();
|
|
6914
|
+
if (relativeUpdatedAt) {
|
|
6915
|
+
parts.push(relativeUpdatedAt);
|
|
6916
|
+
}
|
|
6917
|
+
const timeLabel = getAgentMessageTimeLabel({
|
|
6918
|
+
createdAt: sessionInfo?.updatedAt || ''
|
|
6919
|
+
});
|
|
6920
|
+
if (timeLabel && !relativeUpdatedAt) {
|
|
6921
|
+
parts.push(timeLabel);
|
|
6922
|
+
}
|
|
6923
|
+
const cwd = String(sessionInfo?.cwd || '').trim();
|
|
6924
|
+
if (cwd) {
|
|
6925
|
+
parts.push(shortenPath(cwd, 48));
|
|
6926
|
+
}
|
|
6927
|
+
return parts.join(' · ');
|
|
6928
|
+
}
|
|
6929
|
+
|
|
6930
|
+
function getAgentPromptIntent(agentTab, promptValue) {
|
|
6931
|
+
const source = String(promptValue || '').replace(/^\s+/, '');
|
|
6932
|
+
const firstLine = source.split('\n', 1)[0] || '';
|
|
6933
|
+
if (!firstLine.startsWith('/')) {
|
|
6934
|
+
return { kind: 'none', query: '', commandName: '' };
|
|
6935
|
+
}
|
|
6936
|
+
const body = firstLine.slice(1);
|
|
6937
|
+
const [commandNameRaw = '', ...restParts] = body.split(/\s+/);
|
|
6938
|
+
const commandName = commandNameRaw.toLowerCase();
|
|
6939
|
+
const query = restParts.join(' ').trim();
|
|
6940
|
+
if (!commandName) {
|
|
6941
|
+
return { kind: 'commands', query: '', commandName: '' };
|
|
6942
|
+
}
|
|
6943
|
+
if (commandName === 'resume' && supportsAgentResumeCommand(agentTab)) {
|
|
6944
|
+
return {
|
|
6945
|
+
kind: 'resume',
|
|
6946
|
+
query,
|
|
6947
|
+
commandName
|
|
6948
|
+
};
|
|
6949
|
+
}
|
|
6950
|
+
if (!/\s/.test(body)) {
|
|
6951
|
+
return {
|
|
6952
|
+
kind: 'commands',
|
|
6953
|
+
query: commandName,
|
|
6954
|
+
commandName
|
|
6955
|
+
};
|
|
6956
|
+
}
|
|
6957
|
+
return {
|
|
6958
|
+
kind: 'other',
|
|
6959
|
+
query,
|
|
6960
|
+
commandName
|
|
6961
|
+
};
|
|
6962
|
+
}
|
|
6963
|
+
|
|
6566
6964
|
function bindSingleTapActivation(element, onActivate, options = {}) {
|
|
6567
6965
|
if (!element || typeof onActivate !== 'function') {
|
|
6568
6966
|
return;
|
|
@@ -6724,17 +7122,19 @@ function selectAgentMessageText(previousText, nextText) {
|
|
|
6724
7122
|
}
|
|
6725
7123
|
|
|
6726
7124
|
function getAgentCommandSuggestions(agentTab, promptValue) {
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
const
|
|
6731
|
-
if (
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
7125
|
+
const intent = getAgentPromptIntent(agentTab, promptValue);
|
|
7126
|
+
if (intent.kind !== 'commands') return [];
|
|
7127
|
+
|
|
7128
|
+
const commands = normalizeAgentCommands(agentTab?.availableCommands);
|
|
7129
|
+
if (supportsAgentResumeCommand(agentTab)) {
|
|
7130
|
+
commands.unshift({
|
|
7131
|
+
kind: 'command',
|
|
7132
|
+
name: 'resume',
|
|
7133
|
+
description: 'Continue from a previous session',
|
|
7134
|
+
inputHint: ''
|
|
7135
|
+
});
|
|
7136
|
+
}
|
|
7137
|
+
const query = String(intent.query || '').toLowerCase();
|
|
6738
7138
|
const ranked = commands.filter((command) => {
|
|
6739
7139
|
const name = command.name.toLowerCase();
|
|
6740
7140
|
return !query || name.startsWith(query) || name.includes(query);
|
|
@@ -6752,6 +7152,52 @@ function getAgentCommandSuggestions(agentTab, promptValue) {
|
|
|
6752
7152
|
return ranked.slice(0, 8);
|
|
6753
7153
|
}
|
|
6754
7154
|
|
|
7155
|
+
function getAgentResumeSuggestions(agentTab, promptValue, sessions = []) {
|
|
7156
|
+
const intent = getAgentPromptIntent(agentTab, promptValue);
|
|
7157
|
+
if (intent.kind !== 'resume') return [];
|
|
7158
|
+
const query = String(intent.query || '').toLowerCase();
|
|
7159
|
+
const openSessions = getOpenAgentSessionsForServer(
|
|
7160
|
+
agentTab?.serverId,
|
|
7161
|
+
agentTab?.agentId
|
|
7162
|
+
);
|
|
7163
|
+
const currentSessionId = String(agentTab?.acpSessionId || '').trim();
|
|
7164
|
+
return normalizeListedAgentSessions(sessions)
|
|
7165
|
+
.filter((session) => session.sessionId !== currentSessionId)
|
|
7166
|
+
.map((session, index) => {
|
|
7167
|
+
const displayName = String(
|
|
7168
|
+
session.title || shortenPath(session.cwd, 36)
|
|
7169
|
+
).toLowerCase();
|
|
7170
|
+
const cwd = String(session.cwd || '').toLowerCase();
|
|
7171
|
+
const sessionId = String(session.sessionId || '').toLowerCase();
|
|
7172
|
+
const titleMatch = !query || displayName.includes(query);
|
|
7173
|
+
const otherMatch = !query || cwd.includes(query) || sessionId.includes(query);
|
|
7174
|
+
return {
|
|
7175
|
+
session,
|
|
7176
|
+
index,
|
|
7177
|
+
titleMatch,
|
|
7178
|
+
matched: titleMatch || otherMatch
|
|
7179
|
+
};
|
|
7180
|
+
})
|
|
7181
|
+
.filter(({ matched }) => matched)
|
|
7182
|
+
.sort((left, right) => {
|
|
7183
|
+
if (left.titleMatch !== right.titleMatch) {
|
|
7184
|
+
return left.titleMatch ? -1 : 1;
|
|
7185
|
+
}
|
|
7186
|
+
return left.index - right.index;
|
|
7187
|
+
})
|
|
7188
|
+
.map(({ session }) => session)
|
|
7189
|
+
.slice(0, 12)
|
|
7190
|
+
.map((session) => ({
|
|
7191
|
+
...session,
|
|
7192
|
+
openTabKey: openSessions.get(session.sessionId)?.key || '',
|
|
7193
|
+
displayName: session.title || shortenPath(session.cwd, 36),
|
|
7194
|
+
description: [
|
|
7195
|
+
buildAgentResumeSessionMeta(session) || session.sessionId,
|
|
7196
|
+
openSessions.has(session.sessionId) ? 'Already open' : ''
|
|
7197
|
+
].filter(Boolean).join(' · ')
|
|
7198
|
+
}));
|
|
7199
|
+
}
|
|
7200
|
+
|
|
6755
7201
|
function getCurrentAgentModeLabel(agentTab) {
|
|
6756
7202
|
const currentModeId = agentTab?.currentModeId || '';
|
|
6757
7203
|
if (!currentModeId) return '';
|
|
@@ -9100,13 +9546,19 @@ function upsertAgentInventoryTab(server, data) {
|
|
|
9100
9546
|
const key = makeAgentTabKey(server.id, data.id);
|
|
9101
9547
|
const existing = state.agentTabs.get(key);
|
|
9102
9548
|
if (existing) {
|
|
9103
|
-
existing.applyInventory(data);
|
|
9549
|
+
const changed = existing.applyInventory(data);
|
|
9104
9550
|
existing.connect();
|
|
9105
|
-
return
|
|
9551
|
+
return {
|
|
9552
|
+
agentTab: existing,
|
|
9553
|
+
changed
|
|
9554
|
+
};
|
|
9106
9555
|
}
|
|
9107
9556
|
const agentTab = new AgentTab(data, server);
|
|
9108
9557
|
state.agentTabs.set(key, agentTab);
|
|
9109
|
-
return
|
|
9558
|
+
return {
|
|
9559
|
+
agentTab,
|
|
9560
|
+
changed: true
|
|
9561
|
+
};
|
|
9110
9562
|
}
|
|
9111
9563
|
|
|
9112
9564
|
function reconcileAgentInventory(server, inventory) {
|
|
@@ -9118,8 +9570,11 @@ function reconcileAgentInventory(server, inventory) {
|
|
|
9118
9570
|
const touchedSessions = new Set();
|
|
9119
9571
|
|
|
9120
9572
|
for (const tabData of Array.isArray(inventory.tabs) ? inventory.tabs : []) {
|
|
9121
|
-
const agentTab = upsertAgentInventoryTab(server, tabData);
|
|
9573
|
+
const { agentTab, changed } = upsertAgentInventoryTab(server, tabData);
|
|
9122
9574
|
seenKeys.add(agentTab.key);
|
|
9575
|
+
if (!changed) {
|
|
9576
|
+
continue;
|
|
9577
|
+
}
|
|
9123
9578
|
const session = agentTab.getLinkedSession();
|
|
9124
9579
|
if (session) {
|
|
9125
9580
|
touchedSessions.add(session.key);
|
|
@@ -9331,16 +9786,23 @@ async function createAgentTab(session, agentId, options = {}) {
|
|
|
9331
9786
|
await throwResponseError(response, 'Failed to create agent tab');
|
|
9332
9787
|
}
|
|
9333
9788
|
const data = await response.json();
|
|
9334
|
-
|
|
9789
|
+
return await activateAgentTab(
|
|
9790
|
+
session,
|
|
9791
|
+
upsertAgentTab(session.server, data)
|
|
9792
|
+
);
|
|
9793
|
+
}
|
|
9794
|
+
|
|
9795
|
+
async function activateAgentTab(session, agentTab, options = {}) {
|
|
9796
|
+
if (!session || !agentTab) return null;
|
|
9797
|
+
const shouldSwitchSession = !!options.switchSession;
|
|
9798
|
+
if (shouldSwitchSession && state.activeSessionKey !== session.key) {
|
|
9799
|
+
await switchToSession(session.key, { scrollTabIntoView: true });
|
|
9800
|
+
}
|
|
9335
9801
|
session.workspaceState.activeTabKey = agentTab.key;
|
|
9336
9802
|
noteRecentAgentTab(session, agentTab.key);
|
|
9337
9803
|
session.saveState();
|
|
9338
9804
|
if (state.activeSessionKey === session.key) {
|
|
9339
|
-
|
|
9340
|
-
editorManager.switchTo(session);
|
|
9341
|
-
}
|
|
9342
|
-
editorManager.activateAgentTab(agentTab.key);
|
|
9343
|
-
editorManager.updateEditorPaneVisibility();
|
|
9805
|
+
restoreWorkspaceForSession(session);
|
|
9344
9806
|
requestAnimationFrame(() => {
|
|
9345
9807
|
editorManager.agentPrompt?.focus();
|
|
9346
9808
|
});
|
|
@@ -9350,6 +9812,29 @@ async function createAgentTab(session, agentId, options = {}) {
|
|
|
9350
9812
|
return agentTab;
|
|
9351
9813
|
}
|
|
9352
9814
|
|
|
9815
|
+
async function resumeAgentTabFromHistory(session, agentTab, historySession) {
|
|
9816
|
+
if (!session || !agentTab || !historySession?.sessionId) return null;
|
|
9817
|
+
const response = await session.server.fetch('/api/agents/tabs/resume', {
|
|
9818
|
+
method: 'POST',
|
|
9819
|
+
headers: { 'Content-Type': 'application/json' },
|
|
9820
|
+
body: JSON.stringify({
|
|
9821
|
+
agentId: agentTab.agentId,
|
|
9822
|
+
cwd: agentTab.cwd || session.cwd || session.initialCwd || '/',
|
|
9823
|
+
terminalSessionId: session.id,
|
|
9824
|
+
sessionId: historySession.sessionId,
|
|
9825
|
+
title: historySession.title || ''
|
|
9826
|
+
})
|
|
9827
|
+
});
|
|
9828
|
+
if (!response.ok) {
|
|
9829
|
+
await throwResponseError(response, 'Failed to resume agent session');
|
|
9830
|
+
}
|
|
9831
|
+
const data = await response.json();
|
|
9832
|
+
return await activateAgentTab(
|
|
9833
|
+
session,
|
|
9834
|
+
upsertAgentTab(session.server, data)
|
|
9835
|
+
);
|
|
9836
|
+
}
|
|
9837
|
+
|
|
9353
9838
|
function getServerEndpointKey(server) {
|
|
9354
9839
|
if (!server) return '';
|
|
9355
9840
|
return getServerEndpointKeyFromUrl(server.baseUrl);
|
|
@@ -11686,6 +12171,52 @@ if (shortcutsModal) {
|
|
|
11686
12171
|
});
|
|
11687
12172
|
}
|
|
11688
12173
|
|
|
12174
|
+
function handleAgentCommandMenuShortcut(event) {
|
|
12175
|
+
const agentCommandMenuOpen = !!(
|
|
12176
|
+
editorManager?.agentCommandMenu
|
|
12177
|
+
&& editorManager.agentCommandMenu.style.display !== 'none'
|
|
12178
|
+
&& editorManager.agentCommandSuggestions.length > 0
|
|
12179
|
+
);
|
|
12180
|
+
const eventFromAgentPrompt = editorManager?.agentPrompt
|
|
12181
|
+
&& event.target === editorManager.agentPrompt;
|
|
12182
|
+
if (
|
|
12183
|
+
!agentCommandMenuOpen
|
|
12184
|
+
|| eventFromAgentPrompt
|
|
12185
|
+
|| event.ctrlKey
|
|
12186
|
+
|| event.metaKey
|
|
12187
|
+
|| event.altKey
|
|
12188
|
+
) {
|
|
12189
|
+
return false;
|
|
12190
|
+
}
|
|
12191
|
+
if (event.key === 'Escape') {
|
|
12192
|
+
event.preventDefault();
|
|
12193
|
+
editorManager.hideAgentCommandMenu();
|
|
12194
|
+
return true;
|
|
12195
|
+
}
|
|
12196
|
+
if (event.key === 'ArrowDown') {
|
|
12197
|
+
event.preventDefault();
|
|
12198
|
+
editorManager.moveAgentCommandSelection(1);
|
|
12199
|
+
return true;
|
|
12200
|
+
}
|
|
12201
|
+
if (event.key === 'ArrowUp') {
|
|
12202
|
+
event.preventDefault();
|
|
12203
|
+
editorManager.moveAgentCommandSelection(-1);
|
|
12204
|
+
return true;
|
|
12205
|
+
}
|
|
12206
|
+
if (event.key === 'Tab' || event.key === 'Enter') {
|
|
12207
|
+
event.preventDefault();
|
|
12208
|
+
void editorManager.applyAgentCommandSuggestion();
|
|
12209
|
+
return true;
|
|
12210
|
+
}
|
|
12211
|
+
return false;
|
|
12212
|
+
}
|
|
12213
|
+
|
|
12214
|
+
document.addEventListener('keydown', (e) => {
|
|
12215
|
+
if (handleAgentCommandMenuShortcut(e)) {
|
|
12216
|
+
e.stopImmediatePropagation();
|
|
12217
|
+
}
|
|
12218
|
+
}, true);
|
|
12219
|
+
|
|
11689
12220
|
// Keyboard Shortcuts
|
|
11690
12221
|
document.addEventListener('keydown', (e) => {
|
|
11691
12222
|
if (
|