@xenosystem/agent-interface-panel 0.1.48 → 0.1.50
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/package.json +5 -5
- package/dist/index.d.ts +0 -116
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -232
- package/dist/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/agent-interface-panel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.50",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@xenosystem/panel-agent": "^0.1.0",
|
|
27
|
-
"@xenosystem/agent-conversation": "0.1.
|
|
28
|
-
"@xenosystem/agent-interface-client": "0.1.
|
|
29
|
-
"@xenosystem/agent-interface-embed": "0.1.
|
|
30
|
-
"@xenosystem/agent-interface-contract": "0.1.
|
|
27
|
+
"@xenosystem/agent-conversation": "0.1.50",
|
|
28
|
+
"@xenosystem/agent-interface-client": "0.1.50",
|
|
29
|
+
"@xenosystem/agent-interface-embed": "0.1.50",
|
|
30
|
+
"@xenosystem/agent-interface-contract": "0.1.50"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@xenosystem/panel-sdk": "^1.1.0",
|
package/dist/index.d.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `@xenosystem/agent-interface-panel` — the XENO Agent panel that renders the REAL interface.
|
|
3
|
-
*
|
|
4
|
-
* ONE agent surface, mounted wherever a XENO Panel host can put a tile: xeno-apps, Pixel,
|
|
5
|
-
* Motion, Canvas. Update the interface once and every host that mounts this panel gets it,
|
|
6
|
-
* because there is nothing here to keep in sync — this package contributes a mount, not a UI.
|
|
7
|
-
*
|
|
8
|
-
* ## What this is, precisely
|
|
9
|
-
*
|
|
10
|
-
* `@xenosystem/panel-agent` (xeno-core) is the GENERIC half: manifest, controller, projections,
|
|
11
|
-
* wiring, diff parsing, host-event translation. It depends on no product, which is why it lives
|
|
12
|
-
* in core, and it ships a deliberately minimal default view whose own docblock says what is not
|
|
13
|
-
* in it — no transcript, no tool timeline, no diff, no terminal.
|
|
14
|
-
*
|
|
15
|
-
* This package is the PRODUCT half. It supplies the view, and the view is the shipping XENO Agent
|
|
16
|
-
* interface itself, mounted through `@xenosystem/agent-interface-embed`.
|
|
17
|
-
*
|
|
18
|
-
* 🔴 **It renders the real interface rather than reproducing it, and that is the whole point.**
|
|
19
|
-
* `XENO AGENT PANEL - SPEC.md` D7d refuses a port: three agent UIs already exist because each
|
|
20
|
-
* began as a reasonable copy, and a fourth would drift from the day it was written. The
|
|
21
|
-
* conversation view is ~11.5k lines bound to six stores with no tests — reproducing it is not a
|
|
22
|
-
* task, it is a second product to maintain.
|
|
23
|
-
*
|
|
24
|
-
* ## What a host must supply
|
|
25
|
-
*
|
|
26
|
-
* 1. An `AgentHostClient` whose `surface` is `'panel-embed'`. The embed layer refuses a client
|
|
27
|
-
* whose surface disagrees with the mount, deliberately — a surface that lies about which kind
|
|
28
|
-
* it is gets the wrong chrome and the wrong lifecycle.
|
|
29
|
-
* 2. A platform bridge, installed before mount. The interface reads its data from the bridge, not
|
|
30
|
-
* from props, exactly as it does under `hub-embed`.
|
|
31
|
-
*
|
|
32
|
-
* ⚠️ **Known limit, stated rather than hidden.** The mounted interface holds its own connection to
|
|
33
|
-
* the agent host. The panel's input ports still carry status and intents for host wiring, but they
|
|
34
|
-
* are not yet the interface's source of truth — D7c's "the panel OWNS the conversation" is only
|
|
35
|
-
* half done here. Closing it needs the interface to accept an injected session source, which does
|
|
36
|
-
* not exist today. Until it does, a host should treat this panel as the interface in a tile, and
|
|
37
|
-
* not wire a second conversation into it and expect them to agree.
|
|
38
|
-
*
|
|
39
|
-
* @packageDocumentation
|
|
40
|
-
*/
|
|
41
|
-
import type { PanelModule } from '@xenosystem/panel-sdk';
|
|
42
|
-
import type { AgentHostClient } from '@xenosystem/agent-interface-client';
|
|
43
|
-
import { type XenoAgentConversationProps } from '@xenosystem/agent-conversation';
|
|
44
|
-
/**
|
|
45
|
-
* The platform bridge, structurally. Deliberately not `XenoAPI`: a panel host implements the
|
|
46
|
-
* capabilities the interface reaches and refuses the rest by name, so demanding the full type
|
|
47
|
-
* here would put back exactly the barrier this panel exists to remove.
|
|
48
|
-
*/
|
|
49
|
-
export type AgentPlatformBridgeLike = object;
|
|
50
|
-
/**
|
|
51
|
-
* Options for {@link createXenoAgentInterfacePanel} — supply EITHER a client or a bridge.
|
|
52
|
-
*
|
|
53
|
-
* 🔴 **Two mount modes, because hosts differ in a way that is a security boundary, not a
|
|
54
|
-
* preference.**
|
|
55
|
-
*
|
|
56
|
-
* | mode | supply | for |
|
|
57
|
-
* |---|---|---|
|
|
58
|
-
* | **client** | `createClient` | a host that already holds an `AgentHostClient` — Hub, Shell, the Agent app |
|
|
59
|
-
* | **bridge** | `createBridge` | a PANEL host, which does not and must not |
|
|
60
|
-
*
|
|
61
|
-
* `AgentHostClient` takes a `transport` with a generic `request(method, input)`, so supplying one
|
|
62
|
-
* means the renderer can invoke ANY of the 141 host methods — `workspace.file.write`,
|
|
63
|
-
* `workspace.command.run`, every `workspace.pty.*` verb. That is fine in the Agent app, whose
|
|
64
|
-
* renderer is its own. It is not fine in a panel host, whose renderer runs user-authored panels.
|
|
65
|
-
* `xeno-apps`'s preload says so in its own words: the asymmetry "is the whole security design".
|
|
66
|
-
*
|
|
67
|
-
* ⚠️ The bridge mode exists because it was MEASURED to be sufficient, not assumed. Mounting the
|
|
68
|
-
* real interface against a recording bridge showed it reaches `workspace`, `agentContext` and
|
|
69
|
-
* `subagents` — platform-bridge members, not client methods — and it renders from a bridge alone.
|
|
70
|
-
* The client is the embed lifecycle; the component reads the bridge.
|
|
71
|
-
*/
|
|
72
|
-
export interface CreateXenoAgentInterfacePanelOptions {
|
|
73
|
-
/**
|
|
74
|
-
* Which conversation this panel opens, and how it behaves.
|
|
75
|
-
*
|
|
76
|
-
* Omitted, it opens the same personal assistant the full interface shows — from the same
|
|
77
|
-
* constants, so the panel and the desktop app open the SAME conversation rather than two that
|
|
78
|
-
* merely look alike.
|
|
79
|
-
*
|
|
80
|
-
* ⚠️ Merged OVER the defaults, so a host overrides one field without restating the rest. A host
|
|
81
|
-
* that wants a specific conversation passes `conversationId`; one embedding a project agent
|
|
82
|
-
* passes `agentId`/`agentName`/`model`.
|
|
83
|
-
*/
|
|
84
|
-
conversation?: Partial<XenoAgentConversationProps>;
|
|
85
|
-
/**
|
|
86
|
-
* Build the client this panel mounts against — the EMBED path.
|
|
87
|
-
*
|
|
88
|
-
* 🔴 A FACTORY, not a client. A panel can be mounted more than once in one layout and can be
|
|
89
|
-
* closed and reopened without the host restarting; sharing a single client across those
|
|
90
|
-
* lifetimes means the second mount inherits the first one's teardown. One mount, one client.
|
|
91
|
-
*
|
|
92
|
-
* The client's `surface` must be `'panel-embed'` or the embed layer refuses the mount.
|
|
93
|
-
*/
|
|
94
|
-
createClient?: () => AgentHostClient | Promise<AgentHostClient>;
|
|
95
|
-
/**
|
|
96
|
-
* Build the platform bridge this panel mounts against — the PANEL path, and the one a panel host
|
|
97
|
-
* should use.
|
|
98
|
-
*
|
|
99
|
-
* A factory for the same reason `createClient` is one. Returning `null` means this surface has no
|
|
100
|
-
* agent host, which is the ordinary state of a machine: the panel renders its own empty state
|
|
101
|
-
* rather than the host failing to start.
|
|
102
|
-
*/
|
|
103
|
-
createBridge?: () => AgentPlatformBridgeLike | null | Promise<AgentPlatformBridgeLike | null>;
|
|
104
|
-
/** Called when a mount fails, so a host can surface it rather than showing an empty tile. */
|
|
105
|
-
onError?: (error: unknown) => void;
|
|
106
|
-
}
|
|
107
|
-
/** The surface kind this panel mounts as. */
|
|
108
|
-
export declare const AGENT_PANEL_SURFACE: "panel-embed";
|
|
109
|
-
/**
|
|
110
|
-
* Build the panel module: the generic agent panel, rendered by the real XENO Agent interface.
|
|
111
|
-
*
|
|
112
|
-
* @param options - How to build a client, and where to report a failed mount.
|
|
113
|
-
* @returns A `PanelModule` any XENO Panel host can register.
|
|
114
|
-
*/
|
|
115
|
-
export declare function createXenoAgentInterfacePanel(options: CreateXenoAgentInterfacePanelOptions): PanelModule;
|
|
116
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAA;AASzE,OAAO,EAML,KAAK,0BAA0B,EAChC,MAAM,gCAAgC,CAAA;AAGvC;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAA;AA8D5C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,oCAAoC;IACnD;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAA;IAClD;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC/D;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,uBAAuB,GAAG,IAAI,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAA;IAC7F,6FAA6F;IAC7F,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACnC;AAiBD,6CAA6C;AAC7C,eAAO,MAAM,mBAAmB,EAAG,aAAsB,CAAA;AAEzD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,oCAAoC,GAC5C,WAAW,CAiGb"}
|
package/dist/index.js
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `@xenosystem/agent-interface-panel` — the XENO Agent panel that renders the REAL interface.
|
|
3
|
-
*
|
|
4
|
-
* ONE agent surface, mounted wherever a XENO Panel host can put a tile: xeno-apps, Pixel,
|
|
5
|
-
* Motion, Canvas. Update the interface once and every host that mounts this panel gets it,
|
|
6
|
-
* because there is nothing here to keep in sync — this package contributes a mount, not a UI.
|
|
7
|
-
*
|
|
8
|
-
* ## What this is, precisely
|
|
9
|
-
*
|
|
10
|
-
* `@xenosystem/panel-agent` (xeno-core) is the GENERIC half: manifest, controller, projections,
|
|
11
|
-
* wiring, diff parsing, host-event translation. It depends on no product, which is why it lives
|
|
12
|
-
* in core, and it ships a deliberately minimal default view whose own docblock says what is not
|
|
13
|
-
* in it — no transcript, no tool timeline, no diff, no terminal.
|
|
14
|
-
*
|
|
15
|
-
* This package is the PRODUCT half. It supplies the view, and the view is the shipping XENO Agent
|
|
16
|
-
* interface itself, mounted through `@xenosystem/agent-interface-embed`.
|
|
17
|
-
*
|
|
18
|
-
* 🔴 **It renders the real interface rather than reproducing it, and that is the whole point.**
|
|
19
|
-
* `XENO AGENT PANEL - SPEC.md` D7d refuses a port: three agent UIs already exist because each
|
|
20
|
-
* began as a reasonable copy, and a fourth would drift from the day it was written. The
|
|
21
|
-
* conversation view is ~11.5k lines bound to six stores with no tests — reproducing it is not a
|
|
22
|
-
* task, it is a second product to maintain.
|
|
23
|
-
*
|
|
24
|
-
* ## What a host must supply
|
|
25
|
-
*
|
|
26
|
-
* 1. An `AgentHostClient` whose `surface` is `'panel-embed'`. The embed layer refuses a client
|
|
27
|
-
* whose surface disagrees with the mount, deliberately — a surface that lies about which kind
|
|
28
|
-
* it is gets the wrong chrome and the wrong lifecycle.
|
|
29
|
-
* 2. A platform bridge, installed before mount. The interface reads its data from the bridge, not
|
|
30
|
-
* from props, exactly as it does under `hub-embed`.
|
|
31
|
-
*
|
|
32
|
-
* ⚠️ **Known limit, stated rather than hidden.** The mounted interface holds its own connection to
|
|
33
|
-
* the agent host. The panel's input ports still carry status and intents for host wiring, but they
|
|
34
|
-
* are not yet the interface's source of truth — D7c's "the panel OWNS the conversation" is only
|
|
35
|
-
* half done here. Closing it needs the interface to accept an injected session source, which does
|
|
36
|
-
* not exist today. Until it does, a host should treat this panel as the interface in a tile, and
|
|
37
|
-
* not wire a second conversation into it and expect them to agree.
|
|
38
|
-
*
|
|
39
|
-
* @packageDocumentation
|
|
40
|
-
*/
|
|
41
|
-
import { createElement, useCallback, useEffect, useState } from 'react';
|
|
42
|
-
import { createRoot } from 'react-dom/client';
|
|
43
|
-
import { createAgentPanel } from '@xenosystem/panel-agent';
|
|
44
|
-
import { mountXenoAgentInterface } from '@xenosystem/agent-interface-embed';
|
|
45
|
-
/*
|
|
46
|
-
* 🔴 The conversation comes from its OWN package, not through the shell.
|
|
47
|
-
*
|
|
48
|
-
* That is the inversion this panel exists for. While the conversation lived inside
|
|
49
|
-
* `agent-interface-ui`, the shell was the canonical thing and this was a wrapper around it —
|
|
50
|
-
* improving the panel reached nobody, because nothing downstream depended on it. Now the shell and
|
|
51
|
-
* this panel are peers that render the same conversation.
|
|
52
|
-
*/
|
|
53
|
-
import { MAIN_ASSISTANT_ID, MAIN_ASSISTANT_MODEL, MAIN_ASSISTANT_NAME, XenoAgentConversation, configureAgentPlatformBridge, } from '@xenosystem/agent-conversation';
|
|
54
|
-
import { disposeHubAgentCatalogClient } from '@xenosystem/agent-conversation/adapters/xenoAgentHostCatalog';
|
|
55
|
-
/**
|
|
56
|
-
* What this panel actually renders: the CONVERSATION, not the shell around it.
|
|
57
|
-
*
|
|
58
|
-
* 🔴 Until now both mount paths rendered `XenoAgentInterface` — the whole desktop shell, with its
|
|
59
|
-
* session sidebar, its tab header and its editor/browser split. Dropped into a host that owns its
|
|
60
|
-
* own window that is an application inside a panel: a second sidebar beside the host's, a second
|
|
61
|
-
* tab strip, and two things competing to decide what "the current session" means.
|
|
62
|
-
*
|
|
63
|
-
* The panel is the conversation — the transcript and the composer and the logic behind them — and
|
|
64
|
-
* nothing else. The host supplies the surrounding chrome, because the host already has some.
|
|
65
|
-
*/
|
|
66
|
-
const AgentConversationComponent = XenoAgentConversation;
|
|
67
|
-
/**
|
|
68
|
-
* The panel OWNS which conversation it shows.
|
|
69
|
-
*
|
|
70
|
-
* 🔴 It used to render the conversation once, with fixed props and no `onNavigateConversation`, so every
|
|
71
|
-
* way the conversation moves somewhere else was dead inside a panel host: "New chat" never rendered,
|
|
72
|
-
* opening a delegated sub-agent from the dock's tray did nothing, and a sub-agent's "Back to parent
|
|
73
|
-
* agent" never appeared. The Turn Modes Bench measurement found it — its chat frame has a New chat
|
|
74
|
-
* action the panel could not draw. Now the panel keeps the current conversation as state, moves itself,
|
|
75
|
-
* and still tells a host that wants to know.
|
|
76
|
-
*/
|
|
77
|
-
function PanelConversation(props) {
|
|
78
|
-
const { conversationId: named, onNavigateConversation, onConversationCreated } = props;
|
|
79
|
-
const [conversationId, setConversationId] = useState(named);
|
|
80
|
-
// a host that names a DIFFERENT conversation later still wins
|
|
81
|
-
useEffect(() => { if (named !== undefined)
|
|
82
|
-
setConversationId(named); }, [named]);
|
|
83
|
-
const navigate = useCallback((id) => { setConversationId(id); onNavigateConversation?.(id); }, [onNavigateConversation]);
|
|
84
|
-
// a conversation the view creates for itself becomes the panel's current one
|
|
85
|
-
const created = useCallback((id) => { setConversationId(id); onConversationCreated?.(id); }, [onConversationCreated]);
|
|
86
|
-
return createElement(AgentConversationComponent, {
|
|
87
|
-
...props,
|
|
88
|
-
// omitted rather than `undefined` while no conversation is named or created yet
|
|
89
|
-
...(conversationId !== undefined ? { conversationId } : {}),
|
|
90
|
-
onNavigateConversation: navigate,
|
|
91
|
-
onConversationCreated: created,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* The conversation this panel opens when the host does not name one.
|
|
96
|
-
*
|
|
97
|
-
* Identical to what the full interface shows for the personal inbox, from the same constants —
|
|
98
|
-
* so a panel and the desktop app open the SAME conversation rather than two that merely look
|
|
99
|
-
* alike. Inventing an agent id here is how those quietly diverge.
|
|
100
|
-
*/
|
|
101
|
-
function defaultConversationProps() {
|
|
102
|
-
return {
|
|
103
|
-
agentId: MAIN_ASSISTANT_ID,
|
|
104
|
-
agentName: MAIN_ASSISTANT_NAME,
|
|
105
|
-
model: MAIN_ASSISTANT_MODEL,
|
|
106
|
-
isMainAssistant: true,
|
|
107
|
-
capabilities: { terminal: true, fileRead: true, fileWrite: true, appLaunch: true },
|
|
108
|
-
permissionProfile: 'standard',
|
|
109
|
-
// A host chrome draws its own workbench; the conversation must not draw a second one.
|
|
110
|
-
renderWorkbenchPanel: false,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* The conversation fills the tile it is given. Its root (`.xa-app`) is `flex: 1; min-height: 0`
|
|
115
|
-
* inside a flex COLUMN — the bench's frame — so mounted into a plain block element it sizes to
|
|
116
|
-
* its content and the dock floats mid-tile with dead space beneath (Canvas, 2026-09-17). The
|
|
117
|
-
* mount element is the panel's to shape: every host hands over a box, none of them know the
|
|
118
|
-
* conversation's layout contract, and this is the one place that does.
|
|
119
|
-
*/
|
|
120
|
-
function fillTile(el) {
|
|
121
|
-
// the tile's SIZE stays the host's (a fixed box, a flex item, a grid cell); only its inside
|
|
122
|
-
// becomes the column the conversation's root expects
|
|
123
|
-
el.style.display = 'flex';
|
|
124
|
-
el.style.flexDirection = 'column';
|
|
125
|
-
el.style.minHeight = '0';
|
|
126
|
-
}
|
|
127
|
-
/** The surface kind this panel mounts as. */
|
|
128
|
-
export const AGENT_PANEL_SURFACE = 'panel-embed';
|
|
129
|
-
/**
|
|
130
|
-
* Build the panel module: the generic agent panel, rendered by the real XENO Agent interface.
|
|
131
|
-
*
|
|
132
|
-
* @param options - How to build a client, and where to report a failed mount.
|
|
133
|
-
* @returns A `PanelModule` any XENO Panel host can register.
|
|
134
|
-
*/
|
|
135
|
-
export function createXenoAgentInterfacePanel(options) {
|
|
136
|
-
return createAgentPanel({
|
|
137
|
-
render(el) {
|
|
138
|
-
let handle = null;
|
|
139
|
-
let root = null;
|
|
140
|
-
/* Restores whatever bridge was installed before this mount — a panel can be mounted twice. */
|
|
141
|
-
let restoreBridge = null;
|
|
142
|
-
/*
|
|
143
|
-
* 🔴 Disposal can be requested BEFORE the mount resolves, and a panel closed during its own
|
|
144
|
-
* startup is an ordinary thing in a dockable layout — drag a tile away while it is opening.
|
|
145
|
-
* Without this flag the late `.then` mounts into a container the host has already discarded
|
|
146
|
-
* and nothing ever unmounts it, which is the leak `panel-template` records for this shape.
|
|
147
|
-
*/
|
|
148
|
-
let disposed = false;
|
|
149
|
-
void (async () => {
|
|
150
|
-
try {
|
|
151
|
-
/*
|
|
152
|
-
* The BRIDGE path first, because it is the one a panel host should take: configure the
|
|
153
|
-
* platform bridge and render the interface directly. No AgentHostClient, so no generic
|
|
154
|
-
* `request(method, input)`, so the host never has to widen its renderer's authority to
|
|
155
|
-
* all 141 host methods in order to draw a panel.
|
|
156
|
-
*/
|
|
157
|
-
if (options.createBridge) {
|
|
158
|
-
const bridge = await options.createBridge();
|
|
159
|
-
if (disposed)
|
|
160
|
-
return;
|
|
161
|
-
if (!bridge) {
|
|
162
|
-
// No agent host on this machine — the ordinary state. The panel shows its own empty
|
|
163
|
-
// state rather than the host treating a missing optional agent as a failure.
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
restoreBridge = configureAgentPlatformBridge(bridge);
|
|
167
|
-
fillTile(el);
|
|
168
|
-
root = createRoot(el);
|
|
169
|
-
root.render(createElement(PanelConversation, {
|
|
170
|
-
...defaultConversationProps(),
|
|
171
|
-
...options.conversation,
|
|
172
|
-
}));
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
if (!options.createClient) {
|
|
176
|
-
throw new Error('createXenoAgentInterfacePanel needs either createBridge or createClient.');
|
|
177
|
-
}
|
|
178
|
-
const client = await options.createClient();
|
|
179
|
-
const mounted = await mountXenoAgentInterface(el, {
|
|
180
|
-
surface: AGENT_PANEL_SURFACE,
|
|
181
|
-
client,
|
|
182
|
-
renderer: {
|
|
183
|
-
mount(container) {
|
|
184
|
-
/*
|
|
185
|
-
* Mounted HERE, inside this package, so `react` and `react-dom` resolve to one
|
|
186
|
-
* copy. A host that calls `createRoot` on a view imported across a package
|
|
187
|
-
* boundary can end up with two Reacts, and every hook throws "Invalid hook call".
|
|
188
|
-
*/
|
|
189
|
-
fillTile(container);
|
|
190
|
-
root = createRoot(container);
|
|
191
|
-
root.render(createElement(PanelConversation, {
|
|
192
|
-
...defaultConversationProps(),
|
|
193
|
-
...options.conversation,
|
|
194
|
-
}));
|
|
195
|
-
},
|
|
196
|
-
unmount() {
|
|
197
|
-
root?.unmount();
|
|
198
|
-
root = null;
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
if (disposed) {
|
|
203
|
-
await mounted.unmount();
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
handle = mounted;
|
|
207
|
-
}
|
|
208
|
-
catch (error) {
|
|
209
|
-
options.onError?.(error);
|
|
210
|
-
}
|
|
211
|
-
})();
|
|
212
|
-
return () => {
|
|
213
|
-
disposed = true;
|
|
214
|
-
void handle?.unmount();
|
|
215
|
-
handle = null;
|
|
216
|
-
root?.unmount();
|
|
217
|
-
root = null;
|
|
218
|
-
/*
|
|
219
|
-
* The conversation's catalog adapter keeps ONE module-level host client, built from the
|
|
220
|
-
* bridge on first use. It must go with the mount: a host disposes its bridge right after
|
|
221
|
-
* this, and a client left behind would serve the NEXT mount from a dead transport —
|
|
222
|
-
* close and reopen the tab and the catalog never loads again. `disposeHubAgentCatalogClient`
|
|
223
|
-
* existed for exactly this and was called by nothing (2026-09-17).
|
|
224
|
-
*/
|
|
225
|
-
disposeHubAgentCatalogClient();
|
|
226
|
-
restoreBridge?.();
|
|
227
|
-
restoreBridge = null;
|
|
228
|
-
};
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|