@zhin.js/client 2.0.6 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +7 -1
  2. package/client/bootstrap/loadConsoleEntries.test.ts +28 -2
  3. package/client/bootstrap/loadConsoleEntries.ts +39 -1
  4. package/client/console-utils/remoteApi.test.ts +68 -0
  5. package/client/console-utils/remoteApi.ts +19 -1
  6. package/client/index.ts +16 -0
  7. package/client/mediaSrc.test.ts +34 -0
  8. package/client/mediaSrc.ts +16 -1
  9. package/client/persistence/idb-store.test.ts +128 -0
  10. package/client/persistence/idb-store.ts +16 -16
  11. package/client/websocket/hooks.test.ts +21 -0
  12. package/client/websocket/hooks.ts +56 -27
  13. package/client/websocket/manager.test.ts +216 -0
  14. package/client/websocket/manager.ts +57 -28
  15. package/client/websocket/remote-settings.ts +13 -1
  16. package/dist/bootstrap/loadConsoleEntries.d.ts +9 -0
  17. package/dist/bootstrap/loadConsoleEntries.d.ts.map +1 -1
  18. package/dist/bootstrap/loadConsoleEntries.js +36 -1
  19. package/dist/bootstrap/loadConsoleEntries.js.map +1 -1
  20. package/dist/console-utils/remoteApi.d.ts.map +1 -1
  21. package/dist/console-utils/remoteApi.js +22 -1
  22. package/dist/console-utils/remoteApi.js.map +1 -1
  23. package/dist/index.d.ts +2 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/mediaSrc.d.ts.map +1 -1
  28. package/dist/mediaSrc.js +17 -1
  29. package/dist/mediaSrc.js.map +1 -1
  30. package/dist/persistence/idb-store.d.ts.map +1 -1
  31. package/dist/persistence/idb-store.js +15 -17
  32. package/dist/persistence/idb-store.js.map +1 -1
  33. package/dist/websocket/hooks.d.ts +9 -0
  34. package/dist/websocket/hooks.d.ts.map +1 -1
  35. package/dist/websocket/hooks.js +52 -31
  36. package/dist/websocket/hooks.js.map +1 -1
  37. package/dist/websocket/manager.d.ts.map +1 -1
  38. package/dist/websocket/manager.js +47 -27
  39. package/dist/websocket/manager.js.map +1 -1
  40. package/dist/websocket/remote-settings.d.ts.map +1 -1
  41. package/dist/websocket/remote-settings.js +16 -1
  42. package/dist/websocket/remote-settings.js.map +1 -1
  43. package/package.json +3 -2
