@ggui-ai/mcp-server 0.2.0-alpha.4 → 0.4.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin-blueprints-transport.d.ts.map +1 -1
- package/dist/admin-blueprints-transport.js +2 -1
- package/dist/admin-oauth-providers-transport.d.ts.map +1 -1
- package/dist/admin-oauth-providers-transport.js +7 -5
- package/dist/api-renders-routes.d.ts +85 -0
- package/dist/api-renders-routes.d.ts.map +1 -0
- package/dist/api-renders-routes.js +372 -0
- package/dist/build-mcp.d.ts +2 -2
- package/dist/build-mcp.d.ts.map +1 -1
- package/dist/build-mcp.js +64 -5
- package/dist/code-routes.d.ts +47 -0
- package/dist/code-routes.d.ts.map +1 -0
- package/dist/code-routes.js +81 -0
- package/dist/code-store-fs.js +2 -2
- package/dist/console-auth.d.ts +10 -10
- package/dist/console-auth.d.ts.map +1 -1
- package/dist/console-auth.js +5 -5
- package/dist/console-blueprint-routes.d.ts +71 -0
- package/dist/console-blueprint-routes.d.ts.map +1 -0
- package/dist/console-blueprint-routes.js +348 -0
- package/dist/console-chat-routes.d.ts +80 -0
- package/dist/console-chat-routes.d.ts.map +1 -0
- package/dist/console-chat-routes.js +204 -0
- package/dist/console-config-routes.d.ts +37 -0
- package/dist/console-config-routes.d.ts.map +1 -0
- package/dist/console-config-routes.js +91 -0
- package/dist/console-headers.d.ts +1 -1
- package/dist/console-info-routes.d.ts +84 -0
- package/dist/console-info-routes.d.ts.map +1 -0
- package/dist/console-info-routes.js +135 -0
- package/dist/console-keys-routes.d.ts +50 -0
- package/dist/console-keys-routes.d.ts.map +1 -0
- package/dist/console-keys-routes.js +222 -0
- package/dist/console-llm-keys-routes.d.ts +47 -0
- package/dist/console-llm-keys-routes.d.ts.map +1 -0
- package/dist/console-llm-keys-routes.js +443 -0
- package/dist/console-mcp-tools-routes.d.ts +41 -0
- package/dist/console-mcp-tools-routes.d.ts.map +1 -0
- package/dist/console-mcp-tools-routes.js +60 -0
- package/dist/console-registry-routes.d.ts +66 -0
- package/dist/console-registry-routes.d.ts.map +1 -0
- package/dist/console-registry-routes.js +276 -0
- package/dist/console-session-routes.d.ts +89 -0
- package/dist/console-session-routes.d.ts.map +1 -0
- package/dist/console-session-routes.js +385 -0
- package/dist/console-sessions-routes.d.ts +52 -0
- package/dist/console-sessions-routes.d.ts.map +1 -0
- package/dist/console-sessions-routes.js +106 -0
- package/dist/console-static-routes.d.ts +54 -0
- package/dist/console-static-routes.d.ts.map +1 -0
- package/dist/console-static-routes.js +190 -0
- package/dist/console-theme-routes.d.ts +3 -3
- package/dist/console-theme-routes.js +1 -1
- package/dist/console-timeline.d.ts +5 -5
- package/dist/console-timeline.d.ts.map +1 -1
- package/dist/console-timeline.js +27 -26
- package/dist/console-welcome.js +2 -2
- package/dist/email-login.d.ts.map +1 -1
- package/dist/email-login.js +2 -3
- package/dist/ggui-session-channel/action-ingress.d.ts +54 -0
- package/dist/ggui-session-channel/action-ingress.d.ts.map +1 -0
- package/dist/ggui-session-channel/action-ingress.js +228 -0
- package/dist/ggui-session-channel/channel-subscriptions.d.ts +97 -0
- package/dist/ggui-session-channel/channel-subscriptions.d.ts.map +1 -0
- package/dist/ggui-session-channel/channel-subscriptions.js +224 -0
- package/dist/ggui-session-channel/internal-types.d.ts +102 -0
- package/dist/ggui-session-channel/internal-types.d.ts.map +1 -0
- package/dist/ggui-session-channel/internal-types.js +6 -0
- package/dist/ggui-session-channel/outbound.d.ts +81 -0
- package/dist/ggui-session-channel/outbound.d.ts.map +1 -0
- package/dist/ggui-session-channel/outbound.js +174 -0
- package/dist/ggui-session-channel/socket-router.d.ts +38 -0
- package/dist/ggui-session-channel/socket-router.d.ts.map +1 -0
- package/dist/ggui-session-channel/socket-router.js +213 -0
- package/dist/ggui-session-channel/subscribe.d.ts +165 -0
- package/dist/ggui-session-channel/subscribe.d.ts.map +1 -0
- package/dist/ggui-session-channel/subscribe.js +370 -0
- package/dist/ggui-session-channel/subscriber-lifecycle.d.ts +40 -0
- package/dist/ggui-session-channel/subscriber-lifecycle.d.ts.map +1 -0
- package/dist/ggui-session-channel/subscriber-lifecycle.js +123 -0
- package/dist/ggui-session-channel.d.ts +425 -0
- package/dist/ggui-session-channel.d.ts.map +1 -0
- package/dist/ggui-session-channel.js +262 -0
- package/dist/health-routes.d.ts +76 -0
- package/dist/health-routes.d.ts.map +1 -0
- package/dist/health-routes.js +145 -0
- package/dist/index.d.ts +10 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -9
- package/dist/instructions-presets.d.ts +3 -3
- package/dist/instructions-presets.js +24 -24
- package/dist/llm-backed-negotiator.d.ts +68 -67
- package/dist/llm-backed-negotiator.d.ts.map +1 -1
- package/dist/llm-backed-negotiator.js +82 -221
- package/dist/mcp-apps-outbound.d.ts +47 -48
- package/dist/mcp-apps-outbound.d.ts.map +1 -1
- package/dist/mcp-apps-outbound.js +154 -177
- package/dist/mcp-endpoint-routes.d.ts +88 -0
- package/dist/mcp-endpoint-routes.d.ts.map +1 -0
- package/dist/mcp-endpoint-routes.js +359 -0
- package/dist/mcp-mounts.d.ts +2 -76
- package/dist/mcp-mounts.d.ts.map +1 -1
- package/dist/mcp-mounts.js +0 -76
- package/dist/oauth-as-routes.d.ts +60 -0
- package/dist/oauth-as-routes.d.ts.map +1 -0
- package/dist/oauth-as-routes.js +82 -0
- package/dist/oauth-clients-routes.d.ts +39 -0
- package/dist/oauth-clients-routes.d.ts.map +1 -0
- package/dist/oauth-clients-routes.js +87 -0
- package/dist/oauth-login-types.d.ts +1 -20
- package/dist/oauth-login-types.d.ts.map +1 -1
- package/dist/oauth-login-types.js +30 -7
- package/dist/oauth-login.d.ts.map +1 -1
- package/dist/oauth-login.js +3 -2
- package/dist/oauth-providers-store.d.ts.map +1 -1
- package/dist/oauth-providers-store.js +5 -5
- package/dist/oauth.d.ts +9 -8
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +41 -19
- package/dist/pairing-transport.d.ts.map +1 -1
- package/dist/pairing-transport.js +2 -1
- package/dist/request-context.d.ts +2 -2
- package/dist/request-context.js +2 -2
- package/dist/reserved-validators.d.ts.map +1 -1
- package/dist/reserved-validators.js +9 -1
- package/dist/route-param.d.ts +9 -0
- package/dist/route-param.d.ts.map +1 -0
- package/dist/route-param.js +10 -0
- package/dist/runtime-bundle-route.d.ts +43 -0
- package/dist/runtime-bundle-route.d.ts.map +1 -0
- package/dist/runtime-bundle-route.js +80 -0
- package/dist/schema-compat.d.ts +64 -62
- package/dist/schema-compat.d.ts.map +1 -1
- package/dist/schema-compat.js +23 -51
- package/dist/server.d.ts +179 -193
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +644 -3759
- package/dist/storage.d.ts +5 -5
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +5 -5
- package/dist/thread-transport.d.ts.map +1 -1
- package/dist/thread-transport.js +4 -3
- package/dist/user-session-auth.d.ts +7 -21
- package/dist/user-session-auth.d.ts.map +1 -1
- package/dist/user-session-auth.js +7 -28
- package/package.json +16 -15
- package/dist/mcp-apps-inbound.d.ts +0 -86
- package/dist/mcp-apps-inbound.d.ts.map +0 -1
- package/dist/mcp-apps-inbound.js +0 -283
- package/dist/render-channel.d.ts +0 -694
- package/dist/render-channel.d.ts.map +0 -1
- package/dist/render-channel.js +0 -1775
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OSS live channel — live render plane over WebSocket.
|
|
3
|
+
*
|
|
4
|
+
* The live channel is where the typed-channel contract is enforced on
|
|
5
|
+
* live traffic between the server and the user. It co-hosts on the
|
|
6
|
+
* same Express server as `/mcp` and reuses the
|
|
7
|
+
* `@ggui-ai/mcp-server-handlers/renders` helpers, so every
|
|
8
|
+
* deployment of this server family enforces the same contracts.
|
|
9
|
+
*
|
|
10
|
+
* Scope:
|
|
11
|
+
*
|
|
12
|
+
* - `subscribe` → auth, resolve-or-create render, register subscriber,
|
|
13
|
+
* reply `ack` with the render's current snapshot + sequence.
|
|
14
|
+
* - `action` → inbound user action carried as an {@link ActionEnvelope}.
|
|
15
|
+
* Gated through `assertActionContract` (payload, for data:submit).
|
|
16
|
+
* Persisted to GguiSessionStore as a typed render event.
|
|
17
|
+
* - `ping`/`pong` → heartbeat parity with hosted.
|
|
18
|
+
* - `close`/socket-close → clean subscriber teardown.
|
|
19
|
+
* - `sendToGguiSession(sessionId, data)` → outbound fan-out API for
|
|
20
|
+
* mutation handlers (ggui_emit / connector `ctx.send`). Validated
|
|
21
|
+
* through `assertStreamContract` before delivery.
|
|
22
|
+
*
|
|
23
|
+
* `props_update`: the agent-driven `ggui_update` handler calls
|
|
24
|
+
* `channel.sendPropsUpdate(sessionId, props)` (wired as its
|
|
25
|
+
* `propsUpdateNotifier`) to fan a `{type:'props_update'}` frame to
|
|
26
|
+
* live subscribers. Reaches the renderer's existing `props_update`
|
|
27
|
+
* branch in `iframe-runtime` and applies new props in-place.
|
|
28
|
+
*
|
|
29
|
+
* Not handled here:
|
|
30
|
+
*
|
|
31
|
+
* - Pattern-B daemon-agent notification stream (GET /mcp SSE).
|
|
32
|
+
* - Short-lived render-token mint/consume — that's ggui_render-gated.
|
|
33
|
+
* Dev-mode auth (any bearer via existing AuthAdapter) matches the
|
|
34
|
+
* `/mcp` endpoint's shape and is operator-replaceable.
|
|
35
|
+
*
|
|
36
|
+
* Module layout: this file owns the public surface (options, server
|
|
37
|
+
* interface, composer). The handler families live in
|
|
38
|
+
* `./ggui-session-channel/` as factories taking explicit typed deps:
|
|
39
|
+
*
|
|
40
|
+
* - `outbound.ts` — send/fan-out primitives + the public fan-out
|
|
41
|
+
* surfaces (`sendToGguiSession`, `sendPropsUpdate`, …).
|
|
42
|
+
* - `subscriber-lifecycle.ts` — register / live-tail pump /
|
|
43
|
+
* unregister + the 0↔1 subscriber-count hooks.
|
|
44
|
+
* - `subscribe.ts` — upgrade-time identity resolution (bearer /
|
|
45
|
+
* bootstrap / console cookie) + the `subscribe` handler.
|
|
46
|
+
* - `action-ingress.ts` — `action` contract gate + ledger/pipe
|
|
47
|
+
* dual-write + ack.
|
|
48
|
+
* - `channel-subscriptions.ts` — `channel_subscribe` source-tool
|
|
49
|
+
* polling loops.
|
|
50
|
+
* - `socket-router.ts` — `connection` wiring with the per-socket
|
|
51
|
+
* inbound ordering chain + the message-type dispatcher.
|
|
52
|
+
*/
|
|
53
|
+
import { InMemoryGguiSessionStreamBuffer, InProcessStreamFanout, } from "@ggui-ai/mcp-server-core/in-memory";
|
|
54
|
+
import { WebSocketServer } from "ws";
|
|
55
|
+
import { UnauthenticatedError } from "./auth.js";
|
|
56
|
+
import { createActionIngress } from "./ggui-session-channel/action-ingress.js";
|
|
57
|
+
import { createChannelSubscriptions, } from "./ggui-session-channel/channel-subscriptions.js";
|
|
58
|
+
import { createOutbound } from "./ggui-session-channel/outbound.js";
|
|
59
|
+
import { attachSocketRouter } from "./ggui-session-channel/socket-router.js";
|
|
60
|
+
import { createSubscribeHandlers, } from "./ggui-session-channel/subscribe.js";
|
|
61
|
+
import { createSubscriberLifecycle } from "./ggui-session-channel/subscriber-lifecycle.js";
|
|
62
|
+
/** Default URL path for the channel endpoint. Operators can override. */
|
|
63
|
+
export const DEFAULT_RENDER_CHANNEL_PATH = "/ws";
|
|
64
|
+
/**
|
|
65
|
+
* Build an OSS live-channel server. The returned object is designed to be
|
|
66
|
+
* composed into `createGguiServer` — see `server.ts` for the wire-up.
|
|
67
|
+
*/
|
|
68
|
+
export function createGguiSessionChannelServer(opts) {
|
|
69
|
+
const path = opts.path ?? DEFAULT_RENDER_CHANNEL_PATH;
|
|
70
|
+
// Outbound stream buffer — owns seq assignment + bounded replay
|
|
71
|
+
// storage. Default is in-memory; operators swap via `opts.streamBuffer`.
|
|
72
|
+
const streamBuffer = opts.streamBuffer ?? new InMemoryGguiSessionStreamBuffer();
|
|
73
|
+
// Live-tail pub/sub. Default in-process; multi-process deployments
|
|
74
|
+
// bind a pubsub-backed StreamFanout via `opts.streamFanout`.
|
|
75
|
+
const streamFanout = opts.streamFanout ?? new InProcessStreamFanout();
|
|
76
|
+
// `noServer: true` means we own the upgrade wiring (see handleUpgrade);
|
|
77
|
+
// ws won't try to bind its own port.
|
|
78
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
79
|
+
/**
|
|
80
|
+
* Flat set of all live WS subscribers. Replaces the per-render
|
|
81
|
+
* `subscribersByRender` Map — routing is now StreamFanout's job;
|
|
82
|
+
* this set tracks WS-specific bookkeeping (stats, shutdown-broadcast)
|
|
83
|
+
* that the seam can't see (and shouldn't).
|
|
84
|
+
*/
|
|
85
|
+
const wsSubscribers = new Set();
|
|
86
|
+
/** ws → subscriber reverse index so socket-close can look up cheaply. */
|
|
87
|
+
const subscribersByWs = new WeakMap();
|
|
88
|
+
// Send / fan-out family — wire-write primitives shared by every
|
|
89
|
+
// handler module plus the public fan-out surfaces the returned
|
|
90
|
+
// object delegates to. See `ggui-session-channel/outbound.ts`.
|
|
91
|
+
const outbound = createOutbound({
|
|
92
|
+
logger: opts.logger,
|
|
93
|
+
renderStore: opts.renderStore,
|
|
94
|
+
streamBuffer,
|
|
95
|
+
streamFanout,
|
|
96
|
+
wsSubscribers,
|
|
97
|
+
extraReservedValidators: opts.extraReservedValidators,
|
|
98
|
+
});
|
|
99
|
+
const { send, sendError, sendChannelError } = outbound;
|
|
100
|
+
// Subscriber lifecycle family — registration, the live-tail pump
|
|
101
|
+
// loop, and symmetric teardown. Owns the per-render counter behind
|
|
102
|
+
// the onFirstSubscriber / onLastSubscriberGone hooks. See
|
|
103
|
+
// `ggui-session-channel/subscriber-lifecycle.ts`.
|
|
104
|
+
const { register, unregister } = createSubscriberLifecycle({
|
|
105
|
+
logger: opts.logger,
|
|
106
|
+
wsSubscribers,
|
|
107
|
+
subscribersByWs,
|
|
108
|
+
send,
|
|
109
|
+
onFirstSubscriber: opts.onFirstSubscriber,
|
|
110
|
+
onLastSubscriberGone: opts.onLastSubscriberGone,
|
|
111
|
+
});
|
|
112
|
+
// Channel-subscribe / source-poll family — `channel_subscribe`
|
|
113
|
+
// validation + the server-side polling loops. Resolves the
|
|
114
|
+
// streamWebSocketLocalTools allowlist + cadence once at composition.
|
|
115
|
+
// See `ggui-session-channel/channel-subscriptions.ts`.
|
|
116
|
+
const { handleChannelSubscribe, handleChannelUnsubscribe } = createChannelSubscriptions({
|
|
117
|
+
logger: opts.logger,
|
|
118
|
+
renderStore: opts.renderStore,
|
|
119
|
+
localTools: opts.streamWebSocketLocalTools,
|
|
120
|
+
subscribersByWs,
|
|
121
|
+
send,
|
|
122
|
+
sendChannelError,
|
|
123
|
+
});
|
|
124
|
+
// Action ingress + consume bridge — contract gate, ledger + pipe
|
|
125
|
+
// dual-write, ack. See `ggui-session-channel/action-ingress.ts`.
|
|
126
|
+
const { handleInboundAction } = createActionIngress({
|
|
127
|
+
logger: opts.logger,
|
|
128
|
+
renderStore: opts.renderStore,
|
|
129
|
+
pendingEventConsumer: opts.pendingEventConsumer,
|
|
130
|
+
send,
|
|
131
|
+
sendError,
|
|
132
|
+
});
|
|
133
|
+
// Subscribe / credential-path family — upgrade-time identity
|
|
134
|
+
// resolution (bearer / bootstrap / console cookie) + the
|
|
135
|
+
// `subscribe` handler. See `ggui-session-channel/subscribe.ts`.
|
|
136
|
+
const { resolveIdentityFromUpgrade, handleSubscribe } = createSubscribeHandlers({
|
|
137
|
+
logger: opts.logger,
|
|
138
|
+
auth: opts.auth,
|
|
139
|
+
renderStore: opts.renderStore,
|
|
140
|
+
streamBuffer,
|
|
141
|
+
streamFanout,
|
|
142
|
+
bootstrap: opts.bootstrap,
|
|
143
|
+
cookieAuth: opts.cookieAuth,
|
|
144
|
+
appIdFromIdentity: opts.appIdFromIdentity,
|
|
145
|
+
versionPolicy: opts.versionPolicy,
|
|
146
|
+
send,
|
|
147
|
+
sendError,
|
|
148
|
+
register,
|
|
149
|
+
});
|
|
150
|
+
// WS lifecycle / message routing — the `connection` handler with
|
|
151
|
+
// the per-socket inbound ordering chain, pre-subscribe identity +
|
|
152
|
+
// cookie bindings, and the type dispatcher routing frames to the
|
|
153
|
+
// handler families above. See `ggui-session-channel/socket-router.ts`.
|
|
154
|
+
attachSocketRouter(wss, {
|
|
155
|
+
logger: opts.logger,
|
|
156
|
+
renderStore: opts.renderStore,
|
|
157
|
+
subscribersByWs,
|
|
158
|
+
send,
|
|
159
|
+
sendError,
|
|
160
|
+
unregister,
|
|
161
|
+
handleSubscribe,
|
|
162
|
+
handleInboundAction,
|
|
163
|
+
handleChannelSubscribe,
|
|
164
|
+
handleChannelUnsubscribe,
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
path,
|
|
168
|
+
handleUpgrade(req, socket, head) {
|
|
169
|
+
resolveIdentityFromUpgrade(req)
|
|
170
|
+
.then((identity) => {
|
|
171
|
+
// Stash identity on the request so the 'connection' handler
|
|
172
|
+
// can wire it onto the socket. This is the standard ws
|
|
173
|
+
// per-request piggyback pattern.
|
|
174
|
+
req.__gguiIdentity = identity;
|
|
175
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
176
|
+
// Expose `upgradeReq` for the connection handler.
|
|
177
|
+
wss.emit("connection", ws, req);
|
|
178
|
+
});
|
|
179
|
+
})
|
|
180
|
+
.catch((err) => {
|
|
181
|
+
if (err instanceof UnauthenticatedError) {
|
|
182
|
+
opts.logger.warn("render_channel_auth_failed", {
|
|
183
|
+
reason: err.message,
|
|
184
|
+
});
|
|
185
|
+
socket.write("HTTP/1.1 401 Unauthorized\r\n" +
|
|
186
|
+
"Connection: close\r\n" +
|
|
187
|
+
"Content-Type: text/plain\r\n\r\n" +
|
|
188
|
+
"Unauthorized: " +
|
|
189
|
+
err.message +
|
|
190
|
+
"\r\n");
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
opts.logger.error("render_channel_upgrade_failed", {
|
|
194
|
+
error: String(err),
|
|
195
|
+
});
|
|
196
|
+
socket.write("HTTP/1.1 500 Internal Server Error\r\n" + "Connection: close\r\n\r\n");
|
|
197
|
+
}
|
|
198
|
+
socket.destroy();
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
// The five fan-out surfaces delegate to the outbound module —
|
|
202
|
+
// contracts documented on the interface above, impl decisions in
|
|
203
|
+
// `ggui-session-channel/outbound.ts`.
|
|
204
|
+
sendToGguiSession: outbound.sendToGguiSession,
|
|
205
|
+
notifyGguiSessionCommit: outbound.notifyGguiSessionCommit,
|
|
206
|
+
sendPropsUpdate: outbound.sendPropsUpdate,
|
|
207
|
+
sendDrainAck: outbound.sendDrainAck,
|
|
208
|
+
externalBroadcast: outbound.externalBroadcast,
|
|
209
|
+
get subscriberCount() {
|
|
210
|
+
return wsSubscribers.size;
|
|
211
|
+
},
|
|
212
|
+
get renderCount() {
|
|
213
|
+
// Distinct render count across live WS subscribers. With
|
|
214
|
+
// multi-tab clients, two subscribers may share a sessionId —
|
|
215
|
+
// dedupe before counting.
|
|
216
|
+
const renders = new Set();
|
|
217
|
+
for (const sub of wsSubscribers)
|
|
218
|
+
renders.add(sub.sessionId);
|
|
219
|
+
return renders.size;
|
|
220
|
+
},
|
|
221
|
+
async close() {
|
|
222
|
+
// Close every open socket + drain its StreamFanout subscription.
|
|
223
|
+
// `wss.close` terminates the server but not in-flight sockets,
|
|
224
|
+
// so walk them explicitly. Each `iter.return()` unregisters
|
|
225
|
+
// the subscriber from the seam (idempotent on the in-process impl).
|
|
226
|
+
//
|
|
227
|
+
// Close code 1012 ("Service Restart", RFC 6455 + IANA registry)
|
|
228
|
+
// signals to clients that the server is restarting and they
|
|
229
|
+
// should reconnect immediately rather than treat the close as
|
|
230
|
+
// permanent. The pod's K8s rolling update fits this exactly:
|
|
231
|
+
// a new pod is already accepting connections behind the same
|
|
232
|
+
// load balancer; iframe-runtime + console viewer should
|
|
233
|
+
// reconnect on next message instead of blinking "disconnected".
|
|
234
|
+
// Code 1001 (used previously) means "endpoint going away" with
|
|
235
|
+
// no reconnect hint — semantically inaccurate for the pod-roll
|
|
236
|
+
// case and the wrong signal for client reconnect logic.
|
|
237
|
+
const sessionIds = new Set();
|
|
238
|
+
for (const sub of wsSubscribers) {
|
|
239
|
+
sessionIds.add(sub.sessionId);
|
|
240
|
+
try {
|
|
241
|
+
sub.ws.close(1012, "service_restart");
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
/* best-effort */
|
|
245
|
+
}
|
|
246
|
+
void sub.iter.return?.();
|
|
247
|
+
}
|
|
248
|
+
wsSubscribers.clear();
|
|
249
|
+
// Defensive: also close any renders on the seam that no longer
|
|
250
|
+
// have local WS subscribers (e.g. orphaned renders from a partial
|
|
251
|
+
// unregister race). For InProcessStreamFanout this is a no-op
|
|
252
|
+
// when there are no subscribers; for hosted bindings it ensures
|
|
253
|
+
// the per-render pub/sub channel teardown fires.
|
|
254
|
+
await Promise.all(Array.from(sessionIds, (sessionId) => streamFanout.close(sessionId).catch(() => {
|
|
255
|
+
/* best-effort */
|
|
256
|
+
})));
|
|
257
|
+
await new Promise((resolve) => {
|
|
258
|
+
wss.close(() => resolve());
|
|
259
|
+
});
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Liveness / readiness / authenticated-probe routes.
|
|
3
|
+
*
|
|
4
|
+
* GET /ggui/live — process-alive probe (200 whenever the event
|
|
5
|
+
* loop can run a handler, regardless of
|
|
6
|
+
* readiness).
|
|
7
|
+
* GET /ggui/health — readiness probe; runs the operator-supplied
|
|
8
|
+
* readiness checks and reports per-check
|
|
9
|
+
* results, live-channel counts, and the
|
|
10
|
+
* thread-transport durability claim.
|
|
11
|
+
* GET /ggui/auth-check — authenticated liveness. 204 when the bearer
|
|
12
|
+
* resolves via the configured AuthAdapter,
|
|
13
|
+
* 401 otherwise (with `WWW-Authenticate` when
|
|
14
|
+
* OAuth is enabled).
|
|
15
|
+
*
|
|
16
|
+
* Why live and health are separate: K8s livenessProbe + readinessProbe
|
|
17
|
+
* have distinct semantics. Liveness asks "is the process alive?" and
|
|
18
|
+
* a failure tells the kubelet to RESTART the pod. Readiness asks "is
|
|
19
|
+
* the pod ready to receive traffic?" and a failure tells the service
|
|
20
|
+
* to STOP ROUTING. Tying both probes to a single endpoint that gates
|
|
21
|
+
* on dependency health (Redis, DDB, RAG) means a transient upstream
|
|
22
|
+
* blip kills the pod entirely instead of just removing it from
|
|
23
|
+
* rotation.
|
|
24
|
+
*
|
|
25
|
+
* Self-hoster wiring (K8s):
|
|
26
|
+
*
|
|
27
|
+
* livenessProbe: { httpGet: { path: '/ggui/live', port } }
|
|
28
|
+
* readinessProbe: { httpGet: { path: '/ggui/health', port } }
|
|
29
|
+
*/
|
|
30
|
+
import type { AuthAdapter } from "@ggui-ai/mcp-server-core";
|
|
31
|
+
import type { Express } from "express";
|
|
32
|
+
import type { ServerInfo } from "./build-mcp.js";
|
|
33
|
+
import type { GguiSessionChannelServer } from "./ggui-session-channel.js";
|
|
34
|
+
import type { Logger } from "./logger.js";
|
|
35
|
+
interface MountOptions {
|
|
36
|
+
/** Express app to mount onto. */
|
|
37
|
+
readonly app: Express;
|
|
38
|
+
/** Server identity — `/ggui/health` reports name + version. */
|
|
39
|
+
readonly info: ServerInfo;
|
|
40
|
+
/** Registered tool count reported on `/ggui/health`. */
|
|
41
|
+
readonly toolCount: number;
|
|
42
|
+
/** Operator-supplied readiness checks (empty = always ready). */
|
|
43
|
+
readonly readinessChecks: ReadonlyArray<{
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly check: () => boolean | Promise<boolean>;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Late-bound live-channel reference. The channel is constructed
|
|
49
|
+
* AFTER these routes mount (declaration-order in the composer), so
|
|
50
|
+
* the health route reads through a getter on every request.
|
|
51
|
+
*/
|
|
52
|
+
readonly getChannel: () => GguiSessionChannelServer | null;
|
|
53
|
+
/**
|
|
54
|
+
* Thread-transport presence + durability claim. Absent when the
|
|
55
|
+
* server was booted without `threads:` (no persistent-chat routes
|
|
56
|
+
* mounted).
|
|
57
|
+
*/
|
|
58
|
+
readonly threads?: {
|
|
59
|
+
readonly durability?: "durable" | "ephemeral";
|
|
60
|
+
};
|
|
61
|
+
/** Auth adapter `/ggui/auth-check` resolves bearers against. */
|
|
62
|
+
readonly auth: AuthAdapter;
|
|
63
|
+
/** Whether OAuth is enabled (adds `WWW-Authenticate` on 401). */
|
|
64
|
+
readonly oauthEnabled: boolean;
|
|
65
|
+
/** Operator-configured issuer URL override (OAuth). */
|
|
66
|
+
readonly oauthIssuerUrl?: string;
|
|
67
|
+
/** Structured logger for unexpected auth-check failures. */
|
|
68
|
+
readonly logger: Logger;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mount `/ggui/live` + `/ggui/health` + `/ggui/auth-check` onto the
|
|
72
|
+
* express app. Returns nothing — the routes self-register.
|
|
73
|
+
*/
|
|
74
|
+
export declare function mountHealthRoutes(opts: MountOptions): void;
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=health-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-routes.d.ts","sourceRoot":"","sources":["../src/health-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAU1C,UAAU,YAAY;IACpB,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC;QACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAClD,CAAC,CAAC;IACH;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,wBAAwB,GAAG,IAAI,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,GAAG,WAAW,CAAA;KAAE,CAAC;IACrE,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,uDAAuD;IACvD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAmH1D"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Liveness / readiness / authenticated-probe routes.
|
|
3
|
+
*
|
|
4
|
+
* GET /ggui/live — process-alive probe (200 whenever the event
|
|
5
|
+
* loop can run a handler, regardless of
|
|
6
|
+
* readiness).
|
|
7
|
+
* GET /ggui/health — readiness probe; runs the operator-supplied
|
|
8
|
+
* readiness checks and reports per-check
|
|
9
|
+
* results, live-channel counts, and the
|
|
10
|
+
* thread-transport durability claim.
|
|
11
|
+
* GET /ggui/auth-check — authenticated liveness. 204 when the bearer
|
|
12
|
+
* resolves via the configured AuthAdapter,
|
|
13
|
+
* 401 otherwise (with `WWW-Authenticate` when
|
|
14
|
+
* OAuth is enabled).
|
|
15
|
+
*
|
|
16
|
+
* Why live and health are separate: K8s livenessProbe + readinessProbe
|
|
17
|
+
* have distinct semantics. Liveness asks "is the process alive?" and
|
|
18
|
+
* a failure tells the kubelet to RESTART the pod. Readiness asks "is
|
|
19
|
+
* the pod ready to receive traffic?" and a failure tells the service
|
|
20
|
+
* to STOP ROUTING. Tying both probes to a single endpoint that gates
|
|
21
|
+
* on dependency health (Redis, DDB, RAG) means a transient upstream
|
|
22
|
+
* blip kills the pod entirely instead of just removing it from
|
|
23
|
+
* rotation.
|
|
24
|
+
*
|
|
25
|
+
* Self-hoster wiring (K8s):
|
|
26
|
+
*
|
|
27
|
+
* livenessProbe: { httpGet: { path: '/ggui/live', port } }
|
|
28
|
+
* readinessProbe: { httpGet: { path: '/ggui/health', port } }
|
|
29
|
+
*/
|
|
30
|
+
import { resolveIdentity, UnauthenticatedError } from "./auth.js";
|
|
31
|
+
import { buildWwwAuthenticate, resolveIssuerUrl } from "./oauth.js";
|
|
32
|
+
/**
|
|
33
|
+
* 1s per-check timeout — a hung dependency must not block the K8s
|
|
34
|
+
* liveness probe, which itself runs on a short period. A timeout is
|
|
35
|
+
* treated as a failed check; the dependency is degraded either way.
|
|
36
|
+
*/
|
|
37
|
+
const READINESS_CHECK_TIMEOUT_MS = 1_000;
|
|
38
|
+
/**
|
|
39
|
+
* Mount `/ggui/live` + `/ggui/health` + `/ggui/auth-check` onto the
|
|
40
|
+
* express app. Returns nothing — the routes self-register.
|
|
41
|
+
*/
|
|
42
|
+
export function mountHealthRoutes(opts) {
|
|
43
|
+
const { app, info, toolCount, readinessChecks, getChannel, threads, auth, oauthEnabled, logger } = opts;
|
|
44
|
+
async function runReadinessChecks() {
|
|
45
|
+
if (readinessChecks.length === 0) {
|
|
46
|
+
return { allReady: true, results: {} };
|
|
47
|
+
}
|
|
48
|
+
const results = {};
|
|
49
|
+
let allReady = true;
|
|
50
|
+
await Promise.all(readinessChecks.map(async ({ name, check }) => {
|
|
51
|
+
try {
|
|
52
|
+
const ready = await Promise.race([
|
|
53
|
+
Promise.resolve().then(() => check()),
|
|
54
|
+
new Promise((resolve) => setTimeout(() => resolve(false), READINESS_CHECK_TIMEOUT_MS)),
|
|
55
|
+
]);
|
|
56
|
+
results[name] = ready;
|
|
57
|
+
if (!ready)
|
|
58
|
+
allReady = false;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
results[name] = false;
|
|
62
|
+
allReady = false;
|
|
63
|
+
}
|
|
64
|
+
}));
|
|
65
|
+
return { allReady, results };
|
|
66
|
+
}
|
|
67
|
+
// No body needed for the kubelet's HTTP check (status code is the
|
|
68
|
+
// signal), but a tiny JSON keeps the endpoint debuggable from a
|
|
69
|
+
// shell. No `readinessChecks` invoked — keeping this probe cheap
|
|
70
|
+
// is the point; any heavier work belongs in `/ggui/health`.
|
|
71
|
+
app.get("/ggui/live", (_req, res) => {
|
|
72
|
+
res.status(200).json({ status: "alive", server: info.name });
|
|
73
|
+
});
|
|
74
|
+
app.get("/ggui/health", (_req, res) => {
|
|
75
|
+
void (async () => {
|
|
76
|
+
const { allReady, results } = await runReadinessChecks();
|
|
77
|
+
const body = {
|
|
78
|
+
status: allReady ? "ok" : "degraded",
|
|
79
|
+
server: info.name,
|
|
80
|
+
version: info.version,
|
|
81
|
+
tools: toolCount,
|
|
82
|
+
};
|
|
83
|
+
const channel = getChannel();
|
|
84
|
+
if (channel) {
|
|
85
|
+
body.channel = {
|
|
86
|
+
path: channel.path,
|
|
87
|
+
subscribers: channel.subscriberCount,
|
|
88
|
+
renders: channel.renderCount,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// Thread-transport presence + durability claim. When present,
|
|
92
|
+
// `durability` is exactly what the caller declared — 'ephemeral'
|
|
93
|
+
// by default so Portal does not silently hide its non-durable
|
|
94
|
+
// caveat.
|
|
95
|
+
if (threads) {
|
|
96
|
+
body.threads = {
|
|
97
|
+
enabled: true,
|
|
98
|
+
durability: threads.durability ?? "ephemeral",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (Object.keys(results).length > 0) {
|
|
102
|
+
body.checks = results;
|
|
103
|
+
}
|
|
104
|
+
res.status(allReady ? 200 : 503).json(body);
|
|
105
|
+
})();
|
|
106
|
+
});
|
|
107
|
+
/**
|
|
108
|
+
* Authenticated liveness probe.
|
|
109
|
+
*
|
|
110
|
+
* Identical auth semantics to `/mcp` (same AuthAdapter, same Bearer-
|
|
111
|
+
* parsing) but with a flat 204 / 401 response shape, no body, no
|
|
112
|
+
* render state. Designed for clients that need to distinguish
|
|
113
|
+
* "server is up but my token is stale" from "server is unreachable".
|
|
114
|
+
*
|
|
115
|
+
* A Settings → Servers probe in a host client is the canonical
|
|
116
|
+
* consumer: it hits `/ggui/health` first (open), then
|
|
117
|
+
* `/ggui/auth-check` with the pairing token, and reports
|
|
118
|
+
* `token-invalid` when the first succeeds but the second returns 401.
|
|
119
|
+
*
|
|
120
|
+
* No response body to keep the endpoint cheap — a 401 is the signal.
|
|
121
|
+
* We deliberately skip the MCP error envelope shape used by `/mcp`
|
|
122
|
+
* because this route is explicitly NOT part of the MCP wire.
|
|
123
|
+
*/
|
|
124
|
+
app.get("/ggui/auth-check", async (req, res) => {
|
|
125
|
+
try {
|
|
126
|
+
await resolveIdentity(auth, req);
|
|
127
|
+
res.status(204).end();
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (err instanceof UnauthenticatedError) {
|
|
131
|
+
if (oauthEnabled) {
|
|
132
|
+
// Auth-check is universal-only — no per-app variant route is
|
|
133
|
+
// mounted, so the WWW-Authenticate always points at the
|
|
134
|
+
// universal resource metadata. Symmetric with the universal
|
|
135
|
+
// /mcp handler's 401 behavior.
|
|
136
|
+
res.setHeader("WWW-Authenticate", buildWwwAuthenticate(resolveIssuerUrl(req, opts.oauthIssuerUrl)));
|
|
137
|
+
}
|
|
138
|
+
res.status(401).end();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
logger.error("auth_check_unexpected_error", { error: String(err) });
|
|
142
|
+
res.status(500).end();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,31 +26,30 @@
|
|
|
26
26
|
* The `ggui serve` CLI command boots this server with the OSS defaults.
|
|
27
27
|
*/
|
|
28
28
|
export type { HandlerContext, SharedHandler } from '@ggui-ai/mcp-server-handlers';
|
|
29
|
-
export type { GadgetDescriptor, McpUiDisplayMode,
|
|
30
|
-
export type {
|
|
31
|
-
export {
|
|
29
|
+
export type { GadgetDescriptor, McpUiDisplayMode, GguiSession, SystemGguiSession, } from '@ggui-ai/protocol';
|
|
30
|
+
export type { GenerationDeps } from '@ggui-ai/mcp-server-handlers';
|
|
31
|
+
export { buildNoCredentialsGguiSession } from '@ggui-ai/mcp-server-handlers';
|
|
32
32
|
export { createGguiServer, defaultHandlers } from './server.js';
|
|
33
33
|
export type { CreateGguiServerOptions, GguiServer, } from './server.js';
|
|
34
34
|
export { FileSystemCodeStore } from './code-store-fs.js';
|
|
35
35
|
export type { FileSystemCodeStoreOptions } from './code-store-fs.js';
|
|
36
36
|
export type { McpServerMount } from './mcp-mounts.js';
|
|
37
|
-
export { composeWiredActionRouterFromMounts } from './mcp-mounts.js';
|
|
38
37
|
export type { McpService, ServicePath } from './mcp-mounts.js';
|
|
39
38
|
export { validateMcpServices, validateServicePath } from './mcp-mounts.js';
|
|
40
39
|
export { composePreviewReservedValidator, mergeReservedValidators, } from './reserved-validators.js';
|
|
41
|
-
export { checkRenderSchemaCompat, DEFAULT_SCHEMA_COMPAT_MODE, SchemaCompatError, } from './schema-compat.js';
|
|
42
|
-
export type { SchemaCompatFinding, SchemaCompatMode, SchemaCompatReport,
|
|
40
|
+
export { checkRenderSchemaCompat, DEFAULT_SCHEMA_COMPAT_MODE, hasErrorFinding, SchemaCompatError, } from './schema-compat.js';
|
|
41
|
+
export type { SchemaCompatFinding, SchemaCompatMode, SchemaCompatReport, GguiSessionContractShape, ToolSchemaRef, } from './schema-compat.js';
|
|
43
42
|
export type { ServerInfo } from './build-mcp.js';
|
|
44
43
|
export { UnauthenticatedError, DEFAULT_BUILDER_APP_ID, defaultAppIdFromIdentity, } from './auth.js';
|
|
45
44
|
export { createConsoleLogger } from './logger.js';
|
|
46
45
|
export type { Logger } from './logger.js';
|
|
47
|
-
export {
|
|
48
|
-
export type {
|
|
46
|
+
export { createGguiSessionChannelServer, DEFAULT_RENDER_CHANNEL_PATH, } from './ggui-session-channel.js';
|
|
47
|
+
export type { GguiSessionChannelOptions, GguiSessionChannelServer, } from './ggui-session-channel.js';
|
|
49
48
|
export { resolveStorageFromConfig } from './storage.js';
|
|
50
49
|
export type { ResolveStorageFromConfigOptions, ResolvedStorageStores, } from './storage.js';
|
|
51
50
|
export { DEFAULT_PAIRING_ADMIN_INIT_PATH, DEFAULT_PAIRING_PATH, mountPairingTransport, } from './pairing-transport.js';
|
|
52
51
|
export type { PairingTransportOptions } from './pairing-transport.js';
|
|
53
|
-
export { USER_SESSION_COOKIE_NAME, DEFAULT_USER_SESSION_TTL_SEC, cookieAuthMiddleware, extractUserSessionCookie, formatUserSessionCookieHeader,
|
|
52
|
+
export { USER_SESSION_COOKIE_NAME, DEFAULT_USER_SESSION_TTL_SEC, cookieAuthMiddleware, extractUserSessionCookie, formatUserSessionCookieHeader, readUserSessionCookie, readUserSessionCookieFromHeaders, } from './user-session-auth.js';
|
|
54
53
|
export type { FormatUserSessionCookieInput } from './user-session-auth.js';
|
|
55
54
|
export { createPairLoginRateLimitMiddleware, resolveClientIp, } from './rate-limit-middleware.js';
|
|
56
55
|
export type { PairLoginRateLimitOptions } from './rate-limit-middleware.js';
|
|
@@ -59,7 +58,7 @@ export type { CsrfMiddlewareOptions, MintCsrfTokenInput, MountCsrfTokenRouteOpti
|
|
|
59
58
|
export { createSecurityHeadersMiddleware } from './security-headers-middleware.js';
|
|
60
59
|
export type { SecurityHeadersMiddlewareOptions } from './security-headers-middleware.js';
|
|
61
60
|
export { composeOAuthUserId, } from './oauth-login-types.js';
|
|
62
|
-
export type { OAuthLoginProvider, AuthorizeUrlInput, ExchangeCodeInput, OAuthExchangeResult, OAuthProviderConfigRecord,
|
|
61
|
+
export type { OAuthLoginProvider, AuthorizeUrlInput, ExchangeCodeInput, OAuthExchangeResult, OAuthProviderConfigRecord, } from './oauth-login-types.js';
|
|
63
62
|
export { DEFAULT_OAUTH_START_PATH, DEFAULT_OAUTH_CALLBACK_PATH, DEFAULT_OAUTH_PROVIDERS_LIST_PATH, OAUTH_PKCE_COOKIE_NAME, mountOAuthLoginRoutes, } from './oauth-login.js';
|
|
64
63
|
export { DEFAULT_EMAIL_LOGIN_START_PATH, DEFAULT_EMAIL_LOGIN_VERIFY_PATH, DEFAULT_EMAIL_LOGIN_CONFIG_PATH, ConsoleEmailSender, InMemoryMagicLinkStore, mountEmailLoginRoutes, } from './email-login.js';
|
|
65
64
|
export type { EmailSender, EmailMessage, MagicLinkStore, MagicLinkRecord, MintTokenInput, EmailLoginRoutesOptions, } from './email-login.js';
|
|
@@ -97,6 +96,6 @@ export type { DiscoveredPrimitiveCatalog } from '@ggui-ai/project-config/node';
|
|
|
97
96
|
export type { LoadedTheme } from '@ggui-ai/project-config/node';
|
|
98
97
|
export type { OperatorConfig } from '@ggui-ai/project-config';
|
|
99
98
|
export type { ThemeWriter, ThemeFileUploader, } from './console-theme-routes.js';
|
|
100
|
-
export type { LlmProvider, LlmRoute, LlmSelection, ProviderKeyRef,
|
|
99
|
+
export type { LlmProvider, LlmRoute, LlmSelection, ProviderKeyRef, UiGenerateInput, UiGenerateResult, UiGenerator, GeneratorTier, GeneratorRegistry, GeneratorSlugParts, } from '@ggui-ai/mcp-server-core';
|
|
101
100
|
export { formatGeneratorSlug, isValidGeneratorSlug, parseGeneratorSlug, } from '@ggui-ai/mcp-server-core';
|
|
102
101
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAKlF,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -25,40 +25,39 @@
|
|
|
25
25
|
*
|
|
26
26
|
* The `ggui serve` CLI command boots this server with the OSS defaults.
|
|
27
27
|
*/
|
|
28
|
-
// No-credentials fallback
|
|
28
|
+
// No-credentials fallback helper — re-exported so the OSS CLI can
|
|
29
29
|
// build the no-credentials card render (pointing at the resolved
|
|
30
30
|
// `/settings` URL) without taking a direct `@ggui-ai/mcp-server-handlers`
|
|
31
31
|
// dependency.
|
|
32
|
-
export {
|
|
32
|
+
export { buildNoCredentialsGguiSession } from '@ggui-ai/mcp-server-handlers';
|
|
33
33
|
export { createGguiServer, defaultHandlers } from './server.js';
|
|
34
34
|
// Content-addressable code delivery (2026-05-03). FileSystemCodeStore
|
|
35
35
|
// is the OSS dev default; in-memory variant ships in
|
|
36
36
|
// `@ggui-ai/mcp-server-core/in-memory` for tests + ephemeral runs.
|
|
37
37
|
export { FileSystemCodeStore } from './code-store-fs.js';
|
|
38
|
-
export { composeWiredActionRouterFromMounts } from './mcp-mounts.js';
|
|
39
38
|
export { validateMcpServices, validateServicePath } from './mcp-mounts.js';
|
|
40
39
|
// Reserved-channel payload validator composition.
|
|
41
40
|
// `composePreviewReservedValidator` binds the A2UI adapter
|
|
42
41
|
// for `_ggui:preview`; `mergeReservedValidators` layers caller-provided
|
|
43
42
|
// extras on top. `createGguiServer` composes these automatically —
|
|
44
|
-
// consumers that embed the
|
|
45
|
-
// `
|
|
43
|
+
// consumers that embed the render-channel server directly (via
|
|
44
|
+
// `createGguiSessionChannelServer`) wire them up manually.
|
|
46
45
|
export { composePreviewReservedValidator, mergeReservedValidators, } from './reserved-validators.js';
|
|
47
46
|
// Schema compatibility checker. Exposes the helper, the policy-mode
|
|
48
47
|
// type, the canonical error, and the default mode constant. Consumers
|
|
49
48
|
// embedding their own endpoint paths (custom hosted wrappers) can
|
|
50
49
|
// reuse the helper directly.
|
|
51
|
-
export { checkRenderSchemaCompat, DEFAULT_SCHEMA_COMPAT_MODE, SchemaCompatError, } from './schema-compat.js';
|
|
50
|
+
export { checkRenderSchemaCompat, DEFAULT_SCHEMA_COMPAT_MODE, hasErrorFinding, SchemaCompatError, } from './schema-compat.js';
|
|
52
51
|
export { UnauthenticatedError, DEFAULT_BUILDER_APP_ID, defaultAppIdFromIdentity, } from './auth.js';
|
|
53
52
|
export { createConsoleLogger } from './logger.js';
|
|
54
|
-
export {
|
|
53
|
+
export { createGguiSessionChannelServer, DEFAULT_RENDER_CHANNEL_PATH, } from './ggui-session-channel.js';
|
|
55
54
|
export { resolveStorageFromConfig } from './storage.js';
|
|
56
55
|
export { DEFAULT_PAIRING_ADMIN_INIT_PATH, DEFAULT_PAIRING_PATH, mountPairingTransport, } from './pairing-transport.js';
|
|
57
56
|
// End-user browser-session cookie + login routes. Cookie + endpoints
|
|
58
57
|
// are mounted automatically by `createGguiServer` when pairing is
|
|
59
58
|
// enabled; re-exported here so embedders composing custom transports
|
|
60
59
|
// can reuse the cookie shape directly.
|
|
61
|
-
export { USER_SESSION_COOKIE_NAME, DEFAULT_USER_SESSION_TTL_SEC, cookieAuthMiddleware, extractUserSessionCookie, formatUserSessionCookieHeader,
|
|
60
|
+
export { USER_SESSION_COOKIE_NAME, DEFAULT_USER_SESSION_TTL_SEC, cookieAuthMiddleware, extractUserSessionCookie, formatUserSessionCookieHeader, readUserSessionCookie, readUserSessionCookieFromHeaders, } from './user-session-auth.js';
|
|
62
61
|
// Per-IP rate limit on `/pair`. Mounted automatically by
|
|
63
62
|
// `createGguiServer` when pairing is enabled. Re-exported so hosted
|
|
64
63
|
// bindings can swap in their own RateLimiter (Redis-backed,
|
|
@@ -87,7 +86,7 @@ export { githubLoginProvider } from './oauth-providers/github.js';
|
|
|
87
86
|
export { createOAuthProvidersStore } from './oauth-providers-store.js';
|
|
88
87
|
export { DEFAULT_ADMIN_OAUTH_PROVIDERS_PATH, mountAdminOAuthProvidersTransport, } from './admin-oauth-providers-transport.js';
|
|
89
88
|
export { DEFAULT_BUILDER_OWNER_ID, DEFAULT_THREADS_PATH, defaultThreadOwnerFromIdentity, mountThreadTransport, } from './thread-transport.js';
|
|
90
|
-
// Zero-config in-memory reference for the console shortCode →
|
|
89
|
+
// Zero-config in-memory reference for the console shortCode → render
|
|
91
90
|
// lookup. Re-exported here (alongside `createGguiServer`) so CLI hosts
|
|
92
91
|
// composing the OSS first-run path can pass one without taking a direct
|
|
93
92
|
// dep on `@ggui-ai/mcp-server-core`. For durable deployments the
|
|
@@ -54,9 +54,9 @@ export declare const MCP_INSTRUCTIONS_PRESETS: {
|
|
|
54
54
|
readonly default: string;
|
|
55
55
|
/**
|
|
56
56
|
* Default protocol primer + the host-side action-routing detail
|
|
57
|
-
* (
|
|
58
|
-
*
|
|
59
|
-
*
|
|
57
|
+
* (submit_action relay → per-render pipe → `ggui_consume` drain).
|
|
58
|
+
* Pick when the operator wants the LLM to also reason about how
|
|
59
|
+
* the underlying tools/call envelopes flow.
|
|
60
60
|
*/
|
|
61
61
|
readonly aggressive: string;
|
|
62
62
|
/**
|