From b734a55ba6396c30b8fed549ad6ee14f045cbd4f Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Mon, 20 Jan 2025 17:11:23 +0100 Subject: [PATCH 01/10] Enable AI Assistant panel in code mode --- .../components/operator-mode/code-submode.gts | 1 - .../operator-mode/submode-layout.gts | 27 +++++++------------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/host/app/components/operator-mode/code-submode.gts b/packages/host/app/components/operator-mode/code-submode.gts index 367f260a8b..c7bec99c04 100644 --- a/packages/host/app/components/operator-mode/code-submode.gts +++ b/packages/host/app/components/operator-mode/code-submode.gts @@ -746,7 +746,6 @@ export default class CodeSubmode extends Component { {{/let}}
void; onSearchSheetClosed?: () => void; onCardSelectFromSearch: (cardId: string) => void; @@ -309,23 +308,17 @@ export default class SubmodeLayout extends Component { @onCardSelect={{this.handleCardSelectFromSearch}} @onInputInsertion={{this.storeSearchElement}} /> - {{#if (not @hideAiAssistant)}} - - - {{/if}} + + - {{#if - (and - (not @hideAiAssistant) this.operatorModeStateService.aiAssistantOpen - ) - }} + {{#if this.operatorModeStateService.aiAssistantOpen}} Date: Tue, 21 Jan 2025 21:16:33 +0100 Subject: [PATCH 02/10] Workaround for differently themed monaco editors on the same page --- .../components/matrix/room-message-command.gts | 11 +++++++++++ .../components/operator-mode/code-editor.gts | 10 +++++++++- packages/host/app/modifiers/monaco.ts | 17 +++-------------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/host/app/components/matrix/room-message-command.gts b/packages/host/app/components/matrix/room-message-command.gts index 65498df15b..19fa4addf6 100644 --- a/packages/host/app/components/matrix/room-message-command.gts +++ b/packages/host/app/components/matrix/room-message-command.gts @@ -319,6 +319,17 @@ export default class RoomMessageCommand extends Component { .options-menu :deep(.check-icon) { display: none; } + /* + This filter is a best-effort approximation of a good looking dark theme that is a function of the white theme that + we use for code previews in the AI panel. While Monaco editor does support multiple themes, it does not support + monaco instances with different themes *on the same page*. This is why we are using a filter to approximate the + dark theme. More details here: https://github.com/Microsoft/monaco-editor/issues/338 (monaco uses global style tags + with hardcoded colors; any instance will override the global style tag, making all code editors look the same, + effectively disabling multiple themes to be used on the same page) + */ + :global(.preview-code .monaco-editor) { + filter: invert(1) hue-rotate(151deg) brightness(0.8) grayscale(0.1); + } } diff --git a/packages/host/app/components/operator-mode/code-editor.gts b/packages/host/app/components/operator-mode/code-editor.gts index 28d2d9ac4f..eee7177c8c 100644 --- a/packages/host/app/components/operator-mode/code-editor.gts +++ b/packages/host/app/components/operator-mode/code-editor.gts @@ -324,7 +324,15 @@ export default class CodeEditor extends Component { padding: var(--boxel-sp) 0; } - .monaco-container.readonly { + :global(.monaco-container.readonly) { + background-color: #ebeaed; + } + + :global(.monaco-container.readonly .margin) { + background-color: #ebeaed; + } + + :global(.monaco-container.readonly .monaco-editor-background) { background-color: #ebeaed; } diff --git a/packages/host/app/modifiers/monaco.ts b/packages/host/app/modifiers/monaco.ts index 93197e4140..6c28d3ffa7 100644 --- a/packages/host/app/modifiers/monaco.ts +++ b/packages/host/app/modifiers/monaco.ts @@ -22,7 +22,6 @@ interface Signature { language?: string; readOnly?: boolean; monacoSDK: typeof MonacoSDK; - darkTheme?: boolean; editorDisplayOptions?: MonacoEditorOptions; }; }; @@ -54,7 +53,6 @@ export default class Monaco extends Modifier { onSetup, readOnly, monacoSDK, - darkTheme, editorDisplayOptions, }: Signature['Args']['Named'], ) { @@ -73,21 +71,12 @@ export default class Monaco extends Modifier { this.model.setValue(content); } } else { - monacoSDK.editor.defineTheme('boxel-theme', { + monacoSDK.editor.defineTheme('boxel-monaco-light-theme', { base: 'vs', inherit: true, rules: [], colors: { - 'editor.background': readOnly ? '#EBEAED' : '#FFFFFF', - }, - }); - - monacoSDK.editor.defineTheme('boxel-dark-theme', { - base: 'vs-dark', - inherit: true, - rules: [], - colors: { - 'editor.background': '#000000', + 'editor.background': '#FFFFFF', }, }); @@ -100,7 +89,7 @@ export default class Monaco extends Modifier { minimap: { enabled: false, }, - theme: darkTheme ? 'boxel-dark-theme' : 'boxel-theme', + theme: 'boxel-monaco-light-theme', ...editorDisplayOptions, }; From 36b8cf337aa8fe291ddf6d0eda65a5b51c499d79 Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Wed, 22 Jan 2025 09:24:20 +0100 Subject: [PATCH 03/10] Cleanup, add comment --- packages/host/app/components/matrix/room-message-command.gts | 1 - packages/host/app/modifiers/monaco.ts | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/host/app/components/matrix/room-message-command.gts b/packages/host/app/components/matrix/room-message-command.gts index 19fa4addf6..bad02f9fd5 100644 --- a/packages/host/app/components/matrix/room-message-command.gts +++ b/packages/host/app/components/matrix/room-message-command.gts @@ -211,7 +211,6 @@ export default class RoomMessageCommand extends Component { monacoSDK=@monacoSDK language='json' readOnly=true - darkTheme=true editorDisplayOptions=this.editorDisplayOptions }} data-test-editor diff --git a/packages/host/app/modifiers/monaco.ts b/packages/host/app/modifiers/monaco.ts index 6c28d3ffa7..139436f841 100644 --- a/packages/host/app/modifiers/monaco.ts +++ b/packages/host/app/modifiers/monaco.ts @@ -71,6 +71,11 @@ export default class Monaco extends Modifier { this.model.setValue(content); } } else { + // The light theme editor is used for the main editor in code mode, + // but we also have a dark themed editor for the preview editor in AI panel. + // The latter is themed using a CSS filter as opposed to defining a new monaco theme + // because monaco does not support multiple themes on the same page (check the comment in + // room-message-command.gts for more details) monacoSDK.editor.defineTheme('boxel-monaco-light-theme', { base: 'vs', inherit: true, From 9d3d471ed0f303f87847a493c1a86f3cac6cc39d Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Wed, 22 Jan 2025 09:42:08 +0100 Subject: [PATCH 04/10] Cleanup, fix test --- packages/host/app/components/operator-mode/submode-layout.gts | 2 +- packages/host/tests/acceptance/code-submode/editor-test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/host/app/components/operator-mode/submode-layout.gts b/packages/host/app/components/operator-mode/submode-layout.gts index 0c4e4190a8..5633665207 100644 --- a/packages/host/app/components/operator-mode/submode-layout.gts +++ b/packages/host/app/components/operator-mode/submode-layout.gts @@ -17,7 +17,7 @@ import { TrackedObject } from 'tracked-built-ins'; import { ResizablePanelGroup } from '@cardstack/boxel-ui/components'; import { Avatar, IconButton } from '@cardstack/boxel-ui/components'; -import { and, cn, not } from '@cardstack/boxel-ui/helpers'; +import { cn, not } from '@cardstack/boxel-ui/helpers'; import { BoxelIcon } from '@cardstack/boxel-ui/icons'; diff --git a/packages/host/tests/acceptance/code-submode/editor-test.ts b/packages/host/tests/acceptance/code-submode/editor-test.ts index 52214afc0e..b7bb400e1c 100644 --- a/packages/host/tests/acceptance/code-submode/editor-test.ts +++ b/packages/host/tests/acceptance/code-submode/editor-test.ts @@ -822,7 +822,7 @@ module('Acceptance | code submode | editor tests', function (hooks) { assert.dom('[data-test-realm-indicator-not-writable]').exists(); assert.strictEqual( window - .getComputedStyle(find('.monaco-editor')!) + .getComputedStyle(find('.monaco-editor-background')!) .getPropertyValue('background-color')!, 'rgb(235, 234, 237)', // equivalent to #ebeaed 'monaco editor is greyed out when read-only', From 07e50bc319bea50af1e7bf7695d92a340b20aa10 Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Wed, 22 Jan 2025 09:54:55 +0100 Subject: [PATCH 05/10] If room rerenders, do not let intersection observer to trigger This fixed the "You attempted to get the value of a helper after the helper was destroyed, which is not allowed" error in "Commands tests: a command sent via SendAiAssistantMessageCommand without autoExecute flag is not automatically executed by the bot" --- packages/host/app/components/matrix/room.gts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/host/app/components/matrix/room.gts b/packages/host/app/components/matrix/room.gts index f8e526b848..d923993654 100644 --- a/packages/host/app/components/matrix/room.gts +++ b/packages/host/app/components/matrix/room.gts @@ -59,6 +59,7 @@ import RoomMessage from './room-message'; import type RoomData from '../../lib/matrix-classes/room'; import type { Skill } from '../ai-assistant/skill-menu'; +import { isDestroyed } from '@ember/destroyable'; interface Signature { Args: { @@ -251,6 +252,9 @@ export default class Room extends Component { messageScrollers: new Map(), messageVisibilityObserver: new IntersectionObserver((entries) => { entries.forEach((entry) => { + if (isDestroyed(this)) { + return; + } let index = this.messageElements.get(entry.target as HTMLElement); if (index != null) { if ( From 4c433e6718f7fe232f563ef1e74d7bd539eab2f6 Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Wed, 22 Jan 2025 11:03:03 +0100 Subject: [PATCH 06/10] Add a test --- .../operator-mode-acceptance-test.gts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/host/tests/acceptance/operator-mode-acceptance-test.gts b/packages/host/tests/acceptance/operator-mode-acceptance-test.gts index 8ec5655eb2..6ed16aa643 100644 --- a/packages/host/tests/acceptance/operator-mode-acceptance-test.gts +++ b/packages/host/tests/acceptance/operator-mode-acceptance-test.gts @@ -1141,5 +1141,26 @@ module('Acceptance | operator mode tests', function (hooks) { .hasNoClass('out-of-credit'); assert.dom('[data-test-buy-more-credits]').hasNoClass('out-of-credit'); }); + + test(`ai panel continues being open when switching to code submode`, async function (assert) { + await visitOperatorMode({ + stacks: [ + [ + { + id: `${testRealmURL}Person/fadhlan`, + format: 'isolated', + }, + ], + ], + }); + + await click('[data-test-open-ai-assistant]'); + assert.dom('[data-test-ai-assistant-panel]').exists(); + await click('[data-test-submode-switcher] button'); + await click('[data-test-boxel-menu-item-text="Code"]'); + assert.dom('[data-test-ai-assistant-panel]').exists(); + await click('[data-test-open-ai-assistant]'); + assert.dom('[data-test-ai-assistant-panel]').doesNotExist(); + }); }); }); From c9e01a2448ce1671f9566421d2bbc14dd07a2274 Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Wed, 22 Jan 2025 12:16:50 +0100 Subject: [PATCH 07/10] Lint fix --- packages/host/app/components/matrix/room.gts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/host/app/components/matrix/room.gts b/packages/host/app/components/matrix/room.gts index d923993654..e5eb6c3966 100644 --- a/packages/host/app/components/matrix/room.gts +++ b/packages/host/app/components/matrix/room.gts @@ -1,3 +1,4 @@ +import { isDestroyed } from '@ember/destroyable'; import { fn } from '@ember/helper'; import { on } from '@ember/modifier'; import { action } from '@ember/object'; @@ -59,7 +60,6 @@ import RoomMessage from './room-message'; import type RoomData from '../../lib/matrix-classes/room'; import type { Skill } from '../ai-assistant/skill-menu'; -import { isDestroyed } from '@ember/destroyable'; interface Signature { Args: { @@ -251,10 +251,10 @@ export default class Room extends Component { messageElemements: new WeakMap(), messageScrollers: new Map(), messageVisibilityObserver: new IntersectionObserver((entries) => { + if (isDestroyed(this)) { + return; + } entries.forEach((entry) => { - if (isDestroyed(this)) { - return; - } let index = this.messageElements.get(entry.target as HTMLElement); if (index != null) { if ( From 6ee4389336fbc3e33067541fbf936ab5f7b9599d Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Wed, 22 Jan 2025 13:09:56 +0100 Subject: [PATCH 08/10] For some reason the linter doesn't like the multiline css comment --- packages/host/app/components/matrix/room-message-command.gts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/host/app/components/matrix/room-message-command.gts b/packages/host/app/components/matrix/room-message-command.gts index bad02f9fd5..33c4818915 100644 --- a/packages/host/app/components/matrix/room-message-command.gts +++ b/packages/host/app/components/matrix/room-message-command.gts @@ -240,6 +240,9 @@ export default class RoomMessageCommand extends Component { {{/if}}
+ + {{! template-lint-disable no-whitespace-for-layout }} + {{! ignore the above error because it doesn't like the multi-line comment about the filter below }}