@molecule/app-ide-react 1.12.1 → 1.14.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.
Files changed (36) hide show
  1. package/README.md +504 -1
  2. package/dist/command-metadata.d.ts.map +1 -1
  3. package/dist/command-metadata.js +7 -2
  4. package/dist/command-metadata.js.map +1 -1
  5. package/dist/components/ChatPanel.d.ts +9 -1
  6. package/dist/components/ChatPanel.d.ts.map +1 -1
  7. package/dist/components/ChatPanel.js +161 -22
  8. package/dist/components/ChatPanel.js.map +1 -1
  9. package/dist/components/TestsBar.d.ts +55 -0
  10. package/dist/components/TestsBar.d.ts.map +1 -0
  11. package/dist/components/TestsBar.js +296 -0
  12. package/dist/components/TestsBar.js.map +1 -0
  13. package/dist/components/TestsCard.d.ts +67 -0
  14. package/dist/components/TestsCard.d.ts.map +1 -0
  15. package/dist/components/TestsCard.js +185 -0
  16. package/dist/components/TestsCard.js.map +1 -0
  17. package/dist/components/index.d.ts +3 -0
  18. package/dist/components/index.d.ts.map +1 -1
  19. package/dist/components/index.js +2 -0
  20. package/dist/components/index.js.map +1 -1
  21. package/dist/components/tests-bar-utilities.d.ts +129 -0
  22. package/dist/components/tests-bar-utilities.d.ts.map +1 -0
  23. package/dist/components/tests-bar-utilities.js +236 -0
  24. package/dist/components/tests-bar-utilities.js.map +1 -0
  25. package/dist/components/tests-card-utilities.d.ts +145 -0
  26. package/dist/components/tests-card-utilities.d.ts.map +1 -0
  27. package/dist/components/tests-card-utilities.js +262 -0
  28. package/dist/components/tests-card-utilities.js.map +1 -0
  29. package/dist/index.d.ts +30 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +30 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/types.d.ts +160 -0
  34. package/dist/types.d.ts.map +1 -1
  35. package/dist/types.js.map +1 -1
  36. package/package.json +3 -3
@@ -204,13 +204,21 @@ export interface ChatInnerProps {
204
204
  extraCommands?: readonly CommandDef[];
205
205
  /** Command-menu "Report a problem" URL — see {@link ChatPanelProps.feedbackUrl}. */
206
206
  feedbackUrl?: string;
207
+ /** Lists the project's tests for the Tests bar — see {@link ChatPanelProps.listTests}. */
208
+ listTests?: ChatPanelProps['listTests'];
209
+ /** Runs the selected tests, streaming events — see {@link ChatPanelProps.runTests}. */
210
+ runTests?: ChatPanelProps['runTests'];
211
+ /** Whether this viewer may run tests — see {@link ChatPanelProps.canRunTests}. */
212
+ canRunTests?: boolean;
213
+ /** Whether the environment that runs them is up — see {@link ChatPanelProps.testsAvailable}. */
214
+ testsAvailable?: boolean;
207
215
  }
208
216
  /**
209
217
  * AI chat panel with conversation history dropdown and Claude Code-style tool display.
210
218
  * @param props - Component props (see {@link MessageItemProps}).
211
219
  * @returns The rendered chat panel element.
212
220
  */
213
- export declare function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onRenderError, onProfileClick, currentUserId, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, onRegisterHistoryReconcile, 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, isAnonymous, canEdit, canShare, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, extraCommands, feedbackUrl, className, }: ChatPanelProps): JSX.Element;
221
+ export declare function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onRenderError, onProfileClick, currentUserId, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, onRegisterHistoryReconcile, 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, isAnonymous, canEdit, canShare, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, extraCommands, feedbackUrl, listTests, runTests, canRunTests, testsAvailable, className, }: ChatPanelProps): JSX.Element;
214
222
  export declare namespace ChatPanel {
215
223
  var displayName: string;
216
224
  }
