@shipfox/client-logs 17.0.0 → 21.0.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +18 -0
- package/dist/components/agent-session-rows.d.ts +2 -1
- package/dist/components/agent-session-rows.d.ts.map +1 -1
- package/dist/components/agent-session-rows.js +33 -18
- package/dist/components/agent-session-rows.js.map +1 -1
- package/dist/components/log-group.d.ts +3 -2
- package/dist/components/log-group.d.ts.map +1 -1
- package/dist/components/log-group.js +12 -4
- package/dist/components/log-group.js.map +1 -1
- package/dist/components/log-view.d.ts +2 -1
- package/dist/components/log-view.d.ts.map +1 -1
- package/dist/components/log-view.js +76 -23
- package/dist/components/log-view.js.map +1 -1
- package/dist/components/output-log-row.d.ts.map +1 -1
- package/dist/components/output-log-row.js +1 -1
- package/dist/components/output-log-row.js.map +1 -1
- package/dist/components/system-markers.d.ts.map +1 -1
- package/dist/components/system-markers.js +9 -4
- package/dist/components/system-markers.js.map +1 -1
- package/dist/core/log-search.d.ts +7 -0
- package/dist/core/log-search.d.ts.map +1 -0
- package/dist/core/log-search.js +124 -0
- package/dist/core/log-search.js.map +1 -0
- package/dist/hooks/api/step-logs.d.ts +169 -1
- package/dist/hooks/api/step-logs.d.ts.map +1 -1
- package/dist/hooks/api/step-logs.js +23 -3
- package/dist/hooks/api/step-logs.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/components/agent-session-rows.tsx +35 -23
- package/src/components/log-group.tsx +18 -5
- package/src/components/log-view.test.tsx +146 -18
- package/src/components/log-view.tsx +81 -18
- package/src/components/output-log-row.tsx +5 -1
- package/src/components/system-markers.tsx +14 -4
- package/src/core/log-search.test.ts +96 -0
- package/src/core/log-search.ts +121 -0
- package/src/hooks/api/step-logs-query.test.tsx +42 -0
- package/src/hooks/api/step-logs.ts +19 -3
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled:
|
|
2
|
+
Successfully compiled: 14 files with swc (162.24ms)
|
package/.turbo/turbo-type.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @shipfox/client-logs
|
|
2
2
|
|
|
3
|
+
## 21.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7db4171: Composes job detail logs into the Panel surface with searchable output and display controls.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- f1d127e: Use dark contrast surfaces with readable semantic foregrounds across code and log views, preserve status on log-row edge accents, and add shared highlight and tooltip tokens for code and keyboard affordances.
|
|
12
|
+
- Updated dependencies [0f4abe4]
|
|
13
|
+
- Updated dependencies [71d0c44]
|
|
14
|
+
- Updated dependencies [30beb8f]
|
|
15
|
+
- Updated dependencies [16733a7]
|
|
16
|
+
- Updated dependencies [163c40a]
|
|
17
|
+
- Updated dependencies [6703982]
|
|
18
|
+
- Updated dependencies [f1d127e]
|
|
19
|
+
- @shipfox/react-ui@2.0.0
|
|
20
|
+
|
|
3
21
|
## 17.0.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
|
@@ -4,6 +4,7 @@ export interface AgentSessionRowsProps {
|
|
|
4
4
|
resolvedToolCallIds: ReadonlySet<string>;
|
|
5
5
|
toolCallNames: ReadonlyMap<string, string>;
|
|
6
6
|
indent: number;
|
|
7
|
+
forceOpen?: boolean;
|
|
7
8
|
}
|
|
8
|
-
export declare function AgentSessionRows({ rows, resolvedToolCallIds, toolCallNames, indent, }: AgentSessionRowsProps): import("react").JSX.Element[];
|
|
9
|
+
export declare function AgentSessionRows({ rows, resolvedToolCallIds, toolCallNames, indent, forceOpen, }: AgentSessionRowsProps): import("react").JSX.Element[];
|
|
9
10
|
//# sourceMappingURL=agent-session-rows.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-rows.d.ts","sourceRoot":"","sources":["../../src/components/agent-session-rows.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,cAAc,EAAqB,MAAM,oBAAoB,CAAC;AAO3E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAC;IAChC,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-session-rows.d.ts","sourceRoot":"","sources":["../../src/components/agent-session-rows.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,cAAc,EAAqB,MAAM,oBAAoB,CAAC;AAO3E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAC;IAChC,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,mBAAmB,EACnB,aAAa,EACb,MAAM,EACN,SAAiB,GAClB,EAAE,qBAAqB,iCAYvB"}
|
|
@@ -4,20 +4,31 @@ import { Icon } from '@shipfox/react-ui/icon';
|
|
|
4
4
|
import { LogContent, LogDisclosure, LogDisclosureContent, LogDisclosureTrigger, LogRow } from '@shipfox/react-ui/log';
|
|
5
5
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
6
6
|
import { cn } from '@shipfox/react-ui/utils';
|
|
7
|
-
import { Fragment, useState } from 'react';
|
|
7
|
+
import { Fragment, useEffect, useState } from 'react';
|
|
8
8
|
const PREVIEW_CHAR_LIMIT = 1200;
|
|
9
9
|
const WORD_SUMMARY_CHAR_LIMIT = 5000;
|
|
10
10
|
const WHITESPACE = /\s+/g;
|
|
11
11
|
const WORD_SEPARATOR = /\s+/;
|
|
12
|
-
export function AgentSessionRows({ rows, resolvedToolCallIds, toolCallNames, indent }) {
|
|
12
|
+
export function AgentSessionRows({ rows, resolvedToolCallIds, toolCallNames, indent, forceOpen = false }) {
|
|
13
13
|
return rows.map((row, index)=>/*#__PURE__*/ _jsx(AgentSessionRowView, {
|
|
14
14
|
row: row,
|
|
15
15
|
resolvedToolCallIds: resolvedToolCallIds,
|
|
16
16
|
toolCallNames: toolCallNames,
|
|
17
|
-
indent: indent
|
|
17
|
+
indent: indent,
|
|
18
|
+
forceOpen: forceOpen
|
|
18
19
|
}, `${row.kind}-${index}`));
|
|
19
20
|
}
|
|
20
|
-
function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }) {
|
|
21
|
+
function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent, forceOpen }) {
|
|
22
|
+
const [open, setOpen] = useState(false);
|
|
23
|
+
useEffect(()=>{
|
|
24
|
+
if (forceOpen) setOpen(true);
|
|
25
|
+
}, [
|
|
26
|
+
forceOpen
|
|
27
|
+
]);
|
|
28
|
+
const disclosureProps = {
|
|
29
|
+
open: forceOpen || open,
|
|
30
|
+
onOpenChange: setOpen
|
|
31
|
+
};
|
|
21
32
|
switch(row.kind){
|
|
22
33
|
case 'message':
|
|
23
34
|
return /*#__PURE__*/ _jsx(LogRow, {
|
|
@@ -27,7 +38,7 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
27
38
|
tone: row.terminalFailure ? 'error' : 'default',
|
|
28
39
|
"data-log-terminal-failure": row.terminalFailure ? 'true' : undefined,
|
|
29
40
|
children: /*#__PURE__*/ _jsx(LogContent, {
|
|
30
|
-
className: "text-foreground-
|
|
41
|
+
className: "text-foreground-contrast-primary",
|
|
31
42
|
children: /*#__PURE__*/ _jsxs("span", {
|
|
32
43
|
className: "flex min-w-0 items-start gap-inline",
|
|
33
44
|
children: [
|
|
@@ -66,17 +77,18 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
66
77
|
case 'thinking':
|
|
67
78
|
return /*#__PURE__*/ _jsxs(LogDisclosure, {
|
|
68
79
|
indent: indent,
|
|
80
|
+
...disclosureProps,
|
|
69
81
|
children: [
|
|
70
82
|
/*#__PURE__*/ _jsx(LogDisclosureTrigger, {
|
|
71
83
|
summary: wordSummary(row.text),
|
|
72
84
|
timestamp: new Date(row.timestamp),
|
|
73
|
-
className: "text-foreground-
|
|
85
|
+
className: "text-foreground-contrast-secondary",
|
|
74
86
|
children: "thinking"
|
|
75
87
|
}),
|
|
76
88
|
/*#__PURE__*/ _jsx(LogDisclosureContent, {
|
|
77
|
-
className: "text-foreground-
|
|
89
|
+
className: "text-foreground-contrast-secondary",
|
|
78
90
|
children: /*#__PURE__*/ _jsx(LogContent, {
|
|
79
|
-
className: "text-foreground-
|
|
91
|
+
className: "text-foreground-contrast-secondary",
|
|
80
92
|
children: /*#__PURE__*/ _jsx(PreviewText, {
|
|
81
93
|
text: row.text
|
|
82
94
|
})
|
|
@@ -89,6 +101,7 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
89
101
|
const awaitingResult = row.id != null && !resolvedToolCallIds.has(row.id);
|
|
90
102
|
return /*#__PURE__*/ _jsxs(LogDisclosure, {
|
|
91
103
|
indent: indent,
|
|
104
|
+
...disclosureProps,
|
|
92
105
|
children: [
|
|
93
106
|
/*#__PURE__*/ _jsx(LogDisclosureTrigger, {
|
|
94
107
|
timestamp: new Date(row.timestamp),
|
|
@@ -152,12 +165,13 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
152
165
|
const toolName = row.toolName === 'tool' ? (row.toolCallId != null ? toolCallNames.get(row.toolCallId) : undefined) ?? '(unmatched)' : row.toolName;
|
|
153
166
|
return /*#__PURE__*/ _jsxs(LogDisclosure, {
|
|
154
167
|
indent: indent,
|
|
168
|
+
...disclosureProps,
|
|
155
169
|
children: [
|
|
156
170
|
/*#__PURE__*/ _jsx(LogDisclosureTrigger, {
|
|
157
171
|
timestamp: new Date(row.timestamp),
|
|
158
172
|
summary: compactPreview(row.output),
|
|
159
173
|
trailing: /*#__PURE__*/ _jsxs("span", {
|
|
160
|
-
className: cn('inline-flex items-center gap-tight', row.isError ? 'text-
|
|
174
|
+
className: cn('inline-flex items-center gap-tight', row.isError ? 'text-tag-error-icon' : 'text-foreground-contrast-secondary'),
|
|
161
175
|
children: [
|
|
162
176
|
/*#__PURE__*/ _jsx(Icon, {
|
|
163
177
|
name: row.isError ? 'closeCircleLine' : 'checkLine',
|
|
@@ -188,7 +202,7 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
188
202
|
/*#__PURE__*/ _jsx(LogDisclosureContent, {
|
|
189
203
|
children: /*#__PURE__*/ _jsx(LogContent, {
|
|
190
204
|
variant: "code",
|
|
191
|
-
className:
|
|
205
|
+
className: "text-foreground-contrast-primary",
|
|
192
206
|
children: /*#__PURE__*/ _jsx(PreviewText, {
|
|
193
207
|
text: row.output
|
|
194
208
|
})
|
|
@@ -205,7 +219,7 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
205
219
|
tone: row.tone,
|
|
206
220
|
"data-log-terminal-failure": row.terminalFailure ? 'true' : undefined,
|
|
207
221
|
children: /*#__PURE__*/ _jsx(LogContent, {
|
|
208
|
-
className: "text-foreground-
|
|
222
|
+
className: "text-foreground-contrast-secondary",
|
|
209
223
|
children: /*#__PURE__*/ _jsxs("span", {
|
|
210
224
|
className: "inline-flex w-full items-center gap-inline",
|
|
211
225
|
children: [
|
|
@@ -225,7 +239,7 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
225
239
|
children: [
|
|
226
240
|
' · ',
|
|
227
241
|
/*#__PURE__*/ _jsx("span", {
|
|
228
|
-
className: "text-foreground-
|
|
242
|
+
className: "text-foreground-contrast-secondary",
|
|
229
243
|
children: row.detail
|
|
230
244
|
})
|
|
231
245
|
]
|
|
@@ -246,17 +260,18 @@ function AgentSessionRowView({ row, resolvedToolCallIds, toolCallNames, indent }
|
|
|
246
260
|
case 'raw':
|
|
247
261
|
return /*#__PURE__*/ _jsxs(LogDisclosure, {
|
|
248
262
|
indent: indent,
|
|
263
|
+
...disclosureProps,
|
|
249
264
|
children: [
|
|
250
265
|
/*#__PURE__*/ _jsx(LogDisclosureTrigger, {
|
|
251
266
|
timestamp: new Date(row.timestamp),
|
|
252
267
|
summary: compactPreview(row.raw),
|
|
253
|
-
className: "text-
|
|
268
|
+
className: "text-foreground-contrast-primary",
|
|
254
269
|
children: /*#__PURE__*/ _jsxs("span", {
|
|
255
270
|
className: "inline-flex min-w-0 items-center gap-inline",
|
|
256
271
|
children: [
|
|
257
272
|
/*#__PURE__*/ _jsx(Icon, {
|
|
258
273
|
name: "errorWarningLine",
|
|
259
|
-
className: "size-14 flex-none",
|
|
274
|
+
className: "size-14 flex-none text-tag-warning-icon",
|
|
260
275
|
"aria-hidden": "true"
|
|
261
276
|
}),
|
|
262
277
|
/*#__PURE__*/ _jsx("span", {
|
|
@@ -284,13 +299,13 @@ function MessageIcon({ role, terminalFailure }) {
|
|
|
284
299
|
const name = terminalFailure ? 'closeCircleLine' : role === 'user' ? 'userLine' : role === 'assistant' ? 'robot2Line' : 'message2Line';
|
|
285
300
|
return /*#__PURE__*/ _jsx(Icon, {
|
|
286
301
|
name: name,
|
|
287
|
-
className: cn('mt-[2px] size-14 flex-none', terminalFailure ? 'text-
|
|
302
|
+
className: cn('mt-[2px] size-14 flex-none', terminalFailure ? 'text-tag-error-icon' : 'text-foreground-contrast-secondary'),
|
|
288
303
|
"aria-hidden": "true"
|
|
289
304
|
});
|
|
290
305
|
}
|
|
291
306
|
function MessageRoleLabel({ label, terminalFailure }) {
|
|
292
307
|
return /*#__PURE__*/ _jsx("span", {
|
|
293
|
-
className: cn('min-w-0 font-code text-foreground-
|
|
308
|
+
className: cn('min-w-0 font-code text-foreground-contrast-secondary', terminalFailure && 'text-foreground-contrast-primary'),
|
|
294
309
|
children: /*#__PURE__*/ _jsx("span", {
|
|
295
310
|
className: "truncate",
|
|
296
311
|
children: label
|
|
@@ -302,7 +317,7 @@ function RowMetadata({ meta, className }) {
|
|
|
302
317
|
const inlineMeta = meta.length === 1 && meta[0]?.inline !== false ? meta[0] : null;
|
|
303
318
|
if (inlineMeta != null) {
|
|
304
319
|
return /*#__PURE__*/ _jsx("span", {
|
|
305
|
-
className: cn('font-code text-xs text-foreground-
|
|
320
|
+
className: cn('font-code text-xs text-foreground-contrast-secondary', className),
|
|
306
321
|
title: `${inlineMeta.label}: ${inlineMeta.value}`,
|
|
307
322
|
children: inlineMeta.value
|
|
308
323
|
});
|
|
@@ -321,7 +336,7 @@ function MetadataTrigger({ meta }) {
|
|
|
321
336
|
asChild: true,
|
|
322
337
|
children: /*#__PURE__*/ _jsx("button", {
|
|
323
338
|
type: "button",
|
|
324
|
-
className: "inline-flex size-20 flex-none items-center justify-center rounded-4 text-foreground-
|
|
339
|
+
className: "inline-flex size-20 flex-none items-center justify-center rounded-4 text-foreground-contrast-secondary opacity-60 transition-opacity hover:bg-background-components-hover hover:text-foreground-contrast-primary hover:opacity-100 focus-visible:opacity-100 focus-visible:shadow-[inset_0_0_0_2px_var(--color-primary-500)] group-hover/log-row:opacity-100",
|
|
325
340
|
"aria-label": "Show message metadata",
|
|
326
341
|
children: /*#__PURE__*/ _jsx(Icon, {
|
|
327
342
|
name: "informationLine",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/agent-session-rows.tsx"],"sourcesContent":["'use client';\n\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n LogContent,\n LogDisclosure,\n LogDisclosureContent,\n LogDisclosureTrigger,\n LogRow,\n} from '@shipfox/react-ui/log';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {Fragment, useState} from 'react';\nimport type {SessionViewRow, SessionViewRowMeta} from '#core/log-model.js';\n\nconst PREVIEW_CHAR_LIMIT = 1200;\nconst WORD_SUMMARY_CHAR_LIMIT = 5000;\nconst WHITESPACE = /\\s+/g;\nconst WORD_SEPARATOR = /\\s+/;\n\nexport interface AgentSessionRowsProps {\n rows: readonly SessionViewRow[];\n resolvedToolCallIds: ReadonlySet<string>;\n toolCallNames: ReadonlyMap<string, string>;\n indent: number;\n}\n\nexport function AgentSessionRows({\n rows,\n resolvedToolCallIds,\n toolCallNames,\n indent,\n}: AgentSessionRowsProps) {\n return rows.map((row, index) => (\n <AgentSessionRowView\n // biome-ignore lint/suspicious/noArrayIndexKey: session rows are immutable and never reordered, so the index is stable; content keys would balloon to megabyte strings and collide on repeated id-less tool calls.\n key={`${row.kind}-${index}`}\n row={row}\n resolvedToolCallIds={resolvedToolCallIds}\n toolCallNames={toolCallNames}\n indent={indent}\n />\n ));\n}\n\nfunction AgentSessionRowView({\n row,\n resolvedToolCallIds,\n toolCallNames,\n indent,\n}: {\n row: SessionViewRow;\n resolvedToolCallIds: ReadonlySet<string>;\n toolCallNames: ReadonlyMap<string, string>;\n indent: number;\n}) {\n switch (row.kind) {\n case 'message':\n return (\n <LogRow\n lineNumber={null}\n timestamp={new Date(row.timestamp)}\n indent={indent}\n tone={row.terminalFailure ? 'error' : 'default'}\n data-log-terminal-failure={row.terminalFailure ? 'true' : undefined}\n >\n <LogContent className=\"text-foreground-neutral-base\">\n <span className=\"flex min-w-0 items-start gap-inline\">\n <MessageIcon role={row.role} terminalFailure={row.terminalFailure} />\n <span className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <span className=\"flex min-w-0 items-center gap-inline\">\n <MessageRoleLabel label={row.label} terminalFailure={row.terminalFailure} />\n <RowMetadata meta={row.meta} className=\"ml-auto flex-none\" />\n </span>\n <span className=\"block min-w-0\">\n <PreviewText text={row.text} />\n </span>\n </span>\n </span>\n </LogContent>\n </LogRow>\n );\n case 'thinking':\n return (\n <LogDisclosure indent={indent}>\n <LogDisclosureTrigger\n summary={wordSummary(row.text)}\n timestamp={new Date(row.timestamp)}\n className=\"text-foreground-neutral-subtle\"\n >\n thinking\n </LogDisclosureTrigger>\n <LogDisclosureContent className=\"text-foreground-neutral-subtle\">\n <LogContent className=\"text-foreground-neutral-subtle\">\n <PreviewText text={row.text} />\n </LogContent>\n </LogDisclosureContent>\n </LogDisclosure>\n );\n case 'tool-call': {\n const awaitingResult = row.id != null && !resolvedToolCallIds.has(row.id);\n return (\n <LogDisclosure indent={indent}>\n <LogDisclosureTrigger\n timestamp={new Date(row.timestamp)}\n summary={compactPreview(row.summary ?? row.input)}\n trailing={\n awaitingResult ? (\n <span className=\"inline-flex items-center gap-tight\">\n <Icon\n name=\"loader4Line\"\n className=\"size-12 motion-safe:animate-spin\"\n aria-hidden=\"true\"\n />\n awaiting result\n </span>\n ) : null\n }\n >\n <span className=\"inline-flex min-w-0 items-center gap-inline\">\n <Icon name=\"terminalBoxLine\" className=\"size-14 flex-none\" aria-hidden=\"true\" />\n <span className=\"truncate\">tool {row.name}</span>\n </span>\n </LogDisclosureTrigger>\n <LogDisclosureContent>\n {row.summary != null ? (\n <>\n <LogContent>\n <PreviewText text={row.summary} />\n </LogContent>\n <LogContent variant=\"code\">\n <PreviewText text={row.input} />\n </LogContent>\n </>\n ) : (\n <LogContent variant=\"code\">\n <PreviewText text={row.input} />\n </LogContent>\n )}\n </LogDisclosureContent>\n </LogDisclosure>\n );\n }\n case 'tool-result': {\n const toolName =\n row.toolName === 'tool'\n ? ((row.toolCallId != null ? toolCallNames.get(row.toolCallId) : undefined) ??\n '(unmatched)')\n : row.toolName;\n return (\n <LogDisclosure indent={indent}>\n <LogDisclosureTrigger\n timestamp={new Date(row.timestamp)}\n summary={compactPreview(row.output)}\n trailing={\n <span\n className={cn(\n 'inline-flex items-center gap-tight',\n row.isError ? 'text-red-600 dark:text-red-400' : 'text-foreground-neutral-muted',\n )}\n >\n <Icon\n name={row.isError ? 'closeCircleLine' : 'checkLine'}\n className=\"size-12\"\n aria-hidden=\"true\"\n />\n {row.isError ? 'error' : 'ok'}\n </span>\n }\n >\n <span className=\"inline-flex min-w-0 items-center gap-inline\">\n <Icon name=\"terminalWindowLine\" className=\"size-14 flex-none\" aria-hidden=\"true\" />\n <span className=\"truncate\">result {toolName}</span>\n </span>\n </LogDisclosureTrigger>\n <LogDisclosureContent>\n <LogContent\n variant=\"code\"\n className={cn(row.isError && 'text-red-600 dark:text-red-400')}\n >\n <PreviewText text={row.output} />\n </LogContent>\n </LogDisclosureContent>\n </LogDisclosure>\n );\n }\n case 'lifecycle':\n return (\n <LogRow\n lineNumber={null}\n timestamp={new Date(row.timestamp)}\n indent={indent}\n tone={row.tone}\n data-log-terminal-failure={row.terminalFailure ? 'true' : undefined}\n >\n <LogContent className=\"text-foreground-neutral-muted\">\n <span className=\"inline-flex w-full items-center gap-inline\">\n <Icon name=\"informationLine\" className=\"size-14 flex-none\" aria-hidden=\"true\" />\n <span className=\"min-w-0\">\n <span className=\"font-medium\">{row.label}</span>\n {row.detail != null ? (\n <>\n {' · '}\n <span className=\"text-foreground-neutral-subtle\">{row.detail}</span>\n </>\n ) : null}\n </span>\n <span\n aria-hidden=\"true\"\n className=\"h-px flex-1 border-t border-dashed border-current opacity-30\"\n />\n <RowMetadata meta={row.meta} />\n </span>\n </LogContent>\n </LogRow>\n );\n case 'raw':\n return (\n <LogDisclosure indent={indent}>\n <LogDisclosureTrigger\n timestamp={new Date(row.timestamp)}\n summary={compactPreview(row.raw)}\n className=\"text-orange-600 dark:text-orange-400\"\n >\n <span className=\"inline-flex min-w-0 items-center gap-inline\">\n <Icon name=\"errorWarningLine\" className=\"size-14 flex-none\" aria-hidden=\"true\" />\n <span className=\"truncate\">{row.label}</span>\n </span>\n </LogDisclosureTrigger>\n <LogDisclosureContent>\n <LogContent variant=\"code\">\n <PreviewText text={row.raw} />\n </LogContent>\n </LogDisclosureContent>\n </LogDisclosure>\n );\n default:\n return assertNever(row);\n }\n}\n\nfunction MessageIcon({role, terminalFailure}: {role: string; terminalFailure: boolean}) {\n const name = terminalFailure\n ? 'closeCircleLine'\n : role === 'user'\n ? 'userLine'\n : role === 'assistant'\n ? 'robot2Line'\n : 'message2Line';\n\n return (\n <Icon\n name={name}\n className={cn(\n 'mt-[2px] size-14 flex-none',\n terminalFailure ? 'text-red-600 dark:text-red-400' : 'text-foreground-neutral-muted',\n )}\n aria-hidden=\"true\"\n />\n );\n}\n\nfunction MessageRoleLabel({label, terminalFailure}: {label: string; terminalFailure: boolean}) {\n return (\n <span\n className={cn(\n 'min-w-0 font-code text-foreground-neutral-muted',\n terminalFailure && 'text-foreground-highlight-error',\n )}\n >\n <span className=\"truncate\">{label}</span>\n </span>\n );\n}\n\nfunction RowMetadata({meta, className}: {meta: readonly SessionViewRowMeta[]; className?: string}) {\n if (meta.length === 0) return null;\n\n const inlineMeta = meta.length === 1 && meta[0]?.inline !== false ? meta[0] : null;\n if (inlineMeta != null) {\n return (\n <span\n className={cn('font-code text-xs text-foreground-neutral-muted', className)}\n title={`${inlineMeta.label}: ${inlineMeta.value}`}\n >\n {inlineMeta.value}\n </span>\n );\n }\n\n return (\n <span className={className}>\n <MetadataTrigger meta={meta} />\n </span>\n );\n}\n\nfunction MetadataTrigger({meta}: {meta: readonly SessionViewRowMeta[]}) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex size-20 flex-none items-center justify-center rounded-4 text-foreground-neutral-muted opacity-60 transition-opacity hover:bg-background-components-hover hover:text-foreground-neutral-base hover:opacity-100 focus-visible:opacity-100 focus-visible:shadow-[inset_0_0_0_2px_var(--color-primary-500)] group-hover/log-row:opacity-100\"\n aria-label=\"Show message metadata\"\n >\n <Icon name=\"informationLine\" className=\"size-12\" aria-hidden=\"true\" />\n </button>\n </TooltipTrigger>\n <TooltipContent align=\"end\" variant=\"inverted\" className=\"max-w-360 p-tight\">\n <span className=\"grid grid-cols-[max-content_minmax(0,1fr)] gap-x-[var(--space-inline)] gap-y-[var(--space-tight)] font-code text-xs\">\n {meta.map((item) => (\n <Fragment key={`${item.label}-${item.value}`}>\n <span className=\"text-foreground-contrast-secondary\">{item.label}</span>\n <span className=\"min-w-0 break-all text-foreground-contrast-primary\">\n {item.value}\n </span>\n </Fragment>\n ))}\n </span>\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction PreviewText({text}: {text: string}) {\n const [expanded, setExpanded] = useState(false);\n const truncated = text.length > PREVIEW_CHAR_LIMIT;\n const visible = truncated && !expanded ? `${text.slice(0, PREVIEW_CHAR_LIMIT)}…` : text;\n\n return (\n <>\n {visible}\n {truncated ? (\n <button\n type=\"button\"\n aria-expanded={expanded}\n className=\"ms-inline inline-flex min-h-24 items-center rounded-4 px-tight font-display text-xs text-foreground-highlight-interactive focus-visible:shadow-[inset_0_0_0_2px_var(--color-primary-500)]\"\n onClick={() => setExpanded((value) => !value)}\n >\n {expanded ? 'show less' : 'show more'}\n </button>\n ) : null}\n </>\n );\n}\n\nfunction compactPreview(value: string): string {\n // Normalize only a bounded head: tool output can be megabytes, and this runs\n // per render for every disclosure trigger.\n const head = value.length > 200 ? value.slice(0, 200) : value;\n const singleLine = head.replace(WHITESPACE, ' ').trim();\n if (singleLine.length <= 80) return singleLine;\n return `${singleLine.slice(0, 80)}…`;\n}\n\nfunction wordSummary(value: string): string {\n const truncated = value.length > WORD_SUMMARY_CHAR_LIMIT;\n const head = truncated ? value.slice(0, WORD_SUMMARY_CHAR_LIMIT) : value;\n const count = head.trim().split(WORD_SEPARATOR).filter(Boolean).length;\n const marker = truncated ? '+' : '';\n return `${count}${marker} ${count === 1 ? 'word' : 'words'}`;\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`unexpected agent session row: ${JSON.stringify(value)}`);\n}\n"],"names":["Icon","LogContent","LogDisclosure","LogDisclosureContent","LogDisclosureTrigger","LogRow","Tooltip","TooltipContent","TooltipTrigger","cn","Fragment","useState","PREVIEW_CHAR_LIMIT","WORD_SUMMARY_CHAR_LIMIT","WHITESPACE","WORD_SEPARATOR","AgentSessionRows","rows","resolvedToolCallIds","toolCallNames","indent","map","row","index","AgentSessionRowView","kind","lineNumber","timestamp","Date","tone","terminalFailure","data-log-terminal-failure","undefined","className","span","MessageIcon","role","MessageRoleLabel","label","RowMetadata","meta","PreviewText","text","summary","wordSummary","awaitingResult","id","has","compactPreview","input","trailing","name","aria-hidden","variant","toolName","toolCallId","get","output","isError","detail","raw","assertNever","length","inlineMeta","inline","title","value","MetadataTrigger","asChild","button","type","aria-label","align","item","expanded","setExpanded","truncated","visible","slice","aria-expanded","onClick","head","singleLine","replace","trim","count","split","filter","Boolean","marker","Error","JSON","stringify"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/agent-session-rows.tsx"],"sourcesContent":["'use client';\n\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n LogContent,\n LogDisclosure,\n LogDisclosureContent,\n LogDisclosureTrigger,\n LogRow,\n} from '@shipfox/react-ui/log';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {Fragment, useEffect, useState} from 'react';\nimport type {SessionViewRow, SessionViewRowMeta} from '#core/log-model.js';\n\nconst PREVIEW_CHAR_LIMIT = 1200;\nconst WORD_SUMMARY_CHAR_LIMIT = 5000;\nconst WHITESPACE = /\\s+/g;\nconst WORD_SEPARATOR = /\\s+/;\n\nexport interface AgentSessionRowsProps {\n rows: readonly SessionViewRow[];\n resolvedToolCallIds: ReadonlySet<string>;\n toolCallNames: ReadonlyMap<string, string>;\n indent: number;\n forceOpen?: boolean;\n}\n\nexport function AgentSessionRows({\n rows,\n resolvedToolCallIds,\n toolCallNames,\n indent,\n forceOpen = false,\n}: AgentSessionRowsProps) {\n return rows.map((row, index) => (\n <AgentSessionRowView\n // biome-ignore lint/suspicious/noArrayIndexKey: session rows are immutable and never reordered, so the index is stable; content keys would balloon to megabyte strings and collide on repeated id-less tool calls.\n key={`${row.kind}-${index}`}\n row={row}\n resolvedToolCallIds={resolvedToolCallIds}\n toolCallNames={toolCallNames}\n indent={indent}\n forceOpen={forceOpen}\n />\n ));\n}\n\nfunction AgentSessionRowView({\n row,\n resolvedToolCallIds,\n toolCallNames,\n indent,\n forceOpen,\n}: {\n row: SessionViewRow;\n resolvedToolCallIds: ReadonlySet<string>;\n toolCallNames: ReadonlyMap<string, string>;\n indent: number;\n forceOpen: boolean;\n}) {\n const [open, setOpen] = useState(false);\n useEffect(() => {\n if (forceOpen) setOpen(true);\n }, [forceOpen]);\n const disclosureProps = {open: forceOpen || open, onOpenChange: setOpen};\n\n switch (row.kind) {\n case 'message':\n return (\n <LogRow\n lineNumber={null}\n timestamp={new Date(row.timestamp)}\n indent={indent}\n tone={row.terminalFailure ? 'error' : 'default'}\n data-log-terminal-failure={row.terminalFailure ? 'true' : undefined}\n >\n <LogContent className=\"text-foreground-contrast-primary\">\n <span className=\"flex min-w-0 items-start gap-inline\">\n <MessageIcon role={row.role} terminalFailure={row.terminalFailure} />\n <span className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <span className=\"flex min-w-0 items-center gap-inline\">\n <MessageRoleLabel label={row.label} terminalFailure={row.terminalFailure} />\n <RowMetadata meta={row.meta} className=\"ml-auto flex-none\" />\n </span>\n <span className=\"block min-w-0\">\n <PreviewText text={row.text} />\n </span>\n </span>\n </span>\n </LogContent>\n </LogRow>\n );\n case 'thinking':\n return (\n <LogDisclosure indent={indent} {...disclosureProps}>\n <LogDisclosureTrigger\n summary={wordSummary(row.text)}\n timestamp={new Date(row.timestamp)}\n className=\"text-foreground-contrast-secondary\"\n >\n thinking\n </LogDisclosureTrigger>\n <LogDisclosureContent className=\"text-foreground-contrast-secondary\">\n <LogContent className=\"text-foreground-contrast-secondary\">\n <PreviewText text={row.text} />\n </LogContent>\n </LogDisclosureContent>\n </LogDisclosure>\n );\n case 'tool-call': {\n const awaitingResult = row.id != null && !resolvedToolCallIds.has(row.id);\n return (\n <LogDisclosure indent={indent} {...disclosureProps}>\n <LogDisclosureTrigger\n timestamp={new Date(row.timestamp)}\n summary={compactPreview(row.summary ?? row.input)}\n trailing={\n awaitingResult ? (\n <span className=\"inline-flex items-center gap-tight\">\n <Icon\n name=\"loader4Line\"\n className=\"size-12 motion-safe:animate-spin\"\n aria-hidden=\"true\"\n />\n awaiting result\n </span>\n ) : null\n }\n >\n <span className=\"inline-flex min-w-0 items-center gap-inline\">\n <Icon name=\"terminalBoxLine\" className=\"size-14 flex-none\" aria-hidden=\"true\" />\n <span className=\"truncate\">tool {row.name}</span>\n </span>\n </LogDisclosureTrigger>\n <LogDisclosureContent>\n {row.summary != null ? (\n <>\n <LogContent>\n <PreviewText text={row.summary} />\n </LogContent>\n <LogContent variant=\"code\">\n <PreviewText text={row.input} />\n </LogContent>\n </>\n ) : (\n <LogContent variant=\"code\">\n <PreviewText text={row.input} />\n </LogContent>\n )}\n </LogDisclosureContent>\n </LogDisclosure>\n );\n }\n case 'tool-result': {\n const toolName =\n row.toolName === 'tool'\n ? ((row.toolCallId != null ? toolCallNames.get(row.toolCallId) : undefined) ??\n '(unmatched)')\n : row.toolName;\n return (\n <LogDisclosure indent={indent} {...disclosureProps}>\n <LogDisclosureTrigger\n timestamp={new Date(row.timestamp)}\n summary={compactPreview(row.output)}\n trailing={\n <span\n className={cn(\n 'inline-flex items-center gap-tight',\n row.isError ? 'text-tag-error-icon' : 'text-foreground-contrast-secondary',\n )}\n >\n <Icon\n name={row.isError ? 'closeCircleLine' : 'checkLine'}\n className=\"size-12\"\n aria-hidden=\"true\"\n />\n {row.isError ? 'error' : 'ok'}\n </span>\n }\n >\n <span className=\"inline-flex min-w-0 items-center gap-inline\">\n <Icon name=\"terminalWindowLine\" className=\"size-14 flex-none\" aria-hidden=\"true\" />\n <span className=\"truncate\">result {toolName}</span>\n </span>\n </LogDisclosureTrigger>\n <LogDisclosureContent>\n <LogContent variant=\"code\" className=\"text-foreground-contrast-primary\">\n <PreviewText text={row.output} />\n </LogContent>\n </LogDisclosureContent>\n </LogDisclosure>\n );\n }\n case 'lifecycle':\n return (\n <LogRow\n lineNumber={null}\n timestamp={new Date(row.timestamp)}\n indent={indent}\n tone={row.tone}\n data-log-terminal-failure={row.terminalFailure ? 'true' : undefined}\n >\n <LogContent className=\"text-foreground-contrast-secondary\">\n <span className=\"inline-flex w-full items-center gap-inline\">\n <Icon name=\"informationLine\" className=\"size-14 flex-none\" aria-hidden=\"true\" />\n <span className=\"min-w-0\">\n <span className=\"font-medium\">{row.label}</span>\n {row.detail != null ? (\n <>\n {' · '}\n <span className=\"text-foreground-contrast-secondary\">{row.detail}</span>\n </>\n ) : null}\n </span>\n <span\n aria-hidden=\"true\"\n className=\"h-px flex-1 border-t border-dashed border-current opacity-30\"\n />\n <RowMetadata meta={row.meta} />\n </span>\n </LogContent>\n </LogRow>\n );\n case 'raw':\n return (\n <LogDisclosure indent={indent} {...disclosureProps}>\n <LogDisclosureTrigger\n timestamp={new Date(row.timestamp)}\n summary={compactPreview(row.raw)}\n className=\"text-foreground-contrast-primary\"\n >\n <span className=\"inline-flex min-w-0 items-center gap-inline\">\n <Icon\n name=\"errorWarningLine\"\n className=\"size-14 flex-none text-tag-warning-icon\"\n aria-hidden=\"true\"\n />\n <span className=\"truncate\">{row.label}</span>\n </span>\n </LogDisclosureTrigger>\n <LogDisclosureContent>\n <LogContent variant=\"code\">\n <PreviewText text={row.raw} />\n </LogContent>\n </LogDisclosureContent>\n </LogDisclosure>\n );\n default:\n return assertNever(row);\n }\n}\n\nfunction MessageIcon({role, terminalFailure}: {role: string; terminalFailure: boolean}) {\n const name = terminalFailure\n ? 'closeCircleLine'\n : role === 'user'\n ? 'userLine'\n : role === 'assistant'\n ? 'robot2Line'\n : 'message2Line';\n\n return (\n <Icon\n name={name}\n className={cn(\n 'mt-[2px] size-14 flex-none',\n terminalFailure ? 'text-tag-error-icon' : 'text-foreground-contrast-secondary',\n )}\n aria-hidden=\"true\"\n />\n );\n}\n\nfunction MessageRoleLabel({label, terminalFailure}: {label: string; terminalFailure: boolean}) {\n return (\n <span\n className={cn(\n 'min-w-0 font-code text-foreground-contrast-secondary',\n terminalFailure && 'text-foreground-contrast-primary',\n )}\n >\n <span className=\"truncate\">{label}</span>\n </span>\n );\n}\n\nfunction RowMetadata({meta, className}: {meta: readonly SessionViewRowMeta[]; className?: string}) {\n if (meta.length === 0) return null;\n\n const inlineMeta = meta.length === 1 && meta[0]?.inline !== false ? meta[0] : null;\n if (inlineMeta != null) {\n return (\n <span\n className={cn('font-code text-xs text-foreground-contrast-secondary', className)}\n title={`${inlineMeta.label}: ${inlineMeta.value}`}\n >\n {inlineMeta.value}\n </span>\n );\n }\n\n return (\n <span className={className}>\n <MetadataTrigger meta={meta} />\n </span>\n );\n}\n\nfunction MetadataTrigger({meta}: {meta: readonly SessionViewRowMeta[]}) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex size-20 flex-none items-center justify-center rounded-4 text-foreground-contrast-secondary opacity-60 transition-opacity hover:bg-background-components-hover hover:text-foreground-contrast-primary hover:opacity-100 focus-visible:opacity-100 focus-visible:shadow-[inset_0_0_0_2px_var(--color-primary-500)] group-hover/log-row:opacity-100\"\n aria-label=\"Show message metadata\"\n >\n <Icon name=\"informationLine\" className=\"size-12\" aria-hidden=\"true\" />\n </button>\n </TooltipTrigger>\n <TooltipContent align=\"end\" variant=\"inverted\" className=\"max-w-360 p-tight\">\n <span className=\"grid grid-cols-[max-content_minmax(0,1fr)] gap-x-[var(--space-inline)] gap-y-[var(--space-tight)] font-code text-xs\">\n {meta.map((item) => (\n <Fragment key={`${item.label}-${item.value}`}>\n <span className=\"text-foreground-contrast-secondary\">{item.label}</span>\n <span className=\"min-w-0 break-all text-foreground-contrast-primary\">\n {item.value}\n </span>\n </Fragment>\n ))}\n </span>\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction PreviewText({text}: {text: string}) {\n const [expanded, setExpanded] = useState(false);\n const truncated = text.length > PREVIEW_CHAR_LIMIT;\n const visible = truncated && !expanded ? `${text.slice(0, PREVIEW_CHAR_LIMIT)}…` : text;\n\n return (\n <>\n {visible}\n {truncated ? (\n <button\n type=\"button\"\n aria-expanded={expanded}\n className=\"ms-inline inline-flex min-h-24 items-center rounded-4 px-tight font-display text-xs text-foreground-highlight-interactive focus-visible:shadow-[inset_0_0_0_2px_var(--color-primary-500)]\"\n onClick={() => setExpanded((value) => !value)}\n >\n {expanded ? 'show less' : 'show more'}\n </button>\n ) : null}\n </>\n );\n}\n\nfunction compactPreview(value: string): string {\n // Normalize only a bounded head: tool output can be megabytes, and this runs\n // per render for every disclosure trigger.\n const head = value.length > 200 ? value.slice(0, 200) : value;\n const singleLine = head.replace(WHITESPACE, ' ').trim();\n if (singleLine.length <= 80) return singleLine;\n return `${singleLine.slice(0, 80)}…`;\n}\n\nfunction wordSummary(value: string): string {\n const truncated = value.length > WORD_SUMMARY_CHAR_LIMIT;\n const head = truncated ? value.slice(0, WORD_SUMMARY_CHAR_LIMIT) : value;\n const count = head.trim().split(WORD_SEPARATOR).filter(Boolean).length;\n const marker = truncated ? '+' : '';\n return `${count}${marker} ${count === 1 ? 'word' : 'words'}`;\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`unexpected agent session row: ${JSON.stringify(value)}`);\n}\n"],"names":["Icon","LogContent","LogDisclosure","LogDisclosureContent","LogDisclosureTrigger","LogRow","Tooltip","TooltipContent","TooltipTrigger","cn","Fragment","useEffect","useState","PREVIEW_CHAR_LIMIT","WORD_SUMMARY_CHAR_LIMIT","WHITESPACE","WORD_SEPARATOR","AgentSessionRows","rows","resolvedToolCallIds","toolCallNames","indent","forceOpen","map","row","index","AgentSessionRowView","kind","open","setOpen","disclosureProps","onOpenChange","lineNumber","timestamp","Date","tone","terminalFailure","data-log-terminal-failure","undefined","className","span","MessageIcon","role","MessageRoleLabel","label","RowMetadata","meta","PreviewText","text","summary","wordSummary","awaitingResult","id","has","compactPreview","input","trailing","name","aria-hidden","variant","toolName","toolCallId","get","output","isError","detail","raw","assertNever","length","inlineMeta","inline","title","value","MetadataTrigger","asChild","button","type","aria-label","align","item","expanded","setExpanded","truncated","visible","slice","aria-expanded","onClick","head","singleLine","replace","trim","count","split","filter","Boolean","marker","Error","JSON","stringify"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
2
|
import type { GroupLogNode } from '#core/log-tree.js';
|
|
3
3
|
export interface LogGroupProps {
|
|
4
4
|
node: GroupLogNode;
|
|
@@ -6,6 +6,7 @@ export interface LogGroupProps {
|
|
|
6
6
|
terminated: boolean;
|
|
7
7
|
children: ReactNode;
|
|
8
8
|
defaultOpen?: boolean;
|
|
9
|
+
forceOpen?: boolean;
|
|
9
10
|
}
|
|
10
|
-
export declare function LogGroup({ node, depth, terminated, children, defaultOpen }: LogGroupProps): import("react").JSX.Element;
|
|
11
|
+
export declare function LogGroup({ node, depth, terminated, children, defaultOpen, forceOpen, }: LogGroupProps): import("react").JSX.Element;
|
|
11
12
|
//# sourceMappingURL=log-group.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-group.d.ts","sourceRoot":"","sources":["../../src/components/log-group.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"log-group.d.ts","sourceRoot":"","sources":["../../src/components/log-group.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAC,KAAK,SAAS,EAAsB,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,UAAU,EACV,QAAQ,EACR,WAAmB,EACnB,SAAiB,GAClB,EAAE,aAAa,+BAoBf"}
|
|
@@ -3,11 +3,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Icon } from '@shipfox/react-ui/icon';
|
|
4
4
|
import { LogDisclosure, LogDisclosureContent, LogDisclosureTrigger } from '@shipfox/react-ui/log';
|
|
5
5
|
import { cn, formatDuration } from '@shipfox/react-ui/utils';
|
|
6
|
-
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
7
|
+
export function LogGroup({ node, depth, terminated, children, defaultOpen = false, forceOpen = false }) {
|
|
7
8
|
const lineLabel = `${node.lineCount} ${node.lineCount === 1 ? 'line' : 'lines'}`;
|
|
9
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
10
|
+
useEffect(()=>{
|
|
11
|
+
if (forceOpen) setOpen(true);
|
|
12
|
+
}, [
|
|
13
|
+
forceOpen
|
|
14
|
+
]);
|
|
8
15
|
return /*#__PURE__*/ _jsxs(LogDisclosure, {
|
|
9
16
|
indent: depth,
|
|
10
|
-
|
|
17
|
+
open: forceOpen || open,
|
|
18
|
+
onOpenChange: setOpen,
|
|
11
19
|
children: [
|
|
12
20
|
/*#__PURE__*/ _jsx(LogDisclosureTrigger, {
|
|
13
21
|
summary: lineLabel,
|
|
@@ -37,12 +45,12 @@ function GroupStatus({ node, terminated }) {
|
|
|
37
45
|
// is null). Either way show "incomplete" rather than a blank slot or a forever spinner.
|
|
38
46
|
if (node.closed || terminated) {
|
|
39
47
|
return /*#__PURE__*/ _jsx("span", {
|
|
40
|
-
className: "text-foreground-
|
|
48
|
+
className: "text-foreground-contrast-secondary",
|
|
41
49
|
children: "incomplete"
|
|
42
50
|
});
|
|
43
51
|
}
|
|
44
52
|
return /*#__PURE__*/ _jsxs("span", {
|
|
45
|
-
className: "inline-flex items-center gap-tight text-foreground-
|
|
53
|
+
className: "inline-flex items-center gap-tight text-foreground-contrast-secondary",
|
|
46
54
|
children: [
|
|
47
55
|
/*#__PURE__*/ _jsx(Icon, {
|
|
48
56
|
name: "loader4Line",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/log-group.tsx"],"sourcesContent":["'use client';\n\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {LogDisclosure, LogDisclosureContent, LogDisclosureTrigger} from '@shipfox/react-ui/log';\nimport {cn, formatDuration} from '@shipfox/react-ui/utils';\nimport type
|
|
1
|
+
{"version":3,"sources":["../../src/components/log-group.tsx"],"sourcesContent":["'use client';\n\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {LogDisclosure, LogDisclosureContent, LogDisclosureTrigger} from '@shipfox/react-ui/log';\nimport {cn, formatDuration} from '@shipfox/react-ui/utils';\nimport {type ReactNode, useEffect, useState} from 'react';\nimport type {GroupLogNode} from '#core/log-tree.js';\n\nexport interface LogGroupProps {\n node: GroupLogNode;\n depth: number;\n terminated: boolean;\n children: ReactNode;\n defaultOpen?: boolean;\n forceOpen?: boolean;\n}\n\nexport function LogGroup({\n node,\n depth,\n terminated,\n children,\n defaultOpen = false,\n forceOpen = false,\n}: LogGroupProps) {\n const lineLabel = `${node.lineCount} ${node.lineCount === 1 ? 'line' : 'lines'}`;\n const [open, setOpen] = useState(defaultOpen);\n\n useEffect(() => {\n if (forceOpen) setOpen(true);\n }, [forceOpen]);\n\n return (\n <LogDisclosure indent={depth} open={forceOpen || open} onOpenChange={setOpen}>\n <LogDisclosureTrigger\n summary={lineLabel}\n trailing={<GroupStatus node={node} terminated={terminated} />}\n className={cn(node.hasError && 'shadow-[inset_2px_0_0_var(--color-red-500)]')}\n >\n {node.record.name}\n </LogDisclosureTrigger>\n <LogDisclosureContent rail={false}>{children}</LogDisclosureContent>\n </LogDisclosure>\n );\n}\n\nfunction GroupStatus({node, terminated}: {node: GroupLogNode; terminated: boolean}): ReactNode {\n if (node.closed && node.endTs != null) {\n return (\n <span className=\"font-code tabular-nums\">{formatDuration(node.endTs - node.record.ts)}</span>\n );\n }\n\n // No clean end: either still open under a terminated stream (runner died mid-group), or\n // closed only because an ancestor's group_end cascaded (its own end was dropped, so endTs\n // is null). Either way show \"incomplete\" rather than a blank slot or a forever spinner.\n if (node.closed || terminated) {\n return <span className=\"text-foreground-contrast-secondary\">incomplete</span>;\n }\n\n return (\n <span className=\"inline-flex items-center gap-tight text-foreground-contrast-secondary\">\n <Icon name=\"loader4Line\" className=\"size-12 motion-safe:animate-spin\" aria-hidden=\"true\" />\n running\n </span>\n );\n}\n"],"names":["Icon","LogDisclosure","LogDisclosureContent","LogDisclosureTrigger","cn","formatDuration","useEffect","useState","LogGroup","node","depth","terminated","children","defaultOpen","forceOpen","lineLabel","lineCount","open","setOpen","indent","onOpenChange","summary","trailing","GroupStatus","className","hasError","record","name","rail","closed","endTs","span","ts","aria-hidden"],"mappings":"AAAA;;AAEA,SAAQA,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,aAAa,EAAEC,oBAAoB,EAAEC,oBAAoB,QAAO,wBAAwB;AAChG,SAAQC,EAAE,EAAEC,cAAc,QAAO,0BAA0B;AAC3D,SAAwBC,SAAS,EAAEC,QAAQ,QAAO,QAAQ;AAY1D,OAAO,SAASC,SAAS,EACvBC,IAAI,EACJC,KAAK,EACLC,UAAU,EACVC,QAAQ,EACRC,cAAc,KAAK,EACnBC,YAAY,KAAK,EACH;IACd,MAAMC,YAAY,GAAGN,KAAKO,SAAS,CAAC,CAAC,EAAEP,KAAKO,SAAS,KAAK,IAAI,SAAS,SAAS;IAChF,MAAM,CAACC,MAAMC,QAAQ,GAAGX,SAASM;IAEjCP,UAAU;QACR,IAAIQ,WAAWI,QAAQ;IACzB,GAAG;QAACJ;KAAU;IAEd,qBACE,MAACb;QAAckB,QAAQT;QAAOO,MAAMH,aAAaG;QAAMG,cAAcF;;0BACnE,KAACf;gBACCkB,SAASN;gBACTO,wBAAU,KAACC;oBAAYd,MAAMA;oBAAME,YAAYA;;gBAC/Ca,WAAWpB,GAAGK,KAAKgB,QAAQ,IAAI;0BAE9BhB,KAAKiB,MAAM,CAACC,IAAI;;0BAEnB,KAACzB;gBAAqB0B,MAAM;0BAAQhB;;;;AAG1C;AAEA,SAASW,YAAY,EAACd,IAAI,EAAEE,UAAU,EAA4C;IAChF,IAAIF,KAAKoB,MAAM,IAAIpB,KAAKqB,KAAK,IAAI,MAAM;QACrC,qBACE,KAACC;YAAKP,WAAU;sBAA0BnB,eAAeI,KAAKqB,KAAK,GAAGrB,KAAKiB,MAAM,CAACM,EAAE;;IAExF;IAEA,wFAAwF;IACxF,0FAA0F;IAC1F,wFAAwF;IACxF,IAAIvB,KAAKoB,MAAM,IAAIlB,YAAY;QAC7B,qBAAO,KAACoB;YAAKP,WAAU;sBAAqC;;IAC9D;IAEA,qBACE,MAACO;QAAKP,WAAU;;0BACd,KAACxB;gBAAK2B,MAAK;gBAAcH,WAAU;gBAAmCS,eAAY;;YAAS;;;AAIjG"}
|
|
@@ -9,6 +9,7 @@ export interface LogViewProps {
|
|
|
9
9
|
emptyState?: 'complete' | 'pending';
|
|
10
10
|
defaultGroupsOpen?: boolean;
|
|
11
11
|
anchorToFailure?: boolean;
|
|
12
|
+
search?: string;
|
|
12
13
|
ariaLive?: 'off' | 'polite' | 'assertive';
|
|
13
14
|
className?: string | undefined;
|
|
14
15
|
onScroll?: UIEventHandler<HTMLDivElement> | undefined;
|
|
@@ -16,6 +17,6 @@ export interface LogViewProps {
|
|
|
16
17
|
export interface LogViewSkeletonProps extends Pick<LogViewProps, 'timestamps' | 'wrap' | 'showLineNumbers' | 'className'> {
|
|
17
18
|
rows?: number;
|
|
18
19
|
}
|
|
19
|
-
export declare function LogView({ records, timestamps, wrap, showLineNumbers, emptyState, defaultGroupsOpen, anchorToFailure, ariaLive, className, onScroll, }: LogViewProps): import("react").JSX.Element;
|
|
20
|
+
export declare function LogView({ records, timestamps, wrap, showLineNumbers, emptyState, defaultGroupsOpen, anchorToFailure, search, ariaLive, className, onScroll, }: LogViewProps): import("react").JSX.Element;
|
|
20
21
|
export declare function LogViewSkeleton({ rows, timestamps, wrap, showLineNumbers, className, }: LogViewSkeletonProps): import("react").JSX.Element;
|
|
21
22
|
//# sourceMappingURL=log-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-view.d.ts","sourceRoot":"","sources":["../../src/components/log-view.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AAEzF,OAAO,
|
|
1
|
+
{"version":3,"file":"log-view.d.ts","sourceRoot":"","sources":["../../src/components/log-view.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AAEzF,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAclD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;CACvD;AAED,MAAM,WAAW,oBACf,SAAQ,IAAI,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,GAAG,iBAAiB,GAAG,WAAW,CAAC;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,UAAkB,EAClB,IAAY,EACZ,eAAsB,EACtB,UAAuB,EACvB,iBAAyB,EACzB,eAAuB,EACvB,MAAW,EACX,QAAmB,EACnB,SAAS,EACT,QAAQ,GACT,EAAE,YAAY,+BAwEd;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAQ,EACR,UAAkB,EAClB,IAAY,EACZ,eAAsB,EACtB,SAAS,GACV,EAAE,oBAAoB,+BAuBtB"}
|
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { Icon } from '@shipfox/react-ui/icon';
|
|
4
4
|
import { LogContent, LogRow, LogRows } from '@shipfox/react-ui/log';
|
|
5
5
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
6
|
-
import { useEffect, useMemo, useRef } from 'react';
|
|
6
|
+
import { useDeferredValue, useEffect, useMemo, useRef } from 'react';
|
|
7
|
+
import { buildLogSearchIndex, filterLogNodes } from '#core/log-search.js';
|
|
7
8
|
import { assertNever, buildLogTree } from '#core/log-tree.js';
|
|
8
9
|
import { AgentSessionRows } from './agent-session-rows.js';
|
|
9
10
|
import { LogGroup } from './log-group.js';
|
|
10
11
|
import { OutputLogRow } from './output-log-row.js';
|
|
11
12
|
import { CappedMarker, EndMarker, GapMarker, RunnerLostMarker } from './system-markers.js';
|
|
12
|
-
export function LogView({ records, timestamps = 'off', wrap = false, showLineNumbers = true, emptyState = 'complete', defaultGroupsOpen = false, anchorToFailure = false, ariaLive = 'polite', className, onScroll }) {
|
|
13
|
+
export function LogView({ records, timestamps = 'off', wrap = false, showLineNumbers = true, emptyState = 'complete', defaultGroupsOpen = false, anchorToFailure = false, search = '', ariaLive = 'polite', className, onScroll }) {
|
|
13
14
|
const rowsRef = useRef(null);
|
|
14
15
|
const tree = useMemo(()=>buildLogTree(records), [
|
|
15
16
|
records
|
|
16
17
|
]);
|
|
18
|
+
const deferredSearch = useDeferredValue(search);
|
|
19
|
+
const normalizedSearch = deferredSearch.trim().toLowerCase();
|
|
20
|
+
const searchIndex = useMemo(()=>buildLogSearchIndex(tree.nodes), [
|
|
21
|
+
tree.nodes
|
|
22
|
+
]);
|
|
23
|
+
const visibleNodes = useMemo(()=>normalizedSearch ? filterLogNodes(tree.nodes, normalizedSearch, searchIndex) : tree.nodes, [
|
|
24
|
+
normalizedSearch,
|
|
25
|
+
searchIndex,
|
|
26
|
+
tree.nodes
|
|
27
|
+
]);
|
|
17
28
|
const resolvedToolCalls = useMemo(()=>collectResolvedToolCalls(tree.nodes), [
|
|
18
29
|
tree.nodes
|
|
19
30
|
]);
|
|
20
|
-
const noOutputState = getNoOutputState(tree, emptyState);
|
|
31
|
+
const noOutputState = normalizedSearch ? null : getNoOutputState(tree, emptyState);
|
|
21
32
|
const anchorRecordCount = records.length;
|
|
33
|
+
const searchStatus = normalizedSearch ? visibleNodes.length === 0 ? `No log lines match “${deferredSearch.trim()}”.` : `Log search updated for “${deferredSearch.trim()}”.` : null;
|
|
22
34
|
useEffect(()=>{
|
|
23
35
|
if (!anchorToFailure) return;
|
|
24
36
|
if (anchorRecordCount === 0) return;
|
|
@@ -39,22 +51,36 @@ export function LogView({ records, timestamps = 'off', wrap = false, showLineNum
|
|
|
39
51
|
anchorToFailure,
|
|
40
52
|
anchorRecordCount
|
|
41
53
|
]);
|
|
42
|
-
return /*#__PURE__*/ _jsxs(
|
|
43
|
-
ref: rowsRef,
|
|
44
|
-
timestamps: timestamps,
|
|
45
|
-
wrap: wrap,
|
|
46
|
-
showLineNumbers: showLineNumbers,
|
|
47
|
-
"aria-live": ariaLive,
|
|
48
|
-
className: className,
|
|
49
|
-
onScroll: onScroll,
|
|
50
|
-
...tree.originTs != null ? {
|
|
51
|
-
timestampOrigin: new Date(tree.originTs)
|
|
52
|
-
} : {},
|
|
54
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
53
55
|
children: [
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
searchStatus ? /*#__PURE__*/ _jsx("div", {
|
|
57
|
+
role: "status",
|
|
58
|
+
"aria-live": "polite",
|
|
59
|
+
"aria-atomic": "true",
|
|
60
|
+
className: "sr-only",
|
|
61
|
+
children: searchStatus
|
|
56
62
|
}) : null,
|
|
57
|
-
|
|
63
|
+
/*#__PURE__*/ _jsxs(LogRows, {
|
|
64
|
+
ref: rowsRef,
|
|
65
|
+
timestamps: timestamps,
|
|
66
|
+
wrap: wrap,
|
|
67
|
+
showLineNumbers: showLineNumbers,
|
|
68
|
+
"aria-live": normalizedSearch ? 'off' : ariaLive,
|
|
69
|
+
className: className,
|
|
70
|
+
onScroll: onScroll,
|
|
71
|
+
...tree.originTs != null ? {
|
|
72
|
+
timestampOrigin: new Date(tree.originTs)
|
|
73
|
+
} : {},
|
|
74
|
+
children: [
|
|
75
|
+
noOutputState ? /*#__PURE__*/ _jsx(NoOutputRow, {
|
|
76
|
+
state: noOutputState
|
|
77
|
+
}) : null,
|
|
78
|
+
normalizedSearch && visibleNodes.length === 0 ? /*#__PURE__*/ _jsx(NoSearchMatchesRow, {
|
|
79
|
+
query: deferredSearch.trim()
|
|
80
|
+
}) : null,
|
|
81
|
+
renderNodes(visibleNodes, 0, tree, defaultGroupsOpen, Boolean(normalizedSearch), resolvedToolCalls)
|
|
82
|
+
]
|
|
83
|
+
})
|
|
58
84
|
]
|
|
59
85
|
});
|
|
60
86
|
}
|
|
@@ -113,7 +139,7 @@ function NoOutputRow({ state }) {
|
|
|
113
139
|
return /*#__PURE__*/ _jsx(LogRow, {
|
|
114
140
|
lineNumber: null,
|
|
115
141
|
children: /*#__PURE__*/ _jsx(LogContent, {
|
|
116
|
-
className: "text-foreground-
|
|
142
|
+
className: "text-foreground-contrast-secondary",
|
|
117
143
|
children: /*#__PURE__*/ _jsxs("span", {
|
|
118
144
|
className: "inline-flex min-w-0 items-center gap-inline",
|
|
119
145
|
children: [
|
|
@@ -131,7 +157,7 @@ function NoOutputRow({ state }) {
|
|
|
131
157
|
}),
|
|
132
158
|
' · ',
|
|
133
159
|
/*#__PURE__*/ _jsx("span", {
|
|
134
|
-
className: "text-foreground-
|
|
160
|
+
className: "text-foreground-contrast-secondary",
|
|
135
161
|
children: copy.detail
|
|
136
162
|
})
|
|
137
163
|
]
|
|
@@ -141,7 +167,32 @@ function NoOutputRow({ state }) {
|
|
|
141
167
|
})
|
|
142
168
|
});
|
|
143
169
|
}
|
|
144
|
-
function
|
|
170
|
+
function NoSearchMatchesRow({ query }) {
|
|
171
|
+
return /*#__PURE__*/ _jsx(LogRow, {
|
|
172
|
+
lineNumber: null,
|
|
173
|
+
children: /*#__PURE__*/ _jsx(LogContent, {
|
|
174
|
+
className: "text-foreground-contrast-secondary",
|
|
175
|
+
children: /*#__PURE__*/ _jsxs("span", {
|
|
176
|
+
className: "inline-flex min-w-0 items-center gap-inline",
|
|
177
|
+
children: [
|
|
178
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
179
|
+
name: "searchLine",
|
|
180
|
+
className: "size-14 flex-none",
|
|
181
|
+
"aria-hidden": "true"
|
|
182
|
+
}),
|
|
183
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
184
|
+
children: [
|
|
185
|
+
"No log lines match “",
|
|
186
|
+
query,
|
|
187
|
+
"”."
|
|
188
|
+
]
|
|
189
|
+
})
|
|
190
|
+
]
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function renderNodes(nodes, depth, tree, defaultGroupsOpen, forceOpen, resolvedToolCalls) {
|
|
145
196
|
// `node.seq` is the stable, unique render key (see `LogNodeBase`): a concatenated
|
|
146
197
|
// multi-step/retry stream can repeat a `group_id` or a marker's `(type, ts)` at one
|
|
147
198
|
// level, which a key derived from those fields would collide on.
|
|
@@ -159,7 +210,8 @@ function renderNodes(nodes, depth, tree, defaultGroupsOpen, resolvedToolCalls) {
|
|
|
159
210
|
depth: depth,
|
|
160
211
|
terminated: tree.terminated,
|
|
161
212
|
defaultOpen: defaultGroupsOpen,
|
|
162
|
-
|
|
213
|
+
forceOpen: forceOpen,
|
|
214
|
+
children: renderNodes(node.children, depth + 1, tree, defaultGroupsOpen, forceOpen, resolvedToolCalls)
|
|
163
215
|
}, node.seq);
|
|
164
216
|
case 'marker':
|
|
165
217
|
return /*#__PURE__*/ _jsx(MarkerRow, {
|
|
@@ -173,7 +225,8 @@ function renderNodes(nodes, depth, tree, defaultGroupsOpen, resolvedToolCalls) {
|
|
|
173
225
|
],
|
|
174
226
|
resolvedToolCallIds: resolvedToolCalls.ids,
|
|
175
227
|
toolCallNames: resolvedToolCalls.names,
|
|
176
|
-
indent: depth
|
|
228
|
+
indent: depth,
|
|
229
|
+
forceOpen: forceOpen
|
|
177
230
|
}, node.seq);
|
|
178
231
|
default:
|
|
179
232
|
return assertNever(node);
|