@zhin.js/client 1.1.9 → 1.1.10

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.
@@ -0,0 +1,136 @@
1
+ import { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { apiFetch } from '../console-utils/remoteApi.js';
3
+ import { buildWaterfall, formatTime, toQueryTime, type TraceDetail } from './traceView.js';
4
+
5
+ type SessionRow = { session_key: string; turns: number; last_started_at: number; last_status: string; total_tokens: number };
6
+ type TurnRow = { turn_id: string; started_at: number; duration_ms?: number; model_calls: number; tool_calls: number; total_tokens: number; termination: { status: string; code?: string } };
7
+
8
+ async function getJson<T>(path: string): Promise<T> {
9
+ const res = await apiFetch(path);
10
+ const body = await res.json() as { success?: boolean; error?: string; data?: T };
11
+ if (!res.ok || !body.success) throw new Error(body.error ?? `HTTP ${res.status}`);
12
+ return body.data as T;
13
+ }
14
+
15
+ const statusClass = (status: string) => (status === 'completed' ? 'text-emerald-600' : status === 'running' ? 'text-sky-600' : 'text-rose-600');
16
+
17
+ /** Persisted Agent turn traces: sessions → turns → turn detail (#728). */
18
+ export default function TraceArchivePage() {
19
+ const initialTurn = typeof location !== 'undefined' ? new URLSearchParams(location.search).get('turn') ?? '' : '';
20
+ const [since, setSince] = useState('');
21
+ const [until, setUntil] = useState('');
22
+ const [sessions, setSessions] = useState<SessionRow[]>([]);
23
+ const [session, setSession] = useState('');
24
+ const [turns, setTurns] = useState<TurnRow[]>([]);
25
+ const [detail, setDetail] = useState<TraceDetail | null>(null);
26
+ const [showRaw, setShowRaw] = useState(false);
27
+ const [error, setError] = useState('');
28
+
29
+ const window = useMemo(() => {
30
+ const params = new URLSearchParams();
31
+ const s = toQueryTime(since);
32
+ const u = toQueryTime(until);
33
+ if (s) params.set('since', s);
34
+ if (u) params.set('until', u);
35
+ return params;
36
+ }, [since, until]);
37
+
38
+ const run = useCallback(async (work: () => Promise<void>) => {
39
+ setError('');
40
+ try { await work(); } catch (err) { setError(err instanceof Error ? err.message : String(err)); }
41
+ }, []);
42
+
43
+ const loadSessions = useCallback(() => run(async () => {
44
+ setSessions(await getJson<SessionRow[]>(`/api/agent/trace-archive/sessions?${window}`));
45
+ }), [run, window]);
46
+
47
+ const openSession = useCallback((key: string) => run(async () => {
48
+ setSession(key);
49
+ setDetail(null);
50
+ const params = new URLSearchParams(window);
51
+ params.set('sessionKey', key);
52
+ setTurns(await getJson<TurnRow[]>(`/api/agent/trace-archive/turns?${params}`));
53
+ }), [run, window]);
54
+
55
+ const openTurn = useCallback((turnId: string) => run(async () => {
56
+ setDetail(await getJson<TraceDetail>(`/api/agent/trace-archive/turn?turnId=${encodeURIComponent(turnId)}`));
57
+ }), [run]);
58
+
59
+ useEffect(() => { void loadSessions(); }, [loadSessions]);
60
+ useEffect(() => { if (initialTurn) void openTurn(initialTurn); }, [initialTurn, openTurn]);
61
+
62
+ const bars = useMemo(() => (detail ? buildWaterfall(detail) : []), [detail]);
63
+
64
+ return (
65
+ <div className="p-4 md:p-6 space-y-5 max-w-7xl mx-auto">
66
+ <header className="flex flex-wrap items-end justify-between gap-3 border-b pb-4">
67
+ <div>
68
+ <h1 className="text-xl font-semibold tracking-tight">Agent Trace</h1>
69
+ <p className="mt-1 text-sm text-muted-foreground">已落盘的回合记录(默认保留 7 天):会话 → 回合 → 详情。命令行同样可用 <code>zhin trace --sessions</code>。</p>
70
+ </div>
71
+ <div className="flex flex-wrap items-end gap-2 text-sm">
72
+ <label className="flex flex-col">起<input type="datetime-local" className="border rounded px-2 py-1" value={since} onChange={(e) => setSince(e.target.value)} /></label>
73
+ <label className="flex flex-col">止<input type="datetime-local" className="border rounded px-2 py-1" value={until} onChange={(e) => setUntil(e.target.value)} /></label>
74
+ <button type="button" className="border rounded px-3 py-1" onClick={() => void loadSessions()}>刷新</button>
75
+ </div>
76
+ </header>
77
+ {error && <p className="text-sm text-rose-600">{error}</p>}
78
+ <div className="grid gap-4 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]">
79
+ <section>
80
+ <h2 className="font-medium mb-2">会话({sessions.length})</h2>
81
+ <ul className="divide-y border rounded text-sm">
82
+ {sessions.map((s) => (
83
+ <li key={s.session_key}>
84
+ <button type="button" className={`w-full text-left px-3 py-2 ${s.session_key === session ? 'bg-muted' : ''}`} onClick={() => void openSession(s.session_key)}>
85
+ <div className="font-mono truncate">{s.session_key}</div>
86
+ <div className="text-xs text-muted-foreground">{s.turns} 回合 · {formatTime(s.last_started_at)} · <span className={statusClass(s.last_status)}>{s.last_status}</span> · {s.total_tokens} tokens</div>
87
+ </button>
88
+ </li>
89
+ ))}
90
+ {sessions.length === 0 && <li className="px-3 py-2 text-muted-foreground">没有记录</li>}
91
+ </ul>
92
+ </section>
93
+ <section>
94
+ <h2 className="font-medium mb-2">回合{session ? `(${turns.length})` : ''}</h2>
95
+ <ul className="divide-y border rounded text-sm">
96
+ {turns.map((t) => (
97
+ <li key={t.turn_id}>
98
+ <button type="button" className={`w-full text-left px-3 py-2 ${detail?.turn_id === t.turn_id ? 'bg-muted' : ''}`} onClick={() => void openTurn(t.turn_id)}>
99
+ <div className="font-mono truncate">{t.turn_id}</div>
100
+ <div className="text-xs text-muted-foreground">{formatTime(t.started_at)} · {t.duration_ms ?? '—'}ms · 模型 {t.model_calls} · 工具 {t.tool_calls} · {t.total_tokens} tokens · <span className={statusClass(t.termination.status)}>{t.termination.status}{t.termination.code ? ` (${t.termination.code})` : ''}</span></div>
101
+ </button>
102
+ </li>
103
+ ))}
104
+ {session && turns.length === 0 && <li className="px-3 py-2 text-muted-foreground">没有回合</li>}
105
+ </ul>
106
+ </section>
107
+ </div>
108
+ {detail && (
109
+ <section className="space-y-3 border rounded p-3">
110
+ <div className="flex flex-wrap items-center justify-between gap-2">
111
+ <h2 className="font-medium font-mono">{detail.turn_id}</h2>
112
+ <button type="button" className="border rounded px-3 py-1 text-sm" onClick={() => setShowRaw((v) => !v)}>{showRaw ? '隐藏原始记录' : '原始记录'}</button>
113
+ </div>
114
+ <p className="text-sm text-muted-foreground">
115
+ {detail.session_key} · {detail.principal ? `${detail.principal.display_name ?? detail.principal.subject_id}(${detail.principal.trust_level ?? detail.principal.roles.join(',')})` : '—'} · {formatTime(detail.started_at)} · {detail.duration_ms ?? '—'}ms ·{' '}
116
+ <span className={statusClass(detail.termination.status)}>{[detail.termination.status, detail.termination.code, detail.termination.reason].filter(Boolean).join(' ')}</span>
117
+ </p>
118
+ <div className="space-y-1" aria-label="waterfall">
119
+ {bars.map((bar) => (
120
+ <div key={bar.key} className="flex items-center gap-2 text-xs" title={bar.title}>
121
+ <span className="w-40 shrink-0 truncate font-mono">{bar.label}</span>
122
+ <div className="relative h-3 flex-1 bg-muted rounded">
123
+ <div className={`absolute h-3 rounded ${bar.failed ? 'bg-rose-500' : bar.kind === 'model' ? 'bg-sky-500' : 'bg-emerald-500'}`} style={{ left: `${bar.left}%`, width: `${bar.width}%` }} />
124
+ </div>
125
+ </div>
126
+ ))}
127
+ </div>
128
+ <ol className="text-xs font-mono space-y-0.5 max-h-72 overflow-auto">
129
+ {detail.timeline.map((entry, index) => <li key={index}>+{entry.at_ms}ms {entry.kind} {entry.detail}</li>)}
130
+ </ol>
131
+ {showRaw && <pre className="text-xs overflow-auto max-h-96 bg-muted p-2 rounded">{JSON.stringify(detail, null, 2)}</pre>}
132
+ </section>
133
+ )}
134
+ </div>
135
+ );
136
+ }
@@ -0,0 +1,17 @@
1
+ import type { PluginRegisterHostApi } from '@zhin.js/contract';
2
+ import TraceArchivePage from './TraceArchivePage.js';
3
+
4
+ /** Read-only page over the persisted Agent turn traces (#728). */
5
+ export function registerAgentTraceConsole(api: PluginRegisterHostApi): void {
6
+ api.addRoute({
7
+ path: '/console/agent-trace',
8
+ name: 'Agent Trace',
9
+ element: api.React.createElement(TraceArchivePage),
10
+ meta: { order: 41, group: 'Agent' },
11
+ });
12
+ api.addTool({
13
+ id: 'agent-trace',
14
+ name: 'Agent Trace',
15
+ path: '/console/agent-trace',
16
+ });
17
+ }
@@ -0,0 +1,42 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { buildWaterfall, toQueryTime, type TraceDetail } from './traceView.js';
3
+ import { registerAgentTraceConsole } from './registerAgentTraceConsole.js';
4
+
5
+ const detail: TraceDetail = {
6
+ turn_id: 't', session_key: 's', started_at: 0, duration_ms: 1000,
7
+ model_calls: [{ index: 1, prompt_tokens: 10, completion_tokens: 2, total_tokens: 12 }, { index: 2, prompt_tokens: 20, completion_tokens: 3, total_tokens: 23 }],
8
+ tool_calls: [{ tool_use_id: 'c1', tool_name: 'bash', args_summary: 'ls', status: 'failed', started_at_ms: 400, duration_ms: 200, error: 'boom' }],
9
+ timeline: [
10
+ { at_ms: 0, kind: 'iteration', detail: '1/6' },
11
+ { at_ms: 400, kind: 'model_call', detail: '#1' },
12
+ { at_ms: 400, kind: 'tool_call', detail: 'bash' },
13
+ { at_ms: 600, kind: 'tool_failed', detail: 'bash: boom' },
14
+ { at_ms: 1000, kind: 'model_call', detail: '#2' },
15
+ ],
16
+ termination: { status: 'completed' },
17
+ usage: { prompt_tokens: 30, completion_tokens: 5, total_tokens: 35 },
18
+ };
19
+
20
+ describe('trace archive page helpers (#728)', () => {
21
+ it('lays model and tool calls on the turn time axis', () => {
22
+ const bars = buildWaterfall(detail);
23
+ expect(bars.map((b) => [b.label, Math.round(b.left), Math.round(b.width), b.failed])).toEqual([
24
+ ['模型 #1', 0, 40, false],
25
+ ['bash', 40, 20, true],
26
+ ['模型 #2', 60, 40, false],
27
+ ]);
28
+ });
29
+
30
+ it('converts datetime-local values to epoch query params', () => {
31
+ expect(toQueryTime('')).toBe('');
32
+ expect(toQueryTime('2026-10-14T08:00')).toBe(String(Date.parse('2026-10-14T08:00')));
33
+ });
34
+
35
+ it('registers the Agent Trace route and tool', () => {
36
+ const addRoute = vi.fn();
37
+ const addTool = vi.fn();
38
+ registerAgentTraceConsole({ React: { createElement: vi.fn((type) => ({ type })) } as never, addRoute, addTool } as never);
39
+ expect(addRoute).toHaveBeenCalledWith(expect.objectContaining({ path: '/console/agent-trace' }));
40
+ expect(addTool).toHaveBeenCalledWith(expect.objectContaining({ id: 'agent-trace' }));
41
+ });
42
+ });
@@ -0,0 +1,92 @@
1
+ /** Pure helpers for the trace archive page (#728): waterfall layout and labels. */
2
+
3
+ export type TraceModelCall = { index: number; prompt_tokens: number; completion_tokens: number; total_tokens: number; cache_read_tokens?: number };
4
+ export type TraceToolCall = { tool_use_id: string; tool_name: string; args_summary: string; status: string; started_at_ms: number; duration_ms?: number; result_size?: number; error?: string; policy?: string };
5
+ export type TraceTimelineEntry = { at_ms: number; kind: string; detail: string };
6
+ export type TraceDetail = {
7
+ turn_id: string;
8
+ session_key: string;
9
+ principal?: { subject_id: string; display_name?: string; roles: string[]; trust_level?: string };
10
+ started_at: number;
11
+ duration_ms?: number;
12
+ model_calls: TraceModelCall[];
13
+ tool_calls: TraceToolCall[];
14
+ timeline: TraceTimelineEntry[];
15
+ termination: { status: string; code?: string; reason?: string };
16
+ usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };
17
+ subagents?: TraceDetail[];
18
+ };
19
+
20
+ export type WaterfallBar = {
21
+ readonly key: string;
22
+ readonly kind: 'model' | 'tool';
23
+ readonly label: string;
24
+ /** Left offset and width as percentages of the turn duration. */
25
+ readonly left: number;
26
+ readonly width: number;
27
+ readonly failed: boolean;
28
+ readonly title: string;
29
+ };
30
+
31
+ /**
32
+ * Lay model and tool calls on the turn's time axis. Tool calls carry their own
33
+ * start and duration; a model call ends at its `model_call` timeline entry and
34
+ * starts at the previous step boundary (iteration start or last tool result).
35
+ */
36
+ export function buildWaterfall(trace: TraceDetail): WaterfallBar[] {
37
+ const ends = [
38
+ trace.duration_ms ?? 0,
39
+ ...trace.timeline.map((entry) => entry.at_ms),
40
+ ...trace.tool_calls.map((call) => call.started_at_ms + (call.duration_ms ?? 0)),
41
+ ];
42
+ const total = Math.max(1, ...ends);
43
+ const place = (start: number, duration: number) => {
44
+ const left = Math.min(100, Math.max(0, (start / total) * 100));
45
+ return { left, width: Math.max(0.5, Math.min(100 - left, (duration / total) * 100)) };
46
+ };
47
+ const bars: WaterfallBar[] = [];
48
+ let boundary = 0;
49
+ let modelIndex = 0;
50
+ for (const entry of trace.timeline) {
51
+ if (entry.kind === 'iteration' || entry.kind.startsWith('tool_result') || entry.kind === 'tool_failed' || entry.kind === 'tool_denied') {
52
+ boundary = Math.max(boundary, entry.at_ms);
53
+ }
54
+ if (entry.kind === 'model_call') {
55
+ const call = trace.model_calls[modelIndex];
56
+ modelIndex += 1;
57
+ bars.push({
58
+ key: `m${modelIndex}`,
59
+ kind: 'model',
60
+ label: `模型 #${call?.index ?? modelIndex}`,
61
+ ...place(boundary, entry.at_ms - boundary),
62
+ failed: false,
63
+ title: call
64
+ ? `${entry.at_ms - boundary}ms · in ${call.prompt_tokens} / out ${call.completion_tokens}${call.cache_read_tokens ? ` / cache ${call.cache_read_tokens}` : ''}`
65
+ : entry.detail,
66
+ });
67
+ boundary = entry.at_ms;
68
+ }
69
+ }
70
+ trace.tool_calls.forEach((call, index) => {
71
+ bars.push({
72
+ key: `t${index}`,
73
+ kind: 'tool',
74
+ label: call.tool_name,
75
+ ...place(call.started_at_ms, call.duration_ms ?? 0),
76
+ failed: call.status !== 'ok' && call.status !== 'running',
77
+ title: `${call.status} ${call.duration_ms ?? 0}ms${call.args_summary ? ` · ${call.args_summary}` : ''}${call.error ? ` · ${call.error}` : ''}`,
78
+ });
79
+ });
80
+ return bars.sort((a, b) => a.left - b.left);
81
+ }
82
+
83
+ export function formatTime(epochMs: number | undefined): string {
84
+ return epochMs ? new Date(epochMs).toLocaleString() : '—';
85
+ }
86
+
87
+ /** `datetime-local` input value → epoch ms query param (empty when unset). */
88
+ export function toQueryTime(value: string): string {
89
+ if (!value) return '';
90
+ const parsed = Date.parse(value);
91
+ return Number.isFinite(parsed) ? String(parsed) : '';
92
+ }
package/client/index.ts CHANGED
@@ -118,6 +118,9 @@ export {
118
118
  } from "./bootstrap/loadConsoleEntries.js";