@@ -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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"}
@@ -44,6 +44,8 @@ import { SettingsCard } from './SettingsCard.js';
44
44
  import { ShareModal } from './ShareModal.js';
45
45
  import { SkillsCard } from './SkillsCard.js';
46
46
  import { StreamingIndicator } from './StreamingIndicator.js';
47
+ import { applyTestRunEvent, EMPTY_RUN_STATE, failRun, parseTestCommand, } from './tests-card-utilities.js';
48
+ import { TestsCard } from './TestsCard.js';
47
49
  import { TipCard } from './TipCard.js';
48
50
  import { ToolCallCard } from './ToolCallCard.js';
49
51
  import { UserAvatar } from './UserAvatar.js';
@@ -1279,7 +1281,7 @@ const MessageItem = memo(function MessageItem(props) {
1279
1281
  * @param props - Component props (see {@link MessageItemProps}).
1280
1282
  * @returns The rendered chat inner component.
1281
1283
  */
1282
- function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent, isPro, isAnonymous, canEdit, canShare, buildUpgradeCta, buildHelpUpgradeSection, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onConversationId, onActivityClick, onRenderError, onProfileClick, currentUserId, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, onRegisterHistoryReconcile, autoSubmitSignal, openSettingsSignal, onManageCustomModels, modelSelectionSignal, openReportSignal, openShareSignal, initialInputValue, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, gitStatusTick: externalGitStatusTick, discovery, userAvatar, agentName = DEFAULT_AGENT_NAME, productName = DEFAULT_PRODUCT_NAME, version, extraCommands,
1284
+ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent, isPro, isAnonymous, canEdit, canShare, buildUpgradeCta, buildHelpUpgradeSection, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onConversationId, onActivityClick, onRenderError, onProfileClick, currentUserId, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, onRegisterHistoryReconcile, autoSubmitSignal, openSettingsSignal, onManageCustomModels, modelSelectionSignal, openReportSignal, openShareSignal, initialInputValue, pendingMessage, pendingMessageKey, pendingMessageSuppressUser, pendingMessageUserInitiated, userEditedFile, userEditedFileKey, gitStatusTick: externalGitStatusTick, discovery, userAvatar, agentName = DEFAULT_AGENT_NAME, productName = DEFAULT_PRODUCT_NAME, version, extraCommands, listTests, runTests, canRunTests, testsAvailable,
1283
1285
  // feedbackUrl: prop kept for back-compat (callers still pass it), but no longer
1284
1286
  // consumed here — its only use was the command-menu footer link removed in P3-21.
1285
1287
  }) {
@@ -2623,6 +2625,115 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
2623
2625
  setPanelOverlayQuery(query);
2624
2626
  setPanelOverlay(variant);
2625
2627
  }, []);
