@lvce-editor/chat-view 6.19.0 → 6.22.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.
@@ -1252,6 +1252,10 @@ const showContextMenu2 = async (uid, menuId, x, y, args) => {
1252
1252
  number(y);
1253
1253
  await invoke$2('ContextMenu.show2', uid, menuId, x, y, args);
1254
1254
  };
1255
+ const sendMessagePortToClipBoardWorker$1 = async (port, rpcId) => {
1256
+ const command = 'ClipBoard.handleMessagePort';
1257
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToClipBoardWorker', port, command, rpcId);
1258
+ };
1255
1259
  const sendMessagePortToOpenerWorker$1 = async (port, rpcId) => {
1256
1260
  const command = 'HandleMessagePort.handleMessagePort';
1257
1261
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToOpenerWorker', port, command, rpcId);
@@ -1403,6 +1407,104 @@ const terminate = () => {
1403
1407
  globalThis.close();
1404
1408
  };
1405
1409
 
1410
+ const getVisibleSessions = (sessions, selectedProjectId) => {
1411
+ if (!selectedProjectId) {
1412
+ return sessions;
1413
+ }
1414
+ const hasAssignedProjects = sessions.some(session => !!session.projectId);
1415
+ if (!hasAssignedProjects) {
1416
+ return sessions;
1417
+ }
1418
+ return sessions.filter(session => session.projectId === selectedProjectId);
1419
+ };
1420
+
1421
+ const chatListFocusFirst = async state => {
1422
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
1423
+ if (visibleSessions.length === 0) {
1424
+ return {
1425
+ ...state,
1426
+ focus: 'list',
1427
+ focused: true,
1428
+ listFocusedIndex: -1
1429
+ };
1430
+ }
1431
+ return {
1432
+ ...state,
1433
+ focus: 'list',
1434
+ focused: true,
1435
+ listFocusedIndex: 0
1436
+ };
1437
+ };
1438
+
1439
+ const chatListFocusLast = async state => {
1440
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
1441
+ if (visibleSessions.length === 0) {
1442
+ return {
1443
+ ...state,
1444
+ focus: 'list',
1445
+ focused: true,
1446
+ listFocusedIndex: -1
1447
+ };
1448
+ }
1449
+ return {
1450
+ ...state,
1451
+ focus: 'list',
1452
+ focused: true,
1453
+ listFocusedIndex: visibleSessions.length - 1
1454
+ };
1455
+ };
1456
+
1457
+ const getListFocusIndex = state => {
1458
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
1459
+ if (visibleSessions.length === 0) {
1460
+ return -1;
1461
+ }
1462
+ if (state.listFocusedIndex >= 0 && state.listFocusedIndex < visibleSessions.length) {
1463
+ return state.listFocusedIndex;
1464
+ }
1465
+ return -1;
1466
+ };
1467
+
1468
+ const chatListFocusNext = async state => {
1469
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
1470
+ if (visibleSessions.length === 0) {
1471
+ return {
1472
+ ...state,
1473
+ focus: 'list',
1474
+ focused: true,
1475
+ listFocusedIndex: -1
1476
+ };
1477
+ }
1478
+ const currentIndex = getListFocusIndex(state);
1479
+ const nextIndex = currentIndex === -1 ? 0 : Math.min(currentIndex + 1, visibleSessions.length - 1);
1480
+ return {
1481
+ ...state,
1482
+ focus: 'list',
1483
+ focused: true,
1484
+ listFocusedIndex: nextIndex
1485
+ };
1486
+ };
1487
+
1488
+ const chatListFocusPrevious = async state => {
1489
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
1490
+ if (visibleSessions.length === 0) {
1491
+ return {
1492
+ ...state,
1493
+ focus: 'list',
1494
+ focused: true,
1495
+ listFocusedIndex: -1
1496
+ };
1497
+ }
1498
+ const currentIndex = getListFocusIndex(state);
1499
+ const previousIndex = currentIndex === -1 ? visibleSessions.length - 1 : Math.max(currentIndex - 1, 0);
1500
+ return {
1501
+ ...state,
1502
+ focus: 'list',
1503
+ focused: true,
1504
+ listFocusedIndex: previousIndex
1505
+ };
1506
+ };
1507
+
1406
1508
  const measureTextBlockHeight = async (text, fontFamily, fontSize, lineHeight, width) => {
1407
1509
  // Upstream renderer types currently require number, but runtime accepts px strings.
1408
1510
  // Keep forwarding the string to preserve chat-view behavior until upstream is updated.
@@ -1457,6 +1559,19 @@ const clearInput = async state => {
1457
1559
  };
1458
1560
  };
1459
1561
 
1562
+ let text$1 = '';
1563
+ const writeText = async value => {
1564
+ text$1 = value;
1565
+ };
1566
+ const readText = async () => {
1567
+ return text$1;
1568
+ };
1569
+
1570
+ const copyInput = async state => {
1571
+ await writeText(state.composerValue);
1572
+ return state;
1573
+ };
1574
+
1460
1575
  const emptyObject = {};
1461
1576
  const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1462
1577
  const i18nString = (key, placeholders = emptyObject) => {
@@ -1478,12 +1593,18 @@ const chats = () => {
1478
1593
  const newChat = () => {
1479
1594
  return i18nString('New Chat');
1480
1595
  };
1596
+ const addProject = () => {
1597
+ return i18nString('Add Project');
1598
+ };
1481
1599
  const debug = () => {
1482
1600
  return i18nString('Debug');
1483
1601
  };
1484
1602
  const backToChats = () => {
1485
1603
  return i18nString('Back to chats');
1486
1604
  };
1605
+ const backToChatList = () => {
1606
+ return i18nString('Back to chat list');
1607
+ };
1487
1608
  const settings = () => {
1488
1609
  return i18nString('Settings');
1489
1610
  };
@@ -1697,6 +1818,7 @@ const createDefaultState = () => {
1697
1818
  inputSource: 'script',
1698
1819
  lastNormalViewMode: 'list',
1699
1820
  lastSubmittedSessionId: '',
1821
+ listFocusedIndex: -1,
1700
1822
  listItemHeight: 40,
1701
1823
  maxComposerRows: 5,
1702
1824
  messagesAutoScrollEnabled: true,
@@ -1794,6 +1916,11 @@ const create = (uid, x, y, width, height, platform, assetDir) => {
1794
1916
  set$1(uid, state, state);
1795
1917
  };
1796
1918
 
1919
+ const cutInput = async state => {
1920
+ await writeText(state.composerValue);
1921
+ return clearInput(state);
1922
+ };
1923
+
1797
1924
  const invoke$1 = async (method, ...params) => {
1798
1925
  {
1799
1926
  throw new Error('ChatStorageWorker is not initialized');
@@ -2463,17 +2590,6 @@ const getNextSelectedSessionId = (sessions, deletedId) => {
2463
2590
  return sessions[nextIndex].id;
2464
2591
  };
2465
2592
 
2466
- const getVisibleSessions = (sessions, selectedProjectId) => {
2467
- if (!selectedProjectId) {
2468
- return sessions;
2469
- }
2470
- const hasAssignedProjects = sessions.some(session => !!session.projectId);
2471
- if (!hasAssignedProjects) {
2472
- return sessions;
2473
- }
2474
- return sessions.filter(session => session.projectId === selectedProjectId);
2475
- };
2476
-
2477
2593
  const deleteSession = async (state, id) => {
2478
2594
  const {
2479
2595
  renamingSessionId,
@@ -2591,7 +2707,7 @@ const isEqualProjectExpandedIds = (a, b) => {
2591
2707
  return true;
2592
2708
  };
2593
2709
  const isEqual = (oldState, newState) => {
2594
- return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage && oldState.authStatus === newState.authStatus && oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && oldState.modelPickerOpen === newState.modelPickerOpen && oldState.modelPickerSearchValue === newState.modelPickerSearchValue && oldState.newChatModelPickerEnabled === newState.newChatModelPickerEnabled && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && oldState.projectListScrollTop === newState.projectListScrollTop && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.showRunMode === newState.showRunMode && oldState.runMode === newState.runMode && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.useChatMathWorker === newState.useChatMathWorker && oldState.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
2710
+ return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage && oldState.authStatus === newState.authStatus && oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && oldState.modelPickerOpen === newState.modelPickerOpen && oldState.modelPickerSearchValue === newState.modelPickerSearchValue && oldState.newChatModelPickerEnabled === newState.newChatModelPickerEnabled && oldState.listFocusedIndex === newState.listFocusedIndex && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && oldState.projectListScrollTop === newState.projectListScrollTop && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.showRunMode === newState.showRunMode && oldState.runMode === newState.runMode && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.useChatMathWorker === newState.useChatMathWorker && oldState.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
2595
2711
  };
2596
2712
 
2597
2713
  const diffScrollTop = (oldState, newState) => {
@@ -3004,20 +3120,160 @@ const deleteItem = () => {
3004
3120
  return i18nString(Delete);
3005
3121
  };
3006
3122
 
3007
- const getMenuEntriesChatList = () => {
3123
+ const getMenuEntriesChatHeader = () => {
3124
+ // TODO
3008
3125
  return [{
3126
+ command: 'Chat.handleInputCut',
3127
+ flags: None,
3128
+ id: 'cut',
3129
+ label: cut()
3130
+ }, {
3131
+ command: 'Chat.handleInputCopy',
3132
+ flags: None,
3133
+ id: 'copy',
3134
+ label: copy()
3135
+ }, {
3136
+ command: 'Chat.handleInputPaste',
3137
+ flags: None,
3138
+ id: 'copy',
3139
+ label: paste()
3140
+ }];
3141
+ };
3142
+
3143
+ const getMenuEntriesChatInput = () => {
3144
+ return [{
3145
+ command: 'Chat.handleInputCut',
3146
+ flags: None,
3147
+ id: 'cut',
3148
+ label: cut()
3149
+ }, {
3150
+ command: 'Chat.handleInputCopy',
3151
+ flags: None,
3152
+ id: 'copy',
3153
+ label: copy()
3154
+ }, {
3155
+ command: 'Chat.handleInputPaste',
3156
+ flags: None,
3157
+ id: 'copy',
3158
+ label: paste()
3159
+ }];
3160
+ };
3161
+
3162
+ const getMenuEntriesChatList = (sessionId = '') => {
3163
+ return [{
3164
+ args: [sessionId],
3009
3165
  command: 'Chat.handleClickRename',
3010
3166
  flags: None,
3011
3167
  id: 'rename',
3012
3168
  label: rename()
3013
3169
  }, {
3014
- command: 'Chat.handleClickArchive',
3170
+ args: [sessionId],
3171
+ command: 'Chat.handleClickDelete',
3015
3172
  flags: None,
3016
3173
  id: 'archive',
3017
3174
  label: archive()
3018
3175
  }];
3019
3176
  };
3020
3177
 
3178
+ const Composer = 'composer';
3179
+ const Search = 'search';
3180
+ const ComposerDropTarget = 'composer-drop-target';
3181
+ const AddContext = 'add-context';
3182
+ const Dictate = 'dictate';
3183
+ const Send = 'send';
3184
+ const Back = 'back';
3185
+ const Model = 'model';
3186
+ const ModelPickerToggle = 'model-picker-toggle';
3187
+ const ModelPickerSearch = 'model-picker-search';
3188
+ const ModelPickerSettings = 'model-picker-settings';
3189
+ const RunMode = 'runMode';
3190
+ const ToggleChatFocus = 'toggle-chat-focus';
3191
+ const ToggleSearch = 'toggle-search';
3192
+ const ChatList$1 = 'chat-list';
3193
+ const CreateProject = 'create-project';
3194
+ const CreateSession = 'create-session';
3195
+ const CreateSessionInProjectPrefix = 'create-session-in-project:';
3196
+ const SessionDebug = 'session-debug';
3197
+ const Settings = 'settings';
3198
+ const Login = 'login';
3199
+ const Logout = 'logout';
3200
+ const CloseChat = 'close-chat';
3201
+ const SessionDelete = 'SessionDelete';
3202
+ const ProjectPrefix = 'project:';
3203
+ const SessionPrefix = 'session:';
3204
+ const RenamePrefix = 'session-rename:';
3205
+ const ModelPickerItemPrefix = 'model-picker-item:';
3206
+ const getProjectInputName = projectId => {
3207
+ return `${ProjectPrefix}${projectId}`;
3208
+ };
3209
+ const getCreateSessionInProjectInputName = projectId => {
3210
+ return `${CreateSessionInProjectPrefix}${projectId}`;
3211
+ };
3212
+ const isCreateSessionInProjectInputName = name => {
3213
+ return name.startsWith(CreateSessionInProjectPrefix);
3214
+ };
3215
+ const getProjectIdFromCreateSessionInProjectInputName = name => {
3216
+ return name.slice(CreateSessionInProjectPrefix.length);
3217
+ };
3218
+ const isProjectInputName = name => {
3219
+ return name.startsWith(ProjectPrefix);
3220
+ };
3221
+ const getProjectIdFromInputName = name => {
3222
+ return name.slice(ProjectPrefix.length);
3223
+ };
3224
+ const getSessionInputName = sessionId => {
3225
+ return `${SessionPrefix}${sessionId}`;
3226
+ };
3227
+ const isSessionInputName = name => {
3228
+ return name.startsWith(SessionPrefix);
3229
+ };
3230
+ const getSessionIdFromInputName = name => {
3231
+ return name.slice(SessionPrefix.length);
3232
+ };
3233
+ const isRenameInputName = name => {
3234
+ return name.startsWith(RenamePrefix);
3235
+ };
3236
+ const getRenameIdFromInputName = name => {
3237
+ return name.slice(RenamePrefix.length);
3238
+ };
3239
+ const getModelPickerItemInputName = modelId => {
3240
+ return `${ModelPickerItemPrefix}${modelId}`;
3241
+ };
3242
+ const isModelPickerItemInputName = name => {
3243
+ return name.startsWith(ModelPickerItemPrefix);
3244
+ };
3245
+ const getModelIdFromModelPickerItemInputName = name => {
3246
+ return name.slice(ModelPickerItemPrefix.length);
3247
+ };
3248
+
3249
+ const menuEntryAddProject = {
3250
+ args: [CreateProject],
3251
+ command: 'Chat.handleClick',
3252
+ flags: None,
3253
+ id: 'addProject',
3254
+ label: addProject()
3255
+ };
3256
+ const getMenuEntriesChatProjectList = (projectId = '') => {
3257
+ if (!projectId) {
3258
+ return [menuEntryAddProject];
3259
+ }
3260
+ return [{
3261
+ args: [getCreateSessionInProjectInputName(projectId)],
3262
+ command: 'Chat.handleClick',
3263
+ flags: None,
3264
+ id: 'newChat',
3265
+ label: newChat()
3266
+ }, menuEntryAddProject];
3267
+ };
3268
+
3269
+ const MenuChatList = 2178;
3270
+ const MenuChatHeader = 2179;
3271
+ const MenuChatInput = 2180;
3272
+ const MenuChatProjectList = 2181;
3273
+ const getMenuEntryIds = () => {
3274
+ return [Chat$1, MenuChatList, MenuChatHeader, MenuChatInput, MenuChatProjectList];
3275
+ };
3276
+
3021
3277
  const menuEntrySeparator = {
3022
3278
  command: '',
3023
3279
  flags: Separator,
@@ -3088,19 +3344,21 @@ const menuEntryDelete = {
3088
3344
  const getMenuEntriesFile = () => {
3089
3345
  return [menuEntryCopyAsE2eTest, menuEntryOpenContainingFolder, menuEntryOpenInIntegratedTerminal, menuEntrySeparator, menuEntryCut, menuEntryCopy, menuEntryPaste, menuEntrySeparator, menuEntryCopyPath, menuEntryCopyRelativePath, menuEntrySeparator, menuEntryRename, menuEntryDelete];
3090
3346
  };
3091
- const getMenuEntries = menuId => {
3092
- switch (menuId) {
3093
- case 1:
3347
+ const getMenuEntries = (menuId, props) => {
3348
+ switch (props.menuId) {
3349
+ case MenuChatHeader:
3350
+ return getMenuEntriesChatHeader();
3351
+ case MenuChatInput:
3352
+ return getMenuEntriesChatInput();
3353
+ case MenuChatList:
3094
3354
  return getMenuEntriesChatList();
3355
+ case MenuChatProjectList:
3356
+ return getMenuEntriesChatProjectList(props.projectId);
3095
3357
  default:
3096
3358
  return getMenuEntriesFile();
3097
3359
  }
3098
3360
  };
3099
3361
 
3100
- const getMenuEntryIds = () => {
3101
- return [Chat$1];
3102
- };
3103
-
3104
3362
  const getQuickPickMenuEntries = () => {
3105
3363
  return [];
3106
3364
  };
@@ -3109,6 +3367,10 @@ const getSelectedSessionId = state => {
3109
3367
  return state.selectedSessionId;
3110
3368
  };
3111
3369
 
3370
+ const handleChatDetailWelcomeContextMenu = async state => {
3371
+ return state;
3372
+ };
3373
+
3112
3374
  const handleChatHeaderContextMenu = async state => {
3113
3375
  return state;
3114
3376
  };
@@ -3149,17 +3411,13 @@ const handleChatListContextMenu = async (state, eventX, eventY) => {
3149
3411
  if (!item) {
3150
3412
  return state;
3151
3413
  }
3152
- await showContextMenu2(uid, -1, eventX, eventY, {
3153
- menuId: -1,
3414
+ await showContextMenu2(uid, MenuChatList, eventX, eventY, {
3415
+ menuId: MenuChatList,
3154
3416
  sessionId: item.id
3155
3417
  });
3156
3418
  return state;
3157
3419
  };
3158
3420
 
3159
- const handleChatWelcomeContextMenu = async state => {
3160
- return state;
3161
- };
3162
-
3163
3421
  const generateSessionId = () => {
3164
3422
  return crypto.randomUUID();
3165
3423
  };
@@ -7028,7 +7286,8 @@ const focusInput = state => {
7028
7286
  return {
7029
7287
  ...state,
7030
7288
  focus: 'composer',
7031
- focused: true
7289
+ focused: true,
7290
+ listFocusedIndex: -1
7032
7291
  };
7033
7292
  };
7034
7293
 
@@ -7753,76 +8012,6 @@ const handleClickSend = async state => {
7753
8012
  return handleSubmit(submitState);
7754
8013
  };
7755
8014
 
7756
- const Composer = 'composer';
7757
- const Search = 'search';
7758
- const ComposerDropTarget = 'composer-drop-target';
7759
- const AddContext = 'add-context';
7760
- const Dictate = 'dictate';
7761
- const Send = 'send';
7762
- const Back = 'back';
7763
- const Model = 'model';
7764
- const ModelPickerToggle = 'model-picker-toggle';
7765
- const ModelPickerSearch = 'model-picker-search';
7766
- const ModelPickerSettings = 'model-picker-settings';
7767
- const RunMode = 'runMode';
7768
- const ToggleChatFocus = 'toggle-chat-focus';
7769
- const ToggleSearch = 'toggle-search';
7770
- const CreateProject = 'create-project';
7771
- const CreateSession = 'create-session';
7772
- const CreateSessionInProjectPrefix = 'create-session-in-project:';
7773
- const SessionDebug = 'session-debug';
7774
- const Settings = 'settings';
7775
- const Login = 'login';
7776
- const Logout = 'logout';
7777
- const CloseChat = 'close-chat';
7778
- const SessionDelete = 'SessionDelete';
7779
- const ProjectPrefix = 'project:';
7780
- const SessionPrefix = 'session:';
7781
- const RenamePrefix = 'session-rename:';
7782
- const ModelPickerItemPrefix = 'model-picker-item:';
7783
- const getProjectInputName = projectId => {
7784
- return `${ProjectPrefix}${projectId}`;
7785
- };
7786
- const getCreateSessionInProjectInputName = projectId => {
7787
- return `${CreateSessionInProjectPrefix}${projectId}`;
7788
- };
7789
- const isCreateSessionInProjectInputName = name => {
7790
- return name.startsWith(CreateSessionInProjectPrefix);
7791
- };
7792
- const getProjectIdFromCreateSessionInProjectInputName = name => {
7793
- return name.slice(CreateSessionInProjectPrefix.length);
7794
- };
7795
- const isProjectInputName = name => {
7796
- return name.startsWith(ProjectPrefix);
7797
- };
7798
- const getProjectIdFromInputName = name => {
7799
- return name.slice(ProjectPrefix.length);
7800
- };
7801
- const getSessionInputName = sessionId => {
7802
- return `${SessionPrefix}${sessionId}`;
7803
- };
7804
- const isSessionInputName = name => {
7805
- return name.startsWith(SessionPrefix);
7806
- };
7807
- const getSessionIdFromInputName = name => {
7808
- return name.slice(SessionPrefix.length);
7809
- };
7810
- const isRenameInputName = name => {
7811
- return name.startsWith(RenamePrefix);
7812
- };
7813
- const getRenameIdFromInputName = name => {
7814
- return name.slice(RenamePrefix.length);
7815
- };
7816
- const getModelPickerItemInputName = modelId => {
7817
- return `${ModelPickerItemPrefix}${modelId}`;
7818
- };
7819
- const isModelPickerItemInputName = name => {
7820
- return name.startsWith(ModelPickerItemPrefix);
7821
- };
7822
- const getModelIdFromModelPickerItemInputName = name => {
7823
- return name.slice(ModelPickerItemPrefix.length);
7824
- };
7825
-
7826
8015
  const OpenApiApiKeyInput = 'open-api-api-key';
7827
8016
  const SaveOpenApiApiKey = 'save-openapi-api-key';
7828
8017
  const OpenOpenApiApiKeySettings = 'open-openapi-api-key-settings';
@@ -7931,11 +8120,34 @@ const selectListIndex = async (state, index) => {
7931
8120
  return state;
7932
8121
  }
7933
8122
  const session = visibleSessions[index];
7934
- return selectSession(state, session.id);
8123
+ const nextState = await selectSession(state, session.id);
8124
+ return {
8125
+ ...nextState,
8126
+ focus: 'list',
8127
+ focused: true,
8128
+ listFocusedIndex: index
8129
+ };
7935
8130
  };
7936
8131
 
7937
8132
  const handleClickList = async (state, eventX, eventY) => {
7938
8133
  const index = getListIndex(state, eventX, eventY);
8134
+ if (index === -1) {
8135
+ return {
8136
+ ...state,
8137
+ focus: 'list',
8138
+ focused: true,
8139
+ listFocusedIndex: -1
8140
+ };
8141
+ }
8142
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
8143
+ if (index >= visibleSessions.length) {
8144
+ return {
8145
+ ...state,
8146
+ focus: 'list',
8147
+ focused: true,
8148
+ listFocusedIndex: -1
8149
+ };
8150
+ }
7939
8151
  return selectListIndex(state, index);
7940
8152
  };
7941
8153
 
@@ -8071,6 +8283,10 @@ const handleClickSettings = async () => {
8071
8283
  await invoke$2('Main.openUri', 'app://settings.json');
8072
8284
  };
8073
8285
 
8286
+ const handleContextMenuChatSendAreaBottom = async state => {
8287
+ return state;
8288
+ };
8289
+
8074
8290
  const handleDragEnter = async (state, name, hasFiles = true) => {
8075
8291
  if (name !== ComposerDropTarget) {
8076
8292
  return state;
@@ -8214,21 +8430,37 @@ const handleInputFocus = async (state, name) => {
8214
8430
  return {
8215
8431
  ...state,
8216
8432
  focus: 'send-button',
8217
- focused: true
8433
+ focused: true,
8434
+ listFocusedIndex: -1
8435
+ };
8436
+ }
8437
+ if (name === ChatList$1) {
8438
+ return {
8439
+ ...state,
8440
+ focus: 'list',
8441
+ focused: true,
8442
+ listFocusedIndex: -1
8218
8443
  };
8219
8444
  }
8220
8445
  if (isSessionInputName(name) || name === SessionDelete) {
8446
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
8447
+ const sessionId = isSessionInputName(name) ? getSessionIdFromInputName(name) : '';
8448
+ const focusedIndex = sessionId === '' ? -1 : visibleSessions.findIndex(session => {
8449
+ return session.id === sessionId;
8450
+ });
8221
8451
  return {
8222
8452
  ...state,
8223
8453
  focus: 'list',
8224
- focused: true
8454
+ focused: true,
8455
+ listFocusedIndex: focusedIndex
8225
8456
  };
8226
8457
  }
8227
8458
  if (name === CreateSession || name === SessionDebug || name === Settings || name === CloseChat || name === Back) {
8228
8459
  return {
8229
8460
  ...state,
8230
8461
  focus: 'header',
8231
- focused: true
8462
+ focused: true,
8463
+ listFocusedIndex: -1
8232
8464
  };
8233
8465
  }
8234
8466
  return {
@@ -8281,6 +8513,18 @@ const handleKeyDown = async (state, key, shiftKey) => {
8281
8513
  sessions,
8282
8514
  viewMode
8283
8515
  } = state;
8516
+ if (state.focus === 'list' && viewMode === 'list') {
8517
+ switch (key) {
8518
+ case 'ArrowDown':
8519
+ return chatListFocusNext(state);
8520
+ case 'ArrowUp':
8521
+ return chatListFocusPrevious(state);
8522
+ case 'End':
8523
+ return chatListFocusLast(state);
8524
+ case 'Home':
8525
+ return chatListFocusFirst(state);
8526
+ }
8527
+ }
8284
8528
  if (key !== 'Enter' || shiftKey) {
8285
8529
  return state;
8286
8530
  }
@@ -8329,7 +8573,50 @@ const handleNewline = async state => {
8329
8573
  return handleInput(state, Composer, `${composerValue}\n`);
8330
8574
  };
8331
8575
 
8332
- const handleProjectListContextMenu = async state => {
8576
+ const getProjectRowIds = (projects, sessions, projectExpandedIds) => {
8577
+ const blankProjectId = projects.find(project => project.name === '_blank')?.id || projects[0]?.id || '';
8578
+ const projectRowIds = [];
8579
+ for (const project of projects) {
8580
+ projectRowIds.push(project.id);
8581
+ if (!projectExpandedIds.includes(project.id)) {
8582
+ continue;
8583
+ }
8584
+ for (const session of sessions) {
8585
+ const sessionProjectId = session.projectId || blankProjectId;
8586
+ if (sessionProjectId === project.id) {
8587
+ projectRowIds.push(project.id);
8588
+ }
8589
+ }
8590
+ }
8591
+ return projectRowIds;
8592
+ };
8593
+ const getProjectIdAtPosition = (state, eventY) => {
8594
+ const {
8595
+ headerHeight,
8596
+ listItemHeight,
8597
+ projectExpandedIds,
8598
+ projectListScrollTop,
8599
+ projects,
8600
+ sessions,
8601
+ y
8602
+ } = state;
8603
+ const relativeY = eventY - y - headerHeight + projectListScrollTop;
8604
+ if (relativeY < 0) {
8605
+ return '';
8606
+ }
8607
+ const index = Math.floor(relativeY / listItemHeight);
8608
+ const projectRowIds = getProjectRowIds(projects, sessions, projectExpandedIds);
8609
+ return projectRowIds[index] || '';
8610
+ };
8611
+ const handleProjectListContextMenu = async (state, button, eventX, eventY) => {
8612
+ const {
8613
+ uid
8614
+ } = state;
8615
+ const projectId = getProjectIdAtPosition(state, eventY);
8616
+ await showContextMenu2(uid, MenuChatProjectList, eventX, eventY, {
8617
+ menuId: MenuChatProjectList,
8618
+ projectId
8619
+ });
8333
8620
  return state;
8334
8621
  };
8335
8622
 
@@ -9032,6 +9319,11 @@ const openMockSession = async (state, mockSessionId, mockChatMessages) => {
9032
9319
  };
9033
9320
  };
9034
9321
 
9322
+ const pasteInput = async state => {
9323
+ const text = await readText();
9324
+ return handleInput(state, Composer, text, 'script');
9325
+ };
9326
+
9035
9327
  const registerMockResponse = (state, mockResponse) => {
9036
9328
  reset$2();
9037
9329
  pushChunk(mockResponse.text);
@@ -9076,6 +9368,24 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
9076
9368
  align-items:center;
9077
9369
  }
9078
9370
 
9371
+ .ChatListItemFocused{
9372
+ background: var(--vscode-list-activeSelectionBackground);
9373
+ color: var(--vscode-list-activeSelectionForeground);
9374
+ }
9375
+
9376
+ .ChatMessageContent p + p{
9377
+ margin-top: 0.75em;
9378
+ }
9379
+
9380
+ .MissingApiKeyForm{
9381
+ padding-top: 10px;
9382
+ }
9383
+
9384
+ .ChatHeaderLabel{
9385
+ margin: 0;
9386
+ font-size: 14px;
9387
+ }
9388
+
9079
9389
  .ChatListItemStatusRow{
9080
9390
  width: 16px;
9081
9391
  min-width: 16px;
@@ -9098,6 +9408,8 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
9098
9408
 
9099
9409
  .ChatListItemStatusFinished{
9100
9410
  color: var(--vscode-testing-iconPassed);
9411
+ }
9412
+
9101
9413
  .ChatListItem .SessionArchiveButton{
9102
9414
  opacity: 0;
9103
9415
  }
@@ -9106,6 +9418,13 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
9106
9418
  .ChatListItem:focus-within .SessionArchiveButton{
9107
9419
  opacity: 1;
9108
9420
  }
9421
+
9422
+ .ChatHeaderLabel{
9423
+ white-space: nowrap;
9424
+ overflow: hidden;
9425
+ text-overflow: ellipsis;
9426
+ }
9427
+
9109
9428
  `;
9110
9429
  return `${baseCss}
9111
9430
 
@@ -9140,7 +9459,11 @@ const renderCss = (oldState, newState) => {
9140
9459
  return [SetCss, uid, css];
9141
9460
  };
9142
9461
 
9143
- const getFocusSelector = focus => {
9462
+ const getFocusSelector = state => {
9463
+ const {
9464
+ focus,
9465
+ listFocusedIndex
9466
+ } = state;
9144
9467
  switch (focus) {
9145
9468
  case 'composer':
9146
9469
  case 'input':
@@ -9148,7 +9471,17 @@ const getFocusSelector = focus => {
9148
9471
  case 'header':
9149
9472
  return '[name="create-session"]';
9150
9473
  case 'list':
9151
- return '[name^="session:"]';
9474
+ {
9475
+ if (listFocusedIndex === -1) {
9476
+ return `[name="${ChatList$1}"]`;
9477
+ }
9478
+ const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
9479
+ const session = visibleSessions[listFocusedIndex];
9480
+ if (!session) {
9481
+ return `[name="${ChatList$1}"]`;
9482
+ }
9483
+ return `[name="${getSessionInputName(session.id)}"]`;
9484
+ }
9152
9485
  case 'send-button':
9153
9486
  return '[name="send"]';
9154
9487
  default:
@@ -9156,7 +9489,7 @@ const getFocusSelector = focus => {
9156
9489
  }
9157
9490
  };
9158
9491
  const renderFocus = (oldState, newState) => {
9159
- const selector = getFocusSelector(newState.focus);
9492
+ const selector = getFocusSelector(newState);
9160
9493
  return [FocusSelector, selector];
9161
9494
  };
9162
9495
 
@@ -9189,6 +9522,7 @@ const ChatTodoListItemInProgress = 'ChatTodoListItemInProgress';
9189
9522
  const ChatTodoListItemCompleted = 'ChatTodoListItemCompleted';
9190
9523
  const Chat = 'Chat';
9191
9524
  const ChatHeader = 'ChatHeader';
9525
+ const ChatHeaderLabel = 'ChatHeaderLabel';
9192
9526
  const Button = 'Button';
9193
9527
  const ButtonPrimary = 'ButtonPrimary';
9194
9528
  const ButtonSecondary = 'ButtonSecondary';
@@ -9205,6 +9539,7 @@ const LabelDetail = 'LabelDetail';
9205
9539
  const ChatList = 'ChatList';
9206
9540
  const ChatListEmpty = 'ChatListEmpty';
9207
9541
  const ChatListItem = 'ChatListItem';
9542
+ const ChatListItemFocused = 'ChatListItemFocused';
9208
9543
  const ChatListItemStatusRow = 'ChatListItemStatusRow';
9209
9544
  const ChatListItemStatusIcon = 'ChatListItemStatusIcon';
9210
9545
  const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
@@ -9231,6 +9566,7 @@ const MarkdownMathBlock = 'MarkdownMathBlock';
9231
9566
  const MarkdownTable = 'MarkdownTable';
9232
9567
  const ChatTableWrapper = 'ChatTableWrapper';
9233
9568
  const Message = 'Message';
9569
+ const MissingApiKeyForm = 'MissingApiKeyForm';
9234
9570
  const ChatMessageContent = 'ChatMessageContent';
9235
9571
  const ChatToolCalls = 'ChatToolCalls';
9236
9572
  const ChatToolCallsLabel = 'ChatToolCallsLabel';
@@ -9302,6 +9638,7 @@ const HandleSearchInput = 37;
9302
9638
  const HandleChatWelcomeContextMenu = 39;
9303
9639
  const HandleChatHeaderContextMenu = 40;
9304
9640
  const HandleChatInputContextMenu = 41;
9641
+ const HandleContextMenuChatSendAreaBottom = 42;
9305
9642
 
9306
9643
  const getModelLabel = model => {
9307
9644
  if (model.provider === 'openRouter') {
@@ -9460,6 +9797,20 @@ const getAddContextButtonDom = () => {
9460
9797
  type: Text
9461
9798
  }];
9462
9799
  };
9800
+ const getBackToChatsButtonDom = () => {
9801
+ return [{
9802
+ childCount: 1,
9803
+ className: mergeClassNames(Button, ButtonSecondary),
9804
+ inputType: 'button',
9805
+ name: Back,
9806
+ onClick: HandleClickBack,
9807
+ title: backToChatList(),
9808
+ type: Button$1
9809
+ }, {
9810
+ text: backToChatList(),
9811
+ type: Text
9812
+ }];
9813
+ };
9463
9814
 
9464
9815
  const clampToPercentage = (tokensUsed, tokensMax) => {
9465
9816
  if (tokensMax <= 0) {
@@ -9496,9 +9847,9 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
9496
9847
  }, text(usageLabel)];
9497
9848
  };
9498
9849
 
9499
- const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false) => {
9850
+ const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false, showBackToChatsButton = false) => {
9500
9851
  const isSendDisabled = composerValue.trim() === '';
9501
- const controlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (showRunMode ? 1 : 0) + (addContextButtonEnabled ? 1 : 0);
9852
+ const controlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (showRunMode ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showBackToChatsButton ? 1 : 0);
9502
9853
  const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
9503
9854
  const todoHeaderText = `Todos (${todoListItems.filter(item => item.status === 'completed').length}/${todoListItems.length})`;
9504
9855
  const getTodoItemClassName = status => {
@@ -9550,8 +9901,9 @@ const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchVal
9550
9901
  }, {
9551
9902
  childCount: voiceDictationEnabled ? controlsCount + 1 : controlsCount,
9552
9903
  className: ChatSendAreaBottom,
9904
+ onContextMenu: HandleContextMenuChatSendAreaBottom,
9553
9905
  type: Div
9554
- }, ...(newChatModelPickerEnabled ? getChatModelPickerVirtualDom(models, selectedModelId, modelPickerOpen, modelPickerSearchValue) : getChatSelectVirtualDom(models, selectedModelId)), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
9906
+ }, ...(newChatModelPickerEnabled ? getChatModelPickerVirtualDom(models, selectedModelId, modelPickerOpen, modelPickerSearchValue) : getChatSelectVirtualDom(models, selectedModelId)), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...(showBackToChatsButton ? getBackToChatsButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
9555
9907
  };
9556
9908
 
9557
9909
  const getImageAltText = alt => {
@@ -9963,6 +10315,7 @@ const getMissingApiKeyDom = ({
9963
10315
  inputPattern,
9964
10316
  inputRequired = false,
9965
10317
  openSettingsButtonName,
10318
+ openSettingsUrl,
9966
10319
  placeholder,
9967
10320
  saveButtonDisabled = false,
9968
10321
  saveButtonName,
@@ -9970,10 +10323,14 @@ const getMissingApiKeyDom = ({
9970
10323
  }) => {
9971
10324
  return [{
9972
10325
  childCount: 2,
10326
+ className: MissingApiKeyForm,
9973
10327
  method: 'GET',
9974
10328
  onSubmit: HandleMissingApiKeySubmit,
9975
10329
  type: Form
9976
10330
  }, {
10331
+ autocapitalize: 'off',
10332
+ autocomplete: 'off',
10333
+ autocorrect: 'off',
9977
10334
  childCount: 0,
9978
10335
  className: InputBox,
9979
10336
  name: inputName,
@@ -9983,6 +10340,7 @@ const getMissingApiKeyDom = ({
9983
10340
  } : {}),
9984
10341
  placeholder,
9985
10342
  required: inputRequired,
10343
+ spellcheck: false,
9986
10344
  type: Input
9987
10345
  }, {
9988
10346
  childCount: 2,
@@ -9998,10 +10356,11 @@ const getMissingApiKeyDom = ({
9998
10356
  }, text(saveButtonText), {
9999
10357
  childCount: 1,
10000
10358
  className: mergeClassNames(Button, ButtonSecondary),
10001
- inputType: 'button',
10359
+ href: openSettingsUrl,
10002
10360
  name: openSettingsButtonName,
10003
- onClick: HandleClick,
10004
- type: Button$1
10361
+ rel: 'noopener noreferrer',
10362
+ target: '_blank',
10363
+ type: A
10005
10364
  }, text(getApiKeyText)];
10006
10365
  };
10007
10366
 
@@ -10012,6 +10371,7 @@ const getMissingOpenApiApiKeyDom = () => {
10012
10371
  inputPattern: '^sk-.+',
10013
10372
  inputRequired: true,
10014
10373
  openSettingsButtonName: OpenOpenApiApiKeyWebsite,
10374
+ openSettingsUrl: 'https://platform.openai.com/api-keys',
10015
10375
  placeholder: openApiApiKeyPlaceholder(),
10016
10376
  saveButtonName: SaveOpenApiApiKey
10017
10377
  });
@@ -10023,6 +10383,7 @@ const getMissingOpenRouterApiKeyDom = (openRouterApiKeyState = 'idle') => {
10023
10383
  getApiKeyText: getOpenRouterApiKey(),
10024
10384
  inputName: OpenRouterApiKeyInput,
10025
10385
  openSettingsButtonName: OpenOpenRouterApiKeySettings,
10386
+ openSettingsUrl: 'https://openrouter.ai/settings/keys',
10026
10387
  placeholder: openRouterApiKeyPlaceholder(),
10027
10388
  saveButtonDisabled: isSaving,
10028
10389
  saveButtonName: SaveOpenRouterApiKey,
@@ -11028,7 +11389,7 @@ const getChatModeChatFocusVirtualDom = ({
11028
11389
  onDragEnter: HandleDragEnterChatView,
11029
11390
  onDragOver: HandleDragOverChatView,
11030
11391
  type: Div
11031
- }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
11392
+ }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled, true), ...(isDropOverlayVisible ? [{
11032
11393
  childCount: 1,
11033
11394
  className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
11034
11395
  name: ComposerDropTarget,
@@ -11124,6 +11485,7 @@ const getChatHeaderActionsDom = (viewMode, authEnabled = false, authStatus = 'si
11124
11485
  return [{
11125
11486
  childCount: items.length,
11126
11487
  className: ChatActions,
11488
+ role: 'toolbar',
11127
11489
  type: Div
11128
11490
  }, ...items.flatMap(getHeaderActionVirtualDom)];
11129
11491
  };
@@ -11141,8 +11503,8 @@ const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false, a
11141
11503
  type: Div
11142
11504
  }, ...getBackButtonVirtualDom(), {
11143
11505
  childCount: 1,
11144
- className: Label,
11145
- type: Span
11506
+ className: ChatHeaderLabel,
11507
+ type: H2
11146
11508
  }, text(selectedSessionTitle), ...getChatHeaderActionsDom('detail', authEnabled, authStatus), ...(hasAuthError ? [{
11147
11509
  childCount: 1,
11148
11510
  className: ChatAuthError,
@@ -11219,8 +11581,8 @@ const getChatHeaderListModeDom = (authEnabled = false, authStatus = 'signed-out'
11219
11581
  type: Div
11220
11582
  }, {
11221
11583
  childCount: 1,
11222
- className: Label,
11223
- type: Span
11584
+ className: ChatHeaderLabel,
11585
+ type: H2
11224
11586
  }, text(chats()), ...getChatHeaderActionsDom('list', authEnabled, authStatus, searchEnabled), ...(hasSearchField ? [{
11225
11587
  childCount: 1,
11226
11588
  className: SearchFieldContainer,
@@ -11264,8 +11626,8 @@ const getSessionStatusClassName = session => {
11264
11626
  }
11265
11627
  return ChatListItemStatusStopped;
11266
11628
  };
11267
- const getSessionDom = session => {
11268
- const sessionClassName = ChatListItem;
11629
+ const getSessionDom = (session, focused = false) => {
11630
+ const sessionClassName = focused ? mergeClassNames(ChatListItem, ChatListItemFocused) : ChatListItem;
11269
11631
  const sessionStatusClassName = getSessionStatusClassName(session);
11270
11632
  return [{
11271
11633
  childCount: 3,
@@ -11284,6 +11646,8 @@ const getSessionDom = session => {
11284
11646
  className: ChatListItemLabel,
11285
11647
  name: getSessionInputName(session.id),
11286
11648
  onContextMenu: HandleListContextMenu,
11649
+ onFocus: HandleFocus,
11650
+ tabIndex: 0,
11287
11651
  type: Div
11288
11652
  }, text(session.title), {
11289
11653
  childCount: 1,
@@ -11305,18 +11669,22 @@ const getSessionDom = session => {
11305
11669
  }];
11306
11670
  };
11307
11671
 
11308
- const getChatListDom = (sessions, selectedSessionId, chatListScrollTop = 0) => {
11672
+ const getChatListDom = (sessions, selectedSessionId, listFocusedIndex, chatListScrollTop = 0) => {
11309
11673
  if (sessions.length === 0) {
11310
11674
  return getEmptyChatSessionsDom();
11311
11675
  }
11312
11676
  return [{
11313
11677
  childCount: sessions.length,
11314
11678
  className: ChatList,
11679
+ name: ChatList$1,
11315
11680
  onClick: HandleClickList,
11681
+ onContextMenu: HandleListContextMenu,
11682
+ onFocus: HandleFocus,
11316
11683
  onScroll: HandleChatListScroll,
11317
11684
  scrollTop: chatListScrollTop,
11685
+ tabIndex: 0,
11318
11686
  type: Ul
11319
- }, ...sessions.flatMap(getSessionDom)];
11687
+ }, ...sessions.flatMap((session, index) => getSessionDom(session, index === listFocusedIndex))];
11320
11688
  };
11321
11689
 
11322
11690
  const getChatModeListVirtualDom = ({
@@ -11332,6 +11700,7 @@ const getChatModeListVirtualDom = ({
11332
11700
  composerHeight = 28,
11333
11701
  composerLineHeight = 20,
11334
11702
  composerValue,
11703
+ listFocusedIndex = -1,
11335
11704
  modelPickerOpen = false,
11336
11705
  modelPickerSearchValue = '',
11337
11706
  models,
@@ -11360,7 +11729,7 @@ const getChatModeListVirtualDom = ({
11360
11729
  onDragEnter: HandleDragEnterChatView,
11361
11730
  onDragOver: HandleDragOverChatView,
11362
11731
  type: Div
11363
- }, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
11732
+ }, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, listFocusedIndex, chatListScrollTop), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
11364
11733
  childCount: 1,
11365
11734
  className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
11366
11735
  name: ComposerDropTarget,
@@ -11467,6 +11836,7 @@ const getChatVirtualDom = options => {
11467
11836
  composerHeight,
11468
11837
  composerLineHeight,
11469
11838
  composerValue,
11839
+ listFocusedIndex = -1,
11470
11840
  messagesScrollTop,
11471
11841
  modelPickerOpen = false,
11472
11842
  modelPickerSearchValue = '',
@@ -11587,6 +11957,7 @@ const getChatVirtualDom = options => {
11587
11957
  composerHeight,
11588
11958
  composerLineHeight,
11589
11959
  composerValue,
11960
+ listFocusedIndex,
11590
11961
  modelPickerOpen,
11591
11962
  modelPickerSearchValue,
11592
11963
  models,
@@ -11626,6 +11997,7 @@ const renderItems = (oldState, newState) => {
11626
11997
  composerLineHeight,
11627
11998
  composerValue,
11628
11999
  initial,
12000
+ listFocusedIndex,
11629
12001
  messagesScrollTop,
11630
12002
  modelPickerOpen,
11631
12003
  modelPickerSearchValue,
@@ -11672,6 +12044,7 @@ const renderItems = (oldState, newState) => {
11672
12044
  composerHeight,
11673
12045
  composerLineHeight,
11674
12046
  composerValue,
12047
+ listFocusedIndex,
11675
12048
  messagesScrollTop,
11676
12049
  modelPickerOpen,
11677
12050
  modelPickerSearchValue,
@@ -11932,7 +12305,8 @@ const renderEventListeners = () => {
11932
12305
  preventDefault: true
11933
12306
  }, {
11934
12307
  name: HandleChatWelcomeContextMenu,
11935
- params: ['handleChatWelcomeContextMenu']
12308
+ params: ['handleChatDetailWelcomeContextMenu'],
12309
+ preventDefault: true
11936
12310
  }, {
11937
12311
  name: HandleChatHeaderContextMenu,
11938
12312
  params: ['handleChatHeaderContextMenu'],
@@ -11944,6 +12318,10 @@ const renderEventListeners = () => {
11944
12318
  name: HandleChatInputContextMenu,
11945
12319
  params: ['handleChatInputContextMenu'],
11946
12320
  preventDefault: true
12321
+ }, {
12322
+ name: HandleContextMenuChatSendAreaBottom,
12323
+ params: ['handleContextMenuChatSendAreaBottom'],
12324
+ preventDefault: true
11947
12325
  }, {
11948
12326
  name: HandleKeyDown,
11949
12327
  params: ['handleKeyDown', Key, ShiftKey]
@@ -12190,8 +12568,14 @@ const useMockApi = (state, value, mockApiCommandId = defaultMockApiCommandId) =>
12190
12568
  };
12191
12569
 
12192
12570
  const commandMap = {
12571
+ 'Chat.chatListFocusFirst': wrapCommand(chatListFocusFirst),
12572
+ 'Chat.chatListFocusLast': wrapCommand(chatListFocusLast),
12573
+ 'Chat.chatListFocusNext': wrapCommand(chatListFocusNext),
12574
+ 'Chat.chatListFocusPrevious': wrapCommand(chatListFocusPrevious),
12193
12575
  'Chat.clearInput': wrapCommand(clearInput),
12576
+ 'Chat.copyInput': wrapCommand(copyInput),
12194
12577
  'Chat.create': create,
12578
+ 'Chat.cutInput': wrapCommand(cutInput),
12195
12579
  'Chat.deleteSessionAtIndex': wrapCommand(deleteSessionAtIndex),
12196
12580
  'Chat.diff2': diff2,
12197
12581
  'Chat.enterNewLine': wrapCommand(handleNewline),
@@ -12202,11 +12586,11 @@ const commandMap = {
12202
12586
  'Chat.getMenuEntryIds': getMenuEntryIds,
12203
12587
  'Chat.getQuickPickMenuEntries': getQuickPickMenuEntries,
12204
12588
  'Chat.getSelectedSessionId': wrapGetter(getSelectedSessionId),
12589
+ 'Chat.handleChatDetailWelcomeContextMenu': wrapCommand(handleChatDetailWelcomeContextMenu),
12205
12590
  'Chat.handleChatHeaderContextMenu': wrapCommand(handleChatHeaderContextMenu),
12206
12591
  'Chat.handleChatInputContextMenu': wrapCommand(handleChatInputContextMenu),
12207
- 'Chat.handleChatListContextMenu': handleChatListContextMenu,
12592
+ 'Chat.handleChatListContextMenu': wrapCommand(handleChatListContextMenu),
12208
12593
  'Chat.handleChatListScroll': wrapCommand(handleChatListScroll),
12209
- 'Chat.handleChatWelcomeContextMenu': wrapCommand(handleChatWelcomeContextMenu),
12210
12594
  'Chat.handleClick': wrapCommand(handleClick),
12211
12595
  'Chat.handleClickBack': wrapCommand(handleClickBack),
12212
12596
  'Chat.handleClickClose': handleClickClose,
@@ -12218,6 +12602,7 @@ const commandMap = {
12218
12602
  'Chat.handleClickReadFile': handleClickFileName,
12219
12603
  'Chat.handleClickSessionDebug': wrapCommand(handleClickSessionDebug),
12220
12604
  'Chat.handleClickSettings': handleClickSettings,
12605
+ 'Chat.handleContextMenuChatSendAreaBottom': wrapCommand(handleContextMenuChatSendAreaBottom),
12221
12606
  'Chat.handleDragEnter': wrapCommand(handleDragEnter),
12222
12607
  'Chat.handleDragLeave': wrapCommand(handleDragLeave),
12223
12608
  'Chat.handleDragOver': wrapCommand(handleDragOver),
@@ -12246,6 +12631,7 @@ const commandMap = {
12246
12631
  'Chat.mockOpenApiStreamPushChunk': wrapCommand(mockOpenApiStreamPushChunk),
12247
12632
  'Chat.mockOpenApiStreamReset': wrapCommand(mockOpenApiStreamReset),
12248
12633
  'Chat.openMockSession': wrapCommand(openMockSession),
12634
+ 'Chat.pasteInput': wrapCommand(pasteInput),
12249
12635
  'Chat.registerMockResponse': wrapCommand(registerMockResponse),
12250
12636
  'Chat.render2': render2,
12251
12637
  'Chat.renderEventListeners': renderEventListeners,
@@ -12330,6 +12716,17 @@ const initializeChatToolWorker = async () => {
12330
12716
  set$5(rpc);
12331
12717
  };
12332
12718
 
12719
+ const sendMessagePortToClipBoardWorker = async port => {
12720
+ await sendMessagePortToClipBoardWorker$1(port, 0);
12721
+ };
12722
+ const initializeClipBoardWorker = async () => {
12723
+ const rpc = await create$4({
12724
+ commandMap: {},
12725
+ send: sendMessagePortToClipBoardWorker
12726
+ });
12727
+ set$3(rpc);
12728
+ };
12729
+
12333
12730
  const sendMessagePortToOpenerWorker = async port => {
12334
12731
  await sendMessagePortToOpenerWorker$1(port, 0);
12335
12732
  };
@@ -12347,7 +12744,7 @@ const listen = async () => {
12347
12744
  commandMap: commandMap
12348
12745
  });
12349
12746
  set$2(rpc);
12350
- await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker(), initializeChatToolWorker(), initializeOpenerWorker(), initializeChatStorageWorker()]);
12747
+ await Promise.all([initializeChatCoordinatorWorker(), initializeChatMathWorker(), initializeChatNetworkWorker(), initializeChatStorageWorker(), initializeChatToolWorker(), initializeClipBoardWorker(), initializeOpenerWorker()]);
12351
12748
  };
12352
12749
 
12353
12750
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "6.19.0",
3
+ "version": "6.22.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",