@molecule/app-ide-react 1.15.0 → 1.16.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/README.md +187 -7
- package/dist/components/ChatPanel.d.ts +10 -1
- package/dist/components/ChatPanel.d.ts.map +1 -1
- package/dist/components/ChatPanel.js +79 -13
- package/dist/components/ChatPanel.js.map +1 -1
- package/dist/components/TestsCard.d.ts +15 -2
- package/dist/components/TestsCard.d.ts.map +1 -1
- package/dist/components/TestsCard.js +42 -9
- package/dist/components/TestsCard.js.map +1 -1
- package/dist/components/ToolCallCard.d.ts +7 -1
- package/dist/components/ToolCallCard.d.ts.map +1 -1
- package/dist/components/ToolCallCard.js +133 -94
- package/dist/components/ToolCallCard.js.map +1 -1
- package/dist/components/tests-card-utilities.d.ts +78 -2
- package/dist/components/tests-card-utilities.d.ts.map +1 -1
- package/dist/components/tests-card-utilities.js +134 -6
- package/dist/components/tests-card-utilities.js.map +1 -1
- package/dist/components/tool-call-utilities.d.ts +13 -0
- package/dist/components/tool-call-utilities.d.ts.map +1 -1
- package/dist/components/tool-call-utilities.js +22 -0
- package/dist/components/tool-call-utilities.js.map +1 -1
- package/dist/types.d.ts +60 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
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-09-
|
|
6
|
+
Generated: 2026-09-16T17:39:51.907Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/app-ide-react
|
|
@@ -607,6 +607,13 @@ interface ChatPanelProps {
|
|
|
607
607
|
* browser or letting a Run click fail. Defaults to `true`.
|
|
608
608
|
*/
|
|
609
609
|
testsAvailable?: boolean
|
|
610
|
+
/**
|
|
611
|
+
* Skip the executor's tool call that is running right now, without ending the
|
|
612
|
+
* turn — the call comes back marked as skipped and the turn carries on. The
|
|
613
|
+
* host owns the request; omitting this renders no Skip control on tool calls.
|
|
614
|
+
* Resolving `false` means nothing was in flight, which is a benign race.
|
|
615
|
+
*/
|
|
616
|
+
skipToolCall?: (toolCallId: string) => void | Promise<boolean | void>
|
|
610
617
|
className?: string
|
|
611
618
|
}
|
|
612
619
|
```
|
|
@@ -1470,6 +1477,35 @@ interface TabBarProps {
|
|
|
1470
1477
|
}
|
|
1471
1478
|
```
|
|
1472
1479
|
|
|
1480
|
+
#### `TestCaseProgress`
|
|
1481
|
+
|
|
1482
|
+
What one FILE is doing while it runs: which test is on screen, and how its
|
|
1483
|
+
own tests have gone so far. Discarded the moment the file reports a `result`
|
|
1484
|
+
— the row's verdict pill takes over from there.
|
|
1485
|
+
|
|
1486
|
+
```typescript
|
|
1487
|
+
interface TestCaseProgress {
|
|
1488
|
+
/** The test running right now, or `null` between tests. */
|
|
1489
|
+
current: TestCaseRef | null
|
|
1490
|
+
passed: number
|
|
1491
|
+
failed: number
|
|
1492
|
+
skipped: number
|
|
1493
|
+
}
|
|
1494
|
+
```
|
|
1495
|
+
|
|
1496
|
+
#### `TestCaseRef`
|
|
1497
|
+
|
|
1498
|
+
The one test a file is on right now, named the way its runner names it.
|
|
1499
|
+
|
|
1500
|
+
```typescript
|
|
1501
|
+
interface TestCaseRef {
|
|
1502
|
+
/** The runner's test title. */
|
|
1503
|
+
title: string
|
|
1504
|
+
/** Its enclosing group (`describe`), when it has one. */
|
|
1505
|
+
describe?: string
|
|
1506
|
+
}
|
|
1507
|
+
```
|
|
1508
|
+
|
|
1473
1509
|
#### `TestFailure`
|
|
1474
1510
|
|
|
1475
1511
|
One failing test and the output that explains it.
|
|
@@ -1557,6 +1593,16 @@ Handle to a run in flight, so the bar can stop it.
|
|
|
1557
1593
|
interface TestRunHandle {
|
|
1558
1594
|
/** Stop the run — the host aborts its stream, which cancels the work. */
|
|
1559
1595
|
cancel(): void
|
|
1596
|
+
/**
|
|
1597
|
+
* Skip the command the run is on right now WITHOUT ending the run: the files
|
|
1598
|
+
* that command owned come back as `result`s with `status: 'skipped'`, and the
|
|
1599
|
+
* run moves to the next command.
|
|
1600
|
+
*
|
|
1601
|
+
* Optional, because a host may not serve it. Resolving `false` means there
|
|
1602
|
+
* was nothing to skip (the run had already moved on) — a benign race the card
|
|
1603
|
+
* answers by dropping the control, never by showing an error.
|
|
1604
|
+
*/
|
|
1605
|
+
skipCurrent?(): void | Promise<boolean | void>
|
|
1560
1606
|
}
|
|
1561
1607
|
```
|
|
1562
1608
|
|
|
@@ -1589,8 +1635,14 @@ interface TestsCardProps {
|
|
|
1589
1635
|
canRun: boolean
|
|
1590
1636
|
/** Runs a selection. */
|
|
1591
1637
|
onRun: (selection: TestSelection) => void
|
|
1592
|
-
/** Stops the run in flight. */
|
|
1638
|
+
/** Stops the run in flight — the whole run, every remaining file. */
|
|
1593
1639
|
onCancel: () => void
|
|
1640
|
+
/**
|
|
1641
|
+
* Skips the command the run is on right now, WITHOUT ending it: that file
|
|
1642
|
+
* comes back `Skipped` and the run moves to the next one. Omitted by a host
|
|
1643
|
+
* that does not serve skipping — then no Skip control is rendered.
|
|
1644
|
+
*/
|
|
1645
|
+
onSkipCurrent?: () => void
|
|
1594
1646
|
/**
|
|
1595
1647
|
* Hands the failing tests to the agent as ONE chat message — a real turn it
|
|
1596
1648
|
* answers, exactly like the editor’s “Fix with AI”.
|
|
@@ -1638,6 +1690,19 @@ interface TestsRunState {
|
|
|
1638
1690
|
output: string[]
|
|
1639
1691
|
/** Per-id outcome from this run (and from earlier runs, until re-run). */
|
|
1640
1692
|
results: Record<string, TestResultEntry>
|
|
1693
|
+
/**
|
|
1694
|
+
* Per-id LIVE per-test progress, for the files that are running right now.
|
|
1695
|
+
* An entry exists only between a file's first `case` event and its `result`.
|
|
1696
|
+
*/
|
|
1697
|
+
cases: Record<string, TestCaseProgress>
|
|
1698
|
+
/** A skip was asked for and the run has not answered it yet. */
|
|
1699
|
+
skipPending: boolean
|
|
1700
|
+
/**
|
|
1701
|
+
* Skipping is not on offer: the host wired no `skipCurrent`, or it answered
|
|
1702
|
+
* that there was nothing left to skip. The control is dropped — never
|
|
1703
|
+
* replaced by an error the person cannot act on.
|
|
1704
|
+
*/
|
|
1705
|
+
skipUnavailable: boolean
|
|
1641
1706
|
/** How the run ended, once it has. */
|
|
1642
1707
|
outcome: TestRunOutcome | null
|
|
1643
1708
|
/** A run-level failure message (timeout, transport error) shown in the card. */
|
|
@@ -1674,6 +1739,21 @@ interface ToolCallCardProps {
|
|
|
1674
1739
|
onFileRevert?: (path: string, content: string) => Promise<void>
|
|
1675
1740
|
/** Called when the user responds to an `ask_user` tool call (clicks an option or submits free text). */
|
|
1676
1741
|
onAskUserResponse?: (response: string) => void
|
|
1742
|
+
/**
|
|
1743
|
+
* Skip this tool call while it is RUNNING, without ending the turn: the call
|
|
1744
|
+
* comes back as skipped, the model is told it did not run, and the turn
|
|
1745
|
+
* carries on. Omitted by a host that does not serve it — then no control is
|
|
1746
|
+
* rendered at all. Resolving `false` means nothing was in flight (the call
|
|
1747
|
+
* had already finished), which returns the button to its resting state rather
|
|
1748
|
+
* than reporting an error.
|
|
1749
|
+
*/
|
|
1750
|
+
onSkip?: (id: string) => void | Promise<boolean | void>
|
|
1751
|
+
/**
|
|
1752
|
+
* Why skipping is unavailable to THIS viewer, already translated by the host
|
|
1753
|
+
* — `null` when it is available. The control stays visible and disabled with
|
|
1754
|
+
* the reason on it, rather than vanishing without explanation.
|
|
1755
|
+
*/
|
|
1756
|
+
skipDisabledReason?: string | null
|
|
1677
1757
|
className?: string
|
|
1678
1758
|
}
|
|
1679
1759
|
```
|
|
@@ -1889,6 +1969,16 @@ A role granted by a share link.
|
|
|
1889
1969
|
type ShareRole = (typeof SHARE_ROLES)[number]
|
|
1890
1970
|
```
|
|
1891
1971
|
|
|
1972
|
+
#### `TestCaseStatus`
|
|
1973
|
+
|
|
1974
|
+
How one TEST inside a file is doing: the three verdicts a file can end with,
|
|
1975
|
+
plus `running` — the state a file never reports, because a file is only ever
|
|
1976
|
+
seen finished.
|
|
1977
|
+
|
|
1978
|
+
```typescript
|
|
1979
|
+
type TestCaseStatus = TestStatus | 'running'
|
|
1980
|
+
```
|
|
1981
|
+
|
|
1892
1982
|
#### `TestKind`
|
|
1893
1983
|
|
|
1894
1984
|
What a test file is: an end-to-end spec driven against the LIVE PREVIEW (the
|
|
@@ -1903,12 +1993,25 @@ type TestKind = 'e2e' | 'unit'
|
|
|
1903
1993
|
|
|
1904
1994
|
One event from a run in progress. The host streams these to the bar (over SSE
|
|
1905
1995
|
in molecule.dev) in the order the run produces them: one `start`, then
|
|
1906
|
-
interleaved `output`/`result`, then exactly one `done`.
|
|
1996
|
+
interleaved `output`/`case`/`result`, then exactly one `done`.
|
|
1907
1997
|
|
|
1908
1998
|
```typescript
|
|
1909
1999
|
type TestRunEvent =
|
|
1910
2000
|
| { type: 'start'; runId: string; ids: string[]; startedAt?: string }
|
|
1911
2001
|
| { type: 'output'; id?: string; stream?: 'stdout' | 'stderr'; chunk: string }
|
|
2002
|
+
/**
|
|
2003
|
+
* One TEST within a file — the runner's own title and group, so the person
|
|
2004
|
+
* watching a five-minute spec run sees WHICH test is on screen instead of a
|
|
2005
|
+
* spinner. `id` is the same file id `result` uses.
|
|
2006
|
+
*/
|
|
2007
|
+
| {
|
|
2008
|
+
type: 'case'
|
|
2009
|
+
id: string
|
|
2010
|
+
title: string
|
|
2011
|
+
describe?: string
|
|
2012
|
+
status: TestCaseStatus
|
|
2013
|
+
durationMs?: number
|
|
2014
|
+
}
|
|
1912
2015
|
| {
|
|
1913
2016
|
type: 'result'
|
|
1914
2017
|
id: string
|
|
@@ -1934,10 +2037,14 @@ type TestRunEvent =
|
|
|
1934
2037
|
|
|
1935
2038
|
#### `TestRunOutcome`
|
|
1936
2039
|
|
|
1937
|
-
How a whole run ended.
|
|
2040
|
+
How a whole run ended. `skipped-by-user` is a run that otherwise finished but
|
|
2041
|
+
had at least one command skipped from the card — deliberately its OWN outcome
|
|
2042
|
+
rather than `completed` plus a count, so nothing can read a run with skipped
|
|
2043
|
+
work in it as a clean pass. A real failure still wins: `error`, `timeout` and
|
|
2044
|
+
`cancelled` take precedence over it.
|
|
1938
2045
|
|
|
1939
2046
|
```typescript
|
|
1940
|
-
type TestRunOutcome = 'completed' | 'cancelled' | 'timeout' | 'error'
|
|
2047
|
+
type TestRunOutcome = 'completed' | 'cancelled' | 'timeout' | 'error' | 'skipped-by-user'
|
|
1941
2048
|
```
|
|
1942
2049
|
|
|
1943
2050
|
#### `TestsStatus`
|
|
@@ -2091,8 +2198,10 @@ function activityTypeLabel(type: ActivityType): string
|
|
|
2091
2198
|
Fold one streamed event into the run state.
|
|
2092
2199
|
|
|
2093
2200
|
Deliberately total: an event for an id the card no longer lists is recorded
|
|
2094
|
-
anyway (a re-list may be in flight),
|
|
2095
|
-
|
|
2201
|
+
anyway (a re-list may be in flight), a `case` that arrives out of order (after
|
|
2202
|
+
its file already reported a verdict) is dropped rather than resurrecting a
|
|
2203
|
+
finished row, and an unknown event type leaves the state untouched rather
|
|
2204
|
+
than throwing inside a stream handler.
|
|
2096
2205
|
|
|
2097
2206
|
```typescript
|
|
2098
2207
|
function applyTestRunEvent(state: TestsRunState, event: TestRunEvent): TestsRunState
|
|
@@ -2178,6 +2287,18 @@ function buildTestFixMessage(failures: readonly TestFailure[]): string
|
|
|
2178
2287
|
|
|
2179
2288
|
**Returns:** The message, or `` when there is nothing to fix.
|
|
2180
2289
|
|
|
2290
|
+
#### `canSkipRun(state)`
|
|
2291
|
+
|
|
2292
|
+
Whether the host can be asked to skip right now.
|
|
2293
|
+
|
|
2294
|
+
```typescript
|
|
2295
|
+
function canSkipRun(state: TestsRunState): boolean
|
|
2296
|
+
```
|
|
2297
|
+
|
|
2298
|
+
- `state` — The run state.
|
|
2299
|
+
|
|
2300
|
+
**Returns:** True when a Skip control belongs on screen.
|
|
2301
|
+
|
|
2181
2302
|
#### `ChatPanel(props)`
|
|
2182
2303
|
|
|
2183
2304
|
AI chat panel with conversation history dropdown and Claude Code-style tool display.
|
|
@@ -2243,6 +2364,7 @@ function ChatPanel({
|
|
|
2243
2364
|
runTests,
|
|
2244
2365
|
canRunTests,
|
|
2245
2366
|
testsAvailable,
|
|
2367
|
+
skipToolCall,
|
|
2246
2368
|
className,
|
|
2247
2369
|
}: ChatPanelProps): JSX.Element
|
|
2248
2370
|
```
|
|
@@ -2333,6 +2455,20 @@ function countByKind(tests: readonly TestItem[]): Record<TestKind, number>
|
|
|
2333
2455
|
|
|
2334
2456
|
**Returns:** The per-kind counts.
|
|
2335
2457
|
|
|
2458
|
+
#### `currentRunRowId(state)`
|
|
2459
|
+
|
|
2460
|
+
Which row the Skip acts on: the one the stream named as current, or — when it
|
|
2461
|
+
has not named one yet — the single row still awaiting a verdict, because with
|
|
2462
|
+
exactly one candidate there is nothing to be ambiguous about.
|
|
2463
|
+
|
|
2464
|
+
```typescript
|
|
2465
|
+
function currentRunRowId(state: TestsRunState): string | null
|
|
2466
|
+
```
|
|
2467
|
+
|
|
2468
|
+
- `state` — The run state.
|
|
2469
|
+
|
|
2470
|
+
**Returns:** The row's id, or `null` when the run is not on an identifiable row.
|
|
2471
|
+
|
|
2336
2472
|
#### `DeviceFrameSelector(props)`
|
|
2337
2473
|
|
|
2338
2474
|
A dropdown that selects the preview device frame and hosts the Rotate +
|
|
@@ -2783,6 +2919,20 @@ function livePanelSize(layout: WorkspaceLayout, panelConfigs: PanelConfig[], ind
|
|
|
2783
2919
|
|
|
2784
2920
|
**Returns:** The panel size as a percentage.
|
|
2785
2921
|
|
|
2922
|
+
#### `markSkipUnavailable(state)`
|
|
2923
|
+
|
|
2924
|
+
Record that skipping is not on offer — either the host wired no `skipCurrent`
|
|
2925
|
+
or it answered that the run had already moved on. The control is dropped; the
|
|
2926
|
+
person is not shown an error about a race they did not cause.
|
|
2927
|
+
|
|
2928
|
+
```typescript
|
|
2929
|
+
function markSkipUnavailable(state: TestsRunState): TestsRunState
|
|
2930
|
+
```
|
|
2931
|
+
|
|
2932
|
+
- `state` — The current state.
|
|
2933
|
+
|
|
2934
|
+
**Returns:** The next state.
|
|
2935
|
+
|
|
2786
2936
|
#### `matchesSideChannelCommand(defs, text)`
|
|
2787
2937
|
|
|
2788
2938
|
True when `text` invokes a side-channel command ({@link CommandDef.sideChannel})
|
|
@@ -3028,6 +3178,20 @@ function ReportModal({
|
|
|
3028
3178
|
|
|
3029
3179
|
**Returns:** The rendered report modal.
|
|
3030
3180
|
|
|
3181
|
+
#### `requestSkip(state)`
|
|
3182
|
+
|
|
3183
|
+
Record that the person asked to skip what is running. The state only says a
|
|
3184
|
+
request is OUT — the run's own `result` for the skipped file is what actually
|
|
3185
|
+
moves the row, so nothing here can make a skipped file read as anything else.
|
|
3186
|
+
|
|
3187
|
+
```typescript
|
|
3188
|
+
function requestSkip(state: TestsRunState): TestsRunState
|
|
3189
|
+
```
|
|
3190
|
+
|
|
3191
|
+
- `state` — The current state.
|
|
3192
|
+
|
|
3193
|
+
**Returns:** The next state, or the same one when there is nothing to skip.
|
|
3194
|
+
|
|
3031
3195
|
#### `ResizeHandle(props)`
|
|
3032
3196
|
|
|
3033
3197
|
Draggable handle for resizing adjacent panels. Uses Pointer Events so it works
|
|
@@ -3266,6 +3430,19 @@ function TabBar({
|
|
|
3266
3430
|
|
|
3267
3431
|
**Returns:** The rendered tab bar element, or null if no tabs are open.
|
|
3268
3432
|
|
|
3433
|
+
#### `testCaseLabel(current)`
|
|
3434
|
+
|
|
3435
|
+
The one-line name of the test a file is on: its group and its title, or just
|
|
3436
|
+
its title when the runner gave it no group.
|
|
3437
|
+
|
|
3438
|
+
```typescript
|
|
3439
|
+
function testCaseLabel(current: TestCaseRef | null | undefined): string
|
|
3440
|
+
```
|
|
3441
|
+
|
|
3442
|
+
- `current` — The running test, or `null`.
|
|
3443
|
+
|
|
3444
|
+
**Returns:** The label, or `` when nothing is named.
|
|
3445
|
+
|
|
3269
3446
|
#### `testRowLabel(item)`
|
|
3270
3447
|
|
|
3271
3448
|
The label for a row: the host's title when it gave one, else the file path.
|
|
@@ -3291,6 +3468,7 @@ function TestsCard({
|
|
|
3291
3468
|
canRun,
|
|
3292
3469
|
onRun,
|
|
3293
3470
|
onCancel,
|
|
3471
|
+
onSkipCurrent,
|
|
3294
3472
|
onFix,
|
|
3295
3473
|
fixDisabledReason,
|
|
3296
3474
|
isLight,
|
|
@@ -3685,6 +3863,8 @@ const ToolCallCard: MemoExoticComponent<
|
|
|
3685
3863
|
onFileDiff,
|
|
3686
3864
|
onFileRevert,
|
|
3687
3865
|
onAskUserResponse,
|
|
3866
|
+
onSkip,
|
|
3867
|
+
skipDisabledReason,
|
|
3688
3868
|
className,
|
|
3689
3869
|
}: ToolCallCardProps) => JSX.Element | null
|
|
3690
3870
|
>
|
|
@@ -102,6 +102,13 @@ export interface MessageItemProps {
|
|
|
102
102
|
agentName?: string;
|
|
103
103
|
/** Whether the user may write shared project state — false hides/inertizes write affordances in the message (revert, ask_user answers). */
|
|
104
104
|
canEdit?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Skips a tool call that is running right now, without ending the turn.
|
|
107
|
+
* Undefined when the host serves no such route — then no Skip is rendered.
|
|
108
|
+
*/
|
|
109
|
+
onSkipToolCall?: (toolCallId: string) => void | Promise<boolean | void>;
|
|
110
|
+
/** Why this viewer cannot skip, already translated — `null` when they can. */
|
|
111
|
+
skipToolCallReason?: string | null;
|
|
105
112
|
/**
|
|
106
113
|
* Whether the header row shows the message's time — decided for the whole
|
|
107
114
|
* timeline by `planChatTimestamps` (a run of identical labels shows it once).
|
|
@@ -212,13 +219,15 @@ export interface ChatInnerProps {
|
|
|
212
219
|
canRunTests?: boolean;
|
|
213
220
|
/** Whether the environment that runs them is up — see {@link ChatPanelProps.testsAvailable}. */
|
|
214
221
|
testsAvailable?: boolean;
|
|
222
|
+
/** Skips the executor's running tool call — see {@link ChatPanelProps.skipToolCall}. */
|
|
223
|
+
skipToolCall?: ChatPanelProps['skipToolCall'];
|
|
215
224
|
}
|
|
216
225
|
/**
|
|
217
226
|
* AI chat panel with conversation history dropdown and Claude Code-style tool display.
|
|
218
227
|
* @param props - Component props (see {@link MessageItemProps}).
|
|
219
228
|
* @returns The rendered chat panel element.
|
|
220
229
|
*/
|
|
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;
|
|
230
|
+
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, skipToolCall, className, }: ChatPanelProps): JSX.Element;
|
|
222
231
|
export declare namespace ChatPanel {
|
|
223
232
|
var displayName: string;
|
|
224
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatPanel.d.ts","sourceRoot":"","sources":["../../src/components/ChatPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAa,MAAM,OAAO,CAAA;AAY3C,OAAO,KAAK,EAAa,WAAW,EAAmB,MAAM,uBAAuB,CAAA;AAwCpF,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,eAAe,EAIhB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAevD,OAAO,EAEL,KAAK,UAAU,EAGhB,MAAM,oBAAoB,CAAA;AAY3B,OAAO,KAAK,EAAsB,SAAS,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"ChatPanel.d.ts","sourceRoot":"","sources":["../../src/components/ChatPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -44,7 +44,7 @@ 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, buildTestFixMessage, EMPTY_RUN_STATE, failRun, parseTestCommand, } from './tests-card-utilities.js';
|
|
47
|
+
import { applyTestRunEvent, buildTestFixMessage, EMPTY_RUN_STATE, failRun, markSkipUnavailable, parseTestCommand, requestSkip, } from './tests-card-utilities.js';
|
|
48
48
|
import { TestsCard } from './TestsCard.js';
|
|
49
49
|
import { TipCard } from './TipCard.js';
|
|
50
50
|
import { ToolCallCard } from './ToolCallCard.js';
|
|
@@ -973,7 +973,7 @@ AuthorNameButton.displayName = 'AuthorNameButton';
|
|
|
973
973
|
* @returns The rendered message item.
|
|
974
974
|
*/
|
|
975
975
|
const MessageItem = memo(function MessageItem(props) {
|
|
976
|
-
const { msg, sendMessage, handleAskUserResponse, isLoading, streamingStatus, onNavigatePreview, undoneTcIds, handleUndoToggle, onFileOpen, onFileDoubleClick, onFileDiff, handleFileRevert, setInputAndCursorEnd, setModelPicker, chatMode, userAvatar, onProfileClick, currentUserId, discovery, buildUpgradeCta, agentName, canEdit, showTimestamp, } = props;
|
|
976
|
+
const { msg, sendMessage, handleAskUserResponse, isLoading, streamingStatus, onNavigatePreview, undoneTcIds, handleUndoToggle, onFileOpen, onFileDoubleClick, onFileDiff, handleFileRevert, setInputAndCursorEnd, setModelPicker, chatMode, userAvatar, onProfileClick, currentUserId, discovery, buildUpgradeCta, agentName, canEdit, onSkipToolCall, skipToolCallReason, showTimestamp, } = props;
|
|
977
977
|
const cm = getClassMap();
|
|
978
978
|
const themeMode = useThemeMode();
|
|
979
979
|
const isLight = themeMode === 'light';
|
|
@@ -1176,7 +1176,7 @@ const MessageItem = memo(function MessageItem(props) {
|
|
|
1176
1176
|
const tc = msg.toolCalls?.find((c) => c.id === block.id);
|
|
1177
1177
|
if (!tc)
|
|
1178
1178
|
return null;
|
|
1179
|
-
return (_jsx("div", { style: { marginTop: '4px' }, children: _jsx(ToolCallCard, { id: tc.id, name: tc.name, input: tc.input, output: tc.output, status: tc.status, fileDiff: tc.fileDiff, isUndone: undoneTcIds.has(tc.id), onUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: canEdit === false ? undefined : handleFileRevert, onAskUserResponse: canEdit === false ? undefined : handleAskUserResponse }) }, tc.id));
|
|
1179
|
+
return (_jsx("div", { style: { marginTop: '4px' }, children: _jsx(ToolCallCard, { id: tc.id, name: tc.name, input: tc.input, output: tc.output, status: tc.status, fileDiff: tc.fileDiff, isUndone: undoneTcIds.has(tc.id), onUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: canEdit === false ? undefined : handleFileRevert, onAskUserResponse: canEdit === false ? undefined : handleAskUserResponse, onSkip: onSkipToolCall, skipDisabledReason: skipToolCallReason ?? null }) }, tc.id));
|
|
1180
1180
|
})) : msg.content ? (_jsx(MarkdownContent, { text: msg.content, isStreaming: msg.isStreaming, statusLabel: msg.isStreaming ? streamingStatus : undefined, statusStartedAt: typeof msg.timestamp === 'number' ? msg.timestamp : undefined, onNavigatePreview: onNavigatePreview, hideStreamingIndicator: true })) : null, msg.toolCalls &&
|
|
1181
1181
|
msg.blocks &&
|
|
1182
1182
|
msg.blocks.length > 0 &&
|
|
@@ -1187,10 +1187,10 @@ const MessageItem = memo(function MessageItem(props) {
|
|
|
1187
1187
|
tc.output.status === 'awaiting_response' &&
|
|
1188
1188
|
!msg.blocks.some((b) => b.type === 'tool_call' &&
|
|
1189
1189
|
b.id === tc.id))
|
|
1190
|
-
.map((tc) => (_jsx(ToolCallCard, { id: tc.id, name: tc.name, input: tc.input, output: tc.output, status: tc.status, fileDiff: tc.fileDiff, isUndone: undoneTcIds.has(tc.id), onUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: canEdit === false ? undefined : handleFileRevert, onAskUserResponse: canEdit === false ? undefined : handleAskUserResponse }, `orphan-ask-${tc.id}`))), msg.toolCalls &&
|
|
1190
|
+
.map((tc) => (_jsx(ToolCallCard, { id: tc.id, name: tc.name, input: tc.input, output: tc.output, status: tc.status, fileDiff: tc.fileDiff, isUndone: undoneTcIds.has(tc.id), onUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: canEdit === false ? undefined : handleFileRevert, onAskUserResponse: canEdit === false ? undefined : handleAskUserResponse, onSkip: onSkipToolCall, skipDisabledReason: skipToolCallReason ?? null }, `orphan-ask-${tc.id}`))), msg.toolCalls &&
|
|
1191
1191
|
msg.toolCalls.length > 0 &&
|
|
1192
1192
|
(!msg.blocks || msg.blocks.length === 0) &&
|
|
1193
|
-
msg.toolCalls.map((tc) => (_jsx(ToolCallCard, { id: tc.id, name: tc.name, input: tc.input, output: tc.output, status: tc.status, fileDiff: tc.fileDiff, isUndone: undoneTcIds.has(tc.id), onUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: canEdit === false ? undefined : handleFileRevert, onAskUserResponse: canEdit === false ? undefined : handleAskUserResponse }, tc.id))), msg.aborted && (_jsx("span", { className: cm.cn(cm.textMuted, cm.textSize('xs')), style: { display: 'block', marginTop: 4, fontStyle: 'italic' }, children: t('ide.chat.responseStopped', undefined, {
|
|
1193
|
+
msg.toolCalls.map((tc) => (_jsx(ToolCallCard, { id: tc.id, name: tc.name, input: tc.input, output: tc.output, status: tc.status, fileDiff: tc.fileDiff, isUndone: undoneTcIds.has(tc.id), onUndoToggle: handleUndoToggle, onFileOpen: onFileOpen, onFileDoubleClick: onFileDoubleClick, onFileDiff: onFileDiff, onFileRevert: canEdit === false ? undefined : handleFileRevert, onAskUserResponse: canEdit === false ? undefined : handleAskUserResponse, onSkip: onSkipToolCall, skipDisabledReason: skipToolCallReason ?? null }, tc.id))), msg.aborted && (_jsx("span", { className: cm.cn(cm.textMuted, cm.textSize('xs')), style: { display: 'block', marginTop: 4, fontStyle: 'italic' }, children: t('ide.chat.responseStopped', undefined, {
|
|
1194
1194
|
defaultValue: 'Response stopped',
|
|
1195
1195
|
}) })), msg.loopLimitReached &&
|
|
1196
1196
|
!msg.isStreaming &&
|
|
@@ -1281,7 +1281,7 @@ const MessageItem = memo(function MessageItem(props) {
|
|
|
1281
1281
|
* @param props - Component props (see {@link MessageItemProps}).
|
|
1282
1282
|
* @returns The rendered chat inner component.
|
|
1283
1283
|
*/
|
|
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,
|
|
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, skipToolCall,
|
|
1285
1285
|
// feedbackUrl: prop kept for back-compat (callers still pass it), but no longer
|
|
1286
1286
|
// consumed here — its only use was the command-menu footer link removed in P3-21.
|
|
1287
1287
|
}) {
|
|
@@ -2702,7 +2702,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
|
|
|
2702
2702
|
durationMs: null,
|
|
2703
2703
|
}));
|
|
2704
2704
|
try {
|
|
2705
|
-
|
|
2705
|
+
const handle = runTests(selection, (event) => {
|
|
2706
2706
|
if (!testsMountedRef.current)
|
|
2707
2707
|
return;
|
|
2708
2708
|
setTestsRun((prev) => applyTestRunEvent(prev, event));
|
|
@@ -2713,6 +2713,12 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
|
|
|
2713
2713
|
void refreshTests();
|
|
2714
2714
|
}
|
|
2715
2715
|
});
|
|
2716
|
+
testsRunHandleRef.current = handle;
|
|
2717
|
+
// Whether a Skip control belongs on screen is decided HERE, by whether
|
|
2718
|
+
// this host's handle serves one — not by the card guessing, and not by
|
|
2719
|
+
// a button that would do nothing when clicked.
|
|
2720
|
+
const skips = typeof handle.skipCurrent === 'function';
|
|
2721
|
+
setTestsRun((prev) => ({ ...prev, skipPending: false, skipUnavailable: !skips }));
|
|
2716
2722
|
}
|
|
2717
2723
|
catch (error) {
|
|
2718
2724
|
logger.warn('Failed to start a test run', { error });
|
|
@@ -2741,8 +2747,64 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
|
|
|
2741
2747
|
const cancelTestsRun = useCallback(() => {
|
|
2742
2748
|
testsRunHandleRef.current?.cancel();
|
|
2743
2749
|
testsRunHandleRef.current = null;
|
|
2744
|
-
setTestsRun((prev) => ({
|
|
2750
|
+
setTestsRun((prev) => ({
|
|
2751
|
+
...prev,
|
|
2752
|
+
running: false,
|
|
2753
|
+
currentId: null,
|
|
2754
|
+
cases: {},
|
|
2755
|
+
skipPending: false,
|
|
2756
|
+
skipUnavailable: true,
|
|
2757
|
+
outcome: 'cancelled',
|
|
2758
|
+
}));
|
|
2745
2759
|
}, []);
|
|
2760
|
+
// Skip the executor's in-flight tool call WITHOUT ending the turn — the
|
|
2761
|
+
// model is told the command did not run and carries on. The card owns its own
|
|
2762
|
+
// pressed state, so this just forwards the host's answer: `false` means the
|
|
2763
|
+
// call had already finished (a race the person did not cause), which the card
|
|
2764
|
+
// answers by returning the button to rest rather than reporting anything.
|
|
2765
|
+
const handleSkipToolCall = useCallback(async (toolCallId) => {
|
|
2766
|
+
if (canEdit === false || !skipToolCall)
|
|
2767
|
+
return false;
|
|
2768
|
+
try {
|
|
2769
|
+
return await skipToolCall(toolCallId);
|
|
2770
|
+
}
|
|
2771
|
+
catch (error) {
|
|
2772
|
+
logger.warn('Failed to skip the running tool call', { error });
|
|
2773
|
+
return false;
|
|
2774
|
+
}
|
|
2775
|
+
}, [canEdit, skipToolCall]);
|
|
2776
|
+
// Skip the command the run is ON, leaving the run itself alive. The state
|
|
2777
|
+
// only records that the request went out — the run's own `result` for that
|
|
2778
|
+
// file is what moves the row, so a skip can never paint itself as a pass. A
|
|
2779
|
+
// host answering "there was nothing to skip" is a race the person did not
|
|
2780
|
+
// cause: the control goes away, no error line.
|
|
2781
|
+
const skipCurrentTest = useCallback(() => {
|
|
2782
|
+
if (canEdit === false || canRunTests === false)
|
|
2783
|
+
return;
|
|
2784
|
+
const skip = testsRunHandleRef.current?.skipCurrent;
|
|
2785
|
+
if (!skip) {
|
|
2786
|
+
setTestsRun((prev) => markSkipUnavailable(prev));
|
|
2787
|
+
return;
|
|
2788
|
+
}
|
|
2789
|
+
setTestsRun((prev) => requestSkip(prev));
|
|
2790
|
+
const unavailable = () => {
|
|
2791
|
+
if (testsMountedRef.current)
|
|
2792
|
+
setTestsRun((prev) => markSkipUnavailable(prev));
|
|
2793
|
+
};
|
|
2794
|
+
try {
|
|
2795
|
+
const outcome = skip.call(testsRunHandleRef.current);
|
|
2796
|
+
if (outcome) {
|
|
2797
|
+
void outcome.then((accepted) => {
|
|
2798
|
+
if (accepted === false)
|
|
2799
|
+
unavailable();
|
|
2800
|
+
}, unavailable);
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
catch (error) {
|
|
2804
|
+
logger.warn('Failed to skip the running test', { error });
|
|
2805
|
+
unavailable();
|
|
2806
|
+
}
|
|
2807
|
+
}, [canEdit, canRunTests]);
|
|
2746
2808
|
/** Open the tests browser, re-listing so a spec just written shows up. */
|
|
2747
2809
|
const openTestsBrowser = useCallback((query = '', runAll = false) => {
|
|
2748
2810
|
openPanelOverlay('tests', query);
|
|
@@ -5842,7 +5904,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
|
|
|
5842
5904
|
return (_jsx(ScriptsCard, { projectId: projectId, initialQuery: item.card.query ?? '', isLight: isLight, agentName: agentName }, item.card.id));
|
|
5843
5905
|
}
|
|
5844
5906
|
if (item.card.variant === 'tests') {
|
|
5845
|
-
return (_jsx(TestsCard, { tests: testsList, status: testsStatus, run: testsRun, initialQuery: item.card.query ?? '', canRun: (canRunTests ?? canEdit !== false) && canEdit !== false, onRun: startTestsRun, onCancel: cancelTestsRun, onFix: fixTests, fixDisabledReason: canEdit === false
|
|
5907
|
+
return (_jsx(TestsCard, { tests: testsList, status: testsStatus, run: testsRun, initialQuery: item.card.query ?? '', canRun: (canRunTests ?? canEdit !== false) && canEdit !== false, onRun: startTestsRun, onCancel: cancelTestsRun, onSkipCurrent: skipCurrentTest, onFix: fixTests, fixDisabledReason: canEdit === false
|
|
5846
5908
|
? t('ide.tests.viewerCannotRun', undefined, {
|
|
5847
5909
|
defaultValue: 'Only editors can run this project’s tests.',
|
|
5848
5910
|
})
|
|
@@ -5943,7 +6005,11 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
|
|
|
5943
6005
|
// MessageItem builds the identity from the message's own
|
|
5944
6006
|
// author (teammates included), so the host shows their
|
|
5945
6007
|
// view-only profile and the viewer's editable own.
|
|
5946
|
-
onProfileClick: onProfileClick, currentUserId: currentUserId, showTimestamp: shownTimestampIds.has(msg.id), discovery: discovery, buildUpgradeCta: buildUpgradeCta, agentName: agentName, canEdit: canEdit
|
|
6008
|
+
onProfileClick: onProfileClick, currentUserId: currentUserId, showTimestamp: shownTimestampIds.has(msg.id), discovery: discovery, buildUpgradeCta: buildUpgradeCta, agentName: agentName, canEdit: canEdit, onSkipToolCall: skipToolCall ? handleSkipToolCall : undefined, skipToolCallReason: canEdit === false
|
|
6009
|
+
? t('ide.chat.skipToolCallViewer', undefined, {
|
|
6010
|
+
defaultValue: 'Only editors can skip this.',
|
|
6011
|
+
})
|
|
6012
|
+
: null }, msg.id));
|
|
5947
6013
|
})()) }, item.kind === 'message' ? item.msg.id : item.card.id))), error &&
|
|
5948
6014
|
!isStaleAnonymousLimit &&
|
|
5949
6015
|
(errorMeta?.limitType ? (_jsx(ResourceLimitBanner, { message: error, action: buildUpgradeCta?.({
|
|
@@ -7088,7 +7154,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
|
|
|
7088
7154
|
minHeight: 36,
|
|
7089
7155
|
}
|
|
7090
7156
|
: {}),
|
|
7091
|
-
}, 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, onFix: fixTests, fixDisabledReason: canEdit === false
|
|
7157
|
+
}, 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, onSkipCurrent: skipCurrentTest, onFix: fixTests, fixDisabledReason: canEdit === false
|
|
7092
7158
|
? t('ide.tests.viewerCannotRun', undefined, {
|
|
7093
7159
|
defaultValue: 'Only editors can run this project’s tests.',
|
|
7094
7160
|
})
|
|
@@ -7843,7 +7909,7 @@ function ChatInner({ projectId, endpoint, initialMessage, onInitialMessageSent,
|
|
|
7843
7909
|
* @param props - Component props (see {@link MessageItemProps}).
|
|
7844
7910
|
* @returns The rendered chat panel element.
|
|
7845
7911
|
*/
|
|
7846
|
-
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, }) {
|
|
7912
|
+
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, skipToolCall, className, }) {
|
|
7847
7913
|
const cm = getClassMap();
|
|
7848
7914
|
// Share management may be gated ABOVE canEdit by the host (see
|
|
7849
7915
|
// ChatPanelProps.canShare) — gates the built-in header share button here and
|
|
@@ -8056,7 +8122,7 @@ export function ChatPanel({ projectId, endpoint, initialMessage, onInitialMessag
|
|
|
8056
8122
|
textOverflow: 'ellipsis',
|
|
8057
8123
|
whiteSpace: 'nowrap',
|
|
8058
8124
|
width: '100%',
|
|
8059
|
-
}, 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)] }));
|
|
8125
|
+
}, 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, skipToolCall: skipToolCall }, chatKey)] }));
|
|
8060
8126
|
}
|
|
8061
8127
|
ChatPanel.displayName = 'ChatPanel';
|
|
8062
8128
|
//# sourceMappingURL=ChatPanel.js.map
|