@parlor/server 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
package/dist/actions.js CHANGED
@@ -4,7 +4,7 @@ import { encodeCursor } from "@parlor/sync";
4
4
  import { createPruner, ensureSyncTables, readSyncCursor, recordSyncEvent, } from "@parlor/sync/server";
5
5
  import { requireSurface } from "./access.js";
6
6
  import { AuthFailure } from "./auth.js";
7
- import { createCallerResolver, sourceFor, } from "./caller.js";
7
+ import { createCallerResolver, sourceFor, streamsOf, } from "./caller.js";
8
8
  import { DEFAULT_SCOPE } from "./scope.js";
9
9
  export { clientOf, sourceOf } from "./caller.js";
10
10
  function originOf(source, principal) {
@@ -51,6 +51,7 @@ const INTERNAL_CALLER = {
51
51
  principal: ANONYMOUS,
52
52
  scope: DEFAULT_SCOPE,
53
53
  audience: DEFAULT_SCOPE,
54
+ account: undefined,
54
55
  clientId: undefined,
55
56
  };
56
57
  export function createActionRunner(options) {
@@ -71,8 +72,7 @@ export function createActionRunner(options) {
71
72
  const action = registry.get(name);
72
73
  if (!sync || !database || !action?.reads || isMutating(action))
73
74
  return undefined;
74
- const streams = caller.audience === caller.scope ? [caller.scope] : [caller.scope, caller.audience];
75
- return encodeCursor(await readSyncCursor(database.read(), streams));
75
+ return encodeCursor(await readSyncCursor(database.read(), streamsOf(caller)));
76
76
  };
77
77
  const invoke = async (name, input, request, caller, source, runOptions, trace) => {
78
78
  if (runOptions.surface)
@@ -114,7 +114,7 @@ export function createActionRunner(options) {
114
114
  if (tags.length === 0)
115
115
  return;
116
116
  await recordSyncEvent(tx, {
117
- scope: action.notifies === "user" ? caller.audience : resolvedScope,
117
+ scope: notifiedStream(action.notifies, caller),
118
118
  tags,
119
119
  source: client,
120
120
  });
@@ -179,4 +179,14 @@ async function digest(input) {
179
179
  const hash = await crypto.subtle.digest("SHA-256", bytes);
180
180
  return [...new Uint8Array(hash)].map((b) => b.toString(16).padStart(2, "0")).join("");
181
181
  }
182
+ function notifiedStream(notifies, caller) {
183
+ switch (notifies) {
184
+ case "user":
185
+ return caller.audience;
186
+ case "account":
187
+ return caller.account ?? caller.audience;
188
+ default:
189
+ return caller.scope;
190
+ }
191
+ }
182
192
  //# sourceMappingURL=actions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentOrigin } from \"@parlor/agent-ui\";\nimport type { ConfirmationOutcome, ConfirmationRequest } from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n type ActionMap,\n ANONYMOUS,\n type ActionSource,\n type ConfirmationPolicy,\n type DataProvider,\n isMutating,\n type Principal,\n} from \"@parlor/core\";\nimport {\n type ActionRegistry,\n invokeAction,\n type InvokeResult,\n type PreparedCall,\n} from \"@parlor/core/registry\";\nimport { encodeCursor } from \"@parlor/sync\";\nimport {\n createPruner,\n ensureSyncTables,\n readSyncCursor,\n recordSyncEvent,\n type SyncDatabase,\n} from \"@parlor/sync/server\";\n\nimport { requireSurface, type Surface } from \"./access.js\";\nimport { AuthFailure } from \"./auth.js\";\nimport {\n type Caller,\n type CallerResolver,\n createCallerResolver,\n sourceFor,\n} from \"./caller.js\";\nimport type { ActionAudit, ConfirmationAnswer } from \"./plugin.js\";\nimport { DEFAULT_SCOPE, type ScopeResolver } from \"./scope.js\";\nimport type { RegistryResolver } from \"./visibility.js\";\n\nexport { clientOf, sourceOf } from \"./caller.js\";\n\nexport type Confirm = (request: ConfirmationRequest) => Promise<ConfirmationOutcome>;\n\nexport interface ActionRunnerOptions<T extends ActionMap> {\n readonly actions: ActionRegistry<T>;\n readonly scope: ScopeResolver;\n readonly database?: DataProvider | undefined;\n readonly sync: boolean;\n /** Resolves each request's identity once; without it every caller is anonymous. */\n readonly callers?: CallerResolver | undefined;\n readonly onClient?:\n | ((clientId: string | undefined, audience: string) => void)\n | undefined;\n readonly confirm?: Confirm | undefined;\n /** Which calls are asked about, run or refused; `defaultConfirmationPolicy` when absent. */\n readonly confirmation?: ConfirmationPolicy | undefined;\n readonly audit?: ((record: ActionAudit) => void) | undefined;\n /** Throws for a caller the surface admits but the actions' owner does not; audited like any refusal. */\n readonly admit?: ((caller: Caller) => Promise<void>) | undefined;\n /** The actions a request may call; a hidden one answers `not_found` like an unknown one. */\n readonly registryFor?: RegistryResolver | undefined;\n /** Awaited before every call, so it must memoize; defaults to creating the sync tables. */\n readonly ready?: (() => Promise<void>) | undefined;\n}\n\nexport interface RunOptions {\n readonly signal?: AbortSignal | undefined;\n readonly origin?: AgentOrigin | undefined;\n /** Refuses callers the surface does not admit, inside the call so the refusal is audited. */\n readonly surface?: Surface | undefined;\n /** Also answer the sync cursor a read's result reflects, for a client that keeps it fresh. */\n readonly cursor?: boolean | undefined;\n}\n\nexport interface ActionRun extends InvokeResult {\n /** Set for a read with `cursor`: every sync event of the caller's streams up to it is in `data`. */\n readonly cursor?: string | undefined;\n}\n\nexport interface ActionRunner {\n run(\n name: string,\n input: unknown,\n request: Request | undefined,\n source: ActionSource,\n options?: RunOptions,\n ): Promise<ActionRun>;\n ready(): Promise<void>;\n}\n\ninterface Gate {\n readonly confirm: Confirm;\n readonly answered: (answer: ConfirmationAnswer) => void;\n readonly scope: string;\n readonly clientId: string | undefined;\n readonly origin: AgentOrigin | undefined;\n readonly signal: AbortSignal | undefined;\n}\n\nfunction originOf(source: ActionSource, principal: Principal): AgentOrigin {\n const via = source === \"agent\" ? \"agent\" : \"mcp\";\n if (principal.kind === \"agent\") return { via, name: principal.agent.name };\n if (principal.kind === \"key\") return { via, name: principal.name };\n return { via };\n}\n\nfunction confirmationGate(gate: Gate): (call: PreparedCall) => Promise<void> {\n return async ({ action, name, input, ctx }) => {\n const turn = ctx.principal?.kind === \"agent\" ? ctx.principal.turn : undefined;\n const outcome = await gate.confirm({\n scope: gate.scope,\n clientId: turn?.clientId ?? gate.clientId,\n ...(turn ? { thread: { threadId: turn.threadId, turnId: turn.turnId } } : {}),\n action: name,\n description: action.description,\n input,\n origin: gate.origin ?? originOf(ctx.source, ctx.principal ?? ANONYMOUS),\n signal: gate.signal,\n });\n if (outcome !== \"cancelled\") {\n gate.answered(outcome === \"shutdown\" ? \"unavailable\" : outcome);\n }\n switch (outcome) {\n case \"approved\":\n return;\n case \"declined\":\n throw new ActionError(\n \"declined\",\n `The user declined ${name} in the app; nothing ran. Do not retry unless they ask again.`,\n );\n case \"timeout\":\n throw new ActionError(\n \"confirmation_timeout\",\n `The user did not answer in time; ${name} did not run.`,\n );\n case \"unavailable\":\n throw new ActionError(\n \"confirmation_unavailable\",\n `No open app can ask the user to confirm ${name}. Ask the user to do it in the app themselves.`,\n );\n case \"shutdown\":\n throw new ActionError(\n \"confirmation_unavailable\",\n `The server shut down before the user answered; ${name} did not run. Try again once it is back, or ask the user to do it in the app themselves.`,\n );\n case \"cancelled\":\n throw (\n gate.signal?.reason ?? new DOMException(\"The call was cancelled.\", \"AbortError\")\n );\n }\n };\n}\n\nconst INTERNAL_CALLER: Caller = {\n principal: ANONYMOUS,\n scope: DEFAULT_SCOPE,\n audience: DEFAULT_SCOPE,\n clientId: undefined,\n};\n\nexport function createActionRunner<T extends ActionMap>(\n options: ActionRunnerOptions<T>,\n): ActionRunner {\n const {\n actions,\n scope,\n database,\n sync,\n onClient,\n confirm,\n confirmation,\n audit,\n admit,\n } = options;\n const registryFor = options.registryFor ?? (() => Promise.resolve(actions));\n const callers = options.callers ?? createCallerResolver(undefined, scope);\n const pruner = sync && database ? createPruner(database) : undefined;\n let prepared: Promise<void> | undefined;\n const ready =\n options.ready ??\n (() => {\n prepared ??=\n sync && database\n ? ensureSyncTables(database.read() as SyncDatabase)\n : Promise.resolve();\n return prepared;\n });\n\n const cursorBefore = async (\n registry: ActionRegistry,\n name: string,\n caller: Caller,\n ): Promise<string | undefined> => {\n const action = registry.get(name);\n if (!sync || !database || !action?.reads || isMutating(action)) return undefined;\n const streams =\n caller.audience === caller.scope ? [caller.scope] : [caller.scope, caller.audience];\n return encodeCursor(await readSyncCursor(database.read() as SyncDatabase, streams));\n };\n\n const invoke = async (\n name: string,\n input: unknown,\n request: Request | undefined,\n caller: Caller,\n source: ActionSource,\n runOptions: RunOptions,\n trace: Trace,\n ): Promise<ActionRun> => {\n if (runOptions.surface) requireSurface(caller, runOptions.surface, callers.enforcing);\n await admit?.(caller);\n const registry = await registryFor(request);\n const client = caller.clientId;\n if (caller.principal.kind !== \"key\") onClient?.(client, caller.audience);\n const signal = runOptions.signal ?? request?.signal;\n const resolvedScope = caller.scope;\n const cursor = runOptions.cursor\n ? await cursorBefore(registry, name, caller)\n : undefined;\n const result = await invokeAction(\n registry,\n name,\n input,\n { scope: resolvedScope, source, principal: caller.principal, signal, request },\n {\n data: database,\n enforcing: callers.enforcing,\n onRun: () => {\n trace.stage = \"ran\";\n },\n confirmation,\n onWaived: () => {\n trace.confirmation = \"waived\";\n },\n confirm: confirm\n ? confirmationGate({\n confirm,\n answered: (answer) => {\n trace.confirmation = answer;\n },\n scope: caller.audience,\n clientId: client,\n origin: runOptions.origin,\n signal,\n })\n : undefined,\n onWrite:\n sync && database\n ? async ({ action, tags, tx }) => {\n if (tags.length === 0) return;\n await recordSyncEvent(tx as SyncDatabase, {\n scope: action.notifies === \"user\" ? caller.audience : resolvedScope,\n tags,\n source: client,\n });\n }\n : undefined,\n },\n );\n if (result.writes.length > 0) pruner?.touch();\n return cursor === undefined ? result : { ...result, cursor };\n };\n\n return {\n ready,\n async run(name, input, request, declared, runOptions = {}) {\n await ready();\n const caller = request ? await callers(request) : INTERNAL_CALLER;\n const source = sourceFor(declared, caller, callers.enforcing, runOptions.surface);\n const trace: Trace = { stage: \"refused\", confirmation: undefined };\n if (!audit) return invoke(name, input, request, caller, source, runOptions, trace);\n const at = Date.now();\n const record = async (outcome: ActionAudit[\"outcome\"]) => {\n try {\n audit({\n at,\n action: name,\n principal: caller.principal,\n source,\n scope: caller.scope,\n inputDigest: await digest(input),\n stage: trace.stage,\n outcome,\n ...(trace.confirmation ? { confirmation: trace.confirmation } : {}),\n });\n } catch (error) {\n console.error(\"[parlor] audit failed:\", error);\n }\n };\n try {\n const result = await invoke(\n name,\n input,\n request,\n caller,\n source,\n runOptions,\n trace,\n );\n await record(\"ok\");\n return result;\n } catch (error) {\n await record(outcomeOf(error));\n throw error;\n }\n },\n };\n}\n\ninterface Trace {\n stage: ActionAudit[\"stage\"];\n confirmation: ConfirmationAnswer | undefined;\n}\n\nfunction outcomeOf(error: unknown): ActionAudit[\"outcome\"] {\n if (error instanceof ActionError) return error.code;\n if (error instanceof AuthFailure) return \"unauthenticated\";\n if (error instanceof Error && error.name === \"AbortError\") return \"cancelled\";\n return \"internal\";\n}\n\nasync function digest(input: unknown): Promise<string> {\n const bytes = new TextEncoder().encode(JSON.stringify(input ?? null));\n const hash = await crypto.subtle.digest(\"SHA-256\", bytes);\n return [...new Uint8Array(hash)].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n"]}
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentOrigin } from \"@parlor/agent-ui\";\nimport type { ConfirmationOutcome, ConfirmationRequest } from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n type ActionMap,\n ANONYMOUS,\n type ActionSource,\n type ConfirmationPolicy,\n type DataProvider,\n isMutating,\n type Principal,\n} from \"@parlor/core\";\nimport {\n type ActionRegistry,\n invokeAction,\n type InvokeResult,\n type PreparedCall,\n} from \"@parlor/core/registry\";\nimport { encodeCursor } from \"@parlor/sync\";\nimport {\n createPruner,\n ensureSyncTables,\n readSyncCursor,\n recordSyncEvent,\n type SyncDatabase,\n} from \"@parlor/sync/server\";\n\nimport { requireSurface, type Surface } from \"./access.js\";\nimport { AuthFailure } from \"./auth.js\";\nimport {\n type Caller,\n type CallerResolver,\n createCallerResolver,\n sourceFor,\n streamsOf,\n} from \"./caller.js\";\nimport type { ActionAudit, ConfirmationAnswer } from \"./plugin.js\";\nimport { DEFAULT_SCOPE, type ScopeResolver } from \"./scope.js\";\nimport type { RegistryResolver } from \"./visibility.js\";\n\nexport { clientOf, sourceOf } from \"./caller.js\";\n\nexport type Confirm = (request: ConfirmationRequest) => Promise<ConfirmationOutcome>;\n\nexport interface ActionRunnerOptions<T extends ActionMap> {\n readonly actions: ActionRegistry<T>;\n readonly scope: ScopeResolver;\n readonly database?: DataProvider | undefined;\n readonly sync: boolean;\n /** Resolves each request's identity once; without it every caller is anonymous. */\n readonly callers?: CallerResolver | undefined;\n readonly onClient?:\n | ((clientId: string | undefined, audience: string) => void)\n | undefined;\n readonly confirm?: Confirm | undefined;\n /** Which calls are asked about, run or refused; `defaultConfirmationPolicy` when absent. */\n readonly confirmation?: ConfirmationPolicy | undefined;\n readonly audit?: ((record: ActionAudit) => void) | undefined;\n /** Throws for a caller the surface admits but the actions' owner does not; audited like any refusal. */\n readonly admit?: ((caller: Caller) => Promise<void>) | undefined;\n /** The actions a request may call; a hidden one answers `not_found` like an unknown one. */\n readonly registryFor?: RegistryResolver | undefined;\n /** Awaited before every call, so it must memoize; defaults to creating the sync tables. */\n readonly ready?: (() => Promise<void>) | undefined;\n}\n\nexport interface RunOptions {\n readonly signal?: AbortSignal | undefined;\n readonly origin?: AgentOrigin | undefined;\n /** Refuses callers the surface does not admit, inside the call so the refusal is audited. */\n readonly surface?: Surface | undefined;\n /** Also answer the sync cursor a read's result reflects, for a client that keeps it fresh. */\n readonly cursor?: boolean | undefined;\n}\n\nexport interface ActionRun extends InvokeResult {\n /** Set for a read with `cursor`: every sync event of the caller's streams up to it is in `data`. */\n readonly cursor?: string | undefined;\n}\n\nexport interface ActionRunner {\n run(\n name: string,\n input: unknown,\n request: Request | undefined,\n source: ActionSource,\n options?: RunOptions,\n ): Promise<ActionRun>;\n ready(): Promise<void>;\n}\n\ninterface Gate {\n readonly confirm: Confirm;\n readonly answered: (answer: ConfirmationAnswer) => void;\n readonly scope: string;\n readonly clientId: string | undefined;\n readonly origin: AgentOrigin | undefined;\n readonly signal: AbortSignal | undefined;\n}\n\nfunction originOf(source: ActionSource, principal: Principal): AgentOrigin {\n const via = source === \"agent\" ? \"agent\" : \"mcp\";\n if (principal.kind === \"agent\") return { via, name: principal.agent.name };\n if (principal.kind === \"key\") return { via, name: principal.name };\n return { via };\n}\n\nfunction confirmationGate(gate: Gate): (call: PreparedCall) => Promise<void> {\n return async ({ action, name, input, ctx }) => {\n const turn = ctx.principal?.kind === \"agent\" ? ctx.principal.turn : undefined;\n const outcome = await gate.confirm({\n scope: gate.scope,\n clientId: turn?.clientId ?? gate.clientId,\n ...(turn ? { thread: { threadId: turn.threadId, turnId: turn.turnId } } : {}),\n action: name,\n description: action.description,\n input,\n origin: gate.origin ?? originOf(ctx.source, ctx.principal ?? ANONYMOUS),\n signal: gate.signal,\n });\n if (outcome !== \"cancelled\") {\n gate.answered(outcome === \"shutdown\" ? \"unavailable\" : outcome);\n }\n switch (outcome) {\n case \"approved\":\n return;\n case \"declined\":\n throw new ActionError(\n \"declined\",\n `The user declined ${name} in the app; nothing ran. Do not retry unless they ask again.`,\n );\n case \"timeout\":\n throw new ActionError(\n \"confirmation_timeout\",\n `The user did not answer in time; ${name} did not run.`,\n );\n case \"unavailable\":\n throw new ActionError(\n \"confirmation_unavailable\",\n `No open app can ask the user to confirm ${name}. Ask the user to do it in the app themselves.`,\n );\n case \"shutdown\":\n throw new ActionError(\n \"confirmation_unavailable\",\n `The server shut down before the user answered; ${name} did not run. Try again once it is back, or ask the user to do it in the app themselves.`,\n );\n case \"cancelled\":\n throw (\n gate.signal?.reason ?? new DOMException(\"The call was cancelled.\", \"AbortError\")\n );\n }\n };\n}\n\nconst INTERNAL_CALLER: Caller = {\n principal: ANONYMOUS,\n scope: DEFAULT_SCOPE,\n audience: DEFAULT_SCOPE,\n account: undefined,\n clientId: undefined,\n};\n\nexport function createActionRunner<T extends ActionMap>(\n options: ActionRunnerOptions<T>,\n): ActionRunner {\n const {\n actions,\n scope,\n database,\n sync,\n onClient,\n confirm,\n confirmation,\n audit,\n admit,\n } = options;\n const registryFor = options.registryFor ?? (() => Promise.resolve(actions));\n const callers = options.callers ?? createCallerResolver(undefined, scope);\n const pruner = sync && database ? createPruner(database) : undefined;\n let prepared: Promise<void> | undefined;\n const ready =\n options.ready ??\n (() => {\n prepared ??=\n sync && database\n ? ensureSyncTables(database.read() as SyncDatabase)\n : Promise.resolve();\n return prepared;\n });\n\n const cursorBefore = async (\n registry: ActionRegistry,\n name: string,\n caller: Caller,\n ): Promise<string | undefined> => {\n const action = registry.get(name);\n if (!sync || !database || !action?.reads || isMutating(action)) return undefined;\n return encodeCursor(\n await readSyncCursor(database.read() as SyncDatabase, streamsOf(caller)),\n );\n };\n\n const invoke = async (\n name: string,\n input: unknown,\n request: Request | undefined,\n caller: Caller,\n source: ActionSource,\n runOptions: RunOptions,\n trace: Trace,\n ): Promise<ActionRun> => {\n if (runOptions.surface) requireSurface(caller, runOptions.surface, callers.enforcing);\n await admit?.(caller);\n const registry = await registryFor(request);\n const client = caller.clientId;\n if (caller.principal.kind !== \"key\") onClient?.(client, caller.audience);\n const signal = runOptions.signal ?? request?.signal;\n const resolvedScope = caller.scope;\n const cursor = runOptions.cursor\n ? await cursorBefore(registry, name, caller)\n : undefined;\n const result = await invokeAction(\n registry,\n name,\n input,\n { scope: resolvedScope, source, principal: caller.principal, signal, request },\n {\n data: database,\n enforcing: callers.enforcing,\n onRun: () => {\n trace.stage = \"ran\";\n },\n confirmation,\n onWaived: () => {\n trace.confirmation = \"waived\";\n },\n confirm: confirm\n ? confirmationGate({\n confirm,\n answered: (answer) => {\n trace.confirmation = answer;\n },\n scope: caller.audience,\n clientId: client,\n origin: runOptions.origin,\n signal,\n })\n : undefined,\n onWrite:\n sync && database\n ? async ({ action, tags, tx }) => {\n if (tags.length === 0) return;\n await recordSyncEvent(tx as SyncDatabase, {\n scope: notifiedStream(action.notifies, caller),\n tags,\n source: client,\n });\n }\n : undefined,\n },\n );\n if (result.writes.length > 0) pruner?.touch();\n return cursor === undefined ? result : { ...result, cursor };\n };\n\n return {\n ready,\n async run(name, input, request, declared, runOptions = {}) {\n await ready();\n const caller = request ? await callers(request) : INTERNAL_CALLER;\n const source = sourceFor(declared, caller, callers.enforcing, runOptions.surface);\n const trace: Trace = { stage: \"refused\", confirmation: undefined };\n if (!audit) return invoke(name, input, request, caller, source, runOptions, trace);\n const at = Date.now();\n const record = async (outcome: ActionAudit[\"outcome\"]) => {\n try {\n audit({\n at,\n action: name,\n principal: caller.principal,\n source,\n scope: caller.scope,\n inputDigest: await digest(input),\n stage: trace.stage,\n outcome,\n ...(trace.confirmation ? { confirmation: trace.confirmation } : {}),\n });\n } catch (error) {\n console.error(\"[parlor] audit failed:\", error);\n }\n };\n try {\n const result = await invoke(\n name,\n input,\n request,\n caller,\n source,\n runOptions,\n trace,\n );\n await record(\"ok\");\n return result;\n } catch (error) {\n await record(outcomeOf(error));\n throw error;\n }\n },\n };\n}\n\ninterface Trace {\n stage: ActionAudit[\"stage\"];\n confirmation: ConfirmationAnswer | undefined;\n}\n\nfunction outcomeOf(error: unknown): ActionAudit[\"outcome\"] {\n if (error instanceof ActionError) return error.code;\n if (error instanceof AuthFailure) return \"unauthenticated\";\n if (error instanceof Error && error.name === \"AbortError\") return \"cancelled\";\n return \"internal\";\n}\n\nasync function digest(input: unknown): Promise<string> {\n const bytes = new TextEncoder().encode(JSON.stringify(input ?? null));\n const hash = await crypto.subtle.digest(\"SHA-256\", bytes);\n return [...new Uint8Array(hash)].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nfunction notifiedStream(\n notifies: \"scope\" | \"user\" | \"account\" | undefined,\n caller: Caller,\n): string {\n switch (notifies) {\n case \"user\":\n return caller.audience;\n case \"account\":\n return caller.account ?? caller.audience;\n default:\n return caller.scope;\n }\n}\n"]}
package/dist/auth.d.ts CHANGED
@@ -61,6 +61,8 @@ export interface TurnDelegation {
61
61
  readonly clientId: string;
62
62
  readonly agent: string;
63
63
  readonly ttlMs: number;
64
+ /** The conversation's scope; a provider puts it in the token as `TurnBinding.scope`. */
65
+ readonly scope?: string | undefined;
64
66
  }
65
67
  export interface AgentDelegation {
66
68
  /** How the app names it, such as "Claude Code on Alice's MacBook". */
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAqEA,gGAAgG;AAChG,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AA0EnD,MAAM,OAAO,WAAY,SAAQ,KAAK;IAIzB,MAAM;IAHC,IAAI,GAAG,aAAa,CAAC;IAC9B,SAAS,CAAU;IAC5B,YACW,MAAyB,EAClC,OAAe,EACf,OAAO,GAAuB,EAAE;QAEhC,KAAK,CAAC,OAAO,CAAC,CAAC;sBAJN,MAAM;QAKf,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC7C,CAAC;CACF","sourcesContent":["import type {\n AuthenticatedPrincipal,\n DeviceId,\n GrantId,\n HostPrincipal,\n KeyPrincipal,\n Principal,\n ThreadId,\n TurnId,\n UserId,\n} from \"@parlor/core\";\n\nimport type { ServerPlugin } from \"./plugin.js\";\n\n/**\n * Where identity comes from. The server calls `authenticate` once per request and hands\n * the principal to actions, MCP, sync and agent UI. It installs like any plugin, first.\n */\nexport interface AuthProvider extends ServerPlugin {\n /**\n * When true, an anonymous caller is refused by non-public actions, by MCP (with\n * `challenge`) and by `/ui`, and `x-parlor-source` no longer decides an action's source.\n */\n readonly enforcing: boolean;\n /**\n * Missing credentials resolve to `anonymous`. Present but invalid, expired or revoked\n * credentials throw `AuthFailure`, which every surface answers with 401.\n */\n authenticate(request: Request): Promise<Principal>;\n /** The 401 an MCP client reads to discover the authorization server (RFC 9728). */\n challenge(request: Request): Response;\n /**\n * Aborts when the session or grant behind the principal is revoked. Held connections\n * (sync streams) close on it.\n */\n revoked(principal: AuthenticatedPrincipal): AbortSignal;\n /**\n * Mints the turn token an inline agent's MCP calls carry while one chat turn runs,\n * bound to the host's grant. Optional so providers written before chat still compile;\n * `chat()` refuses to start on a provider without it.\n */\n delegate?(host: HostPrincipal, turn: TurnDelegation): Promise<Delegation>;\n /**\n * Mints the token an agent on the host's computer carries outside any turn, such as\n * Claude Code in a terminal: an external MCP client of the user, revoked with the grant.\n */\n delegateAgent?(host: HostPrincipal, agent: AgentDelegation): Promise<Delegation>;\n /**\n * Whether the host grant still holds. Lists of computers drop a grant that answers\n * false at once, without waiting for the host to notice. Absent means every grant holds.\n */\n hostActive?(grantId: GrantId): Promise<boolean>;\n /** A device's public keys as the account registered them, for prompt and answer signatures. */\n device?(userId: UserId, deviceId: DeviceId): Promise<DeviceKeys | undefined>;\n /** Who the agent works for, for the turn's context block. */\n account?(userId: UserId): Promise<AccountProfile | undefined>;\n}\n\n/**\n * The app's own API keys, which an auth provider routes to it: an `authorization: Bearer`\n * token that starts with `prefix` is a key, checked before any other credential.\n */\nexport interface KeyVerifier {\n /** Must hold a character outside `[A-Za-z0-9]`, such as `_`, so no session token starts with it. */\n readonly prefix: string;\n /** The key's principal, or undefined for an unknown or revoked key, which is answered 401. */\n verify(secret: string, request: Request): Promise<KeyPrincipal | undefined>;\n}\n\n/** Announced when a computer's grant is added or removed; whatever lists computers reads it. */\nexport const HOST_GRANTS_TAG = \"parlor_auth_hosts\";\n\nexport interface TurnDelegation {\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly clientId: string;\n readonly agent: string;\n readonly ttlMs: number;\n}\n\nexport interface AgentDelegation {\n /** How the app names it, such as \"Claude Code on Alice's MacBook\". */\n readonly agent: string;\n readonly ttlMs: number;\n}\n\nexport interface Delegation {\n readonly token: string;\n readonly expiresAt: number;\n}\n\nexport interface DeviceKeys {\n readonly id: DeviceId;\n readonly name: string;\n readonly platform: string;\n readonly signingKey: JsonWebKey;\n readonly presenceKey?: PresenceKey | undefined;\n /** Linked devices' signed word that this one is the user's; each computer checks them itself. */\n readonly vouches?: readonly DeviceVouch[] | undefined;\n}\n\n/** A `VouchStatement` as the voucher signed it, with its presence key. */\nexport interface DeviceVouch {\n readonly voucher: DeviceId;\n readonly commitment: string;\n readonly at: number;\n readonly signature: {\n readonly keyId: string;\n readonly presence: \"none\" | \"user\";\n readonly format: \"es256-raw\" | \"webauthn\";\n readonly signature: string;\n readonly authenticatorData?: string | undefined;\n readonly clientDataJSON?: string | undefined;\n };\n}\n\nexport type PresenceKey =\n | {\n readonly format: \"webauthn\";\n readonly credentialId: string;\n readonly rpId: string;\n readonly publicKey: JsonWebKey;\n }\n | {\n readonly format: \"es256-raw\";\n readonly keyId: string;\n readonly publicKey: JsonWebKey;\n };\n\nexport interface AccountProfile {\n readonly name: string;\n readonly email?: string | undefined;\n}\n\nexport type AuthFailureReason = \"invalid\" | \"expired\" | \"revoked\";\n\nexport interface AuthFailureOptions {\n /**\n * False when signing in cannot fix it, such as a bad API key: MCP then answers a plain 401\n * instead of the provider's `challenge`.\n */\n readonly challenge?: boolean | undefined;\n}\n\nexport class AuthFailure extends Error {\n override readonly name = \"AuthFailure\";\n readonly challenge: boolean;\n constructor(\n readonly reason: AuthFailureReason,\n message: string,\n options: AuthFailureOptions = {},\n ) {\n super(message);\n this.challenge = options.challenge ?? true;\n }\n}\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAqEA,gGAAgG;AAChG,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AA4EnD,MAAM,OAAO,WAAY,SAAQ,KAAK;IAIzB,MAAM;IAHC,IAAI,GAAG,aAAa,CAAC;IAC9B,SAAS,CAAU;IAC5B,YACW,MAAyB,EAClC,OAAe,EACf,OAAO,GAAuB,EAAE;QAEhC,KAAK,CAAC,OAAO,CAAC,CAAC;sBAJN,MAAM;QAKf,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC7C,CAAC;CACF","sourcesContent":["import type {\n AuthenticatedPrincipal,\n DeviceId,\n GrantId,\n HostPrincipal,\n KeyPrincipal,\n Principal,\n ThreadId,\n TurnId,\n UserId,\n} from \"@parlor/core\";\n\nimport type { ServerPlugin } from \"./plugin.js\";\n\n/**\n * Where identity comes from. The server calls `authenticate` once per request and hands\n * the principal to actions, MCP, sync and agent UI. It installs like any plugin, first.\n */\nexport interface AuthProvider extends ServerPlugin {\n /**\n * When true, an anonymous caller is refused by non-public actions, by MCP (with\n * `challenge`) and by `/ui`, and `x-parlor-source` no longer decides an action's source.\n */\n readonly enforcing: boolean;\n /**\n * Missing credentials resolve to `anonymous`. Present but invalid, expired or revoked\n * credentials throw `AuthFailure`, which every surface answers with 401.\n */\n authenticate(request: Request): Promise<Principal>;\n /** The 401 an MCP client reads to discover the authorization server (RFC 9728). */\n challenge(request: Request): Response;\n /**\n * Aborts when the session or grant behind the principal is revoked. Held connections\n * (sync streams) close on it.\n */\n revoked(principal: AuthenticatedPrincipal): AbortSignal;\n /**\n * Mints the turn token an inline agent's MCP calls carry while one chat turn runs,\n * bound to the host's grant. Optional so providers written before chat still compile;\n * `chat()` refuses to start on a provider without it.\n */\n delegate?(host: HostPrincipal, turn: TurnDelegation): Promise<Delegation>;\n /**\n * Mints the token an agent on the host's computer carries outside any turn, such as\n * Claude Code in a terminal: an external MCP client of the user, revoked with the grant.\n */\n delegateAgent?(host: HostPrincipal, agent: AgentDelegation): Promise<Delegation>;\n /**\n * Whether the host grant still holds. Lists of computers drop a grant that answers\n * false at once, without waiting for the host to notice. Absent means every grant holds.\n */\n hostActive?(grantId: GrantId): Promise<boolean>;\n /** A device's public keys as the account registered them, for prompt and answer signatures. */\n device?(userId: UserId, deviceId: DeviceId): Promise<DeviceKeys | undefined>;\n /** Who the agent works for, for the turn's context block. */\n account?(userId: UserId): Promise<AccountProfile | undefined>;\n}\n\n/**\n * The app's own API keys, which an auth provider routes to it: an `authorization: Bearer`\n * token that starts with `prefix` is a key, checked before any other credential.\n */\nexport interface KeyVerifier {\n /** Must hold a character outside `[A-Za-z0-9]`, such as `_`, so no session token starts with it. */\n readonly prefix: string;\n /** The key's principal, or undefined for an unknown or revoked key, which is answered 401. */\n verify(secret: string, request: Request): Promise<KeyPrincipal | undefined>;\n}\n\n/** Announced when a computer's grant is added or removed; whatever lists computers reads it. */\nexport const HOST_GRANTS_TAG = \"parlor_auth_hosts\";\n\nexport interface TurnDelegation {\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly clientId: string;\n readonly agent: string;\n readonly ttlMs: number;\n /** The conversation's scope; a provider puts it in the token as `TurnBinding.scope`. */\n readonly scope?: string | undefined;\n}\n\nexport interface AgentDelegation {\n /** How the app names it, such as \"Claude Code on Alice's MacBook\". */\n readonly agent: string;\n readonly ttlMs: number;\n}\n\nexport interface Delegation {\n readonly token: string;\n readonly expiresAt: number;\n}\n\nexport interface DeviceKeys {\n readonly id: DeviceId;\n readonly name: string;\n readonly platform: string;\n readonly signingKey: JsonWebKey;\n readonly presenceKey?: PresenceKey | undefined;\n /** Linked devices' signed word that this one is the user's; each computer checks them itself. */\n readonly vouches?: readonly DeviceVouch[] | undefined;\n}\n\n/** A `VouchStatement` as the voucher signed it, with its presence key. */\nexport interface DeviceVouch {\n readonly voucher: DeviceId;\n readonly commitment: string;\n readonly at: number;\n readonly signature: {\n readonly keyId: string;\n readonly presence: \"none\" | \"user\";\n readonly format: \"es256-raw\" | \"webauthn\";\n readonly signature: string;\n readonly authenticatorData?: string | undefined;\n readonly clientDataJSON?: string | undefined;\n };\n}\n\nexport type PresenceKey =\n | {\n readonly format: \"webauthn\";\n readonly credentialId: string;\n readonly rpId: string;\n readonly publicKey: JsonWebKey;\n }\n | {\n readonly format: \"es256-raw\";\n readonly keyId: string;\n readonly publicKey: JsonWebKey;\n };\n\nexport interface AccountProfile {\n readonly name: string;\n readonly email?: string | undefined;\n}\n\nexport type AuthFailureReason = \"invalid\" | \"expired\" | \"revoked\";\n\nexport interface AuthFailureOptions {\n /**\n * False when signing in cannot fix it, such as a bad API key: MCP then answers a plain 401\n * instead of the provider's `challenge`.\n */\n readonly challenge?: boolean | undefined;\n}\n\nexport class AuthFailure extends Error {\n override readonly name = \"AuthFailure\";\n readonly challenge: boolean;\n constructor(\n readonly reason: AuthFailureReason,\n message: string,\n options: AuthFailureOptions = {},\n ) {\n super(message);\n this.challenge = options.challenge ?? true;\n }\n}\n"]}
package/dist/caller.d.ts CHANGED
@@ -7,9 +7,13 @@ export interface Caller {
7
7
  readonly scope: string;
8
8
  /** Scope plus user: whose screens this caller may see and drive (`audienceOf`). */
9
9
  readonly audience: string;
10
+ /** The user's stream across scopes (`accountAudience`); undefined for a key or no user. */
11
+ readonly account: string | undefined;
10
12
  /** The tab or app the request came from: a routing hint, never an identity. */
11
13
  readonly clientId: string | undefined;
12
14
  }
15
+ /** The sync streams a caller hears: its scope's, its own in the scope, and its account's. */
16
+ export declare function streamsOf(caller: Caller): string[];
13
17
  export interface CallerResolver {
14
18
  (request: Request): Promise<Caller>;
15
19
  readonly enforcing: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"caller.d.ts","sourceRoot":"","sources":["../src/caller.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,SAAS,EAEf,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AASD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,CAGvD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE7D;AAED,2FAA2F;AAC3F,wBAAgB,SAAS,CACvB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,EAClB,OAAO,CAAC,EAAE,OAAO,GAChB,YAAY,CAKd;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC5B,cAAc,CA2BhB"}
1
+ {"version":3,"file":"caller.d.ts","sourceRoot":"","sources":["../src/caller.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,SAAS,EAGf,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2FAA2F;IAC3F,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAQlD;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AASD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,CAGvD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE7D;AAED,2FAA2F;AAC3F,wBAAgB,SAAS,CACvB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,EAClB,OAAO,CAAC,EAAE,OAAO,GAChB,YAAY,CAKd;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC5B,cAAc,CAmChB"}
package/dist/caller.js CHANGED
@@ -1,6 +1,12 @@
1
- import { audienceOf } from "@parlor/agent-ui/server";
2
- import { ActionError, ANONYMOUS, sourceOfPrincipal, } from "@parlor/core";
1
+ import { accountAudience, audienceOf } from "@parlor/agent-ui/server";
2
+ import { ActionError, ANONYMOUS, sourceOfPrincipal, userOf, } from "@parlor/core";
3
3
  import { CLIENT_HEADER, SOURCE_HEADER } from "./protocol.js";
4
+ /** The sync streams a caller hears: its scope's, its own in the scope, and its account's. */
5
+ export function streamsOf(caller) {
6
+ return [
7
+ ...new Set([caller.scope, caller.audience, caller.account].filter((stream) => stream !== undefined)),
8
+ ];
9
+ }
4
10
  const SOURCES = new Set([
5
11
  "ui",
6
12
  "agent",
@@ -34,10 +40,15 @@ export function createCallerResolver(auth, scope, prepare) {
34
40
  if (principal.kind === "key" && resolvedScope !== principal.scope) {
35
41
  throw new ActionError("forbidden", "This key acts only in its own scope.");
36
42
  }
43
+ const turnScope = principal.kind === "agent" ? principal.turn?.scope : undefined;
44
+ if (turnScope !== undefined && resolvedScope !== turnScope) {
45
+ throw new ActionError("forbidden", "This turn acts only in its conversation's scope.");
46
+ }
37
47
  return {
38
48
  principal,
39
49
  scope: resolvedScope,
40
50
  audience: audienceOf(resolvedScope, principal),
51
+ account: principal.kind === "key" ? undefined : accountAudience(userOf(principal)),
41
52
  clientId: clientOf(request),
42
53
  };
43
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"caller.js","sourceRoot":"","sources":["../src/caller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EACL,WAAW,EACX,SAAS,EAGT,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAItB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAiB7D,MAAM,OAAO,GAAwB,IAAI,GAAG,CAAe;IACzD,IAAI;IACJ,OAAO;IACP,MAAM;IACN,KAAK;CACN,CAAC,CAAC;AAEH,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAClD,OAAO,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAuB,CAAC,CAAC,CAAC,MAAM,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC;AACzD,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,SAAS,CACvB,QAAsB,EACtB,MAAc,EACd,SAAkB,EAClB,OAAiB;IAEjB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAC7B,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,SAAS;QAAE,OAAO,QAAQ,CAAC;IAClE,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACxE,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAC;AACtC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAClC,IAA8B,EAC9B,KAAoB,EACpB,OAA6B;IAE7B,MAAM,OAAO,GAAG,IAAI,OAAO,EAA4B,CAAC;IACxD,MAAM,OAAO,GAAG,KAAK,EAAE,OAAgB,EAAmB,EAAE;QAC1D,IAAI,IAAI;YAAE,MAAM,OAAO,EAAE,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACtD,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,IAAI,aAAa,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;YAClE,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,sCAAsC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO;YACL,SAAS;YACT,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC;YAC9C,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC;SAC5B,CAAC;IACJ,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,OAAgB,EAAE,EAAE;QACnB,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,EAAE,CACxC,CAAC;AACJ,CAAC","sourcesContent":["import { audienceOf } from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n ANONYMOUS,\n type ActionSource,\n type Principal,\n sourceOfPrincipal,\n} from \"@parlor/core\";\n\nimport type { Surface } from \"./access.js\";\nimport type { AuthProvider } from \"./auth.js\";\nimport { CLIENT_HEADER, SOURCE_HEADER } from \"./protocol.js\";\nimport type { ScopeResolver } from \"./scope.js\";\n\nexport interface Caller {\n readonly principal: Principal;\n readonly scope: string;\n /** Scope plus user: whose screens this caller may see and drive (`audienceOf`). */\n readonly audience: string;\n /** The tab or app the request came from: a routing hint, never an identity. */\n readonly clientId: string | undefined;\n}\n\nexport interface CallerResolver {\n (request: Request): Promise<Caller>;\n readonly enforcing: boolean;\n}\n\nconst SOURCES: ReadonlySet<string> = new Set<ActionSource>([\n \"ui\",\n \"agent\",\n \"http\",\n \"mcp\",\n]);\n\nexport function sourceOf(request: Request): ActionSource {\n const header = request.headers.get(SOURCE_HEADER);\n return header && SOURCES.has(header) ? (header as ActionSource) : \"http\";\n}\n\nexport function clientOf(request: Request): string | undefined {\n return request.headers.get(CLIENT_HEADER) ?? undefined;\n}\n\n/** A key's source follows the surface it calls through: `mcp` on MCP, `http` elsewhere. */\nexport function sourceFor(\n declared: ActionSource,\n caller: Caller,\n enforcing: boolean,\n surface?: Surface,\n): ActionSource {\n const { principal } = caller;\n if (principal.kind === \"anonymous\" && !enforcing) return declared;\n if (principal.kind === \"key\") return surface === \"mcp\" ? \"mcp\" : \"http\";\n return sourceOfPrincipal(principal);\n}\n\n/** `prepare` runs before the provider sees a request, so its tables exist by then. */\nexport function createCallerResolver(\n auth: AuthProvider | undefined,\n scope: ScopeResolver,\n prepare?: () => Promise<void>,\n): CallerResolver {\n const callers = new WeakMap<Request, Promise<Caller>>();\n const resolve = async (request: Request): Promise<Caller> => {\n if (auth) await prepare?.();\n const principal = auth ? await auth.authenticate(request) : ANONYMOUS;\n const resolvedScope = await scope(request, principal);\n if (principal.kind === \"key\" && resolvedScope !== principal.scope) {\n throw new ActionError(\"forbidden\", \"This key acts only in its own scope.\");\n }\n return {\n principal,\n scope: resolvedScope,\n audience: audienceOf(resolvedScope, principal),\n clientId: clientOf(request),\n };\n };\n return Object.assign(\n (request: Request) => {\n let caller = callers.get(request);\n if (!caller) {\n caller = resolve(request);\n callers.set(request, caller);\n }\n return caller;\n },\n { enforcing: auth?.enforcing === true },\n );\n}\n"]}
1
+ {"version":3,"file":"caller.js","sourceRoot":"","sources":["../src/caller.ts"],"names":[],"mappings":"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","sourcesContent":["import { accountAudience, audienceOf } from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n ANONYMOUS,\n type ActionSource,\n type Principal,\n sourceOfPrincipal,\n userOf,\n} from \"@parlor/core\";\n\nimport type { Surface } from \"./access.js\";\nimport type { AuthProvider } from \"./auth.js\";\nimport { CLIENT_HEADER, SOURCE_HEADER } from \"./protocol.js\";\nimport type { ScopeResolver } from \"./scope.js\";\n\nexport interface Caller {\n readonly principal: Principal;\n readonly scope: string;\n /** Scope plus user: whose screens this caller may see and drive (`audienceOf`). */\n readonly audience: string;\n /** The user's stream across scopes (`accountAudience`); undefined for a key or no user. */\n readonly account: string | undefined;\n /** The tab or app the request came from: a routing hint, never an identity. */\n readonly clientId: string | undefined;\n}\n\n/** The sync streams a caller hears: its scope's, its own in the scope, and its account's. */\nexport function streamsOf(caller: Caller): string[] {\n return [\n ...new Set(\n [caller.scope, caller.audience, caller.account].filter(\n (stream) => stream !== undefined,\n ),\n ),\n ];\n}\n\nexport interface CallerResolver {\n (request: Request): Promise<Caller>;\n readonly enforcing: boolean;\n}\n\nconst SOURCES: ReadonlySet<string> = new Set<ActionSource>([\n \"ui\",\n \"agent\",\n \"http\",\n \"mcp\",\n]);\n\nexport function sourceOf(request: Request): ActionSource {\n const header = request.headers.get(SOURCE_HEADER);\n return header && SOURCES.has(header) ? (header as ActionSource) : \"http\";\n}\n\nexport function clientOf(request: Request): string | undefined {\n return request.headers.get(CLIENT_HEADER) ?? undefined;\n}\n\n/** A key's source follows the surface it calls through: `mcp` on MCP, `http` elsewhere. */\nexport function sourceFor(\n declared: ActionSource,\n caller: Caller,\n enforcing: boolean,\n surface?: Surface,\n): ActionSource {\n const { principal } = caller;\n if (principal.kind === \"anonymous\" && !enforcing) return declared;\n if (principal.kind === \"key\") return surface === \"mcp\" ? \"mcp\" : \"http\";\n return sourceOfPrincipal(principal);\n}\n\n/** `prepare` runs before the provider sees a request, so its tables exist by then. */\nexport function createCallerResolver(\n auth: AuthProvider | undefined,\n scope: ScopeResolver,\n prepare?: () => Promise<void>,\n): CallerResolver {\n const callers = new WeakMap<Request, Promise<Caller>>();\n const resolve = async (request: Request): Promise<Caller> => {\n if (auth) await prepare?.();\n const principal = auth ? await auth.authenticate(request) : ANONYMOUS;\n const resolvedScope = await scope(request, principal);\n if (principal.kind === \"key\" && resolvedScope !== principal.scope) {\n throw new ActionError(\"forbidden\", \"This key acts only in its own scope.\");\n }\n const turnScope = principal.kind === \"agent\" ? principal.turn?.scope : undefined;\n if (turnScope !== undefined && resolvedScope !== turnScope) {\n throw new ActionError(\n \"forbidden\",\n \"This turn acts only in its conversation's scope.\",\n );\n }\n return {\n principal,\n scope: resolvedScope,\n audience: audienceOf(resolvedScope, principal),\n account: principal.kind === \"key\" ? undefined : accountAudience(userOf(principal)),\n clientId: clientOf(request),\n };\n };\n return Object.assign(\n (request: Request) => {\n let caller = callers.get(request);\n if (!caller) {\n caller = resolve(request);\n callers.set(request, caller);\n }\n return caller;\n },\n { enforcing: auth?.enforcing === true },\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,SAAS,EAEd,KAAK,kBAAkB,EACvB,KAAK,YAAY,EAIlB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAQ3D,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,WAAW,CAAC;AAI5D,OAAO,KAAK,EAMV,YAAY,EACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS;IAChD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACzC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,GAAG,CAAC,EACT;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAC7E,KAAK,GACL,SAAS,CAAC;IACd,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,KAAK,GAAG,SAAS,CAAC;IACtD;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACvD;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACjD;AAKD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAoND,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAC9C,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,eAAe,CA8TjB"}
1
+ {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,SAAS,EAEd,KAAK,kBAAkB,EACvB,KAAK,YAAY,EAIlB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAQ3D,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,WAAW,CAAC;AAI5D,OAAO,KAAK,EAMV,YAAY,EACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS;IAChD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACzC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,GAAG,CAAC,EACT;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAC7E,KAAK,GACL,SAAS,CAAC;IACd,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,KAAK,GAAG,SAAS,CAAC;IACtD;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACvD;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACjD;AAKD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAoND,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAC9C,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,eAAe,CA+TjB"}
@@ -397,6 +397,7 @@ export function createServer(options) {
397
397
  hub,
398
398
  scope: async (request) => (await callers(request)).scope,
399
399
  audience: async (request) => (await callers(request)).audience,
400
+ account: async (request) => (await callers(request)).account,
400
401
  authority: async (request) => {
401
402
  const caller = await callers(request);
402
403
  const { principal } = caller;
@@ -1 +1 @@
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"]}
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,EAGT,kBAAkB,EAClB,OAAO,EACP,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;AAC9D,OAAO,EAEL,sBAAsB,GAEvB,MAAM,iBAAiB,CAAC;AAuDzB,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,EAC5B,YAAY,GACb,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,WAAW,GAAG,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9E,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,EACzC,UAA6B,EACf,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,YAAY;QACZ,KAAK;QACL,KAAK;QACL,WAAW,EAAE,UAAU;QACvB,KAAK;KACN,CAAC,CAAC;IACL,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC1D,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,IAAI,OAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,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,MAAM,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAC5B,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,YAAY;YACZ,WAAW;YACX,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,WAAW,GAAG,CAAC,CAAC,KAAK,YAAY,WAAW,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC;gBACvE,MAAM,UAAU,GACd,CAAC,OAAO,CAAC,IAAI,KAAK,iBAAiB,IAAI,WAAW,CAAC;oBACnD,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,IAAI,CAAC;gBACH,MAAM,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9B,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,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;YAC5D,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,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5E,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 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 account: async (request) => (await callers(request)).account,\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dev-auth.d.ts","sourceRoot":"","sources":["../src/dev-auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,WAAW,EAGZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAe,KAAK,YAAY,EAAuB,MAAM,WAAW,CAAC;AAEhF,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,qFAAqF;AACrF,eAAO,MAAM,aAAa,UAAU,CAAC;AAErC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CAC1C;AA4CD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,YAAY,CAiHlE"}
1
+ {"version":3,"file":"dev-auth.d.ts","sourceRoot":"","sources":["../src/dev-auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,WAAW,EAGZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAe,KAAK,YAAY,EAAuB,MAAM,WAAW,CAAC;AAEhF,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,qFAAqF;AACrF,eAAO,MAAM,aAAa,UAAU,CAAC;AAErC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CAC1C;AA6CD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,YAAY,CAmHlE"}
package/dist/dev-auth.js CHANGED
@@ -84,6 +84,7 @@ export function devAuth(options = {}) {
84
84
  turnId: asId("turn", claims.trn),
85
85
  hostId: asId("host", claims.hid),
86
86
  clientId: claims.cid,
87
+ ...(typeof claims.scp === "string" ? { scope: claims.scp } : {}),
87
88
  },
88
89
  };
89
90
  };
@@ -136,6 +137,7 @@ export function devAuth(options = {}) {
136
137
  trn: turn.turnId,
137
138
  cid: turn.clientId,
138
139
  agt: turn.agent,
140
+ ...(turn.scope === undefined ? {} : { scp: turn.scope }),
139
141
  iat,
140
142
  exp,
141
143
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dev-auth.js","sourceRoot":"","sources":["../src/dev-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHmac, randomBytes, timingSafeEqual } from \"node:crypto\";\n\nimport {\n ANONYMOUS,\n type AgentPrincipal,\n asId,\n DEV_USER_ID,\n type HostPrincipal,\n type Principal,\n} from \"@parlor/core\";\n\nimport { AuthFailure, type AuthProvider, type TurnDelegation } from \"./auth.js\";\n\nexport const DEV_AUTH_PLUGIN = \"dev-auth\";\n\nexport { DEV_USER_ID };\n\n/** `POST /_parlor/dev-auth/host`: mints the dev host token for a loopback caller. */\nexport const DEV_HOST_PATH = \"/host\";\n\nexport interface DevAuthOptions {\n readonly secret?: Uint8Array | undefined;\n}\n\nconst HOST_TYP = \"parlor-dev-host+jwt\";\nconst TURN_TYP = \"parlor-turn+jwt\";\nconst HOST_AUDIENCE = \"parlor:host\";\nconst TURN_AUDIENCE = \"parlor:mcp\";\nconst DEV_GRANT = asId(\"grant\", \"dev\");\nconst DEV_HOST = asId(\"host\", \"dev\");\n\ninterface TurnClaims {\n readonly aud: typeof TURN_AUDIENCE;\n readonly sub: string;\n readonly hid: string;\n readonly thr: string;\n readonly trn: string;\n readonly cid: string;\n readonly agt: string;\n readonly iat: number;\n readonly exp: number;\n}\n\ntype Fields = Readonly<Record<string, unknown>>;\n\nconst encode = (value: unknown) =>\n Buffer.from(JSON.stringify(value)).toString(\"base64url\");\n\nfunction decode(segment: string | undefined): Fields | undefined {\n if (!segment) return undefined;\n try {\n const value: unknown = JSON.parse(Buffer.from(segment, \"base64url\").toString(\"utf8\"));\n return typeof value === \"object\" && value !== null ? (value as Fields) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction isLoopback(ip: string | undefined): boolean {\n if (ip === undefined) return false;\n return ip === \"::1\" || ip.startsWith(\"127.\") || ip.startsWith(\"::ffff:127.\");\n}\n\nconst refuse = (message: string) =>\n Response.json({ error: { code: \"forbidden\", message } }, { status: 403 });\n\n/**\n * What `parlor dev` installs when the app has no auth provider. Not enforcing, so the\n * browser and external MCP clients keep today's anonymous, header-declared behavior; it\n * only adds the host and turn tokens the local inline agent needs. Both are signed with a\n * per-process secret, so restarting the server revokes them all.\n */\nexport function devAuth(options: DevAuthOptions = {}): AuthProvider {\n const secret = options.secret ?? randomBytes(32);\n const mac = (input: string) =>\n createHmac(\"sha256\", secret).update(input).digest(\"base64url\");\n const sign = (typ: string, claims: object) => {\n const input = `${encode({ alg: \"HS256\", typ })}.${encode(claims)}`;\n return `${input}.${mac(input)}`;\n };\n const verify = (token: string, typ: string): Fields | undefined => {\n const [header, payload, signature, ...rest] = token.split(\".\");\n if (rest.length > 0 || !header || !payload || !signature) return undefined;\n const expected = Buffer.from(mac(`${header}.${payload}`));\n const given = Buffer.from(signature);\n if (given.length !== expected.length || !timingSafeEqual(given, expected)) {\n return undefined;\n }\n return decode(header)?.typ === typ ? decode(payload) : undefined;\n };\n const typOf = (token: string) => decode(token.split(\".\")[0])?.typ;\n\n const hostOf = (token: string): HostPrincipal => {\n if (verify(token, HOST_TYP)?.aud !== HOST_AUDIENCE) {\n throw new AuthFailure(\"invalid\", \"This computer is not connected.\");\n }\n return { kind: \"host\", userId: DEV_USER_ID, grantId: DEV_GRANT, hostId: DEV_HOST };\n };\n\n const agentOf = (token: string): AgentPrincipal => {\n const claims = verify(token, TURN_TYP) as Partial<TurnClaims> | undefined;\n if (\n claims?.aud !== TURN_AUDIENCE ||\n typeof claims.exp !== \"number\" ||\n !claims.hid ||\n !claims.thr ||\n !claims.trn ||\n typeof claims.cid !== \"string\" ||\n !claims.agt\n ) {\n throw new AuthFailure(\"invalid\", \"The turn token is not valid.\");\n }\n if (claims.exp * 1000 <= Date.now()) {\n throw new AuthFailure(\"expired\", \"The turn is over.\");\n }\n return {\n kind: \"agent\",\n userId: DEV_USER_ID,\n grantId: DEV_GRANT,\n agent: { name: claims.agt, verified: true },\n turn: {\n threadId: asId(\"thread\", claims.thr),\n turnId: asId(\"turn\", claims.trn),\n hostId: asId(\"host\", claims.hid),\n clientId: claims.cid,\n },\n };\n };\n\n return {\n name: DEV_AUTH_PLUGIN,\n enforcing: false,\n setup: () => ({\n routes: [\n {\n method: \"POST\",\n path: DEV_HOST_PATH,\n access: \"public\",\n handle: async (request) => {\n if (request.headers.has(\"origin\")) {\n return refuse(\"The dev host token is not for web pages.\");\n }\n if (!isLoopback((request as Request & { readonly ip?: string }).ip)) {\n return refuse(\"The dev host token is only for this computer.\");\n }\n return Response.json({\n token: sign(HOST_TYP, { aud: HOST_AUDIENCE, hid: DEV_HOST }),\n hostId: DEV_HOST,\n });\n },\n },\n ],\n }),\n authenticate: async (request): Promise<Principal> => {\n const match = /^(\\w+)\\s+(\\S+)$/.exec(request.headers.get(\"authorization\") ?? \"\");\n const scheme = match?.[1]?.toLowerCase();\n const token = match?.[2];\n if (!token) return ANONYMOUS;\n if (scheme === \"parlorhost\") return hostOf(token);\n if (scheme === \"bearer\" && typOf(token) === TURN_TYP) return agentOf(token);\n return ANONYMOUS;\n },\n challenge: () =>\n Response.json(\n { error: { code: \"unauthenticated\", message: \"The turn is over.\" } },\n { status: 401 },\n ),\n revoked: () => new AbortController().signal,\n delegate: async (host: HostPrincipal, turn: TurnDelegation) => {\n const iat = Math.floor(Date.now() / 1000);\n const exp = iat + Math.ceil(turn.ttlMs / 1000);\n const claims: TurnClaims = {\n aud: TURN_AUDIENCE,\n sub: host.userId,\n hid: host.hostId,\n thr: turn.threadId,\n trn: turn.turnId,\n cid: turn.clientId,\n agt: turn.agent,\n iat,\n exp,\n };\n return { token: sign(TURN_TYP, claims), expiresAt: exp * 1000 };\n },\n };\n}\n"]}
1
+ {"version":3,"file":"dev-auth.js","sourceRoot":"","sources":["../src/dev-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHmac, randomBytes, timingSafeEqual } from \"node:crypto\";\n\nimport {\n ANONYMOUS,\n type AgentPrincipal,\n asId,\n DEV_USER_ID,\n type HostPrincipal,\n type Principal,\n} from \"@parlor/core\";\n\nimport { AuthFailure, type AuthProvider, type TurnDelegation } from \"./auth.js\";\n\nexport const DEV_AUTH_PLUGIN = \"dev-auth\";\n\nexport { DEV_USER_ID };\n\n/** `POST /_parlor/dev-auth/host`: mints the dev host token for a loopback caller. */\nexport const DEV_HOST_PATH = \"/host\";\n\nexport interface DevAuthOptions {\n readonly secret?: Uint8Array | undefined;\n}\n\nconst HOST_TYP = \"parlor-dev-host+jwt\";\nconst TURN_TYP = \"parlor-turn+jwt\";\nconst HOST_AUDIENCE = \"parlor:host\";\nconst TURN_AUDIENCE = \"parlor:mcp\";\nconst DEV_GRANT = asId(\"grant\", \"dev\");\nconst DEV_HOST = asId(\"host\", \"dev\");\n\ninterface TurnClaims {\n readonly aud: typeof TURN_AUDIENCE;\n readonly sub: string;\n readonly hid: string;\n readonly thr: string;\n readonly trn: string;\n readonly cid: string;\n readonly agt: string;\n readonly scp?: string | undefined;\n readonly iat: number;\n readonly exp: number;\n}\n\ntype Fields = Readonly<Record<string, unknown>>;\n\nconst encode = (value: unknown) =>\n Buffer.from(JSON.stringify(value)).toString(\"base64url\");\n\nfunction decode(segment: string | undefined): Fields | undefined {\n if (!segment) return undefined;\n try {\n const value: unknown = JSON.parse(Buffer.from(segment, \"base64url\").toString(\"utf8\"));\n return typeof value === \"object\" && value !== null ? (value as Fields) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction isLoopback(ip: string | undefined): boolean {\n if (ip === undefined) return false;\n return ip === \"::1\" || ip.startsWith(\"127.\") || ip.startsWith(\"::ffff:127.\");\n}\n\nconst refuse = (message: string) =>\n Response.json({ error: { code: \"forbidden\", message } }, { status: 403 });\n\n/**\n * What `parlor dev` installs when the app has no auth provider. Not enforcing, so the\n * browser and external MCP clients keep today's anonymous, header-declared behavior; it\n * only adds the host and turn tokens the local inline agent needs. Both are signed with a\n * per-process secret, so restarting the server revokes them all.\n */\nexport function devAuth(options: DevAuthOptions = {}): AuthProvider {\n const secret = options.secret ?? randomBytes(32);\n const mac = (input: string) =>\n createHmac(\"sha256\", secret).update(input).digest(\"base64url\");\n const sign = (typ: string, claims: object) => {\n const input = `${encode({ alg: \"HS256\", typ })}.${encode(claims)}`;\n return `${input}.${mac(input)}`;\n };\n const verify = (token: string, typ: string): Fields | undefined => {\n const [header, payload, signature, ...rest] = token.split(\".\");\n if (rest.length > 0 || !header || !payload || !signature) return undefined;\n const expected = Buffer.from(mac(`${header}.${payload}`));\n const given = Buffer.from(signature);\n if (given.length !== expected.length || !timingSafeEqual(given, expected)) {\n return undefined;\n }\n return decode(header)?.typ === typ ? decode(payload) : undefined;\n };\n const typOf = (token: string) => decode(token.split(\".\")[0])?.typ;\n\n const hostOf = (token: string): HostPrincipal => {\n if (verify(token, HOST_TYP)?.aud !== HOST_AUDIENCE) {\n throw new AuthFailure(\"invalid\", \"This computer is not connected.\");\n }\n return { kind: \"host\", userId: DEV_USER_ID, grantId: DEV_GRANT, hostId: DEV_HOST };\n };\n\n const agentOf = (token: string): AgentPrincipal => {\n const claims = verify(token, TURN_TYP) as Partial<TurnClaims> | undefined;\n if (\n claims?.aud !== TURN_AUDIENCE ||\n typeof claims.exp !== \"number\" ||\n !claims.hid ||\n !claims.thr ||\n !claims.trn ||\n typeof claims.cid !== \"string\" ||\n !claims.agt\n ) {\n throw new AuthFailure(\"invalid\", \"The turn token is not valid.\");\n }\n if (claims.exp * 1000 <= Date.now()) {\n throw new AuthFailure(\"expired\", \"The turn is over.\");\n }\n return {\n kind: \"agent\",\n userId: DEV_USER_ID,\n grantId: DEV_GRANT,\n agent: { name: claims.agt, verified: true },\n turn: {\n threadId: asId(\"thread\", claims.thr),\n turnId: asId(\"turn\", claims.trn),\n hostId: asId(\"host\", claims.hid),\n clientId: claims.cid,\n ...(typeof claims.scp === \"string\" ? { scope: claims.scp } : {}),\n },\n };\n };\n\n return {\n name: DEV_AUTH_PLUGIN,\n enforcing: false,\n setup: () => ({\n routes: [\n {\n method: \"POST\",\n path: DEV_HOST_PATH,\n access: \"public\",\n handle: async (request) => {\n if (request.headers.has(\"origin\")) {\n return refuse(\"The dev host token is not for web pages.\");\n }\n if (!isLoopback((request as Request & { readonly ip?: string }).ip)) {\n return refuse(\"The dev host token is only for this computer.\");\n }\n return Response.json({\n token: sign(HOST_TYP, { aud: HOST_AUDIENCE, hid: DEV_HOST }),\n hostId: DEV_HOST,\n });\n },\n },\n ],\n }),\n authenticate: async (request): Promise<Principal> => {\n const match = /^(\\w+)\\s+(\\S+)$/.exec(request.headers.get(\"authorization\") ?? \"\");\n const scheme = match?.[1]?.toLowerCase();\n const token = match?.[2];\n if (!token) return ANONYMOUS;\n if (scheme === \"parlorhost\") return hostOf(token);\n if (scheme === \"bearer\" && typOf(token) === TURN_TYP) return agentOf(token);\n return ANONYMOUS;\n },\n challenge: () =>\n Response.json(\n { error: { code: \"unauthenticated\", message: \"The turn is over.\" } },\n { status: 401 },\n ),\n revoked: () => new AbortController().signal,\n delegate: async (host: HostPrincipal, turn: TurnDelegation) => {\n const iat = Math.floor(Date.now() / 1000);\n const exp = iat + Math.ceil(turn.ttlMs / 1000);\n const claims: TurnClaims = {\n aud: TURN_AUDIENCE,\n sub: host.userId,\n hid: host.hostId,\n thr: turn.threadId,\n trn: turn.turnId,\n cid: turn.clientId,\n agt: turn.agent,\n ...(turn.scope === undefined ? {} : { scp: turn.scope }),\n iat,\n exp,\n };\n return { token: sign(TURN_TYP, claims), expiresAt: exp * 1000 };\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parlor/server",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "homepage": "https://cychien.github.io/parlor",
5
5
  "bugs": "https://github.com/cychien/parlor/issues",
6
6
  "license": "MIT",
@@ -24,9 +24,9 @@
24
24
  "drizzle-orm": "^0.45.4",
25
25
  "h3": "^2.0.1",
26
26
  "zod": "^4.6.5",
27
- "@parlor/agent-ui": "0.4.0",
28
- "@parlor/core": "0.4.0",
29
- "@parlor/sync": "0.4.0"
27
+ "@parlor/sync": "0.4.1",
28
+ "@parlor/core": "0.4.1",
29
+ "@parlor/agent-ui": "0.4.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@modelcontextprotocol/client": "^2.3.1",
@@ -34,7 +34,7 @@
34
34
  "srvx": "^1.0.5",
35
35
  "typescript": "^7.0.2",
36
36
  "vitest": "^5.0.3",
37
- "@parlor/data": "0.4.0"
37
+ "@parlor/data": "0.4.1"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "tsc -p tsconfig.json",