2628
+ // ── /test (the tests browser) ───────────────────────────────────────────────
2629
+ // The list and the in-flight run live HERE, not inside TestsCard, for one
2630
+ // reason: the card is an overlay the user closes. A run that is streaming
2631
+ // (a preview-driven spec takes a minute) must survive that close and still be
2632
+ // there when they re-open it, and re-running /test must re-list without
2633
+ // killing it. So the card is presentational and this owns the state.
2634
+ const [testsList, setTestsList] = useState([]);
2635
+ const [testsStatus, setTestsStatus] = useState('loading');
2636
+ const [testsRun, setTestsRun] = useState(EMPTY_RUN_STATE);
2637
+ const testsRunHandleRef = useRef(null);
2638
+ // Live "is a run in flight?" for the dispatchers, so `startTestsRun` keeps a
2639
+ // stable identity — the command callbacks that hold it carry hand-written
2640
+ // dependency lists, and a value that changes every run transition is one they
2641
+ // would eventually capture stale.
2642
+ const testsRunningRef = useRef(false);
2643
+ testsRunningRef.current = testsRun.running;
2644
+ // Live for the async callbacks, so a list resolving after an unmount, or a
2645
+ // run event arriving then, never sets state on a dead tree.
2646
+ const testsMountedRef = useRef(true);
2647
+ useEffect(() => () => {
2648
+ testsMountedRef.current = false;
2649
+ testsRunHandleRef.current?.cancel();
2650
+ }, []);
2651
+ const refreshTests = useCallback(async () => {
2652
+ // A host that wires no discovery has no tests to show. Say so rather than
2653
+ // opening a browser that spins on "Loading…" forever.
2654
+ if (!listTests) {
2655
+ setTestsStatus('error');
2656
+ return;
2657
+ }
2658
+ // Nothing can be discovered while the environment is down, and an empty
2659
+ // answer would WIPE the list the person was reading.
2660
+ if (testsAvailable === false) {
2661
+ setTestsStatus('unavailable');
2662
+ return;
2663
+ }
2664
+ setTestsStatus((prev) => (prev === 'ready' ? prev : 'loading'));
2665
+ try {
2666
+ const list = await listTests();
2667
+ if (!testsMountedRef.current)
2668
+ return;
2669
+ setTestsList(list.tests ?? []);
2670
+ setTestsStatus('ready');
2671
+ }
2672
+ catch (error) {
2673
+ logger.warn('Failed to list project tests', { error });
2674
+ if (!testsMountedRef.current)
2675
+ return;
2676
+ setTestsStatus('error');
2677
+ }
2678
+ }, [listTests, testsAvailable]);
2679
+ const startTestsRun = useCallback((selection) => {
2680
+ if (!runTests)
2681
+ return;
2682
+ if (canRunTests === false || canEdit === false)
2683
+ return;
2684
+ if (testsAvailable === false || testsRunningRef.current)
2685
+ return;
2686
+ if (selection.ids?.length === 0)
2687
+ return;
2688
+ // Seed a running state immediately: the host's `start` event may be a
2689
+ // round trip away, and a Run button that appears to do nothing is the
2690
+ // failure this feature exists to remove.
2691
+ setTestsRun((prev) => ({
2692
+ ...prev,
2693
+ running: true,
2694
+ outcome: null,
2695
+ error: null,
2696
+ output: [],
2697
+ currentId: null,
2698
+ queued: selection.ids ?? [],
2699
+ startedAt: Date.now(),
2700
+ durationMs: null,
2701
+ }));
2702
+ try {
2703
+ testsRunHandleRef.current = runTests(selection, (event) => {
2704
+ if (!testsMountedRef.current)
2705
+ return;
2706
+ setTestsRun((prev) => applyTestRunEvent(prev, event));
2707
+ if (event.type === 'done') {
2708
+ testsRunHandleRef.current = null;
2709
+ // A run cannot create a test, but it CAN finish after the agent wrote
2710
+ // one — re-list once it settles so the card is current.
2711
+ void refreshTests();
2712
+ }
2713
+ });
2714
+ }
2715
+ catch (error) {
2716
+ logger.warn('Failed to start a test run', { error });
2717
+ setTestsRun((prev) => failRun(prev, error instanceof Error
2718
+ ? error.message
2719
+ : t('ide.tests.runError', undefined, {
2720
+ defaultValue: 'The test run could not start.',
2721
+ })));
2722
+ }
2723
+ }, [runTests, canRunTests, canEdit, testsAvailable, refreshTests]);
2724
+ const cancelTestsRun = useCallback(() => {
2725
+ testsRunHandleRef.current?.cancel();
2726
+ testsRunHandleRef.current = null;
2727
+ setTestsRun((prev) => ({ ...prev, running: false, currentId: null, outcome: 'cancelled' }));
2728
+ }, []);
2729
+ /** Open the tests browser, re-listing so a spec just written shows up. */
2730
+ const openTestsBrowser = useCallback((query = '', runAll = false) => {
2731
+ openPanelOverlay('tests', query);
2732
+ void refreshTests().then(() => {
2733
+ if (runAll && testsMountedRef.current)
2734
+ startTestsRun({ kind: 'all' });
2735
+ });
2736
+ }, [openPanelOverlay, refreshTests, startTestsRun]);
2626
2737
  // Keep ref in sync so the streaming callback always sees latest config
