@codingame/monaco-vscode-katex-common 25.0.0 → 25.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingame/monaco-vscode-katex-common",
3
- "version": "25.0.0",
3
+ "version": "25.1.0",
4
4
  "private": false,
5
5
  "description": "VSCode public API plugged on the monaco editor - common package depending on katex",
6
6
  "keywords": [],
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "type": "module",
17
17
  "dependencies": {
18
- "@codingame/monaco-vscode-api": "25.0.0",
18
+ "@codingame/monaco-vscode-api": "25.1.0",
19
19
  "katex": "0.16.27",
20
20
  "marked": "14.0.0"
21
21
  },
@@ -26,8 +26,8 @@ import { MultiDiffEditorInput } from '@codingame/monaco-vscode-api/vscode/vs/wor
26
26
  import { MultiDiffEditorItem } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/multiDiffEditor/browser/multiDiffSourceResolverService';
27
27
  import { ChatContextKeys } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/actions/chatContextKeys';
28
28
  import { getChatSessionType } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/model/chatUri';
29
- import { constObservable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/constObservable';
30
29
  import { isObservable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/utils';
30
+ import { constObservable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/constObservable';
31
31
  import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
32
32
 
33
33
  const $ = $$1;
@@ -112,7 +112,8 @@ let ChatTerminalToolConfirmationSubPart = class ChatTerminalToolConfirmationSubP
112
112
  }
113
113
  };
114
114
  const languageId = this.languageService.getLanguageIdByLanguageName(terminalData.language ?? 'sh') ?? 'shellscript';
115
- const model = this._register(this.modelService.createModel(terminalData.commandLine.toolEdited ?? terminalData.commandLine.original, this.languageService.createById(languageId), this._getUniqueCodeBlockUri(), true));
115
+ const initialContent = (terminalData.commandLine.toolEdited ?? terminalData.commandLine.original).trimStart();
116
+ const model = this._register(this.modelService.createModel(initialContent, this.languageService.createById(languageId), this._getUniqueCodeBlockUri(), true));
116
117
  thenRegisterOrDispose(textModelService.createModelReference(model.uri), this._store);
117
118
  const editor = this._register(this.editorPool.get());
118
119
  const renderPromise = editor.object.render({
@@ -140,7 +141,8 @@ let ChatTerminalToolConfirmationSubPart = class ChatTerminalToolConfirmationSubP
140
141
  this._onDidChangeHeight.fire();
141
142
  }));
142
143
  this._register(model.onDidChangeContent(e => {
143
- terminalData.commandLine.userEdited = model.getValue();
144
+ const currentValue = model.getValue();
145
+ terminalData.commandLine.userEdited = currentValue !== initialContent ? currentValue : undefined;
144
146
  }));
145
147
  const elements = h('.chat-confirmation-message-terminal', [
146
148
  h('.chat-confirmation-message-terminal-editor@editor'),
@@ -183,7 +183,7 @@ let ChatTerminalToolProgressPart = class ChatTerminalToolProgressPart extends Ba
183
183
  h('.chat-terminal-content-message@message')
184
184
  ]);
185
185
  this._titleElement = elements.title;
186
- const command = terminalData.commandLine.userEdited ?? terminalData.commandLine.toolEdited ?? terminalData.commandLine.original;
186
+ const command = (terminalData.commandLine.userEdited ?? terminalData.commandLine.toolEdited ?? terminalData.commandLine.original).trimStart();
187
187
  this._commandText = command;
188
188
  this._terminalOutputContextKey = ChatContextKeys.inChatTerminalToolOutput.bindTo(this._contextKeyService);