@@ -0,0 +1,216 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+
3
+ const mockApplyConsoleEvent = vi.fn(async () => undefined);
4
+
5
+ vi.mock("../persistence/idb-store.js", () => ({
6
+ applyConsoleEvent: (...args: unknown[]) => mockApplyConsoleEvent(...args),
7
+ }));
8
+
9
+ import { WebSocketManager } from "./manager.js";
10
+ import { ConnectionState, type WebSocketMessage } from "./types.js";
11
+
12
+ function mockStorage(map: Record<string, string> = {}): Storage {
13
+ return {
14
+ getItem: (key: string) => map[key] ?? null,
15
+ setItem: (key: string, value: string) => {
16
+ map[key] = value;
17
+ },
18
+ removeItem: (key: string) => {
19
+ delete map[key];
20
+ },
21
+ clear: () => {
22
+ for (const key of Object.keys(map)) delete map[key];
23
+ },
24
+ key: () => null,
25
+ length: 0,
26
+ };
27
+ }
28
+
29
+ function installBrowserGlobals(storage: Storage = mockStorage()) {
30
+ const win = {
31
+ location: { origin: "http://localhost:5173", protocol: "http:", host: "localhost:5173" },
32
+ __ZHIN_API_TOKEN: undefined as string | undefined,
33
+ dispatchEvent: vi.fn(),
34
+ };
35
+ vi.stubGlobal("window", win);
36
+ vi.stubGlobal("localStorage", storage);
37
+ vi.stubGlobal("sessionStorage", mockStorage());
38
+ return { win, storage };
39
+ }
40
+
41
+ function sseResponse(status = 200, body?: ReadableStream<Uint8Array> | null) {
42
+ return {
43
+ ok: status >= 200 && status < 300,
44
+ status,
45
+ body: body === undefined
46
+ ? new ReadableStream<Uint8Array>({
47
+ start(controller) {
48
+ // Keep the stream open until abort; tests control lifecycle via disconnect().
49
+ void controller;
50
+ },
51
+ })
52
+ : body,
53
+ json: async () => ({}),
54
+ } as Response;
55
+ }
56
+
57
+ describe("WebSocketManager REST/SSE transport", () => {
58
+ beforeEach(() => {
59
+ vi.useFakeTimers();
60
+ mockApplyConsoleEvent.mockClear();
61
+ });
62
+
63
+ afterEach(() => {
64
+ vi.useRealTimers();
65
+ vi.unstubAllGlobals();
66
+ vi.restoreAllMocks();
67
+ });
68
+
69
+ it("connects SSE without a token (local Host with empty TokenRegistry)", async () => {
70
+ installBrowserGlobals();
71
+ const fetchMock = vi.fn(async () => sseResponse(200));
72
+ vi.stubGlobal("fetch", fetchMock);
73
+
74
+ const manager = new WebSocketManager({ reconnectInterval: 100, maxReconnectAttempts: 3 });
75
+ const states: boolean[] = [];
76
+ manager.onConnectionChange((c) => states.push(c));
77
+ manager.connect();
78
+
79
+ await vi.advanceTimersByTimeAsync(0);
80
+ await Promise.resolve();
81
+ await Promise.resolve();
82
+
83
+ expect(fetchMock).toHaveBeenCalled();
84
+ const init = fetchMock.mock.calls[0]![1] as RequestInit;
85
+ const headers = init.headers as Record<string, string>;
86
+ expect(headers.Accept).toBe("text/event-stream");
87
+ expect(headers.Authorization).toBeUndefined();
88
+ expect(manager.getState()).toBe(ConnectionState.CONNECTED);
89
+ expect(manager.isConnected()).toBe(true);
90
+ manager.disconnect();
91
+ });
92
+
93
+ it("sends Authorization when a token is stored", async () => {
94
+ installBrowserGlobals(mockStorage({ zhin_api_token: "secret" }));
95
+ const fetchMock = vi.fn(async () => sseResponse(200));
96
+ vi.stubGlobal("fetch", fetchMock);
97
+
98
+ const manager = new WebSocketManager();
99
+ manager.connect();
100
+ await vi.advanceTimersByTimeAsync(0);
101
+ await Promise.resolve();
102
+ await Promise.resolve();
103
+
104
+ const init = fetchMock.mock.calls[0]![1] as RequestInit;
105
+ expect((init.headers as Record<string, string>).Authorization).toBe("Bearer secret");
106
+ manager.disconnect();
107
+ });
108
+
109
+ it("reconnects after a transient SSE failure (no ERROR deadlock)", async () => {
110
+ installBrowserGlobals();
111
+ let calls = 0;
112
+ const fetchMock = vi.fn(async () => {
113
+ calls += 1;
114
+ if (calls === 1) return sseResponse(503, null);
115
+ return sseResponse(200);
116
+ });
117
+ vi.stubGlobal("fetch", fetchMock);
118
+
119
+ const manager = new WebSocketManager({
120
+ reconnectInterval: 100,
121
+ maxReconnectAttempts: 5,
122
+ });
123
+ manager.connect();
124
+
125
+ // First attempt fails → RECONNECTING
126
+ await vi.advanceTimersByTimeAsync(0);
127
+ await Promise.resolve();
128
+ await Promise.resolve();
129
+ expect(manager.getState()).toBe(ConnectionState.RECONNECTING);
130
+ expect(calls).toBe(1);
131
+
132
+ // scheduleReconnect delay = 100 * attempt(1) = 100ms
133
+ await vi.advanceTimersByTimeAsync(100);
134
+ await Promise.resolve();
135
+ await Promise.resolve();
136
+
137
+ expect(calls).toBeGreaterThanOrEqual(2);
138
+ expect(manager.getState()).toBe(ConnectionState.CONNECTED);
139
+ manager.disconnect();
140
+ });
141
+
142
+ it("sendRequest posts without Authorization when no token is stored", async () => {
143
+ installBrowserGlobals();
144
+ const fetchMock = vi.fn(async () => ({
145
+ ok: true,
146
+ status: 200,
147
+ json: async () => ({ success: true, data: { yaml: "http:\n port: 1\n" } }),
148
+ } as Response));
149
+ vi.stubGlobal("fetch", fetchMock);
150
+
151
+ const manager = new WebSocketManager();
152
+ const data = await manager.getConfigYaml();
153
+ expect(data.yaml).toContain("port");
154
+ const init = fetchMock.mock.calls[0]![1] as RequestInit;
155
+ expect((init.headers as Record<string, string>).Authorization).toBeUndefined();
156
+ expect(init.method).toBe("POST");
157
+ });
158
+
159
+ it("sendRequest includes Bearer token when present", async () => {
160
+ installBrowserGlobals(mockStorage({ zhin_api_token: "t" }));
161
+ const fetchMock = vi.fn(async () => ({
162
+ ok: true,
163
+ status: 200,
164
+ json: async () => ({ success: true, data: { ok: true } }),
165
+ } as Response));
166
+ vi.stubGlobal("fetch", fetchMock);
167
+
168
+ const manager = new WebSocketManager();
169
+ await manager.setConfig("sandbox", { endpoints: [] });
170
+ const init = fetchMock.mock.calls[0]![1] as RequestInit;
171
+ expect((init.headers as Record<string, string>).Authorization).toBe("Bearer t");
172
+ });
173
+
174
+ it("normalizes legacy endpoint push names and payload aliases before callbacks", async () => {
175
+ installBrowserGlobals();
176
+ const received: WebSocketMessage[] = [];
177
+ const manager = new WebSocketManager({}, {
178
+ onMessage: (message) => received.push(message),
179
+ });
180
+
181
+ (manager as unknown as { handleMessage(event: MessageEvent): void }).handleMessage({
182
+ data: '{"type":"endpoint:message","data":{"$adapter":"sandbox","endpoint":"bot"}}',
183
+ } as MessageEvent);
184
+ await Promise.resolve();
185
+
186
+ expect(received).toEqual([expect.objectContaining({
187
+ type: "message.receive",
188
+ data: expect.objectContaining({ adapter: "sandbox", endpointId: "bot" }),
189
+ })]);
190
+ expect(mockApplyConsoleEvent).toHaveBeenCalledWith(expect.objectContaining({
191
+ type: "message.receive",
192
+ }));
193
+ });
194
+
195
+ it("stops reconnecting after maxReconnectAttempts", async () => {
196
+ installBrowserGlobals();
197
+ const fetchMock = vi.fn(async () => sseResponse(500, null));
198
+ vi.stubGlobal("fetch", fetchMock);
199
+
200
+ const manager = new WebSocketManager({
201
+ reconnectInterval: 10,
202
+ maxReconnectAttempts: 2,
203
+ });
204
+ manager.connect();
205
+
206
+ for (let i = 0; i < 6; i++) {
207
+ await vi.advanceTimersByTimeAsync(50);
208
+ await Promise.resolve();
209
+ await Promise.resolve();
210
+ }
211
+
212
+ expect(manager.getState()).toBe(ConnectionState.ERROR);
213
+ expect(fetchMock.mock.calls.length).toBeLessThanOrEqual(3);
214
+ manager.disconnect();
215
+ });
216
+ });
@@ -2,6 +2,10 @@ import { ConnectionState, WebSocketError, ConnectionError, MessageError, Request
2
2
 
3
3
  import { getApiBase, getStoredToken, resolveApiUrl } from "./remote-settings.js";
4
4
  import { applyConsoleEvent } from "../persistence/idb-store.js";
5
+ import {
6
+ SIDE_EVENT_PUSH,
7
+ normalizeConsolePushMessage,
8
+ } from "@zhin.js/console-protocol";
5
9
 
6
10
  export class WebSocketManager {
7
11
  private ws: WebSocket | null = null;
@@ -50,25 +54,27 @@ export class WebSocketManager {
50
54
  this.attachEventHandlers();
51
55
  } catch (error) {
52
56
  this.handleConnectionError(new ConnectionError("Failed to create WebSocket", error as Error));
57
+ this.setState(ConnectionState.RECONNECTING);
58
+ this.notifyConnection(false);
59
+ this.scheduleReconnect();
53
60
  }
54
61
  }
55
62
 
56
63
  private async connectRestSse(): Promise<void> {
64
+ // Host without http.token allows unauthenticated SSE (authenticateHttp
65
+ // returns full when TokenRegistry is empty). Still open the stream so
66
+ // local dev Console receives hmr:reload / message.receive broadcasts.
57
67
  const token = getStoredToken();
58
- if (!token) {
59
- this.setState(ConnectionState.DISCONNECTED);
60
- this.notifyConnection(false);
61
- return;
62
- }
63
68
  this.setState(ConnectionState.CONNECTING);
64
69
  this.sseAbort?.abort();
65
70
  this.sseAbort = new AbortController();
66
71
  try {
72
+ const headers: Record<string, string> = {
73
+ Accept: "text/event-stream",
74
+ };
75
+ if (token) headers.Authorization = `Bearer ${token}`;
67
76
  const res = await fetch(resolveApiUrl("/api/events"), {
68
- headers: {
69
- Authorization: `Bearer ${token}`,
70
- Accept: "text/event-stream",
71
- },
77
+ headers,
72
78
  signal: this.sseAbort.signal,
73
79
  });
74
80
  if (!res.ok || !res.body) {
@@ -81,9 +87,13 @@ export class WebSocketManager {
81
87
  void this.pumpSse(res.body);
82
88
  } catch (error) {
83
89
  if ((error as Error).name === "AbortError") return;
84
- this.handleConnectionError(
85
- error instanceof ConnectionError ? error : new ConnectionError("SSE connect failed", error as Error),
86
- );
90
+ // Must set RECONNECTING (not ERROR) before scheduleReconnect — the timer
91
+ // only fires when state === RECONNECTING; handleConnectionError(ERROR)
92
+ // previously deadlocked reconnect after any transient SSE failure.
93
+ this.callbacks.onError?.(error as unknown as Event);
94
+ console.error("[Console transport] SSE connect error:", error);
95
+ this.setState(ConnectionState.RECONNECTING);
96
+ this.notifyConnection(false);
87
97
  this.scheduleReconnect();
88
98
  }
89
99
  }
@@ -104,7 +114,9 @@ export class WebSocketManager {
104
114
  if (!line) continue;
105
115
  const json = line.slice(6);
106
116
  try {
107
- const message = JSON.parse(json) as WebSocketMessage;
117
+ const message = normalizeConsolePushMessage(
118
+ JSON.parse(json) as WebSocketMessage,
119
+ ) as WebSocketMessage;
108
120
  void applyConsoleEvent(message);
109
121
  this.handleBroadcast(message);
110
122
  this.callbacks.onMessage?.(message);
@@ -174,24 +186,23 @@ export class WebSocketManager {
174
186
  }
175
187
 
176
188
  private async sendRestRequest<T>(message: unknown): Promise<T> {
189
+ // Host may run without http.token (local smoke). Only require a token when
190
+ // one is configured client-side; otherwise POST without Authorization and
191
+ // let the Host accept (TokenRegistry empty → full scope).
177
192
  const token = getStoredToken();
178
- if (!token) throw new WebSocketError("Not authenticated", "NOT_CONNECTED");
179
193
  const requestId = ++this.requestId;
180
194
  const body = { ...(message as Record<string, unknown>), requestId };
181
- const timer = setTimeout(() => {
182
- /* handled below */
183
- }, this.config.requestTimeout);
184
195
  try {
196
+ const headers: Record<string, string> = {
197
+ "Content-Type": "application/json",
198
+ };
199
+ if (token) headers.Authorization = `Bearer ${token}`;
185
200
  const res = await fetch(resolveApiUrl("/api/console/request"), {
186
201
  method: "POST",
187
- headers: {
188
- Authorization: `Bearer ${token}`,
189
- "Content-Type": "application/json",
190
- },
202
+ headers,
191
203
  body: JSON.stringify(body),
192
204
  signal: AbortSignal.timeout(this.config.requestTimeout),
193
205
  });
194
- clearTimeout(timer);
195
206
  const json = (await res.json()) as {
196
207
  success?: boolean;
197
208
  data?: T;
@@ -203,7 +214,6 @@ export class WebSocketManager {
203
214
  }
204
215
  return json.data as T;
205
216
  } catch (error) {
206
- clearTimeout(timer);
207
217
  if (error instanceof WebSocketError) throw error;
208
218
  throw new MessageError("REST request failed", error as Error);
209
219
  }
@@ -325,7 +335,9 @@ export class WebSocketManager {
325
335
 
326
336
  private handleMessage(event: MessageEvent): void {
327
337
  try {
328
- const message = JSON.parse(event.data) as WebSocketMessage;
338
+ const message = normalizeConsolePushMessage(
339
+ JSON.parse(event.data) as WebSocketMessage,
340
+ ) as WebSocketMessage;
329
341
  if (message.requestId && this.pendingRequests.has(message.requestId)) {
330
342
  this.handleRequestResponse(message);
331
343
  return;
@@ -340,7 +352,11 @@ export class WebSocketManager {
340
352
 
341
353
  private handleBroadcast(message: WebSocketMessage): void {
342
354
  const t = message.type;
343
- if (t === "request.receive" || t === "notice.receive" || t === "message.receive") {
355
+ if (
356
+ t === SIDE_EVENT_PUSH.REQUEST_RECEIVE
357
+ || t === SIDE_EVENT_PUSH.NOTICE_RECEIVE
358
+ || t === SIDE_EVENT_PUSH.MESSAGE_RECEIVE
359
+ ) {
344
360
  if (typeof window !== "undefined") {
345
361
  window.dispatchEvent(new CustomEvent("zhin-console-bot-push", { detail: message }));
346
362
  }
@@ -381,8 +397,10 @@ export class WebSocketManager {
381
397
  }
382
398
 
383
399
  private handleConnectionError(error: Error): void {
384
- this.clearReconnectTimer();
385
- this.setState(ConnectionState.ERROR);
400
+ // Used by the legacy WS path. Do NOT clear the reconnect timer here —
401
+ // callers that still want to retry should set RECONNECTING then call
402
+ // scheduleReconnect(). Terminal failures go through scheduleReconnect's
403
+ // maxAttempts branch which sets ERROR.
386
404
  console.error("[Console transport] Connection error:", error);
387
405
  this.callbacks.onError?.(error as unknown as Event);
388
406
  }
@@ -390,12 +408,23 @@ export class WebSocketManager {
390
408
  private scheduleReconnect(): void {
391
409
  if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
392
410
  this.setState(ConnectionState.ERROR);
411
+ this.notifyConnection(false);
393
412
  return;
394
413
  }
395
414
  this.reconnectAttempts++;
415
+ // Keep / restore RECONNECTING so the timer callback's state guard passes.
416
+ if (this.state !== ConnectionState.RECONNECTING) {
417
+ this.setState(ConnectionState.RECONNECTING);
418
+ }
396
419
  const delay = this.config.reconnectInterval * this.reconnectAttempts;
420
+ this.clearReconnectTimer();
397
421
  this.reconnectTimer = setTimeout(() => {
398
- if (this.state === ConnectionState.RECONNECTING) this.connect();
422
+ if (
423
+ this.state === ConnectionState.RECONNECTING
424
+ || this.state === ConnectionState.DISCONNECTED
425
+ ) {
426
+ this.connect();
427
+ }
399
428
  }, delay);
400
429
  }
401
430
 
@@ -15,7 +15,19 @@ export function setApiBase(base: string): void {
15
15
  }
16
16
 
17
17
  export function getStoredToken(): string | null {
18
- return getRuntimeToken() ?? localStorage.getItem(TOKEN_KEY);
18
+ const runtime = getRuntimeToken();
19
+ if (runtime) return runtime;
20
+ if (typeof localStorage !== "undefined") {
21
+ const local = localStorage.getItem(TOKEN_KEY)?.trim();
22
+ if (local) return local;
23
+ }
24
+ // Some login flows only persist to sessionStorage; keep transport in sync
25
+ // with sandbox page / agent-stream which already read both stores.
26
+ if (typeof sessionStorage !== "undefined") {
27
+ const session = sessionStorage.getItem(TOKEN_KEY)?.trim();
28
+ if (session) return session;
29
+ }
30
+ return null;
19
31
  }
20
32
 
21
33
  export function resolveApiUrl(path: string): string {
@@ -21,6 +21,15 @@ export type CreatePluginRegisterHostApiOptions = {
21
21
  export declare function createPluginRegisterHostApi(options: CreatePluginRegisterHostApiOptions): PluginRegisterHostApi;
22
22
  export declare function fetchConsoleEntries(options?: FetchConsoleEntriesOptions): Promise<ConsoleEntriesResponse>;
23
23
  export declare function getRegisterFn(mod: Record<string, unknown> | null | undefined): ConsolePluginRegister | null;
24
+ /**
25
+ * Convention pages (ADR 0046) export a React component as `default` + optional `meta`,
26
+ * without a legacy `register(api)`. Synthesize register from entry.route / entry meta
27
+ * so Remote Console can still mount them.
28
+ */
29
+ export declare function resolveEntryRegister(mod: Record<string, unknown> | null | undefined, entry: ConsoleClientEntry & {
30
+ readonly route?: string;
31
+ readonly title?: string;
32
+ }): ConsolePluginRegister | null;
24
33
  export declare function registerConsolePluginsFromEntries(entries: ConsoleClientEntry[], hostApi: PluginRegisterHostApi, onEntryError?: (entry: ConsoleClientEntry, error: unknown) => void, assetOrigin?: string): Promise<void>;
25
34
  export declare function loadConsoleEntries(options: LoadConsoleEntriesOptions): Promise<void>;
26
35
  //# sourceMappingURL=loadConsoleEntries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loadConsoleEntries.d.ts","sourceRoot":"","sources":["../../client/bootstrap/loadConsoleEntries.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,KAAK,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE5K,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,0BAA0B,GAAG;IACnE,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACtC,QAAQ,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC5C,OAAO,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;CAC3C,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,GAC1C,qBAAqB,CAQvB;AAoCD,wBAAsB,mBAAmB,CACvC,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAUjC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,qBAAqB,GAAG,IAAI,CAO3G;AAED,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,kBAAkB,EAAE,EAC7B,OAAO,EAAE,qBAAqB,EAC9B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,EAClE,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1F"}
1
+ {"version":3,"file":"loadConsoleEntries.d.ts","sourceRoot":"","sources":["../../client/bootstrap/loadConsoleEntries.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,KAAK,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG5K,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,0BAA0B,GAAG;IACnE,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACtC,QAAQ,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC5C,OAAO,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;CAC3C,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,GAC1C,qBAAqB,CAQvB;AAoCD,wBAAsB,mBAAmB,CACvC,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAUjC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,qBAAqB,GAAG,IAAI,CAO3G;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC/C,KAAK,EAAE,kBAAkB,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E,qBAAqB,GAAG,IAAI,CA2B9B;AAED,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,kBAAkB,EAAE,EAC7B,OAAO,EAAE,qBAAqB,EAC9B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,EAClE,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1F"}
@@ -65,6 +65,41 @@ export function getRegisterFn(mod) {
65
65
  return d["register"];
66
66
  return null;
67
67
  }
68
+ /**
69
+ * Convention pages (ADR 0046) export a React component as `default` + optional `meta`,
70
+ * without a legacy `register(api)`. Synthesize register from entry.route / entry meta
71
+ * so Remote Console can still mount them.
72
+ */
73
+ export function resolveEntryRegister(mod, entry) {
74
+ const named = getRegisterFn(mod);
75
+ if (named)
76
+ return named;
77
+ if (!mod)
78
+ return null;
79
+ const Component = mod["default"];
80
+ if (typeof Component !== "function" && !(Component && typeof Component === "object")) {
81
+ return null;
82
+ }
83
+ const path = typeof entry.route === "string" && entry.route
84
+ ? entry.route
85
+ : `/${entry.id}`;
86
+ const meta = mod["meta"] && typeof mod["meta"] === "object"
87
+ ? mod["meta"]
88
+ : undefined;
89
+ const name = (typeof meta?.title === "string" && meta.title)
90
+ || (typeof entry.title === "string" && entry.title)
91
+ || entry.meta?.name
92
+ || entry.id;
93
+ return (api) => {
94
+ api.addRoute({
95
+ path,
96
+ name,
97
+ element: api.React.createElement(Component),
98
+ ...(meta?.icon != null ? { icon: meta.icon } : {}),
99
+ meta: { hideInMenu: meta?.hideInNav === true },
100
+ });
101
+ };
102
+ }
68
103
  export async function registerConsolePluginsFromEntries(entries, hostApi, onEntryError, assetOrigin) {
69
104
  if (!entries.length)
70
105
  return;
@@ -72,7 +107,7 @@ export async function registerConsolePluginsFromEntries(entries, hostApi, onEntr
72
107
  try {
73
108
  const specifier = resolvePluginImportUrl(entry.resolvedModule, assetOrigin);
74
109
  const mod = (await import(/* @vite-ignore */ specifier));
75
- const register = getRegisterFn(mod);
110
+ const register = resolveEntryRegister(mod, entry);
76
111
  if (register)
77
112
  await register(hostApi);
78
113
  else
@@ -1 +1 @@
1
- {"version":3,"file":"loadConsoleEntries.js","sourceRoot":"","sources":["../../client/bootstrap/loadConsoleEntries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loadConsoleEntries.js","sourceRoot":"","sources":["../../client/bootstrap/loadConsoleEntries.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"remoteApi.d.ts","sourceRoot":"","sources":["../../client/console-utils/remoteApi.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAExC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,kFAAkF;AAClF,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,QAAQ,CAAC,CAiBnB"}
1
+ {"version":3,"file":"remoteApi.d.ts","sourceRoot":"","sources":["../../client/console-utils/remoteApi.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAYxC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,kFAAkF;AAClF,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,QAAQ,CAAC,CAoBnB"}
@@ -9,7 +9,20 @@ export function getApiBase() {
9
9
  return "";
10
10
  }
11
11
  export function getToken() {
12
- return getRuntimeToken() ?? localStorage.getItem(TOKEN_KEY);
12
+ const runtime = getRuntimeToken();
13
+ if (runtime)
14
+ return runtime;
15
+ if (typeof localStorage !== "undefined") {
16
+ const local = localStorage.getItem(TOKEN_KEY)?.trim();
17
+ if (local)
18
+ return local;
19
+ }
20
+ if (typeof sessionStorage !== "undefined") {
21
+ const session = sessionStorage.getItem(TOKEN_KEY)?.trim();
22
+ if (session)
23
+ return session;
24
+ }
25
+ return null;
13
26
  }
14
27
  export function resolveApiUrl(path) {
15
28
  const base = getApiBase();
@@ -33,6 +46,9 @@ export async function apiFetch(input, init) {
33
46
  : input;
34
47
  const res = await fetch(url, { ...init, headers });
35
48
  if (res.status === 401) {
49
+ // runtime token(Demo 预置)过期后也必须失效,否则 getToken() 永远优先命中它,
50
+ // local/sessionStorage 清理不掉,造成 401 死循环。
51
+ clearRuntimeToken();
36
52
  sessionStorage.removeItem(TOKEN_KEY);
37
53
  localStorage.removeItem(TOKEN_KEY);
38
54
  window.dispatchEvent(new CustomEvent("zhin:auth-required"));
@@ -48,4 +64,9 @@ function getRuntimeToken() {
48
64
  const token = window.__ZHIN_API_TOKEN;
49
65
  return token?.trim() || null;
50
66
  }
67
+ function clearRuntimeToken() {
68
+ if (typeof window === "undefined")
69
+ return;
70
+ delete window.__ZHIN_API_TOKEN;
71
+ }
51
72
  //# sourceMappingURL=remoteApi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"remoteApi.js","sourceRoot":"","sources":["../../client/console-utils/remoteApi.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC;AACnC,MAAM,YAAY,GAAG,eAAe,CAAC;AAErC,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC;IAC1D,IAAI,MAAM;QAAE,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IACjE,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,eAAe,EAAE,IAAI,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IACnD,OAAO,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1D,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAwB,EACxB,IAAkB;IAElB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;IAE3D,MAAM,GAAG,GACP,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAChD,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC;QACtB,CAAC,CAAC,KAAK,CAAC;IAEZ,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACnD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACrC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1D,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,KAAK,GAAI,MAAmD,CAAC,gBAAgB,CAAC;IACpF,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"remoteApi.js","sourceRoot":"","sources":["../../client/console-utils/remoteApi.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./types";
2
+ export { ENDPOINT_RPC, ENDPOINT_MANAGEMENT_CAPABILITIES, INBOX_RPC, SIDE_EVENT_PUSH, SIDE_EVENT_RPC, normalizeConsolePushMessage, normalizeConsolePushType, parseConsoleInboxEvent, type ConsoleInboxEvent, type ConsoleInboxEventKind, type ConsoleEndpointPhase, type ConsoleEndpointSummary, type EndpointManagementCapability, } from "@zhin.js/console-protocol";
2
3
  export { resolveMediaSrc, pickMediaRawUrl, type MediaKind } from "./mediaSrc";
3
4
  export { segmentsForImDelivery, segmentsForAgentPanel } from "./segments.js";
4
5
  export { app, type ConsoleApp, type AddRouteInput, type AddToolInput, type ConsoleRouteRecord, type RouteTreeNode, type ToolTreeNode, type ConsoleRouteRenderer, } from "./app";
@@ -7,7 +8,7 @@ export { configureConsole, getRuntimeEnv } from "./runtime/index.js";
7
8
  export { createRegistryStore, useRegistry, type RegistryStore, } from "./store/createRegistryStore.js";
8
9
  export { cn } from "./console-utils/cn.js";
9
10
  export { apiFetch, getApiBase, getToken, resolveApiUrl, resolveWebSocketUrl, } from "./console-utils/remoteApi.js";
10
- export { fetchConsoleEntries, createPluginRegisterHostApi, getRegisterFn, loadConsoleEntries, registerConsolePluginsFromEntries, type CreatePluginRegisterHostApiOptions, type FetchConsoleEntriesOptions, type LoadConsoleEntriesOptions, } from "./bootstrap/loadConsoleEntries.js";
11
+ export { fetchConsoleEntries, createPluginRegisterHostApi, getRegisterFn, loadConsoleEntries, registerConsolePluginsFromEntries, resolveEntryRegister, type CreatePluginRegisterHostApiOptions, type FetchConsoleEntriesOptions, type LoadConsoleEntriesOptions, } from "./bootstrap/loadConsoleEntries.js";
11
12
  export { registerOrchestrationConsole } from "./orchestration/registerOrchestrationConsole.js";
12
13
  export { default as OrchestrationRunsPage } from "./orchestration/OrchestrationRunsPage.js";
13
14
  export { startAgentSession, continueAgentSession, subscribeAgentStream, iterateAgentStreamNdjson, foldAgentStreamNdjson, type AgentStreamClientOptions, type SubscribeAgentStreamOptions, } from "./agent-stream.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAG9E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EACL,GAAG,EACH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,OAAO,CAAC;AAGf,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,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,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,KAAK,kCAAkC,EACvC,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,GAC/B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAE5F,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":"AACA,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,GAClC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAG9E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EACL,GAAG,EACH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,OAAO,CAAC;AAGf,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,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,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,EACpB,KAAK,kCAAkC,EACvC,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,GAC/B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAE5F,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // Types
2
2
  export * from "./types";
3
+ export { ENDPOINT_RPC, ENDPOINT_MANAGEMENT_CAPABILITIES, INBOX_RPC, SIDE_EVENT_PUSH, SIDE_EVENT_RPC, normalizeConsolePushMessage, normalizeConsolePushType, parseConsoleInboxEvent, } from "@zhin.js/console-protocol";
3
4
  // Media URL resolution
4
5
  export { resolveMediaSrc, pickMediaRawUrl } from "./mediaSrc";
5
6
  // Segment IM visibility (inbox vs agent panel)
@@ -12,7 +13,7 @@ export { configureConsole, getRuntimeEnv } from "./runtime/index.js";
12
13
  export { createRegistryStore, useRegistry, } from "./store/createRegistryStore.js";
13
14
  export { cn } from "./console-utils/cn.js";
14
15
  export { apiFetch, getApiBase, getToken, resolveApiUrl, resolveWebSocketUrl, } from "./console-utils/remoteApi.js";
15
- export { fetchConsoleEntries, createPluginRegisterHostApi, getRegisterFn, loadConsoleEntries, registerConsolePluginsFromEntries, } from "./bootstrap/loadConsoleEntries.js";
16
+ export { fetchConsoleEntries, createPluginRegisterHostApi, getRegisterFn, loadConsoleEntries, registerConsolePluginsFromEntries, resolveEntryRegister, } from "./bootstrap/loadConsoleEntries.js";
16
17
  export { registerOrchestrationConsole } from "./orchestration/registerOrchestrationConsole.js";
17
18
  export { default as OrchestrationRunsPage } from "./orchestration/OrchestrationRunsPage.js";
18
19
  export { startAgentSession, continueAgentSession, subscribeAgentStream, iterateAgentStreamNdjson, foldAgentStreamNdjson, } from "./agent-stream.js";
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;AAExB,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAE9E,+CAA+C;AAC/C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE7E,uDAAuD;AACvD,OAAO,EACL,GAAG,GAQJ,MAAM,OAAO,CAAC;AAEf,iCAAiC;AACjC,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,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,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,GAIlC,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAE5F,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,SAAS,EACT,eAAe,EACf,cAAc,EACd,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,GAMvB,MAAM,2BAA2B,CAAC;AAEnC,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAE9E,+CAA+C;AAC/C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE7E,uDAAuD;AACvD,OAAO,EACL,GAAG,GAQJ,MAAM,OAAO,CAAC;AAEf,iCAAiC;AACjC,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,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,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,GAIrB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAE5F,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,GAGtB,MAAM,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mediaSrc.d.ts","sourceRoot":"","sources":["../client/mediaSrc.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAInD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAC9B,IAAI,GAAE,SAAmB,GACxB,MAAM,GAAG,SAAS,CAyBpB;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAS7F"}
1
+ {"version":3,"file":"mediaSrc.d.ts","sourceRoot":"","sources":["../client/mediaSrc.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAInD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAC9B,IAAI,GAAE,SAAmB,GACxB,MAAM,GAAG,SAAS,CAyBpB;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAwB7F"}
package/dist/mediaSrc.js CHANGED
@@ -43,6 +43,22 @@ export function pickMediaRawUrl(data) {
43
43
  return value.trim();
44
44
  }
45
45
  const v = data.url ?? data.file ?? data.src ?? data.href;
46
- return typeof v === 'string' && v.trim() ? v.trim() : undefined;
46
+ if (typeof v === 'string' && v.trim())
47
+ return v.trim();
48
+ // agent 出站媒体段(media-publisher)直接携带纯 base64,无 url/file;
49
+ // 有 mime 时拼成 data: URL 透传,否则走 base64:// 让 resolveMediaSrc 按 kind 补默认 MIME
50
+ const b64 = data.base64;
51
+ if (typeof b64 === 'string' && b64.trim()) {
52
+ const payload = b64.trim();
53
+ if (payload.startsWith('data:') || payload.startsWith('base64://')
54
+ || payload.startsWith('http://') || payload.startsWith('https://')) {
55
+ return payload;
56
+ }
57
+ const mime = typeof data.mime === 'string' && data.mime.trim() ? data.mime.trim() : '';
58
+ return mime
59
+ ? `data:${mime};base64,${payload.replace(/\s/g, '')}`
60
+ : `base64://${payload}`;
61
+ }
62
+ return undefined;
47
63
  }
48
64
  //# sourceMappingURL=mediaSrc.js.map