2627
2738
  useEffect(() => {
2628
2739
  soundsConfigRef.current = soundsConfig;
@@ -4125,6 +4236,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
4125
4236
  files: res.data.files ?? [],
4126
4237
  timestamp: Date.now(),
4127
4238
  status: 'done',
4239
+ hash: res.data.hash,
4128
4240
  },
4129
4241
  ]);
4130
4242
  refreshGitStatus();
@@ -4137,7 +4249,10 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
4137
4249
  }
4138
4250
  else if (id === 'test') {
4139
4251
  setInputValue('');
4140
- sendMessage('Run the project test suite (npm test) and report the results. If tests fail, analyze the failures.');
4252
+ // Was: a natural-language "run npm test and report" message to the
4253
+ // agent — a whole turn spent to read output the platform can run
4254
+ // directly. Now it opens the tests browser, like /scripts.
4255
+ openTestsBrowser('');
4141
4256
  }
4142
4257
  else if (id === 'explain') {
4143
4258
  setInputAndCursorEnd('/explain ');
@@ -4377,6 +4492,14 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
4377
4492
  openPanelOverlay('scripts', scriptsMatch.query);
4378
4493
  return;
4379
4494
  }
4495
+ // Handle /test [query | all] locally — opens the tests browser overlay,
4496
+ // seeded with the query (if any); `all` runs everything straight away.
4497
+ const testMatch = parseTestCommand(trimmed);
4498
+ if (testMatch) {
4499
+ setInputValue('');
4500
+ openTestsBrowser(testMatch.query, testMatch.runAll);
4501
+ return;
4502
+ }
4380
4503
  // Handle /run <name> command locally — resolves + runs a saved script.
4381
4504
  const runMatch = parseRunCommand(trimmed);
4382
4505
  if (runMatch) {
@@ -4603,9 +4726,19 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
4603
4726
  t('ide.chat.maxLoopsReached', undefined, {
4604
4727
  defaultValue: 'Max loops limit reached.',
4605
4728
  }),
4606
- // Host owns the upgrade/sign-in button(s); `requiresSignup` is the
4607
- // backend's hint that the user must sign up rather than upgrade.
4608
- { action: buildUpgradeCta?.({ requiresSignup: data.requiresSignup }) ?? undefined });
4729
+ // Host owns the upgrade/sign-in button(s); forward the backend's whole
4730
+ // description of the refusal `requiresSignup`, the `limitType` that
4731
+ // fired, the `billingAction` remedy it resolved, and `upgradeTier`
4732
+ // (null = no higher plan) — so the host picks the right one instead of
4733
+ // defaulting to "Upgrade".
4734
+ {
4735
+ action: buildUpgradeCta?.({
4736
+ requiresSignup: data.requiresSignup,
4737
+ limitType: data.limitType,
4738
+ billingAction: data.billingAction,
4739
+ upgradeTier: data.upgradeTier,
4740
+ }) ?? undefined,
4741
+ });
4609
4742
  }
