@parlor/server 0.3.3 → 0.4.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/access.d.ts +3 -3
- package/dist/access.d.ts.map +1 -1
- package/dist/access.js +4 -4
- package/dist/access.js.map +1 -1
- package/dist/actions.d.ts +6 -1
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +21 -8
- package/dist/actions.js.map +1 -1
- package/dist/auth.d.ts +20 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +3 -1
- package/dist/auth.js.map +1 -1
- package/dist/caller.d.ts +3 -1
- package/dist/caller.d.ts.map +1 -1
- package/dist/caller.js +12 -5
- package/dist/caller.js.map +1 -1
- package/dist/create-server.d.ts +16 -1
- package/dist/create-server.d.ts.map +1 -1
- package/dist/create-server.js +28 -10
- package/dist/create-server.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +8 -3
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +38 -18
- package/dist/mcp.js.map +1 -1
- package/dist/plugin.d.ts +7 -3
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/scope.d.ts +4 -1
- package/dist/scope.d.ts.map +1 -1
- package/dist/scope.js +1 -1
- package/dist/scope.js.map +1 -1
- package/dist/visibility.d.ts +16 -0
- package/dist/visibility.d.ts.map +1 -0
- package/dist/visibility.js +32 -0
- package/dist/visibility.js.map +1 -0
- package/package.json +5 -5
package/dist/create-server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pagePattern, UNROUTED_HEADER } from "@parlor/agent-ui";
|
|
2
2
|
import { createAgentUi, registerAgentUiRoutes, } from "@parlor/agent-ui/server";
|
|
3
|
-
import { ActionError, ANONYMOUS, decodeReadRequests, REFRESH_HEADER, } from "@parlor/core";
|
|
3
|
+
import { ActionError, ANONYMOUS, decodeReadRequests, hasUser, REFRESH_HEADER, } from "@parlor/core";
|
|
4
4
|
import { ensureSyncTables, recordSyncEvent, registerSyncRoutes, SyncHub, } from "@parlor/sync/server";
|
|
5
5
|
import { H3, readBody } from "h3";
|
|
6
6
|
import { admits, requireAccess, requireSurface } from "./access.js";
|
|
@@ -14,6 +14,7 @@ import { applyMigrations, checkMigrations } from "./migrations.js";
|
|
|
14
14
|
import { DEFAULT_BASE_PATH, PROTOCOL_VERSION } from "./protocol.js";
|
|
15
15
|
import { refreshReads } from "./refresh.js";
|
|
16
16
|
import { defaultScope } from "./scope.js";
|
|
17
|
+
import { createRegistryResolver, } from "./visibility.js";
|
|
17
18
|
const STATUS_BY_CODE = {
|
|
18
19
|
not_found: 404,
|
|
19
20
|
invalid_input: 400,
|
|
@@ -180,7 +181,7 @@ function refuseUnless(callers, surface) {
|
|
|
180
181
|
};
|
|
181
182
|
}
|
|
182
183
|
export function createServer(options) {
|
|
183
|
-
const { actions, scope = defaultScope, plugins = [], basePath = DEFAULT_BASE_PATH, cors = {}, database, mcp = {}, sync = {}, agentUi: agentUiOptions = {}, } = options;
|
|
184
|
+
const { actions, scope = defaultScope, plugins = [], basePath = DEFAULT_BASE_PATH, cors = {}, database, mcp = {}, sync = {}, agentUi: agentUiOptions = {}, confirmation, } = options;
|
|
184
185
|
const auth = options.auth ?? (process.env.PARLOR_DEV === "1" ? devAuth() : undefined);
|
|
185
186
|
const app = new H3();
|
|
186
187
|
const appName = process.env.PARLOR_APP_NAME || undefined;
|
|
@@ -200,6 +201,7 @@ export function createServer(options) {
|
|
|
200
201
|
runtime.start?.();
|
|
201
202
|
})());
|
|
202
203
|
const callers = createCallerResolver(auth, scope, ready);
|
|
204
|
+
const registryFor = createRegistryResolver(actions, options.visible, callers);
|
|
203
205
|
const host = {
|
|
204
206
|
basePath,
|
|
205
207
|
database,
|
|
@@ -234,7 +236,7 @@ export function createServer(options) {
|
|
|
234
236
|
...agentUiOptions,
|
|
235
237
|
audience: async (request) => (await callers(request)).audience,
|
|
236
238
|
});
|
|
237
|
-
const runnerFor = (registry, admit) => createActionRunner({
|
|
239
|
+
const runnerFor = (registry, admit, registryOf) => createActionRunner({
|
|
238
240
|
actions: registry,
|
|
239
241
|
scope,
|
|
240
242
|
callers,
|
|
@@ -242,11 +244,13 @@ export function createServer(options) {
|
|
|
242
244
|
sync: syncEnabled,
|
|
243
245
|
onClient: agentUi?.touch,
|
|
244
246
|
confirm: agentUi?.confirm,
|
|
247
|
+
confirmation,
|
|
245
248
|
audit,
|
|
246
249
|
admit,
|
|
250
|
+
registryFor: registryOf,
|
|
247
251
|
ready,
|
|
248
252
|
});
|
|
249
|
-
const runner = runnerFor(actions);
|
|
253
|
+
const runner = runnerFor(actions, undefined, registryFor);
|
|
250
254
|
const hub = database ? new SyncHub(database) : undefined;
|
|
251
255
|
const inflight = new Set();
|
|
252
256
|
let closing;
|
|
@@ -267,7 +271,14 @@ export function createServer(options) {
|
|
|
267
271
|
if (!admits("manifest", caller, callers.enforcing))
|
|
268
272
|
return summary;
|
|
269
273
|
const ui = agentUi?.manifest();
|
|
270
|
-
|
|
274
|
+
let visible;
|
|
275
|
+
try {
|
|
276
|
+
visible = await registryFor(event.req);
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
return errorResponse(error);
|
|
280
|
+
}
|
|
281
|
+
return { ...summary, actions: visible.describe(), ...(ui ? { ui } : {}) };
|
|
271
282
|
});
|
|
272
283
|
app.post(`${basePath}/actions/:name`, async (event) => {
|
|
273
284
|
const name = event.context.params?.name ?? "";
|
|
@@ -285,7 +296,7 @@ export function createServer(options) {
|
|
|
285
296
|
const reads = decodeReadRequests(event.req.headers.get(REFRESH_HEADER));
|
|
286
297
|
if (!reads)
|
|
287
298
|
return answer;
|
|
288
|
-
const refreshed = await refreshReads(
|
|
299
|
+
const refreshed = await refreshReads(await registryFor(event.req), reads, result.writes, async (action, actionInput) => {
|
|
289
300
|
const read = await run(action, actionInput);
|
|
290
301
|
return { data: read.data, tags: read.reads, cursor: read.cursor };
|
|
291
302
|
}, (error) => toActionError(error).toBody());
|
|
@@ -349,6 +360,8 @@ export function createServer(options) {
|
|
|
349
360
|
runner,
|
|
350
361
|
agentUi,
|
|
351
362
|
callers,
|
|
363
|
+
confirmation,
|
|
364
|
+
registryFor,
|
|
352
365
|
app: mcpApp,
|
|
353
366
|
...mcp,
|
|
354
367
|
});
|
|
@@ -359,10 +372,17 @@ export function createServer(options) {
|
|
|
359
372
|
}
|
|
360
373
|
catch (error) {
|
|
361
374
|
const refusal = toActionError(error);
|
|
362
|
-
const
|
|
375
|
+
const signInHelps = !(error instanceof AuthFailure) || error.challenge;
|
|
376
|
+
const challenged = (refusal.code === "unauthenticated" && signInHelps) ||
|
|
363
377
|
(await callers(event.req).then(({ principal }) => principal.kind === "host", () => false));
|
|
364
378
|
return challenged && auth ? auth.challenge(event.req) : errorResponse(refusal);
|
|
365
379
|
}
|
|
380
|
+
try {
|
|
381
|
+
await registryFor(event.req);
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
return errorResponse(error);
|
|
385
|
+
}
|
|
366
386
|
return handler.fetch(event.req);
|
|
367
387
|
});
|
|
368
388
|
}
|
|
@@ -385,9 +405,7 @@ export function createServer(options) {
|
|
|
385
405
|
channels: admits("channels", caller, callers.enforcing)
|
|
386
406
|
? true
|
|
387
407
|
: (channel) => principal.kind === "host" && channel.hosts === true,
|
|
388
|
-
...(auth && principal.
|
|
389
|
-
? { revoked: auth.revoked(principal) }
|
|
390
|
-
: {}),
|
|
408
|
+
...(auth && hasUser(principal) ? { revoked: auth.revoked(principal) } : {}),
|
|
391
409
|
};
|
|
392
410
|
},
|
|
393
411
|
transport: syncOptions?.transport,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAEL,aAAa,EACb,qBAAqB,GAGtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,WAAW,EAGX,SAAS,EAET,kBAAkB,EAClB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAElB,OAAO,GAER,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,EAAE,EAAgB,QAAQ,EAAE,MAAM,IAAI,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAClF,OAAO,EAAqB,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,WAAW,EAAqB,MAAM,WAAW,CAAC;AAC3D,OAAO,EAGL,QAAQ,EACR,oBAAoB,EACpB,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAmB,cAAc,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASnE,OAAO,EAAE,iBAAiB,EAAiB,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AAyC9D,MAAM,cAAc,GAAG;IACrB,SAAS,EAAE,GAAG;IACd,aAAa,EAAE,GAAG;IAClB,QAAQ,EAAE,GAAG;IACb,oBAAoB,EAAE,GAAG;IACzB,wBAAwB,EAAE,GAAG;IAC7B,eAAe,EAAE,GAAG;IACpB,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,GAAG;CACqC,CAAC;AAErD,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC;AAE1F,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,YAAY,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,KAAK,YAAY,WAAW;QAC9B,OAAO,IAAI,WAAW,CAAC,iBAAiB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IACrE,OAAO,IAAI,WAAW,CAAC,UAAU,EAAE,gBAAgB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,SAAS,CAAC,KAAc,EAAE,KAAc;IAC/C,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,WAAW,CAAC,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE;QACzC,MAAM,EAAE,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC;KACzC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,WAAW,GAAG,mBAAmB,CAAC;AACxC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IAClD,SAAS;IACT,UAAU;IACV,KAAK;IACL,MAAM;IACN,IAAI;CACL,CAAC,CAAC;AAEH,SAAS,YAAY,CACnB,OAAgC,EAChC,QAAkC;IAElC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,yBAAyB,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;QAC7D,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,eAAe,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,CAAC,IAAI,4BAA4B,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;AACH,CAAC;AAQD,MAAM,UAAU,GAAG,CAAC,KAAqB,EAAE,EAAE,CAC3C,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AAEpE,SAAS,WAAW,CAClB,QAAuF,EACvF,QAAgB;IAEhB,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC;oBACX,MAAM,EAAE,MAAM,CAAC,IAAI;oBACnB,KAAK;oBACL,IAAI,EAAE,GAAG,QAAQ,IAAI,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE;iBAChD,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;YAC/B,IAAI,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CACb,QAAQ,MAAM,CAAC,IAAI,6BAA6B,MAAM,IAAI,IAAI,yBAAyB,CACxF,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;gBACzD,MAAM,IAAI,KAAK,CACb,QAAQ,MAAM,CAAC,IAAI,6BAA6B,MAAM,IAAI,IAAI,aAAa,QAAQ,+BAA+B,CACnH,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CACb,KAAK,KAAK,MAAM,CAAC,IAAI;oBACnB,CAAC,CAAC,QAAQ,KAAK,mBAAmB,GAAG,SAAS;oBAC9C,CAAC,CAAC,QAAQ,KAAK,UAAU,MAAM,CAAC,IAAI,wBAAwB,GAAG,GAAG,CACrE,CAAC;YACJ,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CAC3B,QAAqC,EACrC,MAA+B;IAE/B,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3C,IAAI;QACJ,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;KAChC,CAAC,CAAC,CAAC;IACJ,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,MAAM,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK;YAAE,SAAS;QACxD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,QAAQ,MAAM,iCAAiC,KAAK,CAAC,IAAI,sCAAsC,MAAM,CAAC,IAAI,CAAC,IAAI,iEAAiE,CACjL,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CACf,QAAkC;IAElC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,KAAK,MAAM,OAAO,IAAI,KAAK;YAAE,OAAO,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC;AAOD,KAAK,UAAU,SAAS,CAAC,EAAE,OAAO,EAAa,EAAE,MAAoB;IACnE,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,UAAU,CAAC,SAAoB;IACtC,OAAO,KAAK,EAAE,MAAoB,EAAiB,EAAE;QACnD,IAAI,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;YAAE,OAAO;QAC/C,MAAM,IAAI,WAAW,CACnB,WAAW,EACX,2BAA2B,SAAS,CAAC,MAAM,CAAC,IAAI,GAAG,CACpD,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,SAAS,YAAY,CAAC,SAAoB,EAAE,OAAsB;IAChE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC;IAC9C,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,CAAC,UAAU;YAChB,IAAI,MAAgC,CAAC;YACrC,IAAI,IAAI,GAAG,KAAK,CAAC;YACjB,SAAS,CAAC,SAAS,EAAE;gBACnB,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,SAAS;gBAC5C,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB,CAAC,CAAC,IAAI,CACL,CAAC,OAAO,EAAE,EAAE;gBACV,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;oBACpD,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;gBACjB,OAAO,CAAC,KAAK,CAAC,YAAY,SAAS,CAAC,MAAM,CAAC,IAAI,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAClF,CAAC,CACF,CAAC;YACF,OAAO,GAAG,EAAE;gBACV,IAAI,GAAG,IAAI,CAAC;gBACZ,MAAM,EAAE,EAAE,CAAC;YACb,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,OAAuB,EAAE,OAAgB;IACtD,OAAO,KAAK,EAAE,OAAgB,EAAmB,EAAE,CACjD,cAAc,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,YAAY,CAAC,OAAuB,EAAE,OAAgB;IAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,KAAK,EAAE,KAAc,EAAiC,EAAE;QAC7D,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,OAAyB;IAEzB,MAAM,EACJ,OAAO,EACP,KAAK,GAAG,YAAY,EACpB,OAAO,GAAG,EAAE,EACZ,QAAQ,GAAG,iBAAiB,EAC5B,IAAI,GAAG,EAAE,EACT,QAAQ,EACR,GAAG,GAAG,EAAE,EACR,IAAI,GAAG,EAAE,EACT,OAAO,EAAE,cAAc,GAAG,EAAE,GAC7B,GAAG,OAAO,CAAC;IACZ,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACtF,MAAM,GAAG,GAAG,IAAI,EAAE,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,SAAS,CAAC;IACzD,MAAM,WAAW,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACtD,MAAM,WAAW,GAAG,WAAW,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,CAAC;IACxE,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC;IACxD,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAClC,IAAI,QAAmC,CAAC;IACxC,MAAM,KAAK,GAAG,GAAG,EAAE,CACjB,CAAC,QAAQ,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3B,IAAI,WAAW;gBAAE,MAAM,gBAAgB,CAAC,QAAQ,CAAC,IAAI,EAAkB,CAAC,CAAC;YACzE,MAAM,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7C,CAAC;QACD,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,QAAQ;YAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IACxD,CAAC,CAAC,EAAE,CAAC,CAAC;IACR,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACzD,MAAM,IAAI,GAAe;QACvB,QAAQ;QACR,QAAQ;QACR,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,iBAAiB,EAAE,MAAM,IAAI,OAAO,IAAI,IAAI,KAAK,SAAS;QAC1D,QAAQ,EAAE,OAAO;QACjB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAClE,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;QACjE,CAAC;QACD,KAAK;QACL,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;YACvC,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAC3D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,eAAe,CAAC,MAAsB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvE,OAAO;YACT,CAAC;YACD,MAAM,KAAK,EAAE,CAAC;YACd,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAChC,eAAe,CAAC,EAAkB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAC7D,CAAC;QACJ,CAAC;KACF,CAAC;IACF,MAAM,QAAQ,GAAgB,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvD,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;KAC5B,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GACX,cAAc,KAAK,KAAK;QACtB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,aAAa,CAAC;YACZ,GAAG,cAAc;YACjB,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;SAC/D,CAAC,CAAC;IACT,MAAM,SAAS,GAAG,CAChB,QAAwB,EACxB,KAAyC,EAC3B,EAAE,CAChB,kBAAkB,CAAC;QACjB,OAAO,EAAE,QAAQ;QACjB,KAAK;QACL,OAAO;QACP,QAAQ;QACR,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,OAAO,EAAE,KAAK;QACxB,OAAO,EAAE,OAAO,EAAE,OAAO;QACzB,KAAK;QACL,KAAK;QACL,KAAK;KACN,CAAC,CAAC;IACL,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC7C,IAAI,OAAkC,CAAC;IAEvC,IAAI,IAAI,KAAK,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;IAElD,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,WAAW,EAAE,KAAK,EAAE,KAAK,EAA0B,EAAE;QACtE,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,MAAM,OAAO,GAAoB;YAC/B,QAAQ,EAAE,gBAAgB;YAC1B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC;YAAE,OAAO,OAAO,CAAC;QACnE,MAAM,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC7C,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,CAAC,MAAc,EAAE,WAAoB,EAAE,EAAE,CACnD,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE;gBACjD,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YACL,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACtC,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;YAChF,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;YACxE,IAAI,CAAC,KAAK;gBAAE,OAAO,MAAM,CAAC;YAC1B,MAAM,SAAS,GAAG,MAAM,YAAY,CAClC,OAAO,EACP,KAAK,EACL,MAAM,CAAC,MAAM,EACb,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;gBAC5B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;gBAC5C,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YACpE,CAAC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CACzC,CAAC;YACF,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,KAAK,EACvB,KAAqB,EACrB,OAAgB,EAChB,KAA8C,EAC9C,EAAE;QACF,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACtF,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAChE,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAClC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAE,CAAC;YAC1C,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACpF,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,MAAM,CAAC,IAAI,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACnE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;gBAC9C,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;wBAC7C,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAAC;oBACtE,CAAC,CAAC,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CACnC,IAAI,EACJ,KAAK,EACL,KAAK,CAAC,GAAG,EACT,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EACnB,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,CAC3C,CAAC;oBACF,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC1E,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QACrC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACzC,IAAI,CAAC;gBACH,MAAM,KAAK,EAAE,CAAC;gBACd,OAAO,MAAM,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACpD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,OAAO;YACpB,CAAC,CAAC;gBACE,IAAI,EAAE,OAAO;gBACb,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB;oBACpC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE;oBACrD,CAAC,CAAC,EAAE,CAAC;aACR;YACH,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,OAAO,GAAG,gBAAgB,CAAC;YAC/B,OAAO;YACP,MAAM;YACN,OAAO;YACP,OAAO;YACP,GAAG,EAAE,MAAM;YACX,GAAG,GAAG;SACP,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACvC,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACzC,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrC,MAAM,UAAU,GACd,OAAO,CAAC,IAAI,KAAK,iBAAiB;oBAClC,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAC5B,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,EAC5C,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC,CAAC;gBACL,OAAO,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACjF,CAAC;YACD,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,WAAW,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC;QACnC,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,UAAU,EAAE,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9D,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,UAAU,EAAE,KAAK,IAAI,EAAE;YACxC,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,kBAAkB,CAAC,GAAG,EAAE;YACtB,QAAQ;YACR,IAAI,EAAE,QAAQ;YACd,GAAG;YACH,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;YACxD,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;YAC9D,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;gBAC3B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;gBACtC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;gBAC7B,OAAO;oBACL,SAAS;oBACT,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC;wBACrD,CAAC,CAAC,IAAI;wBACN,CAAC,CAAC,CAAC,OAAsB,EAAE,EAAE,CACzB,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI;oBACzD,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW;wBACxC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;wBACtC,CAAC,CAAC,EAAE,CAAC;iBACR,CAAC;YACJ,CAAC;YACD,SAAS,EAAE,WAAW,EAAE,SAAS;YACjC,cAAc,EAAE,WAAW,EAAE,cAAc;YAC3C,QAAQ,EAAE;gBACR,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAmB,EAAE,CAC7C,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAC1E;aACF;YACD,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,KAAK,EAAE,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACvD,qBAAqB,CAAC,GAAG,EAAE;YACzB,QAAQ;YACR,OAAO;YACP,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;YAC9D,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,aAAa,CAC5B,IAAI,WAAW,CACb,WAAW,EACX,gBAAgB,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CACzD,CACF,CAAC;QACF,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;QAC3C,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE;YAC5B,oBAAoB,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;YACvC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACrD,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAChC,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,KAAK,EAAE,GAAG,EAAE,CACV,CAAC,OAAO,KAAK,CAAC,KAAK,IAAI,EAAE;YACvB,OAAO,EAAE,KAAK,EAAE,CAAC;YACjB,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;YAC3E,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5B,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC","sourcesContent":["import { pagePattern, UNROUTED_HEADER } from \"@parlor/agent-ui\";\nimport {\n type AgentUiOptions,\n createAgentUi,\n registerAgentUiRoutes,\n type UiManifestInput,\n type UiManifestSource,\n} from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n type ActionErrorCode,\n type ActionMap,\n ANONYMOUS,\n type DataProvider,\n decodeReadRequests,\n REFRESH_HEADER,\n} from \"@parlor/core\";\nimport type { ActionRegistry } from \"@parlor/core/registry\";\nimport type { ServerChannel } from \"@parlor/sync\";\nimport {\n ensureSyncTables,\n recordSyncEvent,\n registerSyncRoutes,\n type SyncDatabase,\n SyncHub,\n type SyncTransport,\n} from \"@parlor/sync/server\";\nimport { H3, type H3Event, readBody } from \"h3\";\n\nimport { admits, requireAccess, requireSurface, type Surface } from \"./access.js\";\nimport { type ActionRunner, createActionRunner } from \"./actions.js\";\nimport { AuthFailure, type AuthProvider } from \"./auth.js\";\nimport {\n type Caller,\n type CallerResolver,\n clientOf,\n createCallerResolver,\n sourceOf,\n} from \"./caller.js\";\nimport { type CorsConfig, corsMiddleware } from \"./cors.js\";\nimport { devAuth } from \"./dev-auth.js\";\nimport { createMcpHandler } from \"./mcp.js\";\nimport { applyMigrations, checkMigrations } from \"./migrations.js\";\nimport type {\n ActionAudit,\n AnyPluginRoute,\n PluginCaller,\n PluginHost,\n PluginRuntime,\n ServerPlugin,\n} from \"./plugin.js\";\nimport { DEFAULT_BASE_PATH, type Manifest, PROTOCOL_VERSION } from \"./protocol.js\";\nimport { refreshReads } from \"./refresh.js\";\nimport { defaultScope, type ScopeResolver } from \"./scope.js\";\n\nexport interface SyncOptions {\n readonly transport?: SyncTransport | undefined;\n readonly pollIntervalMs?: number | undefined;\n}\n\nexport interface ServerOptions<T extends ActionMap> {\n readonly actions: ActionRegistry<T>;\n readonly scope?: ScopeResolver | undefined;\n /**\n * Without it every caller is anonymous, the action source is the `x-parlor-source`\n * header, and confirmations are a UX guard.\n */\n readonly auth?: AuthProvider | undefined;\n /** Framework features with their own tables and routes, installed after `auth`. */\n readonly plugins?: readonly ServerPlugin[] | undefined;\n readonly basePath?: string | undefined;\n readonly cors?: CorsConfig | false | undefined;\n readonly database?: DataProvider | undefined;\n readonly mcp?:\n | { readonly name?: string | undefined; readonly version?: string | undefined }\n | false\n | undefined;\n readonly sync?: SyncOptions | false | undefined;\n readonly agentUi?: AgentUiOptions | false | undefined;\n}\n\ntype ManifestSummary = Pick<Manifest, \"protocol\" | \"app\">;\ntype ManifestReply = Manifest | ManifestSummary | Response;\n\nexport interface FrameworkServer {\n /**\n * Hands the server the app's page routes, called by the host before the first request.\n * Throws when a page route would take a document request meant for an absolute route.\n */\n readonly installUiManifest?: ((source: UiManifestSource) => void) | undefined;\n readonly fetch: (request: Request) => Promise<Response>;\n readonly close: () => Promise<void>;\n}\n\nconst STATUS_BY_CODE = {\n not_found: 404,\n invalid_input: 400,\n declined: 403,\n confirmation_timeout: 504,\n confirmation_unavailable: 503,\n unauthenticated: 401,\n forbidden: 403,\n internal: 500,\n} as const satisfies Record<ActionErrorCode, number>;\n\nconst isAbort = (error: unknown) => error instanceof Error && error.name === \"AbortError\";\n\nfunction toActionError(error: unknown): ActionError {\n if (error instanceof ActionError) return error;\n if (error instanceof AuthFailure)\n return new ActionError(\"unauthenticated\", error.message);\n if (!isAbort(error)) console.error(\"[parlor] action failed:\", error);\n return new ActionError(\"internal\", \"Internal error\", { cause: error });\n}\n\nfunction errorBody(event: H3Event, error: unknown) {\n const actionError = toActionError(error);\n event.res.status = STATUS_BY_CODE[actionError.code];\n return actionError.toBody();\n}\n\nfunction errorResponse(error: unknown): Response {\n const actionError = toActionError(error);\n return Response.json(actionError.toBody(), {\n status: STATUS_BY_CODE[actionError.code],\n });\n}\n\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\nconst RESERVED_NAMES: ReadonlySet<string> = new Set([\n \"actions\",\n \"manifest\",\n \"mcp\",\n \"sync\",\n \"ui\",\n]);\n\nfunction checkPlugins(\n plugins: readonly ServerPlugin[],\n database: DataProvider | undefined,\n): void {\n const names = new Set<string>();\n for (const plugin of plugins) {\n if (!PLUGIN_NAME.test(plugin.name) || RESERVED_NAMES.has(plugin.name)) {\n throw new Error(`\"${plugin.name}\" cannot name a plugin.`);\n }\n if (names.has(plugin.name))\n throw new Error(`Two plugins are named \"${plugin.name}\".`);\n names.add(plugin.name);\n checkMigrations(plugin);\n if (plugin.migrations?.length && !database) {\n throw new Error(`The \"${plugin.name}\" plugin needs a database.`);\n }\n }\n}\n\ninterface MountedRoute {\n readonly plugin: string;\n readonly route: AnyPluginRoute;\n readonly path: string;\n}\n\nconst isAbsolute = (route: AnyPluginRoute) =>\n route.absolute === true || route.path.startsWith(\"/.well-known/\");\n\nfunction mountRoutes(\n runtimes: readonly { readonly plugin: ServerPlugin; readonly runtime: PluginRuntime }[],\n basePath: string,\n): MountedRoute[] {\n const mounted: MountedRoute[] = [];\n const owners = new Map<string, string>();\n for (const { plugin, runtime } of runtimes) {\n for (const route of runtime.routes ?? []) {\n if (!isAbsolute(route)) {\n mounted.push({\n plugin: plugin.name,\n route,\n path: `${basePath}/${plugin.name}${route.path}`,\n });\n continue;\n }\n const { method, path } = route;\n if (route.absolute && /[:*]/.test(path)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} must be a static path.`,\n );\n }\n if (path === basePath || path.startsWith(`${basePath}/`)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} is under ${basePath}, which the framework serves.`,\n );\n }\n const key = `${method} ${path}`;\n const owner = owners.get(key);\n if (owner !== undefined) {\n throw new Error(\n owner === plugin.name\n ? `The \"${owner}\" plugin serves ${key} twice.`\n : `The \"${owner}\" and \"${plugin.name}\" plugins both serve ${key}.`,\n );\n }\n owners.set(key, plugin.name);\n mounted.push({ plugin: plugin.name, route, path });\n }\n }\n return mounted;\n}\n\nfunction refuseShadowedRoutes(\n manifest: UiManifestInput | undefined,\n routes: readonly MountedRoute[],\n): void {\n if (!manifest) return;\n const pages = manifest.routes.map((page) => ({\n page,\n pattern: pagePattern(page.path),\n }));\n for (const { plugin, route } of routes) {\n if (!route.absolute || route.method !== \"GET\") continue;\n const shadow = pages.find(({ pattern }) => pattern.test(route.path));\n if (shadow) {\n throw new Error(\n `The \"${plugin}\" plugin's absolute route GET ${route.path} is also matched by the page route ${shadow.page.path}, so a browser opening it would get the page. Move one of them.`,\n );\n }\n }\n}\n\nfunction auditAll(\n runtimes: readonly PluginRuntime[],\n): ((record: ActionAudit) => void) | undefined {\n const hooks = runtimes.filter((runtime) => runtime.audit);\n if (hooks.length === 0) return undefined;\n return (record) => {\n for (const runtime of hooks) runtime.audit?.(record);\n };\n}\n\ninterface Installed {\n readonly plugin: ServerPlugin;\n readonly runtime: PluginRuntime;\n}\n\nasync function allowedBy({ runtime }: Installed, caller: PluginCaller): Promise<boolean> {\n return !runtime.allows || (await runtime.allows(caller));\n}\n\nfunction admitterOf(installed: Installed) {\n return async (caller: PluginCaller): Promise<void> => {\n if (await allowedBy(installed, caller)) return;\n throw new ActionError(\n \"forbidden\",\n `This account cannot use ${installed.plugin.name}.`,\n );\n };\n}\n\n/** Joins a connection to `channel` only once the plugin admits its holder. */\nfunction gatedChannel(installed: Installed, channel: ServerChannel): ServerChannel {\n if (!installed.runtime.allows) return channel;\n return {\n event: channel.event,\n hosts: channel.hosts,\n connect(connection) {\n let detach: (() => void) | undefined;\n let left = false;\n allowedBy(installed, {\n principal: connection.principal ?? ANONYMOUS,\n scope: connection.scope,\n }).then(\n (allowed) => {\n if (allowed && !left && !connection.closed?.aborted) {\n detach = channel.connect(connection);\n }\n },\n (error: unknown) => {\n console.error(`[parlor] ${installed.plugin.name}: access check failed:`, error);\n },\n );\n return () => {\n left = true;\n detach?.();\n };\n },\n };\n}\n\nfunction guard(callers: CallerResolver, surface: Surface) {\n return async (request: Request): Promise<Caller> =>\n requireSurface(await callers(request), surface, callers.enforcing);\n}\n\nfunction refuseUnless(callers: CallerResolver, surface: Surface) {\n const check = guard(callers, surface);\n return async (event: H3Event): Promise<Response | undefined> => {\n try {\n await check(event.req);\n return undefined;\n } catch (error) {\n return errorResponse(error);\n }\n };\n}\n\nexport function createServer<T extends ActionMap>(\n options: ServerOptions<T>,\n): FrameworkServer {\n const {\n actions,\n scope = defaultScope,\n plugins = [],\n basePath = DEFAULT_BASE_PATH,\n cors = {},\n database,\n mcp = {},\n sync = {},\n agentUi: agentUiOptions = {},\n } = options;\n const auth = options.auth ?? (process.env.PARLOR_DEV === \"1\" ? devAuth() : undefined);\n const app = new H3();\n const appName = process.env.PARLOR_APP_NAME || undefined;\n const syncOptions = sync === false ? undefined : sync;\n const syncEnabled = syncOptions !== undefined && database !== undefined;\n const installed = [...(auth ? [auth] : []), ...plugins];\n checkPlugins(installed, database);\n let prepared: Promise<void> | undefined;\n const ready = () =>\n (prepared ??= (async () => {\n if (database) {\n await database.prepare?.();\n if (syncEnabled) await ensureSyncTables(database.read() as SyncDatabase);\n await applyMigrations(database, installed);\n }\n for (const { runtime } of runtimes) runtime.start?.();\n })());\n const callers = createCallerResolver(auth, scope, ready);\n const host: PluginHost = {\n basePath,\n database,\n ...(auth ? { auth } : {}),\n authMisconfigured: \"auth\" in options && auth === undefined,\n callerOf: callers,\n allows: async (name, caller) => {\n const entry = runtimes.find(({ plugin }) => plugin.name === name);\n return entry === undefined || (await allowedBy(entry, caller));\n },\n ready,\n announce: async (target, tags, within) => {\n if (!syncEnabled || !database || tags.length === 0) return;\n if (within !== undefined) {\n await recordSyncEvent(within as SyncDatabase, { scope: target, tags });\n return;\n }\n await ready();\n await database.transaction((tx) =>\n recordSyncEvent(tx as SyncDatabase, { scope: target, tags }),\n );\n },\n };\n const runtimes: Installed[] = installed.map((plugin) => ({\n plugin,\n runtime: plugin.setup(host),\n }));\n const routes = mountRoutes(runtimes, basePath);\n const audit = auditAll(runtimes.map(({ runtime }) => runtime));\n const agentUi =\n agentUiOptions === false\n ? undefined\n : createAgentUi({\n ...agentUiOptions,\n audience: async (request) => (await callers(request)).audience,\n });\n const runnerFor = (\n registry: ActionRegistry,\n admit?: (caller: Caller) => Promise<void>,\n ): ActionRunner =>\n createActionRunner({\n actions: registry,\n scope,\n callers,\n database,\n sync: syncEnabled,\n onClient: agentUi?.touch,\n confirm: agentUi?.confirm,\n audit,\n admit,\n ready,\n });\n const runner = runnerFor(actions);\n const hub = database ? new SyncHub(database) : undefined;\n const inflight = new Set<Promise<unknown>>();\n let closing: Promise<void> | undefined;\n\n if (cors !== false) app.use(corsMiddleware(cors));\n\n app.get(`${basePath}/manifest`, async (event): Promise<ManifestReply> => {\n let caller: Caller;\n try {\n caller = await callers(event.req);\n } catch (error) {\n return errorResponse(error);\n }\n const summary: ManifestSummary = {\n protocol: PROTOCOL_VERSION,\n ...(appName ? { app: { name: appName } } : {}),\n };\n if (!admits(\"manifest\", caller, callers.enforcing)) return summary;\n const ui = agentUi?.manifest();\n return { ...summary, actions: actions.describe(), ...(ui ? { ui } : {}) };\n });\n\n app.post(`${basePath}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const source = sourceOf(event.req);\n const run = (action: string, actionInput: unknown) =>\n runner.run(action, actionInput, event.req, source, {\n surface: \"actions\",\n cursor: true,\n });\n const result = await run(name, input);\n const answer = { data: result.data, tags: result.reads, cursor: result.cursor };\n const reads = decodeReadRequests(event.req.headers.get(REFRESH_HEADER));\n if (!reads) return answer;\n const refreshed = await refreshReads(\n actions,\n reads,\n result.writes,\n async (action, actionInput) => {\n const read = await run(action, actionInput);\n return { data: read.data, tags: read.reads, cursor: read.cursor };\n },\n (error) => toActionError(error).toBody(),\n );\n return { ...answer, writes: result.writes, refreshed };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n\n const handleRoute = async (\n route: AnyPluginRoute,\n request: Request,\n admit: (caller: PluginCaller) => Promise<void>,\n ) => {\n if (route.access === \"public\") return route.handle(request);\n const caller = requireAccess(await callers(request), route.access, callers.enforcing);\n await admit(caller);\n return route.handle(request, caller);\n };\n\n const admitters = new Map(\n runtimes.map((entry) => [entry.plugin.name, admitterOf(entry)]),\n );\n for (const entry of runtimes) {\n const { plugin, runtime } = entry;\n if (runtime.actions) {\n const admit = admitters.get(plugin.name)!;\n const pluginRunner = runnerFor(runtime.actions, runtime.allows ? admit : undefined);\n app.post(`${basePath}/${plugin.name}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const result = await pluginRunner.run(\n name,\n input,\n event.req,\n sourceOf(event.req),\n { surface: \"pluginActions\", cursor: true },\n );\n return { data: result.data, tags: result.reads, cursor: result.cursor };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n }\n }\n for (const { plugin, route, path } of routes) {\n const admit = admitters.get(plugin)!;\n app.on(route.method, path, async (event) => {\n try {\n await ready();\n return await handleRoute(route, event.req, admit);\n } catch (error) {\n return errorResponse(error);\n }\n });\n }\n\n if (mcp !== false) {\n const mcpApp = appName\n ? {\n name: appName,\n ...(process.env.PARLOR_APP_DESCRIPTION\n ? { description: process.env.PARLOR_APP_DESCRIPTION }\n : {}),\n }\n : undefined;\n const handler = createMcpHandler({\n actions,\n runner,\n agentUi,\n callers,\n app: mcpApp,\n ...mcp,\n });\n const guardMcp = guard(callers, \"mcp\");\n app.all(`${basePath}/mcp`, async (event) => {\n try {\n await guardMcp(event.req);\n } catch (error) {\n const refusal = toActionError(error);\n const challenged =\n refusal.code === \"unauthenticated\" ||\n (await callers(event.req).then(\n ({ principal }) => principal.kind === \"host\",\n () => false,\n ));\n return challenged && auth ? auth.challenge(event.req) : errorResponse(refusal);\n }\n return handler.fetch(event.req);\n });\n }\n\n if (syncEnabled && database && hub) {\n app.use(`${basePath}/sync/**`, refuseUnless(callers, \"sync\"));\n app.use(`${basePath}/sync/**`, async () => {\n await ready();\n });\n registerSyncRoutes(app, {\n basePath,\n data: database,\n hub,\n scope: async (request) => (await callers(request)).scope,\n audience: async (request) => (await callers(request)).audience,\n authority: async (request) => {\n const caller = await callers(request);\n const { principal } = caller;\n return {\n principal,\n channels: admits(\"channels\", caller, callers.enforcing)\n ? true\n : (channel: ServerChannel) =>\n principal.kind === \"host\" && channel.hosts === true,\n ...(auth && principal.kind !== \"anonymous\"\n ? { revoked: auth.revoked(principal) }\n : {}),\n };\n },\n transport: syncOptions?.transport,\n pollIntervalMs: syncOptions?.pollIntervalMs,\n channels: [\n ...(agentUi ? [agentUi.channel] : []),\n ...runtimes.flatMap((entry): ServerChannel[] =>\n entry.runtime.channel ? [gatedChannel(entry, entry.runtime.channel)] : [],\n ),\n ],\n clientId: clientOf,\n });\n }\n\n if (agentUi) {\n app.use(`${basePath}/ui`, refuseUnless(callers, \"ui\"));\n registerAgentUiRoutes(app, {\n basePath,\n agentUi,\n audience: async (request) => (await callers(request)).audience,\n clientId: clientOf,\n });\n }\n\n app.all(\"/**\", (event) => {\n const response = errorResponse(\n new ActionError(\n \"not_found\",\n `No route for ${event.req.method} ${event.url.pathname}`,\n ),\n );\n response.headers.set(UNROUTED_HEADER, \"1\");\n return response;\n });\n\n return {\n installUiManifest: (source) => {\n refuseShadowedRoutes(source(), routes);\n agentUi?.install(source);\n },\n fetch: (request) => {\n const response = Promise.resolve(app.fetch(request));\n const settled = () => void inflight.delete(response);\n inflight.add(response);\n response.then(settled, settled);\n return response;\n },\n close: () =>\n (closing ??= (async () => {\n agentUi?.close();\n await Promise.allSettled(runtimes.map(({ runtime }) => runtime.close?.()));\n await Promise.all([hub?.stop(), Promise.allSettled([...inflight])]);\n await database?.close?.();\n })()),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"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","sourcesContent":["import { pagePattern, UNROUTED_HEADER } from \"@parlor/agent-ui\";\nimport {\n type AgentUiOptions,\n createAgentUi,\n registerAgentUiRoutes,\n type UiManifestInput,\n type UiManifestSource,\n} from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n type ActionErrorCode,\n type ActionMap,\n ANONYMOUS,\n type ConfirmationPolicy,\n type DataProvider,\n decodeReadRequests,\n hasUser,\n REFRESH_HEADER,\n} from \"@parlor/core\";\nimport type { ActionRegistry } from \"@parlor/core/registry\";\nimport type { ServerChannel } from \"@parlor/sync\";\nimport {\n ensureSyncTables,\n recordSyncEvent,\n registerSyncRoutes,\n type SyncDatabase,\n SyncHub,\n type SyncTransport,\n} from \"@parlor/sync/server\";\nimport { H3, type H3Event, readBody } from \"h3\";\n\nimport { admits, requireAccess, requireSurface, type Surface } from \"./access.js\";\nimport { type ActionRunner, createActionRunner } from \"./actions.js\";\nimport { AuthFailure, type AuthProvider } from \"./auth.js\";\nimport {\n type Caller,\n type CallerResolver,\n clientOf,\n createCallerResolver,\n sourceOf,\n} from \"./caller.js\";\nimport { type CorsConfig, corsMiddleware } from \"./cors.js\";\nimport { devAuth } from \"./dev-auth.js\";\nimport { createMcpHandler } from \"./mcp.js\";\nimport { applyMigrations, checkMigrations } from \"./migrations.js\";\nimport type {\n ActionAudit,\n AnyPluginRoute,\n PluginCaller,\n PluginHost,\n PluginRuntime,\n ServerPlugin,\n} from \"./plugin.js\";\nimport { DEFAULT_BASE_PATH, type Manifest, PROTOCOL_VERSION } from \"./protocol.js\";\nimport { refreshReads } from \"./refresh.js\";\nimport { defaultScope, type ScopeResolver } from \"./scope.js\";\nimport {\n type ActionVisibility,\n createRegistryResolver,\n type RegistryResolver,\n} from \"./visibility.js\";\n\nexport interface SyncOptions {\n readonly transport?: SyncTransport | undefined;\n readonly pollIntervalMs?: number | undefined;\n}\n\nexport interface ServerOptions<T extends ActionMap> {\n readonly actions: ActionRegistry<T>;\n readonly scope?: ScopeResolver | undefined;\n /**\n * Without it every caller is anonymous, the action source is the `x-parlor-source`\n * header, and confirmations are a UX guard.\n */\n readonly auth?: AuthProvider | undefined;\n /** Framework features with their own tables and routes, installed after `auth`. */\n readonly plugins?: readonly ServerPlugin[] | undefined;\n readonly basePath?: string | undefined;\n readonly cors?: CorsConfig | false | undefined;\n readonly database?: DataProvider | undefined;\n readonly mcp?:\n | { readonly name?: string | undefined; readonly version?: string | undefined }\n | false\n | undefined;\n readonly sync?: SyncOptions | false | undefined;\n readonly agentUi?: AgentUiOptions | false | undefined;\n /**\n * Decides, for each call, whether the user approves it in the app first (`ask`), it runs\n * (`proceed`) or it fails with `confirmation_unavailable` (`refuse`). Defaults to\n * `defaultConfirmationPolicy`: agents are asked about `confirm: true` actions and keys are\n * refused them.\n */\n readonly confirmation?: ConfirmationPolicy | undefined;\n /**\n * Which of `actions` each caller may see and call, decided once per request. A hidden\n * action is left out of the manifest and MCP `tools/list`, and a call to it answers\n * `not_found` like an action that does not exist. Plugins' actions are never filtered.\n * Absent, every action is visible.\n */\n readonly visible?: ActionVisibility | undefined;\n}\n\ntype ManifestSummary = Pick<Manifest, \"protocol\" | \"app\">;\ntype ManifestReply = Manifest | ManifestSummary | Response;\n\nexport interface FrameworkServer {\n /**\n * Hands the server the app's page routes, called by the host before the first request.\n * Throws when a page route would take a document request meant for an absolute route.\n */\n readonly installUiManifest?: ((source: UiManifestSource) => void) | undefined;\n readonly fetch: (request: Request) => Promise<Response>;\n readonly close: () => Promise<void>;\n}\n\nconst STATUS_BY_CODE = {\n not_found: 404,\n invalid_input: 400,\n declined: 403,\n confirmation_timeout: 504,\n confirmation_unavailable: 503,\n unauthenticated: 401,\n forbidden: 403,\n internal: 500,\n} as const satisfies Record<ActionErrorCode, number>;\n\nconst isAbort = (error: unknown) => error instanceof Error && error.name === \"AbortError\";\n\nfunction toActionError(error: unknown): ActionError {\n if (error instanceof ActionError) return error;\n if (error instanceof AuthFailure)\n return new ActionError(\"unauthenticated\", error.message);\n if (!isAbort(error)) console.error(\"[parlor] action failed:\", error);\n return new ActionError(\"internal\", \"Internal error\", { cause: error });\n}\n\nfunction errorBody(event: H3Event, error: unknown) {\n const actionError = toActionError(error);\n event.res.status = STATUS_BY_CODE[actionError.code];\n return actionError.toBody();\n}\n\nfunction errorResponse(error: unknown): Response {\n const actionError = toActionError(error);\n return Response.json(actionError.toBody(), {\n status: STATUS_BY_CODE[actionError.code],\n });\n}\n\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\nconst RESERVED_NAMES: ReadonlySet<string> = new Set([\n \"actions\",\n \"manifest\",\n \"mcp\",\n \"sync\",\n \"ui\",\n]);\n\nfunction checkPlugins(\n plugins: readonly ServerPlugin[],\n database: DataProvider | undefined,\n): void {\n const names = new Set<string>();\n for (const plugin of plugins) {\n if (!PLUGIN_NAME.test(plugin.name) || RESERVED_NAMES.has(plugin.name)) {\n throw new Error(`\"${plugin.name}\" cannot name a plugin.`);\n }\n if (names.has(plugin.name))\n throw new Error(`Two plugins are named \"${plugin.name}\".`);\n names.add(plugin.name);\n checkMigrations(plugin);\n if (plugin.migrations?.length && !database) {\n throw new Error(`The \"${plugin.name}\" plugin needs a database.`);\n }\n }\n}\n\ninterface MountedRoute {\n readonly plugin: string;\n readonly route: AnyPluginRoute;\n readonly path: string;\n}\n\nconst isAbsolute = (route: AnyPluginRoute) =>\n route.absolute === true || route.path.startsWith(\"/.well-known/\");\n\nfunction mountRoutes(\n runtimes: readonly { readonly plugin: ServerPlugin; readonly runtime: PluginRuntime }[],\n basePath: string,\n): MountedRoute[] {\n const mounted: MountedRoute[] = [];\n const owners = new Map<string, string>();\n for (const { plugin, runtime } of runtimes) {\n for (const route of runtime.routes ?? []) {\n if (!isAbsolute(route)) {\n mounted.push({\n plugin: plugin.name,\n route,\n path: `${basePath}/${plugin.name}${route.path}`,\n });\n continue;\n }\n const { method, path } = route;\n if (route.absolute && /[:*]/.test(path)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} must be a static path.`,\n );\n }\n if (path === basePath || path.startsWith(`${basePath}/`)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} is under ${basePath}, which the framework serves.`,\n );\n }\n const key = `${method} ${path}`;\n const owner = owners.get(key);\n if (owner !== undefined) {\n throw new Error(\n owner === plugin.name\n ? `The \"${owner}\" plugin serves ${key} twice.`\n : `The \"${owner}\" and \"${plugin.name}\" plugins both serve ${key}.`,\n );\n }\n owners.set(key, plugin.name);\n mounted.push({ plugin: plugin.name, route, path });\n }\n }\n return mounted;\n}\n\nfunction refuseShadowedRoutes(\n manifest: UiManifestInput | undefined,\n routes: readonly MountedRoute[],\n): void {\n if (!manifest) return;\n const pages = manifest.routes.map((page) => ({\n page,\n pattern: pagePattern(page.path),\n }));\n for (const { plugin, route } of routes) {\n if (!route.absolute || route.method !== \"GET\") continue;\n const shadow = pages.find(({ pattern }) => pattern.test(route.path));\n if (shadow) {\n throw new Error(\n `The \"${plugin}\" plugin's absolute route GET ${route.path} is also matched by the page route ${shadow.page.path}, so a browser opening it would get the page. Move one of them.`,\n );\n }\n }\n}\n\nfunction auditAll(\n runtimes: readonly PluginRuntime[],\n): ((record: ActionAudit) => void) | undefined {\n const hooks = runtimes.filter((runtime) => runtime.audit);\n if (hooks.length === 0) return undefined;\n return (record) => {\n for (const runtime of hooks) runtime.audit?.(record);\n };\n}\n\ninterface Installed {\n readonly plugin: ServerPlugin;\n readonly runtime: PluginRuntime;\n}\n\nasync function allowedBy({ runtime }: Installed, caller: PluginCaller): Promise<boolean> {\n return !runtime.allows || (await runtime.allows(caller));\n}\n\nfunction admitterOf(installed: Installed) {\n return async (caller: PluginCaller): Promise<void> => {\n if (await allowedBy(installed, caller)) return;\n throw new ActionError(\n \"forbidden\",\n `This account cannot use ${installed.plugin.name}.`,\n );\n };\n}\n\n/** Joins a connection to `channel` only once the plugin admits its holder. */\nfunction gatedChannel(installed: Installed, channel: ServerChannel): ServerChannel {\n if (!installed.runtime.allows) return channel;\n return {\n event: channel.event,\n hosts: channel.hosts,\n connect(connection) {\n let detach: (() => void) | undefined;\n let left = false;\n allowedBy(installed, {\n principal: connection.principal ?? ANONYMOUS,\n scope: connection.scope,\n }).then(\n (allowed) => {\n if (allowed && !left && !connection.closed?.aborted) {\n detach = channel.connect(connection);\n }\n },\n (error: unknown) => {\n console.error(`[parlor] ${installed.plugin.name}: access check failed:`, error);\n },\n );\n return () => {\n left = true;\n detach?.();\n };\n },\n };\n}\n\nfunction guard(callers: CallerResolver, surface: Surface) {\n return async (request: Request): Promise<Caller> =>\n requireSurface(await callers(request), surface, callers.enforcing);\n}\n\nfunction refuseUnless(callers: CallerResolver, surface: Surface) {\n const check = guard(callers, surface);\n return async (event: H3Event): Promise<Response | undefined> => {\n try {\n await check(event.req);\n return undefined;\n } catch (error) {\n return errorResponse(error);\n }\n };\n}\n\nexport function createServer<T extends ActionMap>(\n options: ServerOptions<T>,\n): FrameworkServer {\n const {\n actions,\n scope = defaultScope,\n plugins = [],\n basePath = DEFAULT_BASE_PATH,\n cors = {},\n database,\n mcp = {},\n sync = {},\n agentUi: agentUiOptions = {},\n confirmation,\n } = options;\n const auth = options.auth ?? (process.env.PARLOR_DEV === \"1\" ? devAuth() : undefined);\n const app = new H3();\n const appName = process.env.PARLOR_APP_NAME || undefined;\n const syncOptions = sync === false ? undefined : sync;\n const syncEnabled = syncOptions !== undefined && database !== undefined;\n const installed = [...(auth ? [auth] : []), ...plugins];\n checkPlugins(installed, database);\n let prepared: Promise<void> | undefined;\n const ready = () =>\n (prepared ??= (async () => {\n if (database) {\n await database.prepare?.();\n if (syncEnabled) await ensureSyncTables(database.read() as SyncDatabase);\n await applyMigrations(database, installed);\n }\n for (const { runtime } of runtimes) runtime.start?.();\n })());\n const callers = createCallerResolver(auth, scope, ready);\n const registryFor = createRegistryResolver(actions, options.visible, callers);\n const host: PluginHost = {\n basePath,\n database,\n ...(auth ? { auth } : {}),\n authMisconfigured: \"auth\" in options && auth === undefined,\n callerOf: callers,\n allows: async (name, caller) => {\n const entry = runtimes.find(({ plugin }) => plugin.name === name);\n return entry === undefined || (await allowedBy(entry, caller));\n },\n ready,\n announce: async (target, tags, within) => {\n if (!syncEnabled || !database || tags.length === 0) return;\n if (within !== undefined) {\n await recordSyncEvent(within as SyncDatabase, { scope: target, tags });\n return;\n }\n await ready();\n await database.transaction((tx) =>\n recordSyncEvent(tx as SyncDatabase, { scope: target, tags }),\n );\n },\n };\n const runtimes: Installed[] = installed.map((plugin) => ({\n plugin,\n runtime: plugin.setup(host),\n }));\n const routes = mountRoutes(runtimes, basePath);\n const audit = auditAll(runtimes.map(({ runtime }) => runtime));\n const agentUi =\n agentUiOptions === false\n ? undefined\n : createAgentUi({\n ...agentUiOptions,\n audience: async (request) => (await callers(request)).audience,\n });\n const runnerFor = (\n registry: ActionRegistry,\n admit?: (caller: Caller) => Promise<void>,\n registryOf?: RegistryResolver,\n ): ActionRunner =>\n createActionRunner({\n actions: registry,\n scope,\n callers,\n database,\n sync: syncEnabled,\n onClient: agentUi?.touch,\n confirm: agentUi?.confirm,\n confirmation,\n audit,\n admit,\n registryFor: registryOf,\n ready,\n });\n const runner = runnerFor(actions, undefined, registryFor);\n const hub = database ? new SyncHub(database) : undefined;\n const inflight = new Set<Promise<unknown>>();\n let closing: Promise<void> | undefined;\n\n if (cors !== false) app.use(corsMiddleware(cors));\n\n app.get(`${basePath}/manifest`, async (event): Promise<ManifestReply> => {\n let caller: Caller;\n try {\n caller = await callers(event.req);\n } catch (error) {\n return errorResponse(error);\n }\n const summary: ManifestSummary = {\n protocol: PROTOCOL_VERSION,\n ...(appName ? { app: { name: appName } } : {}),\n };\n if (!admits(\"manifest\", caller, callers.enforcing)) return summary;\n const ui = agentUi?.manifest();\n let visible: ActionRegistry;\n try {\n visible = await registryFor(event.req);\n } catch (error) {\n return errorResponse(error);\n }\n return { ...summary, actions: visible.describe(), ...(ui ? { ui } : {}) };\n });\n\n app.post(`${basePath}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const source = sourceOf(event.req);\n const run = (action: string, actionInput: unknown) =>\n runner.run(action, actionInput, event.req, source, {\n surface: \"actions\",\n cursor: true,\n });\n const result = await run(name, input);\n const answer = { data: result.data, tags: result.reads, cursor: result.cursor };\n const reads = decodeReadRequests(event.req.headers.get(REFRESH_HEADER));\n if (!reads) return answer;\n const refreshed = await refreshReads(\n await registryFor(event.req),\n reads,\n result.writes,\n async (action, actionInput) => {\n const read = await run(action, actionInput);\n return { data: read.data, tags: read.reads, cursor: read.cursor };\n },\n (error) => toActionError(error).toBody(),\n );\n return { ...answer, writes: result.writes, refreshed };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n\n const handleRoute = async (\n route: AnyPluginRoute,\n request: Request,\n admit: (caller: PluginCaller) => Promise<void>,\n ) => {\n if (route.access === \"public\") return route.handle(request);\n const caller = requireAccess(await callers(request), route.access, callers.enforcing);\n await admit(caller);\n return route.handle(request, caller);\n };\n\n const admitters = new Map(\n runtimes.map((entry) => [entry.plugin.name, admitterOf(entry)]),\n );\n for (const entry of runtimes) {\n const { plugin, runtime } = entry;\n if (runtime.actions) {\n const admit = admitters.get(plugin.name)!;\n const pluginRunner = runnerFor(runtime.actions, runtime.allows ? admit : undefined);\n app.post(`${basePath}/${plugin.name}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const result = await pluginRunner.run(\n name,\n input,\n event.req,\n sourceOf(event.req),\n { surface: \"pluginActions\", cursor: true },\n );\n return { data: result.data, tags: result.reads, cursor: result.cursor };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n }\n }\n for (const { plugin, route, path } of routes) {\n const admit = admitters.get(plugin)!;\n app.on(route.method, path, async (event) => {\n try {\n await ready();\n return await handleRoute(route, event.req, admit);\n } catch (error) {\n return errorResponse(error);\n }\n });\n }\n\n if (mcp !== false) {\n const mcpApp = appName\n ? {\n name: appName,\n ...(process.env.PARLOR_APP_DESCRIPTION\n ? { description: process.env.PARLOR_APP_DESCRIPTION }\n : {}),\n }\n : undefined;\n const handler = createMcpHandler({\n actions,\n runner,\n agentUi,\n callers,\n confirmation,\n registryFor,\n app: mcpApp,\n ...mcp,\n });\n const guardMcp = guard(callers, \"mcp\");\n app.all(`${basePath}/mcp`, async (event) => {\n try {\n await guardMcp(event.req);\n } catch (error) {\n const refusal = toActionError(error);\n const signInHelps = !(error instanceof AuthFailure) || error.challenge;\n const challenged =\n (refusal.code === \"unauthenticated\" && signInHelps) ||\n (await callers(event.req).then(\n ({ principal }) => principal.kind === \"host\",\n () => false,\n ));\n return challenged && auth ? auth.challenge(event.req) : errorResponse(refusal);\n }\n try {\n await registryFor(event.req);\n } catch (error) {\n return errorResponse(error);\n }\n return handler.fetch(event.req);\n });\n }\n\n if (syncEnabled && database && hub) {\n app.use(`${basePath}/sync/**`, refuseUnless(callers, \"sync\"));\n app.use(`${basePath}/sync/**`, async () => {\n await ready();\n });\n registerSyncRoutes(app, {\n basePath,\n data: database,\n hub,\n scope: async (request) => (await callers(request)).scope,\n audience: async (request) => (await callers(request)).audience,\n authority: async (request) => {\n const caller = await callers(request);\n const { principal } = caller;\n return {\n principal,\n channels: admits(\"channels\", caller, callers.enforcing)\n ? true\n : (channel: ServerChannel) =>\n principal.kind === \"host\" && channel.hosts === true,\n ...(auth && hasUser(principal) ? { revoked: auth.revoked(principal) } : {}),\n };\n },\n transport: syncOptions?.transport,\n pollIntervalMs: syncOptions?.pollIntervalMs,\n channels: [\n ...(agentUi ? [agentUi.channel] : []),\n ...runtimes.flatMap((entry): ServerChannel[] =>\n entry.runtime.channel ? [gatedChannel(entry, entry.runtime.channel)] : [],\n ),\n ],\n clientId: clientOf,\n });\n }\n\n if (agentUi) {\n app.use(`${basePath}/ui`, refuseUnless(callers, \"ui\"));\n registerAgentUiRoutes(app, {\n basePath,\n agentUi,\n audience: async (request) => (await callers(request)).audience,\n clientId: clientOf,\n });\n }\n\n app.all(\"/**\", (event) => {\n const response = errorResponse(\n new ActionError(\n \"not_found\",\n `No route for ${event.req.method} ${event.url.pathname}`,\n ),\n );\n response.headers.set(UNROUTED_HEADER, \"1\");\n return response;\n });\n\n return {\n installUiManifest: (source) => {\n refuseShadowedRoutes(source(), routes);\n agentUi?.install(source);\n },\n fetch: (request) => {\n const response = Promise.resolve(app.fetch(request));\n const settled = () => void inflight.delete(response);\n inflight.add(response);\n response.then(settled, settled);\n return response;\n },\n close: () =>\n (closing ??= (async () => {\n agentUi?.close();\n await Promise.allSettled(runtimes.map(({ runtime }) => runtime.close?.()));\n await Promise.all([hub?.stop(), Promise.allSettled([...inflight])]);\n await database?.close?.();\n })()),\n };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { type CallerOf, type KindsOf, requireAccess, requireSurface, ROUTE_ACCESS, type Surface, } from "./access.js";
|
|
2
2
|
export { type ActionRun, type ActionRunner, type Confirm, createActionRunner, type RunOptions, } from "./actions.js";
|
|
3
|
-
export { type AccountProfile, AuthFailure, type AuthFailureReason, type AuthProvider, type AgentDelegation, type Delegation, type DeviceKeys, type DeviceVouch, HOST_GRANTS_TAG, type PresenceKey, type TurnDelegation, } from "./auth.js";
|
|
3
|
+
export { type AccountProfile, AuthFailure, type AuthFailureOptions, type AuthFailureReason, type AuthProvider, type AgentDelegation, type Delegation, type DeviceKeys, type DeviceVouch, HOST_GRANTS_TAG, type KeyVerifier, type PresenceKey, type TurnDelegation, } from "./auth.js";
|
|
4
4
|
export { readBoundedText } from "./body.js";
|
|
5
5
|
export { REVOCATION_HORIZON_MS } from "./revocation-horizon.js";
|
|
6
6
|
export { type Caller, type CallerResolver, clientOf, createCallerResolver, sourceFor, sourceOf, } from "./caller.js";
|
|
@@ -11,4 +11,5 @@ export { createMcpHandler, type McpOptions } from "./mcp.js";
|
|
|
11
11
|
export { type ActionAudit, type AnyPluginRoute, type ConfirmationAnswer, type Migration, type PluginCaller, type PluginHost, type PluginRoute, pluginRoute, type PluginRuntime, type PublicPluginRoute, type ServerPlugin, } from "./plugin.js";
|
|
12
12
|
export { CLIENT_HEADER, DEFAULT_BASE_PATH, type Manifest, PROTOCOL_VERSION, SESSION_TOKEN_HEADER, SOURCE_HEADER, } from "./protocol.js";
|
|
13
13
|
export { DEFAULT_SCOPE, defaultScope, type ScopeResolver } from "./scope.js";
|
|
14
|
+
export { type ActionVisibility, type VisibleTest } from "./visibility.js";
|
|
14
15
|
//# 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,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,OAAO,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,kBAAkB,EAClB,KAAK,UAAU,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,cAAc,EACnB,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,QAAQ,EACR,oBAAoB,EACpB,SAAS,EACT,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EACL,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,OAAO,EACP,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,KAAK,QAAQ,EACb,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,OAAO,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,kBAAkB,EAClB,KAAK,UAAU,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,cAAc,EACnB,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,QAAQ,EACR,oBAAoB,EACpB,SAAS,EACT,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EACL,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,OAAO,EACP,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,KAAK,QAAQ,EACb,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,4 +11,5 @@ export { createMcpHandler } from "./mcp.js";
|
|
|
11
11
|
export { pluginRoute, } from "./plugin.js";
|
|
12
12
|
export { CLIENT_HEADER, DEFAULT_BASE_PATH, PROTOCOL_VERSION, SESSION_TOKEN_HEADER, SOURCE_HEADER, } from "./protocol.js";
|
|
13
13
|
export { DEFAULT_SCOPE, defaultScope } from "./scope.js";
|
|
14
|
+
export {} from "./visibility.js";
|
|
14
15
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EACb,cAAc,EACd,YAAY,GAEb,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,kBAAkB,GAEnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,WAAW,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EACb,cAAc,EACd,YAAY,GAEb,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,kBAAkB,GAEnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,WAAW,EAQX,eAAe,GAIhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAGL,QAAQ,EACR,oBAAoB,EACpB,SAAS,EACT,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAmB,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EACL,YAAY,GAIb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,OAAO,GAER,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAmB,MAAM,UAAU,CAAC;AAC7D,OAAO,EAQL,WAAW,GAIZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,aAAa,EACb,iBAAiB,EAEjB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AAC7E,OAAO,EAA2C,MAAM,iBAAiB,CAAC","sourcesContent":["export {\n type CallerOf,\n type KindsOf,\n requireAccess,\n requireSurface,\n ROUTE_ACCESS,\n type Surface,\n} from \"./access.js\";\nexport {\n type ActionRun,\n type ActionRunner,\n type Confirm,\n createActionRunner,\n type RunOptions,\n} from \"./actions.js\";\nexport {\n type AccountProfile,\n AuthFailure,\n type AuthFailureOptions,\n type AuthFailureReason,\n type AuthProvider,\n type AgentDelegation,\n type Delegation,\n type DeviceKeys,\n type DeviceVouch,\n HOST_GRANTS_TAG,\n type KeyVerifier,\n type PresenceKey,\n type TurnDelegation,\n} from \"./auth.js\";\nexport { readBoundedText } from \"./body.js\";\nexport { REVOCATION_HORIZON_MS } from \"./revocation-horizon.js\";\nexport {\n type Caller,\n type CallerResolver,\n clientOf,\n createCallerResolver,\n sourceFor,\n sourceOf,\n} from \"./caller.js\";\nexport { type CorsConfig, isAllowedOrigin, SHELL_ORIGINS } from \"./cors.js\";\nexport {\n createServer,\n type FrameworkServer,\n type ServerOptions,\n type SyncOptions,\n} from \"./create-server.js\";\nexport {\n DEV_AUTH_PLUGIN,\n DEV_HOST_PATH,\n DEV_USER_ID,\n devAuth,\n type DevAuthOptions,\n} from \"./dev-auth.js\";\nexport { createMcpHandler, type McpOptions } from \"./mcp.js\";\nexport {\n type ActionAudit,\n type AnyPluginRoute,\n type ConfirmationAnswer,\n type Migration,\n type PluginCaller,\n type PluginHost,\n type PluginRoute,\n pluginRoute,\n type PluginRuntime,\n type PublicPluginRoute,\n type ServerPlugin,\n} from \"./plugin.js\";\nexport {\n CLIENT_HEADER,\n DEFAULT_BASE_PATH,\n type Manifest,\n PROTOCOL_VERSION,\n SESSION_TOKEN_HEADER,\n SOURCE_HEADER,\n} from \"./protocol.js\";\nexport { DEFAULT_SCOPE, defaultScope, type ScopeResolver } from \"./scope.js\";\nexport { type ActionVisibility, type VisibleTest } from \"./visibility.js\";\n"]}
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type McpHttpHandler, type ServerContext } from "@modelcontextprotocol/server";
|
|
2
2
|
import type { AgentOrigin } from "@parlor/agent-ui";
|
|
3
3
|
import { type AgentUi } from "@parlor/agent-ui/server";
|
|
4
|
-
import { type ActionMap } from "@parlor/core";
|
|
4
|
+
import { type ActionMap, type ConfirmationPolicy, type Principal } from "@parlor/core";
|
|
5
5
|
import type { ActionRegistry } from "@parlor/core/registry";
|
|
6
6
|
import type { ActionRunner } from "./actions.js";
|
|
7
|
-
import type
|
|
7
|
+
import { type CallerResolver } from "./caller.js";
|
|
8
|
+
import type { RegistryResolver } from "./visibility.js";
|
|
8
9
|
export interface McpOptions<T extends ActionMap> {
|
|
9
10
|
readonly actions: ActionRegistry<T>;
|
|
10
11
|
readonly runner: ActionRunner;
|
|
@@ -20,8 +21,12 @@ export interface McpOptions<T extends ActionMap> {
|
|
|
20
21
|
} | undefined;
|
|
21
22
|
readonly agentUi?: AgentUi | undefined;
|
|
22
23
|
readonly callers?: CallerResolver | undefined;
|
|
24
|
+
/** The server's confirmation policy, so each tool says what a call from this caller meets. */
|
|
25
|
+
readonly confirmation?: ConfirmationPolicy | undefined;
|
|
26
|
+
/** The actions a request may see; defaults to all of `actions`. */
|
|
27
|
+
readonly registryFor?: RegistryResolver | undefined;
|
|
23
28
|
}
|
|
24
|
-
export declare function appIdentity(app: McpOptions<ActionMap>["app"], origin: string | undefined): string;
|
|
29
|
+
export declare function appIdentity(app: McpOptions<ActionMap>["app"], origin: string | undefined, principal?: Principal): string;
|
|
25
30
|
export declare const PROGRESS_INTERVAL_MS = 10000;
|
|
26
31
|
export declare function originOf(ctx: ServerContext): AgentOrigin;
|
|
27
32
|
export declare function withProgress<T>(ctx: ServerContext, work: () => Promise<T>, intervalMs?: number): Promise<T>;
|
package/dist/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EAGnB,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,KAAK,OAAO,EAAmC,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAGL,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EAGnB,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,KAAK,OAAO,EAAmC,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAGL,KAAK,SAAS,EAId,KAAK,kBAAkB,EAGvB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,KAAK,cAAc,EAAa,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,SAAS;IAC7C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EACT;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GACpE,SAAS,CAAC;IACd,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAC9C,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACvD,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACrD;AASD,wBAAgB,WAAW,CACzB,GAAG,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EACjC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,GAAE,SAAqB,GAC/B,MAAM,CAMR;AAoED,eAAO,MAAM,oBAAoB,QAAS,CAAC;AA6B3C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,WAAW,CAQxD;AAED,wBAAsB,YAAY,CAAC,CAAC,EAClC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,UAAU,GAAE,MAA6B,GACxC,OAAO,CAAC,CAAC,CAAC,CAqBZ;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAClD,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GACrB,cAAc,CAiJhB"}
|
package/dist/mcp.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CLIENT_INFO_META_KEY, createMcpHandler as createSdkHandler, McpServer, } from "@modelcontextprotocol/server";
|
|
2
2
|
import { UI_MANIFEST_RESOURCE, UiFailure } from "@parlor/agent-ui/server";
|
|
3
|
-
import { ActionError, isMutating, } from "@parlor/core";
|
|
3
|
+
import { ActionError, ANONYMOUS, defaultConfirmationPolicy, isMutating, } from "@parlor/core";
|
|
4
|
+
import { sourceFor } from "./caller.js";
|
|
4
5
|
import { McpCalls } from "./mcp-calls.js";
|
|
5
6
|
/** The public origin first, then the one `parlor dev` serves the app on, then the request's. */
|
|
6
7
|
function appOrigin(request) {
|
|
@@ -9,11 +10,12 @@ function appOrigin(request) {
|
|
|
9
10
|
return new URL(configured).origin;
|
|
10
11
|
return request ? new URL(request.url).origin : undefined;
|
|
11
12
|
}
|
|
12
|
-
export function appIdentity(app, origin) {
|
|
13
|
+
export function appIdentity(app, origin, principal = ANONYMOUS) {
|
|
13
14
|
const where = origin ? ` at ${origin}` : "";
|
|
14
15
|
const what = app?.description ? ` ${app.description.trim()}` : "";
|
|
15
16
|
const who = app ? app.name : "this app";
|
|
16
|
-
|
|
17
|
+
const actor = principal.kind === "key" ? principal.name : "the signed-in user";
|
|
18
|
+
return `These tools belong to ${who}${where}.${what} They act only on ${who}, as ${actor}; any other app's tools are a separate server.`;
|
|
17
19
|
}
|
|
18
20
|
function toolResult(result) {
|
|
19
21
|
const text = result === undefined ? "ok" : JSON.stringify(result, null, 2);
|
|
@@ -59,10 +61,15 @@ function toolError(error) {
|
|
|
59
61
|
function unvalidated(schema) {
|
|
60
62
|
return { "~standard": { ...schema["~standard"], validate: (value) => ({ value }) } };
|
|
61
63
|
}
|
|
62
|
-
function actionDescription(action) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
function actionDescription(action, decision) {
|
|
65
|
+
switch (decision) {
|
|
66
|
+
case "ask":
|
|
67
|
+
return `${action.description} When an agent calls it, the user must approve it in the app first; the call waits for that answer and fails with declined, confirmation_timeout or confirmation_unavailable without running.`;
|
|
68
|
+
case "refuse":
|
|
69
|
+
return `${action.description} It needs a person's approval, which nobody can give for this caller, so a call fails with confirmation_unavailable without running.`;
|
|
70
|
+
case "proceed":
|
|
71
|
+
return action.description;
|
|
72
|
+
}
|
|
66
73
|
}
|
|
67
74
|
export const PROGRESS_INTERVAL_MS = 10_000;
|
|
68
75
|
async function verifiedOrigin(callers, request, ctx) {
|
|
@@ -74,6 +81,8 @@ async function verifiedOrigin(callers, request, ctx) {
|
|
|
74
81
|
if (principal?.kind === "agent" && principal.agent.verified) {
|
|
75
82
|
return { via: "mcp", name: principal.agent.name };
|
|
76
83
|
}
|
|
84
|
+
if (principal?.kind === "key")
|
|
85
|
+
return { via: "mcp", name: principal.name };
|
|
77
86
|
return originOf(ctx);
|
|
78
87
|
}
|
|
79
88
|
async function turnClientOf(callers, request) {
|
|
@@ -115,13 +124,20 @@ export async function withProgress(ctx, work, intervalMs = PROGRESS_INTERVAL_MS)
|
|
|
115
124
|
}
|
|
116
125
|
}
|
|
117
126
|
export function createMcpHandler(options) {
|
|
118
|
-
const {
|
|
127
|
+
const { runner, agentUi, callers, confirmation = defaultConfirmationPolicy, registryFor = () => Promise.resolve(options.actions), app, name = app?.name ?? "parlor", version = "0.0.0", } = options;
|
|
119
128
|
const calls = new McpCalls();
|
|
120
129
|
const inCall = (ctx, toolCtx, work) => calls.run(ctx.requestInfo, toolCtx.mcpReq.id, [...(ctx.requestInfo ? [ctx.requestInfo.signal] : []), toolCtx.mcpReq.signal], work);
|
|
121
|
-
const factory = (ctx) => {
|
|
130
|
+
const factory = async (ctx) => {
|
|
131
|
+
const caller = callers && ctx.requestInfo ? await callers(ctx.requestInfo) : undefined;
|
|
132
|
+
const principal = caller?.principal ?? ANONYMOUS;
|
|
133
|
+
const source = caller
|
|
134
|
+
? sourceFor("mcp", caller, callers?.enforcing === true, "mcp")
|
|
135
|
+
: "mcp";
|
|
136
|
+
const screen = principal.kind === "key" ? undefined : agentUi;
|
|
137
|
+
const registry = await registryFor(ctx.requestInfo);
|
|
122
138
|
const instructions = [
|
|
123
|
-
appIdentity(app, appOrigin(ctx.requestInfo)),
|
|
124
|
-
|
|
139
|
+
appIdentity(app, appOrigin(ctx.requestInfo), principal),
|
|
140
|
+
screen?.instructions("mcp"),
|
|
125
141
|
]
|
|
126
142
|
.filter(Boolean)
|
|
127
143
|
.join("\n\n");
|
|
@@ -131,19 +147,23 @@ export function createMcpHandler(options) {
|
|
|
131
147
|
if (ctx.requestInfo && requestId !== undefined)
|
|
132
148
|
calls.cancel(ctx.requestInfo, requestId, reason);
|
|
133
149
|
});
|
|
134
|
-
for (const actionName of
|
|
135
|
-
const action =
|
|
150
|
+
for (const actionName of registry.names()) {
|
|
151
|
+
const action = registry.get(actionName);
|
|
136
152
|
if (!action)
|
|
137
153
|
continue;
|
|
138
154
|
server.registerTool(actionName, {
|
|
139
|
-
description: actionDescription(action),
|
|
155
|
+
description: actionDescription(action, confirmation({ name: actionName, action, principal, source })),
|
|
140
156
|
inputSchema: unvalidated(action.input),
|
|
141
157
|
annotations: { readOnlyHint: !isMutating(action) },
|
|
142
158
|
}, async (args, toolCtx) => {
|
|
143
159
|
try {
|
|
144
160
|
const origin = await verifiedOrigin(callers, ctx.requestInfo, toolCtx);
|
|
145
161
|
const result = await inCall(ctx, toolCtx, (signal) => {
|
|
146
|
-
const run = () => runner.run(actionName, args, ctx.requestInfo, "mcp", {
|
|
162
|
+
const run = () => runner.run(actionName, args, ctx.requestInfo, "mcp", {
|
|
163
|
+
signal,
|
|
164
|
+
origin,
|
|
165
|
+
surface: "mcp",
|
|
166
|
+
});
|
|
147
167
|
return action.confirm ? withProgress(toolCtx, run) : run();
|
|
148
168
|
});
|
|
149
169
|
return toolResult(result.data);
|
|
@@ -153,8 +173,8 @@ export function createMcpHandler(options) {
|
|
|
153
173
|
}
|
|
154
174
|
});
|
|
155
175
|
}
|
|
156
|
-
const uiTools =
|
|
157
|
-
const uiManifest = uiTools.length > 0 ?
|
|
176
|
+
const uiTools = screen?.tools("mcp") ?? [];
|
|
177
|
+
const uiManifest = uiTools.length > 0 ? screen?.manifest() : undefined;
|
|
158
178
|
if (uiManifest) {
|
|
159
179
|
server.registerResource("ui-manifest", UI_MANIFEST_RESOURCE, {
|
|
160
180
|
description: "The app's pages and the views they show, with full JSON schemas for each view's value.",
|
|
@@ -182,7 +202,7 @@ export function createMcpHandler(options) {
|
|
|
182
202
|
issues: input.error.issues,
|
|
183
203
|
});
|
|
184
204
|
}
|
|
185
|
-
return toolResult(await inCall(ctx, toolCtx, async (signal) => tool.run(input.data, await
|
|
205
|
+
return toolResult(await inCall(ctx, toolCtx, async (signal) => tool.run(input.data, await screen.contextFor(ctx.requestInfo, await verifiedOrigin(callers, ctx.requestInfo, toolCtx), signal, await turnClientOf(callers, ctx.requestInfo)))));
|
|
186
206
|
}
|
|
187
207
|
catch (error) {
|
|
188
208
|
if (!(error instanceof UiFailure))
|