189
189
  this._decoration = this._register(this._instantiationService.createInstance(TerminalCommandDecoration, {
@@ -193,6 +193,16 @@ export declare class ChatInputPart extends Disposable implements IHistoryNavigat
193
193
  private readonly _waitForPersistedLanguageModel;
194
194
  private _onDidChangeCurrentLanguageModel;
195
195
  private readonly _chatSessionOptionEmitters;
196
+ /**
197
+ * Scoped context key service for this chat input part.
198
+ * Used to isolate option group context keys to this specific chat input instance.
199
+ */
200
+ private _scopedContextKeyService;
201
+ /**
202
+ * Map of option group ID to its context key.
203
+ * Keys follow the pattern `chatSessionOption.<groupId>` and hold the currently selected option item ID.
204
+ */
205
+ private readonly _optionContextKeys;
196
206
  private _currentLanguageModel;
197
207
  get currentLanguageModel(): string | undefined;
198
208
  get selectedLanguageModel(): ILanguageModelChatMetadataAndIdentifier | undefined;
@@ -297,6 +307,21 @@ export declare class ChatInputPart extends Disposable implements IHistoryNavigat
297
307
  private _acceptInputForVoiceover;
298
308
  private _handleAttachedContextChange;
299
309
  private getOrCreateOptionEmitter;
310
+ /**
311
+ * Get or create a context key for an option group.
312
+ * Context keys follow the pattern `chatSessionOption.<groupId>`.
313
+ */
314
+ private getOrCreateOptionContextKey;
315
+ /**
316
+ * Update the context key for an option group with the current selection.
317
+ * This enables `when` expressions on other option groups to react to changes.
318
+ */
319
+ private updateOptionContextKey;
320
+ /**
321
+ * Evaluate whether an option group should be visible based on its `when` expression.
322
+ * Returns true if the option group should be visible, false otherwise.
323
+ */
324
+ private evaluateOptionGroupVisibility;
300
325
  /**
301
326
  * Refresh all registered option groups for the current chat session.
302
327
  * Fires events for each option group with their current selection.
@@ -45,6 +45,7 @@ import { MenuWorkbenchButtonBar } from '../../../../../../platform/actions/brows
45
45
  import { MenuWorkbenchToolBar, HiddenItemStrategy } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/browser/toolbar';
46
46
  import { MenuId, MenuItemAction } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions';
47
47
  import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
48
+ import { RawContextKey, ContextKeyExpr } from '@codingame/monaco-vscode-api/vscode/vs/platform/contextkey/common/contextkey';
48
49
  import { IContextKeyService } from '@codingame/monaco-vscode-api/vscode/vs/platform/contextkey/common/contextkey.service';
49
50
  import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
50
51
  import { registerAndCreateHistoryNavigationContext } from '@codingame/monaco-vscode-api/vscode/vs/platform/history/browser/contextScopedHistoryWidget';
@@ -273,6 +274,7 @@ let ChatInputPart = class ChatInputPart extends Disposable {
273
274
  this._waitForPersistedLanguageModel = this._register(( new MutableDisposable()));
274
275
  this._onDidChangeCurrentLanguageModel = this._register(( new Emitter()));
275
276
  this._chatSessionOptionEmitters = ( new Map());
277
+ this._optionContextKeys = ( new Map());
276
278
  this._onDidChangeCurrentChatMode = this._register(( new Emitter()));
277
279
  this.onDidChangeCurrentChatMode = this._onDidChangeCurrentChatMode.event;
278
280
  this.inputUri = ( URI.parse(`${Schemas.vscodeChatInput}:input-${ChatInputPart_1._counter++}`));
@@ -489,6 +491,16 @@ let ChatInputPart = class ChatInputPart extends Disposable {
489
491
  return [];
490
492
  }
491
493
  this.disposeSessionPickerWidgets();
494
+ for (const optionGroup of optionGroups) {
495
+ if (!ctx) {
496
+ continue;
497
+ }
498
+ const currentOption = this.chatSessionsService.getSessionOption(ctx.chatSessionResource, optionGroup.id);
499
+ if (currentOption) {
500
+ const optionId = typeof currentOption === 'string' ? currentOption : currentOption.id;
501
+ this.updateOptionContextKey(optionGroup.id, optionId);
502
+ }
503
+ }
492
504
  const widgets = [];
493
505
  for (const optionGroup of optionGroups) {
494
506
  if (!ctx) {
@@ -497,6 +509,9 @@ let ChatInputPart = class ChatInputPart extends Disposable {
497
509
  if (!this.chatSessionsService.getSessionOption(ctx.chatSessionResource, optionGroup.id)) {
498
510
  continue;
499
511
  }
512
+ if (!this.evaluateOptionGroupVisibility(optionGroup)) {
513
+ continue;
514
+ }
500
515
  const initialItem = this.getCurrentOptionForGroup(optionGroup.id);
501
516
  const initialState = { group: optionGroup, item: initialItem };
502
517
  const itemDelegate = {
@@ -507,8 +522,10 @@ let ChatInputPart = class ChatInputPart extends Disposable {
507
522
  if (!ctx) {
508
523
  return;
509
524
  }
525
+ this.updateOptionContextKey(optionGroup.id, option.id);
510
526
  this.getOrCreateOptionEmitter(optionGroup.id).fire(option);
511
527
  this.chatSessionsService.notifySessionOptionsChange(ctx.chatSessionResource, [{ optionId: optionGroup.id, value: option }]).catch(err => this.logService.error(`Failed to notify extension of ${optionGroup.id} change:`, err));
528
+ this.refreshChatSessionPickers();
512
529
  },
513
530
  getAllOptions: () => {
514
531
  const ctx = resolveChatSessionContext();
@@ -929,6 +946,38 @@ let ChatInputPart = class ChatInputPart extends Disposable {
929
946
  }
930
947
  return emitter;
931
948
  }
949
+ getOrCreateOptionContextKey(optionGroupId) {
950
+ if (!this._scopedContextKeyService) {
951
+ return undefined;
952
+ }
953
+ let contextKey = this._optionContextKeys.get(optionGroupId);
954
+ if (!contextKey) {
955
+ const rawKey = ( new RawContextKey(`chatSessionOption.${optionGroupId}`, ''));
956
+ contextKey = rawKey.bindTo(this._scopedContextKeyService);
957
+ this._optionContextKeys.set(optionGroupId, contextKey);
958
+ }
959
+ return contextKey;
960
+ }
961
+ updateOptionContextKey(optionGroupId, optionItemId) {
962
+ const normalizedOptionId = optionItemId.trim();
963
+ const contextKey = this.getOrCreateOptionContextKey(optionGroupId);
964
+ if (contextKey) {
965
+ contextKey.set(normalizedOptionId);
966
+ }
967
+ }
968
+ evaluateOptionGroupVisibility(optionGroup) {
969
+ if (!optionGroup.when) {
970
+ return true;
971
+ }
972
+ if (!this._scopedContextKeyService) {
973
+ return true;
974
+ }
975
+ const expr = ContextKeyExpr.deserialize(optionGroup.when);
976
+ if (!expr) {
977
+ return true;
978
+ }
979
+ return this._scopedContextKeyService.contextMatchesRules(expr);
980
+ }
932
981
  refreshChatSessionPickers() {
933
982
  const sessionResource = this._widget?.viewModel?.model.sessionResource;
934
983
  const hideAll = () => {
@@ -949,11 +998,32 @@ let ChatInputPart = class ChatInputPart extends Disposable {
949
998
  if (!this.chatSessionsService.hasAnySessionOptions(ctx.chatSessionResource)) {
950
999
  return hideAll();
951
1000
  }
1001
+ for (const optionGroup of optionGroups) {
1002
+ const currentOption = this.chatSessionsService.getSessionOption(ctx.chatSessionResource, optionGroup.id);
1003
+ if (currentOption) {
1004
+ const optionId = typeof currentOption === 'string' ? currentOption : currentOption.id;
1005
+ this.updateOptionContextKey(optionGroup.id, optionId);
1006
+ }
1007
+ else {
1008
+ this.logService.trace(`[ChatInputPart] No session option set for group '${optionGroup.id}'`);
1009
+ }
1010
+ }
1011
+ const visibleGroupIds = ( new Set());
1012
+ for (const optionGroup of optionGroups) {
1013
+ if (!this.chatSessionsService.getSessionOption(ctx.chatSessionResource, optionGroup.id)) {
1014
+ continue;
1015
+ }
1016
+ if (this.evaluateOptionGroupVisibility(optionGroup)) {
1017
+ visibleGroupIds.add(optionGroup.id);
1018
+ }
1019
+ }
1020
+ if (visibleGroupIds.size === 0) {
1021
+ return hideAll();
1022
+ }
952
1023
  this.chatSessionHasOptions.set(true);
953
1024
  const currentWidgetGroupIds = ( new Set(( this.chatSessionPickerWidgets.keys())));
954
- const requiredGroupIds = ( new Set(( optionGroups.map(g => g.id))));
955
- const needsRecreation = currentWidgetGroupIds.size !== requiredGroupIds.size ||
956
- !Array.from(requiredGroupIds).every(id => ( currentWidgetGroupIds.has(id)));
1025
+ const needsRecreation = currentWidgetGroupIds.size !== visibleGroupIds.size ||
1026
+ !Array.from(visibleGroupIds).every(id => ( currentWidgetGroupIds.has(id)));
957
1027
  if (needsRecreation && this._lastSessionPickerAction && this.chatSessionPickerContainer) {
958
1028
  const widgets = this.createChatSessionPickerWidgets(this._lastSessionPickerAction);
959
1029
  clearNode(this.chatSessionPickerContainer);
@@ -1015,7 +1085,8 @@ let ChatInputPart = class ChatInputPart extends Disposable {
1015
1085
  return;
1016
1086
  }
1017
1087
  if (typeof currentOptionValue === 'string') {
1018
- return optionGroup.items.find(m => m.id === currentOptionValue);
1088
+ const normalizedOptionId = currentOptionValue.trim();
1089
+ return optionGroup.items.find(m => m.id === normalizedOptionId);
1019
1090
  }
1020
1091
  else {
1021
1092
  return currentOptionValue;
@@ -1089,6 +1160,7 @@ let ChatInputPart = class ChatInputPart extends Disposable {
1089
1160
  container.append(this.container);
1090
1161
  this.container.append(this.chatInputOverlay);
1091
1162
  this.container.classList.toggle('compact', this.options.renderStyle === 'compact');
1163
+ this._scopedContextKeyService = this._register(this.contextKeyService.createScoped(this.container));
1092
1164
  this.followupsContainer = elements.followupsContainer;
1093
1165
  const inputAndSideToolbar = elements.inputAndSideToolbar;
1094
1166
  const inputContainer = elements.inputContainer;