4610
4743
  else {
4611
4744
  addSystemCard(t('ide.chat.maxLoopsError', undefined, {
@@ -4616,17 +4749,6 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
4616
4749
  setInputValue('');
4617
4750
  return;
4618
4751
  }
4619
- // Handle /test [args] — inject prompt for AI to run tests
4620
- const testMatch = trimmed.match(/^\/test(?:\s+(.*))?$/i);
4621
- if (testMatch) {
4622
- const args = testMatch[1]?.trim();
4623
- const prompt = args
4624
- ? `Run this test command and report the results: npm test -- ${args}`
4625
- : 'Run the project test suite (npm test) and report the results. If tests fail, analyze the failures.';
4626
- setInputValue('');
4627
- sendMessage(prompt);
4628
- return;
4629
- }
4630
4752
  // Handle /explain [target] — inject prompt for AI to explain code
4631
4753
  // NOTE: does NOT return early — falls through to attachment processing below
4632
4754
  // so that @-attached files are included in the message sent to the AI.
@@ -5451,8 +5573,15 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
5451
5573
  items.push({ kind: 'message', msg });
5452
5574
  }
5453
5575
  }
5576
+ // The commit endpoint both returns the commit AND persists it as a `commitRecord`
5577
+ // message, so once any history reload (tab refocus, end-of-turn reconcile) pulls
5578
+ // that record into `messages`, this session's local card for the same commit is a
5579
+ // duplicate. The persisted record wins; a local card is kept only until it lands.
5580
+ const persistedCommitHashes = new Set(visibleMessages.map((msg) => msg.commitRecord?.hash).filter((hash) => !!hash));
5454
5581
  // systemCards now holds ONLY this session's local command cards (ephemeral, see above).
5455
- items.push(...commitCards.map((card) => ({ kind: 'commit', card })), ...systemCards.map((card) => ({ kind: 'system', card })), ...activityCards.map((card) => ({ kind: 'activity', card })), ...tipCards.map((card) => ({ kind: 'tip', card })));
5582
+ items.push(...commitCards
5583
+ .filter((card) => !card.hash || !persistedCommitHashes.has(card.hash))
5584
+ .map((card) => ({ kind: 'commit', card })), ...systemCards.map((card) => ({ kind: 'system', card })), ...activityCards.map((card) => ({ kind: 'activity', card })), ...tipCards.map((card) => ({ kind: 'tip', card })));
5456
5585
  // Order by timestamp, EXCEPT an empty (still-thinking) streaming response sorts
5457
5586
  // last — so a turn's preamble cards (mode/model/skills notices, onboarding tips),
5458
5587
  // emitted a beat after the placeholder is created, render ABOVE the response
@@ -5693,6 +5822,9 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
5693
5822
  if (item.card.variant === 'scripts') {
5694
5823
  return (_jsx(ScriptsCard, { projectId: projectId, initialQuery: item.card.query ?? '', isLight: isLight, agentName: agentName }, item.card.id));
5695
5824
  }
5825
+ if (item.card.variant === 'tests') {
5826
+ return (_jsx(TestsCard, { tests: testsList, status: testsStatus, run: testsRun, initialQuery: item.card.query ?? '', canRun: (canRunTests ?? canEdit !== false) && canEdit !== false, onRun: startTestsRun, onCancel: cancelTestsRun, isLight: isLight }, item.card.id));
5827
+ }
5696
5828
  if (item.card.variant === 'help') {
5697
5829
  // The plan/upgrade blurb is app-specific (pricing, plan names), so the
5698
5830
  // host supplies it via buildHelpUpgradeSection — this shared package
@@ -5787,7 +5919,12 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
5787
5919
  onProfileClick: onProfileClick, currentUserId: currentUserId, showTimestamp: shownTimestampIds.has(msg.id), discovery: discovery, buildUpgradeCta: buildUpgradeCta, agentName: agentName, canEdit: canEdit }, msg.id));
5788
5920
  })()) }, item.kind === 'message' ? item.msg.id : item.card.id))), error &&
5789
5921
  !isStaleAnonymousLimit &&