119
119
 
120
120
  export { registerWorkroomConsole } from "./workroom/registerWorkroomConsole.js";
121
+ export { registerAgentTraceConsole } from "./agent-trace/registerAgentTraceConsole.js";
122
+ export { buildWaterfall } from "./agent-trace/traceView.js";
123
+ export { default as TraceArchivePage } from "./agent-trace/TraceArchivePage.js";
121
124
  export { default as WorkroomRunsPage } from "./workroom/WorkroomRunsPage.js";
122
125
 
123
126
  export {
@@ -0,0 +1,3 @@
1
+ /** Persisted Agent turn traces: sessions → turns → turn detail (#728). */
2
+ export default function TraceArchivePage(): import("react").JSX.Element;
3
+ //# sourceMappingURL=TraceArchivePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraceArchivePage.d.ts","sourceRoot":"","sources":["../../client/agent-trace/TraceArchivePage.tsx"],"names":[],"mappings":"AAgBA,0EAA0E;AAC1E,MAAM,CAAC,OAAO,UAAU,gBAAgB,gCAsHvC"}
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { apiFetch } from '../console-utils/remoteApi.js';
4
+ import { buildWaterfall, formatTime, toQueryTime } from './traceView.js';
5
+ async function getJson(path) {
6
+ const res = await apiFetch(path);
7
+ const body = await res.json();
8
+ if (!res.ok || !body.success)
9
+ throw new Error(body.error ?? `HTTP ${res.status}`);
10
+ return body.data;
11
+ }
12
+ const statusClass = (status) => (status === 'completed' ? 'text-emerald-600' : status === 'running' ? 'text-sky-600' : 'text-rose-600');
13
+ /** Persisted Agent turn traces: sessions → turns → turn detail (#728). */
14
+ export default function TraceArchivePage() {
15
+ const initialTurn = typeof location !== 'undefined' ? new URLSearchParams(location.search).get('turn') ?? '' : '';
16
+ const [since, setSince] = useState('');
17
+ const [until, setUntil] = useState('');
18
+ const [sessions, setSessions] = useState([]);
19
+ const [session, setSession] = useState('');
20
+ const [turns, setTurns] = useState([]);
21
+ const [detail, setDetail] = useState(null);
22
+ const [showRaw, setShowRaw] = useState(false);
23
+ const [error, setError] = useState('');
24
+ const window = useMemo(() => {
25
+ const params = new URLSearchParams();
26
+ const s = toQueryTime(since);
27
+ const u = toQueryTime(until);
28
+ if (s)
29
+ params.set('since', s);
30
+ if (u)
31
+ params.set('until', u);
32
+ return params;
33
+ }, [since, until]);
34
+ const run = useCallback(async (work) => {
35
+ setError('');
36
+ try {
37
+ await work();
38
+ }
39
+ catch (err) {
40
+ setError(err instanceof Error ? err.message : String(err));
41
+ }
42
+ }, []);
43
+ const loadSessions = useCallback(() => run(async () => {
44
+ setSessions(await getJson(`/api/agent/trace-archive/sessions?${window}`));
45
+ }), [run, window]);
46
+ const openSession = useCallback((key) => run(async () => {
47
+ setSession(key);
48
+ setDetail(null);
49
+ const params = new URLSearchParams(window);
50
+ params.set('sessionKey', key);
51
+ setTurns(await getJson(`/api/agent/trace-archive/turns?${params}`));
52
+ }), [run, window]);
53
+ const openTurn = useCallback((turnId) => run(async () => {
54
+ setDetail(await getJson(`/api/agent/trace-archive/turn?turnId=${encodeURIComponent(turnId)}`));
55
+ }), [run]);
56
+ useEffect(() => { void loadSessions(); }, [loadSessions]);
57
+ useEffect(() => { if (initialTurn)
58
+ void openTurn(initialTurn); }, [initialTurn, openTurn]);
59
+ const bars = useMemo(() => (detail ? buildWaterfall(detail) : []), [detail]);
60
+ return (_jsxs("div", { className: "p-4 md:p-6 space-y-5 max-w-7xl mx-auto", children: [_jsxs("header", { className: "flex flex-wrap items-end justify-between gap-3 border-b pb-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold tracking-tight", children: "Agent Trace" }), _jsxs("p", { className: "mt-1 text-sm text-muted-foreground", children: ["\u5DF2\u843D\u76D8\u7684\u56DE\u5408\u8BB0\u5F55\uFF08\u9ED8\u8BA4\u4FDD\u7559 7 \u5929\uFF09\uFF1A\u4F1A\u8BDD \u2192 \u56DE\u5408 \u2192 \u8BE6\u60C5\u3002\u547D\u4EE4\u884C\u540C\u6837\u53EF\u7528 ", _jsx("code", { children: "zhin trace --sessions" }), "\u3002"] })] }), _jsxs("div", { className: "flex flex-wrap items-end gap-2 text-sm", children: [_jsxs("label", { className: "flex flex-col", children: ["\u8D77", _jsx("input", { type: "datetime-local", className: "border rounded px-2 py-1", value: since, onChange: (e) => setSince(e.target.value) })] }), _jsxs("label", { className: "flex flex-col", children: ["\u6B62", _jsx("input", { type: "datetime-local", className: "border rounded px-2 py-1", value: until, onChange: (e) => setUntil(e.target.value) })] }), _jsx("button", { type: "button", className: "border rounded px-3 py-1", onClick: () => void loadSessions(), children: "\u5237\u65B0" })] })] }), error && _jsx("p", { className: "text-sm text-rose-600", children: error }), _jsxs("div", { className: "grid gap-4 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]", children: [_jsxs("section", { children: [_jsxs("h2", { className: "font-medium mb-2", children: ["\u4F1A\u8BDD\uFF08", sessions.length, "\uFF09"] }), _jsxs("ul", { className: "divide-y border rounded text-sm", children: [sessions.map((s) => (_jsx("li", { children: _jsxs("button", { type: "button", className: `w-full text-left px-3 py-2 ${s.session_key === session ? 'bg-muted' : ''}`, onClick: () => void openSession(s.session_key), children: [_jsx("div", { className: "font-mono truncate", children: s.session_key }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [s.turns, " \u56DE\u5408 \u00B7 ", formatTime(s.last_started_at), " \u00B7 ", _jsx("span", { className: statusClass(s.last_status), children: s.last_status }), " \u00B7 ", s.total_tokens, " tokens"] })] }) }, s.session_key))), sessions.length === 0 && _jsx("li", { className: "px-3 py-2 text-muted-foreground", children: "\u6CA1\u6709\u8BB0\u5F55" })] })] }), _jsxs("section", { children: [_jsxs("h2", { className: "font-medium mb-2", children: ["\u56DE\u5408", session ? `(${turns.length})` : ''] }), _jsxs("ul", { className: "divide-y border rounded text-sm", children: [turns.map((t) => (_jsx("li", { children: _jsxs("button", { type: "button", className: `w-full text-left px-3 py-2 ${detail?.turn_id === t.turn_id ? 'bg-muted' : ''}`, onClick: () => void openTurn(t.turn_id), children: [_jsx("div", { className: "font-mono truncate", children: t.turn_id }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [formatTime(t.started_at), " \u00B7 ", t.duration_ms ?? '—', "ms \u00B7 \u6A21\u578B ", t.model_calls, " \u00B7 \u5DE5\u5177 ", t.tool_calls, " \u00B7 ", t.total_tokens, " tokens \u00B7 ", _jsxs("span", { className: statusClass(t.termination.status), children: [t.termination.status, t.termination.code ? ` (${t.termination.code})` : ''] })] })] }) }, t.turn_id))), session && turns.length === 0 && _jsx("li", { className: "px-3 py-2 text-muted-foreground", children: "\u6CA1\u6709\u56DE\u5408" })] })] })] }), detail && (_jsxs("section", { className: "space-y-3 border rounded p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx("h2", { className: "font-medium font-mono", children: detail.turn_id }), _jsx("button", { type: "button", className: "border rounded px-3 py-1 text-sm", onClick: () => setShowRaw((v) => !v), children: showRaw ? '隐藏原始记录' : '原始记录' })] }), _jsxs("p", { className: "text-sm text-muted-foreground", children: [detail.session_key, " \u00B7 ", detail.principal ? `${detail.principal.display_name ?? detail.principal.subject_id}(${detail.principal.trust_level ?? detail.principal.roles.join(',')})` : '—', " \u00B7 ", formatTime(detail.started_at), " \u00B7 ", detail.duration_ms ?? '—', "ms \u00B7", ' ', _jsx("span", { className: statusClass(detail.termination.status), children: [detail.termination.status, detail.termination.code, detail.termination.reason].filter(Boolean).join(' ') })] }), _jsx("div", { className: "space-y-1", "aria-label": "waterfall", children: bars.map((bar) => (_jsxs("div", { className: "flex items-center gap-2 text-xs", title: bar.title, children: [_jsx("span", { className: "w-40 shrink-0 truncate font-mono", children: bar.label }), _jsx("div", { className: "relative h-3 flex-1 bg-muted rounded", children: _jsx("div", { className: `absolute h-3 rounded ${bar.failed ? 'bg-rose-500' : bar.kind === 'model' ? 'bg-sky-500' : 'bg-emerald-500'}`, style: { left: `${bar.left}%`, width: `${bar.width}%` } }) })] }, bar.key))) }), _jsx("ol", { className: "text-xs font-mono space-y-0.5 max-h-72 overflow-auto", children: detail.timeline.map((entry, index) => _jsxs("li", { children: ["+", entry.at_ms, "ms ", entry.kind, " ", entry.detail] }, index)) }), showRaw && _jsx("pre", { className: "text-xs overflow-auto max-h-96 bg-muted p-2 rounded", children: JSON.stringify(detail, null, 2) })] }))] }));
61
+ }
62
+ //# sourceMappingURL=TraceArchivePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraceArchivePage.js","sourceRoot":"","sources":["../../client/agent-trace/TraceArchivePage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { PluginRegisterHostApi } from '@zhin.js/contract';
2
+ /** Read-only page over the persisted Agent turn traces (#728). */
3
+ export declare function registerAgentTraceConsole(api: PluginRegisterHostApi): void;
4
+ //# sourceMappingURL=registerAgentTraceConsole.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerAgentTraceConsole.d.ts","sourceRoot":"","sources":["../../client/agent-trace/registerAgentTraceConsole.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/D,kEAAkE;AAClE,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,qBAAqB,GAAG,IAAI,CAY1E"}
@@ -0,0 +1,16 @@
1
+ import TraceArchivePage from './TraceArchivePage.js';
2
+ /** Read-only page over the persisted Agent turn traces (#728). */
3
+ export function registerAgentTraceConsole(api) {
4
+ api.addRoute({
5
+ path: '/console/agent-trace',
6
+ name: 'Agent Trace',
7
+ element: api.React.createElement(TraceArchivePage),
8
+ meta: { order: 41, group: 'Agent' },
9
+ });
10
+ api.addTool({
11
+ id: 'agent-trace',
12
+ name: 'Agent Trace',
13
+ path: '/console/agent-trace',
14
+ });
15
+ }
16
+ //# sourceMappingURL=registerAgentTraceConsole.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerAgentTraceConsole.js","sourceRoot":"","sources":["../../client/agent-trace/registerAgentTraceConsole.ts"],"names":[],"mappings":"AACA,OAAO,gBAAgB,MAAM,uBAAuB,CAAC;AAErD,kEAAkE;AAClE,MAAM,UAAU,yBAAyB,CAAC,GAA0B;IAClE,GAAG,CAAC,QAAQ,CAAC;QACX,IAAI,EAAE,sBAAsB;QAC5B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;QAClD,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;KACpC,CAAC,CAAC;IACH,GAAG,CAAC,OAAO,CAAC;QACV,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,sBAAsB;KAC7B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,70 @@
1
+ /** Pure helpers for the trace archive page (#728): waterfall layout and labels. */
2
+ export type TraceModelCall = {
3
+ index: number;
4
+ prompt_tokens: number;
5
+ completion_tokens: number;
6
+ total_tokens: number;
7
+ cache_read_tokens?: number;
8
+ };
9
+ export type TraceToolCall = {
10
+ tool_use_id: string;
11
+ tool_name: string;
12
+ args_summary: string;
13
+ status: string;
14
+ started_at_ms: number;
15
+ duration_ms?: number;
16
+ result_size?: number;
17
+ error?: string;
18
+ policy?: string;
19
+ };
20
+ export type TraceTimelineEntry = {
21
+ at_ms: number;
22
+ kind: string;
23
+ detail: string;
24
+ };
25
+ export type TraceDetail = {
26
+ turn_id: string;
27
+ session_key: string;
28
+ principal?: {
29
+ subject_id: string;
30
+ display_name?: string;
31
+ roles: string[];
32
+ trust_level?: string;
33
+ };
34
+ started_at: number;
35
+ duration_ms?: number;
36
+ model_calls: TraceModelCall[];
37
+ tool_calls: TraceToolCall[];
38
+ timeline: TraceTimelineEntry[];
39
+ termination: {
40
+ status: string;
41
+ code?: string;
42
+ reason?: string;
43
+ };
44
+ usage: {
45
+ prompt_tokens: number;
46
+ completion_tokens: number;
47
+ total_tokens: number;
48
+ };
49
+ subagents?: TraceDetail[];
50
+ };
51
+ export type WaterfallBar = {
52
+ readonly key: string;
53
+ readonly kind: 'model' | 'tool';
54
+ readonly label: string;
55
+ /** Left offset and width as percentages of the turn duration. */
56
+ readonly left: number;
57
+ readonly width: number;
58
+ readonly failed: boolean;
59
+ readonly title: string;
60
+ };
61
+ /**
62
+ * Lay model and tool calls on the turn's time axis. Tool calls carry their own
63
+ * start and duration; a model call ends at its `model_call` timeline entry and
64
+ * starts at the previous step boundary (iteration start or last tool result).
65
+ */
66
+ export declare function buildWaterfall(trace: TraceDetail): WaterfallBar[];
67
+ export declare function formatTime(epochMs: number | undefined): string;
68
+ /** `datetime-local` input value → epoch ms query param (empty when unset). */
69
+ export declare function toQueryTime(value: string): string;
70
+ //# sourceMappingURL=traceView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceView.d.ts","sourceRoot":"","sources":["../../client/agent-trace/traceView.ts"],"names":[],"mappings":"AAAA,mFAAmF;AAEnF,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACnJ,MAAM,MAAM,aAAa,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACjN,MAAM,MAAM,kBAAkB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACjF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjG,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,KAAK,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,EAAE,CA6CjE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE9D;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD"}
@@ -0,0 +1,63 @@
1
+ /** Pure helpers for the trace archive page (#728): waterfall layout and labels. */
2
+ /**
3
+ * Lay model and tool calls on the turn's time axis. Tool calls carry their own
4
+ * start and duration; a model call ends at its `model_call` timeline entry and
5
+ * starts at the previous step boundary (iteration start or last tool result).
6
+ */
7
+ export function buildWaterfall(trace) {
8
+ const ends = [
9
+ trace.duration_ms ?? 0,
10
+ ...trace.timeline.map((entry) => entry.at_ms),
11
+ ...trace.tool_calls.map((call) => call.started_at_ms + (call.duration_ms ?? 0)),
12
+ ];
13
+ const total = Math.max(1, ...ends);
14
+ const place = (start, duration) => {
15
+ const left = Math.min(100, Math.max(0, (start / total) * 100));
16
+ return { left, width: Math.max(0.5, Math.min(100 - left, (duration / total) * 100)) };
17
+ };
18
+ const bars = [];
19
+ let boundary = 0;
20
+ let modelIndex = 0;
21
+ for (const entry of trace.timeline) {
22
+ if (entry.kind === 'iteration' || entry.kind.startsWith('tool_result') || entry.kind === 'tool_failed' || entry.kind === 'tool_denied') {
23
+ boundary = Math.max(boundary, entry.at_ms);
24
+ }
25
+ if (entry.kind === 'model_call') {
26
+ const call = trace.model_calls[modelIndex];
27
+ modelIndex += 1;
28
+ bars.push({
29
+ key: `m${modelIndex}`,
30
+ kind: 'model',
31
+ label: `模型 #${call?.index ?? modelIndex}`,
32
+ ...place(boundary, entry.at_ms - boundary),
33
+ failed: false,
34
+ title: call
35
+ ? `${entry.at_ms - boundary}ms · in ${call.prompt_tokens} / out ${call.completion_tokens}${call.cache_read_tokens ? ` / cache ${call.cache_read_tokens}` : ''}`
36
+ : entry.detail,
37
+ });
38
+ boundary = entry.at_ms;
39
+ }
40
+ }
41
+ trace.tool_calls.forEach((call, index) => {
42
+ bars.push({
43
+ key: `t${index}`,
44
+ kind: 'tool',
45
+ label: call.tool_name,
46
+ ...place(call.started_at_ms, call.duration_ms ?? 0),
47
+ failed: call.status !== 'ok' && call.status !== 'running',
48
+ title: `${call.status} ${call.duration_ms ?? 0}ms${call.args_summary ? ` · ${call.args_summary}` : ''}${call.error ? ` · ${call.error}` : ''}`,
49
+ });
50
+ });
51
+ return bars.sort((a, b) => a.left - b.left);
52
+ }
53
+ export function formatTime(epochMs) {
54
+ return epochMs ? new Date(epochMs).toLocaleString() : '—';
55
+ }
56
+ /** `datetime-local` input value → epoch ms query param (empty when unset). */
57
+ export function toQueryTime(value) {
58
+ if (!value)
59
+ return '';
60
+ const parsed = Date.parse(value);
61
+ return Number.isFinite(parsed) ? String(parsed) : '';
62
+ }
63
+ //# sourceMappingURL=traceView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceView.js","sourceRoot":"","sources":["../../client/agent-trace/traceView.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -14,6 +14,9 @@ export { cn } from "./console-utils/cn.js";
14
14
  export { apiFetch, getApiBase, getToken, resolveApiUrl, } from "./console-utils/remoteApi.js";
15
15
  export { fetchConsoleEntries, getRegisterFn, loadConsoleEntries, registerConsolePluginsFromEntries, resolveEntryRegister, type FetchConsoleEntriesOptions, type LoadConsoleEntriesOptions, } from "./bootstrap/loadConsoleEntries.js";
16
16
  export { registerWorkroomConsole } from "./workroom/registerWorkroomConsole.js";
17
+ export { registerAgentTraceConsole } from "./agent-trace/registerAgentTraceConsole.js";
18
+ export { buildWaterfall } from "./agent-trace/traceView.js";
19
+ export { default as TraceArchivePage } from "./agent-trace/TraceArchivePage.js";
17
20
  export { default as WorkroomRunsPage } from "./workroom/WorkroomRunsPage.js";
18
21
  export { startAgentSession, continueAgentSession, subscribeAgentStream, iterateAgentStreamNdjson, foldAgentStreamNdjson, type AgentStreamClientOptions, type SubscribeAgentStreamOptions, } from "./agent-stream.js";
19
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EACjC,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAG9E,OAAO,EACL,eAAe,EACf,SAAS,EACT,KAAK,oBAAoB,GAC1B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,aAAa,GACnB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,0BAA0B,GAChC,MAAM,6BAA6B,CAAC;AAGrC,cAAc,sBAAsB,CAAC;AAErC,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,KAAK,aAAa,GACnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,aAAa,GACd,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,EACpB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,GAC/B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -20,6 +20,9 @@ export { cn } from "./console-utils/cn.js";
20
20
  export { apiFetch, getApiBase, getToken, resolveApiUrl, } from "./console-utils/remoteApi.js";
21
21
  export { fetchConsoleEntries, getRegisterFn, loadConsoleEntries, registerConsolePluginsFromEntries, resolveEntryRegister, } from "./bootstrap/loadConsoleEntries.js";
22
22
  export { registerWorkroomConsole } from "./workroom/registerWorkroomConsole.js";
23
+ export { registerAgentTraceConsole } from "./agent-trace/registerAgentTraceConsole.js";
24
+ export { buildWaterfall } from "./agent-trace/traceView.js";
25
+ export { default as TraceArchivePage } from "./agent-trace/TraceArchivePage.js";
23
26
  export { default as WorkroomRunsPage } from "./workroom/WorkroomRunsPage.js";
24
27
  export { startAgentSession, continueAgentSession, subscribeAgentStream, iterateAgentStreamNdjson, foldAgentStreamNdjson, } from "./agent-stream.js";
25
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,sBAAsB,EActB,oBAAoB,GAcrB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,wBAAwB,GAEzB,MAAM,qBAAqB,CAAC;AAE7B,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAE9E,8EAA8E;AAC9E,OAAO,EACL,eAAe,EACf,SAAS,GAEV,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GAKnB,MAAM,+BAA+B,CAAC;AAEvC,+CAA+C;AAC/C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE7E,uDAAuD;AACvD,OAAO,EACL,UAAU,EACV,gBAAgB,GASjB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,mBAAmB,GAEpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GAEjB,MAAM,6BAA6B,CAAC;AAErC,kCAAkC;AAClC,cAAc,sBAAsB,CAAC;AAErC,OAAO,EACL,mBAAmB,EACnB,WAAW,GAEZ,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,aAAa,GACd,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,GAGrB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,GAGtB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,sBAAsB,EActB,oBAAoB,GAcrB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,wBAAwB,GAEzB,MAAM,qBAAqB,CAAC;AAE7B,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAE9E,8EAA8E;AAC9E,OAAO,EACL,eAAe,EACf,SAAS,GAEV,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GAKnB,MAAM,+BAA+B,CAAC;AAEvC,+CAA+C;AAC/C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE7E,uDAAuD;AACvD,OAAO,EACL,UAAU,EACV,gBAAgB,GASjB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,mBAAmB,GAEpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GAEjB,MAAM,6BAA6B,CAAC;AAErC,kCAAkC;AAClC,cAAc,sBAAsB,CAAC;AAErC,OAAO,EACL,mBAAmB,EACnB,WAAW,GAEZ,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,aAAa,GACd,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,GAGrB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,GAGtB,MAAM,mBAAmB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/client",
3
- "version": "1.1.9",
3
+ "version": "1.1.10",
4
4
  "description": "Zhin Remote Console client SDK (entries loader, app registry, REST/SSE) — UI lives in zhin-console repo",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -14,8 +14,8 @@
14
14
  "dependencies": {
15
15
  "clsx": "^2.1.1",
16
16
  "tailwind-merge": "^3.6.0",
17
- "@zhin.js/console-protocol": "1.1.7",
18
- "@zhin.js/contract": "1.1.4"
17
+ "@zhin.js/console-protocol": "1.1.8",
18
+ "@zhin.js/contract": "1.1.5"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=18"