@molecule/app-ide-react 1.1.2 → 1.2.1

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/README.md CHANGED
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-08-12T21:41:36.283Z
6
+ Generated: 2026-08-14T03:10:30.998Z
7
7
  -->
8
8
 
9
9
  # @molecule/app-ide-react
@@ -245,6 +245,13 @@ interface ChatPanelProps {
245
245
  onCommit?: () => void
246
246
  /** Called when an inline activity card is clicked — should open the Activity panel filtered to this activity. */
247
247
  onActivityClick?: (activity: ActivityFromCard) => void
248
+ /**
249
+ * Reports a chat timeline item that threw during render, caught by that item's
250
+ * error boundary. The item degrades to an inline notice either way; this is how the
251
+ * host gets the crash into its telemetry instead of it being visible only to the
252
+ * one user who hit it.
253
+ */
254
+ onRenderError?: (error: Error, info: ErrorInfo) => void
248
255
  /**
249
256
  * Called when a user avatar in the chat timeline is clicked — the host opens
250
257
  * that user's profile (e.g. molecule.dev's profile modal). Receives the clicked
@@ -1617,6 +1624,7 @@ function ChatPanel({
1617
1624
  onFileDeleted,
1618
1625
  onCommit,
1619
1626
  onActivityClick,
1627
+ onRenderError,
1620
1628
  onProfileClick,
1621
1629
  onReadyToBuild,
1622
1630
  awaitingSandboxBoot,
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Per-item error boundary for the chat timeline.
3
+ *
4
+ * Everything in the chat timeline is built from data an LLM authored — tool-call
5
+ * inputs, tool outputs, card payloads, streamed markdown. None of it is validated
6
+ * by the type system: a tool schema saying `type: 'string'` is a request to a model,
7
+ * not a guarantee, and a value of the wrong shape reaching JSX throws during render.
8
+ *
9
+ * A throw during render unwinds to the nearest boundary. With only an app-level
10
+ * boundary, one malformed option object blanks the entire IDE — the editor, the
11
+ * preview, the file tree and every other message included — at the moment the user
12
+ * submits their first prompt. That is the difference between a cosmetic defect and
13
+ * an outage, and it is decided entirely by where the boundary sits.
14
+ *
15
+ * So each timeline item renders inside its own boundary: a bad item degrades to one
16
+ * inline notice and every sibling keeps working. The item body is invoked from a
17
+ * CHILD component (`RenderSlot`), not from this component's own render, because a
18
+ * boundary cannot catch what it throws itself — that placement is what extends the
19
+ * protection to synchronous throws in the item's own branching, not just to its
20
+ * descendants.
21
+ *
22
+ * @module
23
+ */
24
+ import type { ErrorInfo, ReactNode } from 'react';
25
+ import { Component } from 'react';
26
+ interface Props {
27
+ /** Produces the timeline item's element tree. Called during render, below the boundary. */
28
+ render: () => ReactNode;
29
+ /** Reports a caught render error (telemetry). Never throws. */
30
+ onError?: (error: Error, info: ErrorInfo) => void;
31
+ }
32
+ interface State {
33
+ failed: boolean;
34
+ }
35
+ /**
36
+ * Error boundary around a single chat timeline item.
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * <ChatItemBoundary key={id} render={() => <MessageItem msg={msg} />} />
41
+ * ```
42
+ */
43
+ export declare class ChatItemBoundary extends Component<Props, State> {
44
+ state: State;
45
+ /**
46
+ * Switches this item to its fallback after a render throw.
47
+ * @returns The failed state.
48
+ */
49
+ static getDerivedStateFromError(): State;
50
+ /**
51
+ * Reports the caught error so a malformed item is visible in telemetry rather
52
+ * than only to the one user who hit it.
53
+ * @param error - The thrown error.
54
+ * @param info - React's component stack for the throw.
55
+ */
56
+ componentDidCatch(error: Error, info: ErrorInfo): void;
57
+ /**
58
+ * Renders the timeline item, or its fallback once the item has failed.
59
+ *
60
+ * @returns The item, or an inline notice when rendering it threw.
61
+ */
62
+ render(): ReactNode;
63
+ }
64
+ export {};
65
+ //# sourceMappingURL=ChatItemBoundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatItemBoundary.d.ts","sourceRoot":"","sources":["../../src/components/ChatItemBoundary.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAO,SAAS,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAkBjC,UAAU,KAAK;IACb,2FAA2F;IAC3F,MAAM,EAAE,MAAM,SAAS,CAAA;IACvB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CAClD;AAED,UAAU,KAAK;IACb,MAAM,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;IAClD,KAAK,EAAE,KAAK,CAAoB;IAEzC;;;OAGG;IACH,MAAM,CAAC,wBAAwB,IAAI,KAAK;IAIxC;;;;;OAKG;IACM,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAe/D;;;;OAIG;IACM,MAAM,IAAI,SAAS;CAiB7B"}
@@ -0,0 +1,70 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Component } from 'react';
3
+ import { t } from '@molecule/app-i18n';
4
+ import { getLogger } from '@molecule/app-logger';
5
+ import { getClassMap } from '@molecule/app-ui';
6
+ /**
7
+ * Invokes the item's render body as a child of the boundary, so a synchronous throw
8
+ * in that body is caught by the boundary above rather than escaping to the app.
9
+ *
10
+ * @param props - Component props.
11
+ * @param props.render - Produces the item's element tree.
12
+ * @returns The rendered item.
13
+ */
14
+ function RenderSlot({ render }) {
15
+ return _jsx(_Fragment, { children: render() });
16
+ }
17
+ /**
18
+ * Error boundary around a single chat timeline item.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <ChatItemBoundary key={id} render={() => <MessageItem msg={msg} />} />
23
+ * ```
24
+ */
25
+ export class ChatItemBoundary extends Component {
26
+ state = { failed: false };
27
+ /**
28
+ * Switches this item to its fallback after a render throw.
29
+ * @returns The failed state.
30
+ */
31
+ static getDerivedStateFromError() {
32
+ return { failed: true };
33
+ }
34
+ /**
35
+ * Reports the caught error so a malformed item is visible in telemetry rather
36
+ * than only to the one user who hit it.
37
+ * @param error - The thrown error.
38
+ * @param info - React's component stack for the throw.
39
+ */
40
+ componentDidCatch(error, info) {
41
+ // Log unconditionally: a host that wires no reporter must still leave a trace,
42
+ // or a contained failure becomes an invisible one.
43
+ getLogger().error('Chat timeline item failed to render', {
44
+ error,
45
+ componentStack: info.componentStack,
46
+ });
47
+ try {
48
+ this.props.onError?.(error, info);
49
+ }
50
+ catch (_error) {
51
+ // A failing error reporter must never escalate into a second render throw —
52
+ // the whole point of this boundary is that nothing here can take the app down.
53
+ }
54
+ }
55
+ /**
56
+ * Renders the timeline item, or its fallback once the item has failed.
57
+ *
58
+ * @returns The item, or an inline notice when rendering it threw.
59
+ */
60
+ render() {
61
+ if (this.state.failed) {
62
+ const cm = getClassMap();
63
+ return (_jsx("div", { "data-mol-id": "chat-item-render-error", className: cm.cn(cm.textSize('xs'), cm.textMuted), style: { padding: '6px 12px', fontStyle: 'italic' }, children: t('ide.chat.itemRenderError', undefined, {
64
+ defaultValue: "This message couldn't be displayed.",
65
+ }) }));
66
+ }
67
+ return _jsx(RenderSlot, { render: this.props.render });
68
+ }
69
+ }
70
+ //# sourceMappingURL=ChatItemBoundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatItemBoundary.js","sourceRoot":"","sources":["../../src/components/ChatItemBoundary.tsx"],"names":[],"mappings":";AAyBA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;;;GAOG;AACH,SAAS,UAAU,CAAC,EAAE,MAAM,EAA+B;IACzD,OAAO,4BAAG,MAAM,EAAE,GAAI,CAAA;AACxB,CAAC;AAaD;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAiB,SAAQ,SAAuB;IAClD,KAAK,GAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;IAEzC;;;OAGG;IACH,MAAM,CAAC,wBAAwB;QAC7B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IACzB,CAAC;IAED;;;;;OAKG;IACM,iBAAiB,CAAC,KAAY,EAAE,IAAe;QACtD,+EAA+E;QAC/E,mDAAmD;QACnD,SAAS,EAAE,CAAC,KAAK,CAAC,qCAAqC,EAAE;YACvD,KAAK;YACL,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC,CAAA;QACF,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,4EAA4E;YAC5E,+EAA+E;QACjF,CAAC;IACH,CAAC;IAED;;;;OAIG;IACM,MAAM;QACb,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;YACxB,OAAO,CACL,6BACc,wBAAwB,EACpC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,EACjD,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAElD,CAAC,CAAC,0BAA0B,EAAE,SAAS,EAAE;oBACxC,YAAY,EAAE,qCAAqC;iBACpD,CAAC,GACE,CACP,CAAA;QACH,CAAC;QACD,OAAO,KAAC,UAAU,IAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAI,CAAA;IAClD,CAAC;CACF"}
@@ -120,6 +120,8 @@ export interface ChatInnerProps {
120
120
  onConversationId?: (id: string) => void;
121
121
  /** Called when an inline activity card is clicked — should open the Activity panel filtered to this activity. */
122
122
  onActivityClick?: (activity: Activity) => void;
123
+ /** See {@link ChatPanelProps.onRenderError}. */
124
+ onRenderError?: ChatPanelProps['onRenderError'];
123
125
  /** Called when a user avatar in the chat timeline is clicked — see {@link ChatPanelProps.onProfileClick}. */
124
126
  onProfileClick?: ChatPanelProps['onProfileClick'];
125
127
  /** Called on the `ready_to_build` stream event — discovery is done; boot the sandbox. */
@@ -176,7 +178,7 @@ export interface ChatInnerProps {
176
178
  * @param props - Component props (see {@link MessageItemProps}).
177
179
  * @returns The rendered chat panel element.
178
180
  */
179
- export declare function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onProfileClick, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, autoSubmitSignal, initialInputValue, hideConversationMenu, renderConversationHeader, conversationId: controlledConversationId, chatKey: controlledChatKey, onConversationId: controlledOnConversationId, openShareSignal: controlledShareSignal, openReportSignal: controlledReportSignal, openSettingsSignal: controlledSettingsSignal, onManageCustomModels, gitStatusTick, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, isPro, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, feedbackUrl, className, }: ChatPanelProps): JSX.Element;
181
+ export declare function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onRenderError, onProfileClick, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, autoSubmitSignal, initialInputValue, hideConversationMenu, renderConversationHeader, conversationId: controlledConversationId, chatKey: controlledChatKey, onConversationId: controlledOnConversationId, openShareSignal: controlledShareSignal, openReportSignal: controlledReportSignal, openSettingsSignal: controlledSettingsSignal, onManageCustomModels, gitStatusTick, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, isPro, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, feedbackUrl, className, }: ChatPanelProps): JSX.Element;
180
182
  export declare namespace ChatPanel {
181
183
  var displayName: string;
182
184
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ChatPanel.d.ts","sourceRoot":"","sources":["../../src/components/ChatPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatPanel.d.ts","sourceRoot":"","sources":["../../src/components/ChatPanel.tsx"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@ import { cachedPromptTokens, formatTokenTotal } from './chat-cost-utilities.js';
22
22
  import { effortOptionsForModel, nativeEffortName, parseEffortCommand, resolveEffortArg, } from './chat-effort-utilities.js';
23
23
  import { buildHelpText } from './chat-help-utilities.js';
24
24
  import { effectiveModeModelId, freeTierLockReason, freeTierUsableMode, isModeModelLocked, modeSettingKey, parseModelModeCommand, resolveModeModel, } from './chat-model-mode-utilities.js';
25
- import { modelUsageRate, sortModels } from './chat-models-utilities.js';
25
+ import { modelHasPeakPricing, modelPeakMultiplier, modelPeakWindowLabels, modelUsageRate, sortModels, } from './chat-models-utilities.js';
26
26
  import { formatReportConfirmation, parseReportCommand } from './chat-report-utilities.js';
27
27
  import { findScriptByName, formatRunOutput, parseRunCommand, parseScriptsCommand, runSucceeded, } from './chat-scripts-utilities.js';
28
28
  import { buildSettingsList, summarizeSounds } from './chat-settings-utilities.js';
@@ -30,6 +30,7 @@ import { buildShareUrl, DEFAULT_SHARE_ROLE, parseShareCommand, SHARE_ROLES, } fr
30
30
  import { buildNewSkillTemplate, loadProjectSkills, newSkillPath, parseSkillMeta, pickRelevantSkill, recentUserText, } from './chat-skills-utilities.js';
31
31
  import { estimateTurnTokens } from './chat-stream-utilities.js';
32
32
  import { ENTRY_TIP, pickIdleTip, shouldShowIdleTip, TIP_IDLE_MS, TIP_MIN_MESSAGES, } from './chat-tips-utilities.js';
33
+ import { ChatItemBoundary } from './ChatItemBoundary.js';
33
34
  import { HelpCard } from './HelpCard.js';
34
35
  import { Icon } from './Icon.js';
35
36
  import { MarkdownContent } from './MarkdownContent.js';
@@ -1245,7 +1246,7 @@ const MessageItem = memo(function MessageItem(props) {
1245
1246
  * @param props - Component props (see {@link MessageItemProps}).
1246
1247
  * @returns The rendered chat inner component.
1247
1248
  */
1248
- function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent, isPro, buildUpgradeCta, buildHelpUpgradeSection, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onConversationId, onActivityClick, onProfileClick, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, autoSubmitSignal, openSettingsSignal, onManageCustomModels, openReportSignal, openShareSignal, initialInputValue, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, gitStatusTick: externalGitStatusTick, discovery, userAvatar, agentName = DEFAULT_AGENT_NAME, productName = DEFAULT_PRODUCT_NAME, version,
1249
+ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent, isPro, buildUpgradeCta, buildHelpUpgradeSection, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onConversationId, onActivityClick, onRenderError, onProfileClick, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, autoSubmitSignal, openSettingsSignal, onManageCustomModels, openReportSignal, openShareSignal, initialInputValue, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, gitStatusTick: externalGitStatusTick, discovery, userAvatar, agentName = DEFAULT_AGENT_NAME, productName = DEFAULT_PRODUCT_NAME, version,
1249
1250
  // feedbackUrl: prop kept for back-compat (callers still pass it), but no longer
1250
1251
  // consumed here — its only use was the command-menu footer link removed in P3-21.
1251
1252
  }) {
@@ -4690,7 +4691,22 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
4690
4691
  case 'custom': {
4691
4692
  // App-registered renderer (registerCustomEventCard) builds the copy/actions/tone
4692
4693
  // from the raw data — keeping app-specific text out of this shared package.
4693
- const card = getCustomEventCardFactory(cardEvent.name)?.(cardEvent.data);
4694
+ //
4695
+ // This runs in a memo ABOVE the timeline's per-item boundaries, so a factory
4696
+ // that throws would take the whole panel down rather than one card — and the
4697
+ // factory is host code reading model-authored `data`, exactly the combination
4698
+ // that caused the 2026-08-14 outage. One unrenderable card must cost one card.
4699
+ let card;
4700
+ try {
4701
+ card = getCustomEventCardFactory(cardEvent.name)?.(cardEvent.data);
4702
+ }
4703
+ catch (error) {
4704
+ logger.error('Custom chat card factory threw — dropping the card', {
4705
+ error,
4706
+ name: cardEvent.name,
4707
+ });
4708
+ return null;
4709
+ }
4694
4710
  if (!card)
4695
4711
  return null;
4696
4712
  return {
@@ -4849,117 +4865,117 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
4849
4865
  opacity: 0.7,
4850
4866
  }, children: t('ide.chat.showEarlier', undefined, {
4851
4867
  defaultValue: 'Show earlier messages',
4852
- }) }) })), (timeline.length > maxVisibleItems ? timeline.slice(-maxVisibleItems) : timeline).map((item) => {
4853
- if (item.kind === 'commit')
4854
- return (_jsx(CommitCardItem, { card: item.card, onRevert: handleRevertCommit }, item.card.id));
4855
- if (item.kind === 'activity')
4856
- return (_jsx(ActivityCard, { activity: item.card.activity, onActivityClick: onActivityClick }, item.card.id));
4857
- if (item.kind === 'tip')
4858
- return (_jsx(TipCard, { text: item.card.text, onDismiss: () => dismissTip(item.card.id) }, item.card.id));
4859
- if (item.kind === 'system') {
4860
- if (item.card.variant === 'settings') {
4861
- // Legacy inline branch — kept so any 'settings' card persisted
4862
- // before /settings became an overlay still renders. New /settings
4863
- // invocations open the closeable overlay (see panelOverlay below).
4864
- return (_jsx(SettingsCard, { settings: computeSettingsList(), onRunCommand: (commandId) => void executeCommand(commandId), onPrefillInput: (input) => setInputAndCursorEnd(`${input} `), isLight: isLight, agentName: agentName }, item.card.id));
4865
- }
4866
- if (item.card.variant === 'skills' || item.card.variant === 'skillsCreate') {
4867
- return (_jsx(SkillsCard, { projectId: projectId, initialQuery: item.card.query ?? '', onLoad: loadSkill, onCreate: createSkill,
4868
- // The 'skillsCreate' variant opens the card with its "New skill" form
4869
- // already open (vs plain 'skills', which opens the browser).
4870
- startCreating: item.card.variant === 'skillsCreate', loadedSkillPaths: loadedSkillPaths, defaultSkillPaths: defaultSkillPaths, onToggleDefault: toggleDefaultSkill, onResetDefault: resetDefaultSkills, defaultsExplicit: defaultSkillsExplicitRef.current, isLight: isLight }, item.card.id));
4871
- }
4872
- if (item.card.variant === 'scripts') {
4873
- return (_jsx(ScriptsCard, { projectId: projectId, initialQuery: item.card.query ?? '', isLight: isLight, agentName: agentName }, item.card.id));
4874
- }
4875
- if (item.card.variant === 'help') {
4876
- // The plan/upgrade blurb is app-specific (pricing, plan names), so the
4877
- // host supplies it via buildHelpUpgradeSection — this shared package
4878
- // hardcodes none. Read at render time (like the settings card's list).
4879
- const upgradeSection = buildHelpUpgradeSection?.();
4880
- return (_jsx(HelpCard, { isLight: isLight, agentName: agentName, productName: productName, upgradeLines: upgradeSection?.lines, upgradeAction: upgradeSection?.action ?? undefined }, item.card.id));
4881
- }
4882
- if (item.card.variant === 'skillsLoaded') {
4883
- // "🧠 Loaded {{count}} skills" — styled like the plain "🔨 Building your
4884
- // app" phase notice (centered, muted, xs, emoji baked into the text), but
4885
- // CLICKABLE: its onClick is created HERE at render time — opening the
4886
- // /skills browser overlay, exactly what typing /skills does — so it
4887
- // survives the persistence round-trip (which stores only variant + count +
4888
- // text, never callbacks). Text restores from the persisted copy; re-derive
4889
- // from `count` if a caller passed none.
4890
- const skillsLoadedLabel = item.card.text ||
4891
- t('ide.chat.skills.loadedCount', { count: item.card.count ?? 0 }, { defaultValue: '🧠 Loaded {{count}} skills' });
4892
- return (_jsx("div", { style: { textAlign: 'center', marginBottom: TIMELINE_ITEM_GAP }, children: _jsx("button", { type: "button", "data-mol-id": "chat-skills-loaded", onClick: () => openPanelOverlay('skills'), className: cm.cn(cm.textSize('xs'), cm.textMuted), style: {
4893
- // Plain text like the build-phase notice — no border/fill/pill.
4894
- background: 'none',
4895
- border: 'none',
4896
- margin: 0,
4897
- padding: '6px 0',
4898
- fontFamily: 'inherit',
4899
- cursor: 'pointer',
4900
- },
4901
- // Underline on hover is the only clickability hint (it otherwise
4902
- // reads exactly like the plain phase message).
4903
- onMouseEnter: (e) => {
4904
- ;
4905
- e.currentTarget.style.textDecoration = 'underline';
4906
- }, onMouseLeave: (e) => {
4907
- ;
4908
- e.currentTarget.style.textDecoration = 'none';
4909
- }, children: skillsLoadedLabel }) }, item.card.id));
4868
+ }) }) })), (timeline.length > maxVisibleItems ? timeline.slice(-maxVisibleItems) : timeline).map((item) => (_jsx(ChatItemBoundary, { onError: onRenderError, render: () => {
4869
+ if (item.kind === 'commit')
4870
+ return (_jsx(CommitCardItem, { card: item.card, onRevert: handleRevertCommit }, item.card.id));
4871
+ if (item.kind === 'activity')
4872
+ return (_jsx(ActivityCard, { activity: item.card.activity, onActivityClick: onActivityClick }, item.card.id));
4873
+ if (item.kind === 'tip')
4874
+ return (_jsx(TipCard, { text: item.card.text, onDismiss: () => dismissTip(item.card.id) }, item.card.id));
4875
+ if (item.kind === 'system') {
4876
+ if (item.card.variant === 'settings') {
4877
+ // Legacy inline branch — kept so any 'settings' card persisted
4878
+ // before /settings became an overlay still renders. New /settings
4879
+ // invocations open the closeable overlay (see panelOverlay below).
4880
+ return (_jsx(SettingsCard, { settings: computeSettingsList(), onRunCommand: (commandId) => void executeCommand(commandId), onPrefillInput: (input) => setInputAndCursorEnd(`${input} `), isLight: isLight, agentName: agentName }, item.card.id));
4881
+ }
4882
+ if (item.card.variant === 'skills' || item.card.variant === 'skillsCreate') {
4883
+ return (_jsx(SkillsCard, { projectId: projectId, initialQuery: item.card.query ?? '', onLoad: loadSkill, onCreate: createSkill,
4884
+ // The 'skillsCreate' variant opens the card with its "New skill" form
4885
+ // already open (vs plain 'skills', which opens the browser).
4886
+ startCreating: item.card.variant === 'skillsCreate', loadedSkillPaths: loadedSkillPaths, defaultSkillPaths: defaultSkillPaths, onToggleDefault: toggleDefaultSkill, onResetDefault: resetDefaultSkills, defaultsExplicit: defaultSkillsExplicitRef.current, isLight: isLight }, item.card.id));
4887
+ }
4888
+ if (item.card.variant === 'scripts') {
4889
+ return (_jsx(ScriptsCard, { projectId: projectId, initialQuery: item.card.query ?? '', isLight: isLight, agentName: agentName }, item.card.id));
4890
+ }
4891
+ if (item.card.variant === 'help') {
4892
+ // The plan/upgrade blurb is app-specific (pricing, plan names), so the
4893
+ // host supplies it via buildHelpUpgradeSection — this shared package
4894
+ // hardcodes none. Read at render time (like the settings card's list).
4895
+ const upgradeSection = buildHelpUpgradeSection?.();
4896
+ return (_jsx(HelpCard, { isLight: isLight, agentName: agentName, productName: productName, upgradeLines: upgradeSection?.lines, upgradeAction: upgradeSection?.action ?? undefined }, item.card.id));
4897
+ }
4898
+ if (item.card.variant === 'skillsLoaded') {
4899
+ // "🧠 Loaded {{count}} skills" — styled like the plain "🔨 Building your
4900
+ // app" phase notice (centered, muted, xs, emoji baked into the text), but
4901
+ // CLICKABLE: its onClick is created HERE at render time — opening the
4902
+ // /skills browser overlay, exactly what typing /skills does — so it
4903
+ // survives the persistence round-trip (which stores only variant + count +
4904
+ // text, never callbacks). Text restores from the persisted copy; re-derive
4905
+ // from `count` if a caller passed none.
4906
+ const skillsLoadedLabel = item.card.text ||
4907
+ t('ide.chat.skills.loadedCount', { count: item.card.count ?? 0 }, { defaultValue: '🧠 Loaded {{count}} skills' });
4908
+ return (_jsx("div", { style: { textAlign: 'center', marginBottom: TIMELINE_ITEM_GAP }, children: _jsx("button", { type: "button", "data-mol-id": "chat-skills-loaded", onClick: () => openPanelOverlay('skills'), className: cm.cn(cm.textSize('xs'), cm.textMuted), style: {
4909
+ // Plain text like the build-phase notice — no border/fill/pill.
4910
+ background: 'none',
4911
+ border: 'none',
4912
+ margin: 0,
4913
+ padding: '6px 0',
4914
+ fontFamily: 'inherit',
4915
+ cursor: 'pointer',
4916
+ },
4917
+ // Underline on hover is the only clickability hint (it otherwise
4918
+ // reads exactly like the plain phase message).
4919
+ onMouseEnter: (e) => {
4920
+ ;
4921
+ e.currentTarget.style.textDecoration = 'underline';
4922
+ }, onMouseLeave: (e) => {
4923
+ ;
4924
+ e.currentTarget.style.textDecoration = 'none';
4925
+ }, children: skillsLoadedLabel }) }, item.card.id));
4926
+ }
4927
+ // Every rich variant is handled above; what remains is the plain notice /
4928
+ // tip card (no variant). Narrow to PlainSystemCard so the compiler knows
4929
+ // tone/content/emphasized exist here — and render nothing for any future
4930
+ // unhandled variant rather than mis-rendering it as a plain card.
4931
+ if (item.card.variant !== undefined)
4932
+ return null;
4933
+ // ── Unified tip / notice card ────────────────────────────────────────────
4934
+ // EVERY host notice (upgrade, sign-up, model-intro, pre-alpha, saved-script,
4935
+ // build-degraded) renders through ONE structure so they look consistent: an
4936
+ // icon, a tinted body with a uniform 1px border, and — for action cards — a row
4937
+ // of accent buttons. Only the ACCENT COLOUR + ICON change, by `tone`. Picking a
4938
+ // tone (or `emphasized`, or merely having an action) opts a card in; a card with
4939
+ // none of those stays a plain muted inline line (e.g. a "Now using <model>"
4940
+ // notice). `emphasized` without a tone → the neutral `info` tone.
4941
+ const tipTone = item.card.tone ?? (item.card.emphasized || item.card.action ? 'info' : null);
4942
+ if (tipTone) {
4943
+ // ONE shared treatment for every tone-accented notice — see NoticeCard.
4944
+ // The resource-limit / upgrade banner renders through the same component,
4945
+ // so their icon + buttons stay in lockstep.
4946
+ return (_jsx(NoticeCard, { tone: tipTone, text: item.card.text, content: item.card.content, action: item.card.action, icon: item.card.icon }, item.card.id));
4947
+ }
4948
+ // Plain muted inline notice (no tone / not emphasized / no action) — e.g. a
4949
+ // "Now using <model>" line. Centered for one-liners; left-aligned mono for
4950
+ // multi-line.
4951
+ const isMultiLine = item.card.text.includes('\n');
4952
+ return (_jsx("div", { className: cm.cn(cm.textSize('xs'), cm.textMuted), style: {
4953
+ textAlign: isMultiLine ? 'left' : 'center',
4954
+ padding: isMultiLine ? '8px 12px' : '6px 0',
4955
+ marginBottom: TIMELINE_ITEM_GAP,
4956
+ whiteSpace: isMultiLine ? 'pre-wrap' : undefined,
4957
+ fontFamily: isMultiLine ? 'var(--mol-font-mono, monospace)' : undefined,
4958
+ lineHeight: isMultiLine ? 1.5 : undefined,
4959
+ }, children: item.card.content
4960
+ ? item.card.content.map((seg, i) => renderCardSegment(seg, i))
4961
+ : item.card.text }, item.card.id));
4910
4962
  }
4911
- // Every rich variant is handled above; what remains is the plain notice /
4912
- // tip card (no variant). Narrow to PlainSystemCard so the compiler knows
4913
- // tone/content/emphasized exist here — and render nothing for any future
4914
- // unhandled variant rather than mis-rendering it as a plain card.
4915
- if (item.card.variant !== undefined)
4916
- return null;
4917
- // ── Unified tip / notice card ────────────────────────────────────────────
4918
- // EVERY host notice (upgrade, sign-up, model-intro, pre-alpha, saved-script,
4919
- // build-degraded) renders through ONE structure so they look consistent: an
4920
- // icon, a tinted body with a uniform 1px border, and — for action cards — a row
4921
- // of accent buttons. Only the ACCENT COLOUR + ICON change, by `tone`. Picking a
4922
- // tone (or `emphasized`, or merely having an action) opts a card in; a card with
4923
- // none of those stays a plain muted inline line (e.g. a "Now using <model>"
4924
- // notice). `emphasized` without a tone → the neutral `info` tone.
4925
- const tipTone = item.card.tone ?? (item.card.emphasized || item.card.action ? 'info' : null);
4926
- if (tipTone) {
4927
- // ONE shared treatment for every tone-accented notice — see NoticeCard.
4928
- // The resource-limit / upgrade banner renders through the same component,
4929
- // so their icon + buttons stay in lockstep.
4930
- return (_jsx(NoticeCard, { tone: tipTone, text: item.card.text, content: item.card.content, action: item.card.action, icon: item.card.icon }, item.card.id));
4963
+ const { msg } = item;
4964
+ // Persisted commit records render as commit cards
4965
+ if (msg.commitRecord) {
4966
+ const files = msg.commitRecord.files.map((f) => typeof f === 'string' ? f : f.path);
4967
+ const hash = msg.commitRecord.hash;
4968
+ return (_jsx(CommitCardItem, { card: {
4969
+ id: msg.id,
4970
+ message: msg.commitRecord.message,
4971
+ files,
4972
+ timestamp: msg.timestamp,
4973
+ status: 'done',
4974
+ hash,
4975
+ }, onRevert: handleRevertCommit }, msg.id));
4931
4976
  }
4932
- // Plain muted inline notice (no tone / not emphasized / no action) e.g. a
4933
- // "Now using <model>" line. Centered for one-liners; left-aligned mono for
4934
- // multi-line.
4935
- const isMultiLine = item.card.text.includes('\n');
4936
- return (_jsx("div", { className: cm.cn(cm.textSize('xs'), cm.textMuted), style: {
4937
- textAlign: isMultiLine ? 'left' : 'center',
4938
- padding: isMultiLine ? '8px 12px' : '6px 0',
4939
- marginBottom: TIMELINE_ITEM_GAP,
4940
- whiteSpace: isMultiLine ? 'pre-wrap' : undefined,
4941
- fontFamily: isMultiLine ? 'var(--mol-font-mono, monospace)' : undefined,
4942
- lineHeight: isMultiLine ? 1.5 : undefined,
4943
- }, children: item.card.content
4944
- ? item.card.content.map((seg, i) => renderCardSegment(seg, i))
4945
- : item.card.text }, item.card.id));
4946
- }
4947
- const { msg } = item;
4948
- // Persisted commit records render as commit cards
4949
- if (msg.commitRecord) {
4950
- const files = msg.commitRecord.files.map((f) => typeof f === 'string' ? f : f.path);
4951
- const hash = msg.commitRecord.hash;
4952
- return (_jsx(CommitCardItem, { card: {
4953
- id: msg.id,
4954
- message: msg.commitRecord.message,
4955
- files,
4956
- timestamp: msg.timestamp,
4957
- status: 'done',
4958
- hash,
4959
- }, onRevert: handleRevertCommit }, msg.id));
4960
- }
4961
- return (_jsx(MessageItem, { msg: msg, editingQueuedId: editingQueuedId, editingQueuedText: editingQueuedText, setEditingQueuedId: setEditingQueuedId, setEditingQueuedText: setEditingQueuedText, editQueuedMessage: editQueuedMessage, deleteQueuedMessage: deleteQueuedMessage, sendMessage: sendMessage, handleAskUserResponse: handleAskUserResponse, isLoading: isLoading, streamingStatus: streamingStatus, onNavigatePreview: onNavigatePreview, undoneTcIds: undoneTcIds, handleUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, handleFileRevert: handleFileRevert, setInputAndCursorEnd: setInputAndCursorEnd, setModelPicker: setModelPicker, userAvatar: userAvatar, onAvatarClick: onUserAvatarClick, discovery: discovery, buildUpgradeCta: buildUpgradeCta }, msg.id));
4962
- }), error &&
4977
+ return (_jsx(MessageItem, { msg: msg, editingQueuedId: editingQueuedId, editingQueuedText: editingQueuedText, setEditingQueuedId: setEditingQueuedId, setEditingQueuedText: setEditingQueuedText, editQueuedMessage: editQueuedMessage, deleteQueuedMessage: deleteQueuedMessage, sendMessage: sendMessage, handleAskUserResponse: handleAskUserResponse, isLoading: isLoading, streamingStatus: streamingStatus, onNavigatePreview: onNavigatePreview, undoneTcIds: undoneTcIds, handleUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, handleFileRevert: handleFileRevert, setInputAndCursorEnd: setInputAndCursorEnd, setModelPicker: setModelPicker, userAvatar: userAvatar, onAvatarClick: onUserAvatarClick, discovery: discovery, buildUpgradeCta: buildUpgradeCta }, msg.id));
4978
+ } }, item.kind === 'message' ? item.msg.id : item.card.id))), error &&
4963
4979
  (errorMeta?.limitType ? (_jsx(ResourceLimitBanner, { message: error, action: buildUpgradeCta?.({ requiresSignup: errorMeta.requiresSignup }) })) : (_jsx("div", { className: cm.cn(cm.textSize('sm'), cm.sp('p', 2), cm.sp('mb', 2), cm.bgErrorSubtle, cm.textError), style: { borderRadius: '6px' }, children: error }))), (() => {
4964
4980
  const showActivity = isLoading || awaitingSandboxBoot;
4965
4981
  const streamingMsg = isLoading
@@ -5479,6 +5495,8 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
5479
5495
  // region immediately re-rates the row (e.g. DeepSeek V4
5480
5496
  // Pro: ×3 native-CN vs ×9 US-rehosted).
5481
5497
  const usageRate = modelUsageRate(model, AVAILABLE_MODELS, modelRegion);
5498
+ // Whether the rate above is currently inflated by a peak window.
5499
+ const peakNow = modelPeakMultiplier(model, modelRegion);
5482
5500
  const priceColor = usageRate <= 5
5483
5501
  ? isLight
5484
5502
  ? 'rgb(22,163,74)'
@@ -5601,7 +5619,17 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
5601
5619
  defaultValue: 'your key',
5602
5620
  }) })) : (_jsx("span", { style: { color: priceColor }, title: t('ide.chat.models.usageRateHint', undefined, {
5603
5621
  defaultValue: 'How fast this model uses your AI allowance, relative to the most economical model',
5604
- }), children: t('ide.chat.models.usageRateValue', { rate: usageRate }, { defaultValue: '×{{rate}} usage' }) })), model.knowledgeCutoff ? _jsxs(_Fragment, { children: [" \u00B7 ", model.knowledgeCutoff] }) : null] }), (badges.length > 0 || showRegionPill) && (_jsxs("span", { style: {
5622
+ }), children: t('ide.chat.models.usageRateValue', { rate: usageRate }, { defaultValue: '×{{rate}} usage' }) })), !isCustom && modelHasPeakPricing(model, modelRegion) && (_jsxs(_Fragment, { children: [' · ', _jsx("span", { style: {
5623
+ color: peakNow > 1 ? priceColor : undefined,
5624
+ opacity: peakNow > 1 ? 1 : 0.8,
5625
+ }, title: t('ide.chat.models.peakHint', {
5626
+ multiplier: model.peakPricing?.multiplier ?? 2,
5627
+ windows: modelPeakWindowLabels(model).join(', '),
5628
+ }, {
5629
+ defaultValue: 'This model costs ×{{multiplier}} between {{windows}}. It is the normal rate the rest of the day.',
5630
+ }), children: peakNow > 1
5631
+ ? t('ide.chat.models.peakNow', { multiplier: model.peakPricing?.multiplier ?? 2 }, { defaultValue: 'peak ×{{multiplier}} now' })
5632
+ : t('ide.chat.models.peakLater', { multiplier: model.peakPricing?.multiplier ?? 2 }, { defaultValue: '×{{multiplier}} at peak hours' }) })] })), model.knowledgeCutoff ? _jsxs(_Fragment, { children: [" \u00B7 ", model.knowledgeCutoff] }) : null] }), (badges.length > 0 || showRegionPill) && (_jsxs("span", { style: {
5605
5633
  display: 'flex',
5606
5634
  gap: '4px',
5607
5635
  flexWrap: 'wrap',
@@ -6550,7 +6578,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
6550
6578
  * @param props - Component props (see {@link MessageItemProps}).
6551
6579
  * @returns The rendered chat panel element.
6552
6580
  */
6553
- export function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onProfileClick, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, autoSubmitSignal, initialInputValue, hideConversationMenu, renderConversationHeader = true, conversationId: controlledConversationId, chatKey: controlledChatKey, onConversationId: controlledOnConversationId, openShareSignal: controlledShareSignal, openReportSignal: controlledReportSignal, openSettingsSignal: controlledSettingsSignal, onManageCustomModels, gitStatusTick, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, isPro, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, feedbackUrl, className, }) {
6581
+ export function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onRenderError, onProfileClick, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, autoSubmitSignal, initialInputValue, hideConversationMenu, renderConversationHeader = true, conversationId: controlledConversationId, chatKey: controlledChatKey, onConversationId: controlledOnConversationId, openShareSignal: controlledShareSignal, openReportSignal: controlledReportSignal, openSettingsSignal: controlledSettingsSignal, onManageCustomModels, gitStatusTick, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, isPro, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, feedbackUrl, className, }) {
6554
6582
  const cm = getClassMap();
6555
6583
  const isNarrow = useNarrowViewport();
6556
6584
  const isCoarse = useCoarsePointer();
@@ -6759,7 +6787,7 @@ export function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessag
6759
6787
  textOverflow: 'ellipsis',
6760
6788
  whiteSpace: 'nowrap',
6761
6789
  width: '100%',
6762
- }, children: conv.preview ?? 'New conversation' }), _jsx("span", { className: cm.cn(cm.textMuted, cm.textSize('xs')), style: { opacity: 0.55 }, children: relativeTime(conv.updatedAt) })] }, conv.id)))] }))] })), _jsx(ChatInner, { projectId: projectId, endpoint: chatEndpoint, initialMessage: initialMessage, onInitialMessageSent: onInitialMessageSent, isPro: isPro, buildUpgradeCta: buildUpgradeCta, buildHelpUpgradeSection: buildHelpUpgradeSection, activeFile: activeFile, openTabs: openTabs, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: onFileRevert, onFileChange: onFileChange, onFileDeleted: onFileDeleted, onCommit: onCommit, onConversationId: reportConversationId, onActivityClick: onActivityClick, onProfileClick: onProfileClick, onReadyToBuild: onReadyToBuild, awaitingSandboxBoot: awaitingSandboxBoot, onClientAction: onClientAction, onTurnComplete: onTurnComplete, onLoadingChange: onLoadingChange, onNavigatePreview: onNavigatePreview, onRegisterPushHandler: onRegisterPushHandler, autoSubmitSignal: autoSubmitSignal, openSettingsSignal: effectiveSettingsSignal, onManageCustomModels: onManageCustomModels, openReportSignal: effectiveReportSignal, openShareSignal: effectiveShareSignal, initialInputValue: initialInputValue, pendingMessage: pendingMessage, pendingMessageKey: pendingMessageKey, pendingMessageSuppressUser: pendingMessageSuppressUser, pendingMessageUserInitiated: pendingMessageUserInitiated, userEditedFile: userEditedFile, userEditedFileKey: userEditedFileKey, gitStatusTick: gitStatusTick, discovery: hideConversationMenu, userAvatar: userAvatar, agentName: agentName, productName: productName, version: version, feedbackUrl: feedbackUrl }, chatKey)] }));
6790
+ }, children: conv.preview ?? 'New conversation' }), _jsx("span", { className: cm.cn(cm.textMuted, cm.textSize('xs')), style: { opacity: 0.55 }, children: relativeTime(conv.updatedAt) })] }, conv.id)))] }))] })), _jsx(ChatInner, { projectId: projectId, endpoint: chatEndpoint, initialMessage: initialMessage, onInitialMessageSent: onInitialMessageSent, isPro: isPro, buildUpgradeCta: buildUpgradeCta, buildHelpUpgradeSection: buildHelpUpgradeSection, activeFile: activeFile, openTabs: openTabs, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: onFileRevert, onFileChange: onFileChange, onFileDeleted: onFileDeleted, onCommit: onCommit, onConversationId: reportConversationId, onActivityClick: onActivityClick, onRenderError: onRenderError, onProfileClick: onProfileClick, onReadyToBuild: onReadyToBuild, awaitingSandboxBoot: awaitingSandboxBoot, onClientAction: onClientAction, onTurnComplete: onTurnComplete, onLoadingChange: onLoadingChange, onNavigatePreview: onNavigatePreview, onRegisterPushHandler: onRegisterPushHandler, autoSubmitSignal: autoSubmitSignal, openSettingsSignal: effectiveSettingsSignal, onManageCustomModels: onManageCustomModels, openReportSignal: effectiveReportSignal, openShareSignal: effectiveShareSignal, initialInputValue: initialInputValue, pendingMessage: pendingMessage, pendingMessageKey: pendingMessageKey, pendingMessageSuppressUser: pendingMessageSuppressUser, pendingMessageUserInitiated: pendingMessageUserInitiated, userEditedFile: userEditedFile, userEditedFileKey: userEditedFileKey, gitStatusTick: gitStatusTick, discovery: hideConversationMenu, userAvatar: userAvatar, agentName: agentName, productName: productName, version: version, feedbackUrl: feedbackUrl }, chatKey)] }));
6763
6791
  }
6764
6792
  ChatPanel.displayName = 'ChatPanel';
6765
6793
  //# sourceMappingURL=ChatPanel.js.map