5790
- (errorMeta?.limitType ? (_jsx(ResourceLimitBanner, { message: error, action: buildUpgradeCta?.({ requiresSignup: errorMeta.requiresSignup }) })) : isViewerAccessDenied ? (
5922
+ (errorMeta?.limitType ? (_jsx(ResourceLimitBanner, { message: error, action: buildUpgradeCta?.({
5923
+ requiresSignup: errorMeta.requiresSignup,
5924
+ limitType: errorMeta.limitType,
5925
+ billingAction: errorMeta.billingAction,
5926
+ upgradeTier: errorMeta.upgradeTier,
5927
+ }) })) : isViewerAccessDenied ? (
5791
5928
  // A viewer's denial is expected state, not an alarm: a brief, calm,
5792
5929
  // gold view-only notice (matching the viewer tip / team-note
5793
5930
  // treatment) that clears itself — never the persistent red banner.
@@ -6902,7 +7039,9 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
6902
7039
  ? t('ide.chat.skills.heading', undefined, { defaultValue: 'Skills' })
6903
7040
  : panelOverlay === 'scripts'
6904
7041
  ? t('ide.chat.scripts.heading', undefined, { defaultValue: 'Scripts' })
6905
- : t('ide.chat.settings.heading', undefined, { defaultValue: 'Settings' }) }), _jsx("button", { type: "button", "data-mol-id": "panel-overlay-close", "aria-label": t('ide.chat.closeOverlay', undefined, { defaultValue: 'Close' }), onClick: () => setPanelOverlay(null), style: {
7042
+ : panelOverlay === 'tests'
7043
+ ? t('ide.tests.heading', undefined, { defaultValue: 'Tests' })
7044
+ : t('ide.chat.settings.heading', undefined, { defaultValue: 'Settings' }) }), _jsx("button", { type: "button", "data-mol-id": "panel-overlay-close", "aria-label": t('ide.chat.closeOverlay', undefined, { defaultValue: 'Close' }), onClick: () => setPanelOverlay(null), style: {
6906
7045
  background: 'none',
6907
7046
  border: 'none',
6908
7047
  cursor: 'pointer',
@@ -6922,7 +7061,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
6922
7061
  minHeight: 36,
6923
7062
  }
6924
7063
  : {}),
6925
- }, children: '✕' })] }), _jsxs("div", { style: { overflowY: 'auto', flex: 1 }, children: [panelOverlay === 'settings' && (_jsx(SettingsCard, { settings: computeSettingsList(), onRunCommand: (commandId) => void executeCommand(commandId), onPrefillInput: (input) => setInputAndCursorEnd(`${input} `), isLight: isLight, agentName: agentName, embedded: true })), panelOverlay === 'skills' && (_jsx(SkillsCard, { projectId: projectId, initialQuery: panelOverlayQuery, onLoad: loadSkill, onCreate: createSkill, loadedSkillPaths: loadedSkillPaths, defaultSkillPaths: defaultSkillPaths, onToggleDefault: toggleDefaultSkill, onResetDefault: resetDefaultSkills, defaultsExplicit: defaultSkillsExplicitRef.current, isLight: isLight, embedded: true })), panelOverlay === 'scripts' && (_jsx(ScriptsCard, { projectId: projectId, initialQuery: panelOverlayQuery, isLight: isLight, agentName: agentName, embedded: true }))] })] })), filePicker &&
7064
+ }, children: '✕' })] }), _jsxs("div", { style: { overflowY: 'auto', flex: 1 }, children: [panelOverlay === 'settings' && (_jsx(SettingsCard, { settings: computeSettingsList(), onRunCommand: (commandId) => void executeCommand(commandId), onPrefillInput: (input) => setInputAndCursorEnd(`${input} `), isLight: isLight, agentName: agentName, embedded: true })), panelOverlay === 'skills' && (_jsx(SkillsCard, { projectId: projectId, initialQuery: panelOverlayQuery, onLoad: loadSkill, onCreate: createSkill, loadedSkillPaths: loadedSkillPaths, defaultSkillPaths: defaultSkillPaths, onToggleDefault: toggleDefaultSkill, onResetDefault: resetDefaultSkills, defaultsExplicit: defaultSkillsExplicitRef.current, isLight: isLight, embedded: true })), panelOverlay === 'scripts' && (_jsx(ScriptsCard, { projectId: projectId, initialQuery: panelOverlayQuery, isLight: isLight, agentName: agentName, embedded: true })), panelOverlay === 'tests' && (_jsx(TestsCard, { tests: testsList, status: testsStatus, run: testsRun, initialQuery: panelOverlayQuery, canRun: (canRunTests ?? canEdit !== false) && canEdit !== false, onRun: startTestsRun, onCancel: cancelTestsRun, isLight: isLight, embedded: true }))] })] })), filePicker &&
6926
7065
  filteredEntries.length > 0 &&
6927
7066
  (() => {
6928
7067
  const normalizeTabPath = (p) => p.startsWith('/workspace/')
@@ -7669,7 +7808,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
7669
7808
  * @param props - Component props (see {@link MessageItemProps}).
7670
7809
  * @returns The rendered chat panel element.
7671
7810
  */
7672
- export function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onRenderError, onProfileClick, currentUserId, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, onRegisterHistoryReconcile, 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, isAnonymous, canEdit = true, canShare, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, extraCommands, feedbackUrl, className, }) {
7811
+ export function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessageSent, activeFile, openTabs, onFileOpen, onFileDoubleClick, onFileDiff, onFileRevert, onFileChange, onFileDeleted, onCommit, onActivityClick, onRenderError, onProfileClick, currentUserId, onReadyToBuild, awaitingSandboxBoot, onClientAction, onTurnComplete, onLoadingChange, onNavigatePreview, onRegisterPushHandler, onRegisterHistoryReconcile, 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, isAnonymous, canEdit = true, canShare, buildUpgradeCta, buildHelpUpgradeSection, userAvatar, agentName, productName, version, extraCommands, feedbackUrl, listTests, runTests, canRunTests, testsAvailable, className, }) {
7673
7812
  const cm = getClassMap();
7674
7813
  // Share management may be gated ABOVE canEdit by the host (see
7675
7814
  // ChatPanelProps.canShare) — gates the built-in header share button here and
@@ -7882,7 +8021,7 @@ export function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessag
7882
8021
  textOverflow: 'ellipsis',
7883
8022
  whiteSpace: 'nowrap',
7884
8023
  width: '100%',
7885
- }, 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, isAnonymous: isAnonymous, canEdit: canEdit, canShare: shareAllowed, 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, currentUserId: currentUserId, onReadyToBuild: onReadyToBuild, awaitingSandboxBoot: awaitingSandboxBoot, onClientAction: onClientAction, onTurnComplete: onTurnComplete, onLoadingChange: onLoadingChange, onNavigatePreview: onNavigatePreview, onRegisterPushHandler: onRegisterPushHandler, onRegisterHistoryReconcile: onRegisterHistoryReconcile, 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, extraCommands: extraCommands, feedbackUrl: feedbackUrl }, chatKey)] }));
8024
+ }, 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, isAnonymous: isAnonymous, canEdit: canEdit, canShare: shareAllowed, 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, currentUserId: currentUserId, onReadyToBuild: onReadyToBuild, awaitingSandboxBoot: awaitingSandboxBoot, onClientAction: onClientAction, onTurnComplete: onTurnComplete, onLoadingChange: onLoadingChange, onNavigatePreview: onNavigatePreview, onRegisterPushHandler: onRegisterPushHandler, onRegisterHistoryReconcile: onRegisterHistoryReconcile, 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, extraCommands: extraCommands, feedbackUrl: feedbackUrl, listTests: listTests, runTests: runTests, canRunTests: canRunTests, testsAvailable: testsAvailable }, chatKey)] }));
7886
8025
  }
7887
8026
  ChatPanel.displayName = 'ChatPanel';
7888
8027
  //# sourceMappingURL=ChatPanel.js.map