@parlor/agent-ui 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/client/agent-ui-client.d.ts +60 -0
  4. package/dist/client/agent-ui-client.d.ts.map +1 -0
  5. package/dist/client/agent-ui-client.js +407 -0
  6. package/dist/client/agent-ui-client.js.map +1 -0
  7. package/dist/client/confirmations.d.ts +34 -0
  8. package/dist/client/confirmations.d.ts.map +1 -0
  9. package/dist/client/confirmations.js +95 -0
  10. package/dist/client/confirmations.js.map +1 -0
  11. package/dist/client/environment.d.ts +37 -0
  12. package/dist/client/environment.d.ts.map +1 -0
  13. package/dist/client/environment.js +79 -0
  14. package/dist/client/environment.js.map +1 -0
  15. package/dist/client/highlight.d.ts +12 -0
  16. package/dist/client/highlight.d.ts.map +1 -0
  17. package/dist/client/highlight.js +98 -0
  18. package/dist/client/highlight.js.map +1 -0
  19. package/dist/client/index.d.ts +7 -0
  20. package/dist/client/index.d.ts.map +1 -0
  21. package/dist/client/index.js +7 -0
  22. package/dist/client/index.js.map +1 -0
  23. package/dist/client/json-equal.d.ts +2 -0
  24. package/dist/client/json-equal.d.ts.map +1 -0
  25. package/dist/client/json-equal.js +20 -0
  26. package/dist/client/json-equal.js.map +1 -0
  27. package/dist/client/registry.d.ts +54 -0
  28. package/dist/client/registry.d.ts.map +1 -0
  29. package/dist/client/registry.js +280 -0
  30. package/dist/client/registry.js.map +1 -0
  31. package/dist/client/screen.d.ts +20 -0
  32. package/dist/client/screen.d.ts.map +1 -0
  33. package/dist/client/screen.js +196 -0
  34. package/dist/client/screen.js.map +1 -0
  35. package/dist/client/write.d.ts +13 -0
  36. package/dist/client/write.d.ts.map +1 -0
  37. package/dist/client/write.js +101 -0
  38. package/dist/client/write.js.map +1 -0
  39. package/dist/index.d.ts +5 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +5 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/manifest.d.ts +44 -0
  44. package/dist/manifest.d.ts.map +1 -0
  45. package/dist/manifest.js +23 -0
  46. package/dist/manifest.js.map +1 -0
  47. package/dist/pages.d.ts +11 -0
  48. package/dist/pages.d.ts.map +1 -0
  49. package/dist/pages.js +42 -0
  50. package/dist/pages.js.map +1 -0
  51. package/dist/protocol.d.ts +206 -0
  52. package/dist/protocol.d.ts.map +1 -0
  53. package/dist/protocol.js +152 -0
  54. package/dist/protocol.js.map +1 -0
  55. package/dist/server/agent-ui.d.ts +36 -0
  56. package/dist/server/agent-ui.d.ts.map +1 -0
  57. package/dist/server/agent-ui.js +89 -0
  58. package/dist/server/agent-ui.js.map +1 -0
  59. package/dist/server/audience.d.ts +9 -0
  60. package/dist/server/audience.d.ts.map +1 -0
  61. package/dist/server/audience.js +15 -0
  62. package/dist/server/audience.js.map +1 -0
  63. package/dist/server/broker.d.ts +29 -0
  64. package/dist/server/broker.d.ts.map +1 -0
  65. package/dist/server/broker.js +152 -0
  66. package/dist/server/broker.js.map +1 -0
  67. package/dist/server/confirmations.d.ts +40 -0
  68. package/dist/server/confirmations.d.ts.map +1 -0
  69. package/dist/server/confirmations.js +230 -0
  70. package/dist/server/confirmations.js.map +1 -0
  71. package/dist/server/directory.d.ts +41 -0
  72. package/dist/server/directory.d.ts.map +1 -0
  73. package/dist/server/directory.js +193 -0
  74. package/dist/server/directory.js.map +1 -0
  75. package/dist/server/index.d.ts +10 -0
  76. package/dist/server/index.d.ts.map +1 -0
  77. package/dist/server/index.js +10 -0
  78. package/dist/server/index.js.map +1 -0
  79. package/dist/server/manifest-source.d.ts +10 -0
  80. package/dist/server/manifest-source.d.ts.map +1 -0
  81. package/dist/server/manifest-source.js +36 -0
  82. package/dist/server/manifest-source.js.map +1 -0
  83. package/dist/server/routes.d.ts +11 -0
  84. package/dist/server/routes.d.ts.map +1 -0
  85. package/dist/server/routes.js +38 -0
  86. package/dist/server/routes.js.map +1 -0
  87. package/dist/server/schemas.d.ts +69 -0
  88. package/dist/server/schemas.d.ts.map +1 -0
  89. package/dist/server/schemas.js +78 -0
  90. package/dist/server/schemas.js.map +1 -0
  91. package/dist/server/tools.d.ts +49 -0
  92. package/dist/server/tools.d.ts.map +1 -0
  93. package/dist/server/tools.js +312 -0
  94. package/dist/server/tools.js.map +1 -0
  95. package/dist/view.d.ts +54 -0
  96. package/dist/view.d.ts.map +1 -0
  97. package/dist/view.js +15 -0
  98. package/dist/view.js.map +1 -0
  99. package/dist/vite/index.d.ts +3 -0
  100. package/dist/vite/index.d.ts.map +1 -0
  101. package/dist/vite/index.js +3 -0
  102. package/dist/vite/index.js.map +1 -0
  103. package/dist/vite/manifest.d.ts +5 -0
  104. package/dist/vite/manifest.d.ts.map +1 -0
  105. package/dist/vite/manifest.js +107 -0
  106. package/dist/vite/manifest.js.map +1 -0
  107. package/dist/vite/plugin.d.ts +16 -0
  108. package/dist/vite/plugin.d.ts.map +1 -0
  109. package/dist/vite/plugin.js +192 -0
  110. package/dist/vite/plugin.js.map +1 -0
  111. package/package.json +65 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport {\n type JsonSchema,\n routeHref,\n type RouteEntry,\n type UiManifest,\n} from \"../manifest.js\";\nimport {\n type AgentOrigin,\n type ClientSummary,\n type ScreenSnapshot,\n UI_OPS,\n type UiOp,\n type UiOpResults,\n uiOpReadOnly,\n} from \"../protocol.js\";\nimport { type UiBroker, UiFailure } from \"./broker.js\";\nimport type { ClientDirectory, Selection } from \"./directory.js\";\nimport { uiOpInputs } from \"./schemas.js\";\n\nexport type UiToolName = `ui_${UiOp}`;\n\nconst toolName = <O extends UiOp>(op: O): `ui_${O}` => `ui_${op}`;\n\nexport const UI_TOOLS: readonly UiToolName[] = UI_OPS.map(toolName);\n\nexport const UI_MANIFEST_RESOURCE = \"parlor://manifest\";\n\nexport interface AgentToolContext {\n readonly scope: string;\n readonly clientId?: string | undefined;\n readonly origin: AgentOrigin;\n readonly signal?: AbortSignal | undefined;\n readonly webOrigin?: string | undefined;\n}\n\nexport interface AgentTool<I extends z.ZodObject = z.ZodObject> {\n readonly name: UiToolName;\n readonly description: string;\n readonly input: I;\n readonly readOnly: boolean;\n run(input: z.output<I>, ctx: AgentToolContext): Promise<unknown>;\n}\n\nexport interface ScreenToolResult extends ScreenSnapshot {\n readonly client: ClientSummary;\n readonly otherClients: readonly ClientSummary[];\n readonly tiedWith?: readonly string[] | undefined;\n}\n\nexport interface NavigateToolResult {\n readonly client: ClientSummary;\n readonly screen: ScreenSnapshot;\n}\n\nexport type SetToolResult = UiOpResults[\"set\"] & { readonly client: ClientSummary };\n\nexport type HighlightToolResult = UiOpResults[\"highlight\"] & {\n readonly client: ClientSummary;\n};\n\nexport interface UnreachableResult {\n readonly reachable: false;\n readonly reason: \"no_client\";\n readonly href?: string | undefined;\n}\n\nexport interface UiToolDeps {\n readonly directory: ClientDirectory;\n readonly broker: UiBroker;\n}\n\nconst clientIdInput = z\n .string()\n .optional()\n .describe(\n \"Target a specific app client by id, as listed in client or otherClients of a ui_screen result. Omit to use the one the user is looking at.\",\n );\n\nconst UNREACHABLE: UnreachableResult = { reachable: false, reason: \"no_client\" };\n\nfunction sentence(text: string): string {\n const trimmed = text.trim();\n return /[.!?]$/.test(trimmed) ? trimmed : `${trimmed}.`;\n}\n\nfunction viewCatalog(manifest: UiManifest | undefined): string {\n if (!manifest || manifest.views.length === 0) return \"\";\n const lines = manifest.views.map(\n (view) =>\n `- ${view.name}${view.keyed ? \" (keyed)\" : \"\"}: ${sentence(view.description)}`,\n );\n return `\\n\\nViews this app can show:\\n${lines.join(\"\\n\")}`;\n}\n\nfunction typeOf(schema: JsonSchema | undefined): string {\n if (!schema) return \"value\";\n if (Array.isArray(schema.enum))\n return schema.enum.map((value) => JSON.stringify(value)).join(\" | \");\n if (\"const\" in schema) return JSON.stringify(schema.const);\n const union = (schema.anyOf ?? schema.oneOf) as JsonSchema[] | undefined;\n if (Array.isArray(union)) return union.map(typeOf).join(\" | \");\n if (schema.type === \"array\")\n return `${typeOf(schema.items as JsonSchema | undefined)}[]`;\n return typeof schema.type === \"string\" ? schema.type : \"value\";\n}\n\n/** `filter?: \"all\" | \"done\", page?: number`: what a page's search params take. */\nfunction searchOf(search: JsonSchema | undefined): string | undefined {\n const properties = search?.properties as Record<string, JsonSchema> | undefined;\n if (!properties || Object.keys(properties).length === 0) return undefined;\n const required = new Set(Array.isArray(search?.required) ? search.required : []);\n return Object.entries(properties)\n .map(([name, schema]) => `${name}${required.has(name) ? \"\" : \"?\"}: ${typeOf(schema)}`)\n .join(\", \");\n}\n\nfunction routeCatalog(manifest: UiManifest | undefined): string {\n if (!manifest || manifest.routes.length === 0) return \"\";\n const lines = manifest.routes.map((route) => {\n const parts = [`- ${route.path}`];\n if (route.description) parts.push(` - ${sentence(route.description)}`);\n const search = searchOf(route.search);\n if (search) parts.push(` Search: ${search}.`);\n if (route.views.length > 0) parts.push(` Views: ${route.views.join(\", \")}.`);\n return parts.join(\"\");\n });\n return `\\n\\nPages:\\n${lines.join(\"\\n\")}`;\n}\n\nfunction screenDescription(manifest: UiManifest | undefined): string {\n return (\n [\n \"Read what the user currently sees in the app: the route, the actions feeding the screen (name and input, never data), the views on screen with their values, and attention.\",\n \"route is the page the url matched, with notFound: false, its path pattern, params, search and url; when the url matches no page and the app shows its not-found screen, route is notFound: true with only the url.\",\n \"attention holds focus (the focused element), selection (the text the user selected and the view holding it; null unless the selection lies inside one view), lastInteracted (the view the user last clicked or focused), lastEntered (the view the user last scrolled into view; null until the user scrolls, since items already on screen when the page renders never count), and focal (the view nearest the middle of the viewport).\",\n \"Keyed views list only the items inside the viewport, in screen order, plus an offscreen count.\",\n \"The result names the app client it came from and every other open client.\",\n \"Returns reachable: false when the app is not open anywhere.\",\n ].join(\" \") + viewCatalog(manifest)\n );\n}\n\nfunction navigateDescription(manifest: UiManifest | undefined): string {\n return (\n [\n \"Take the user's app to a page, filling $params in the path from params.\",\n \"Waits for the page's data to load (up to 1.5 s) and returns the new screen in ui_screen's shape, so its route shows the page the app landed on.\",\n \"Returns reachable: false with an href to hand the user when the app is not open.\",\n ].join(\" \") + routeCatalog(manifest)\n );\n}\n\nfunction writableCatalog(manifest: UiManifest | undefined): string {\n const lines = (manifest?.views ?? [])\n .filter((view) => view.writable.length > 0)\n .map(\n (view) =>\n `- ${view.name}${view.keyed ? \" (keyed)\" : \"\"}: ${sentence(view.description)} Fields: ${view.writable.join(\", \")}.`,\n );\n return lines.length === 0 ? \"\" : `\\n\\nForms you can fill:\\n${lines.join(\"\\n\")}`;\n}\n\nfunction setDescription(manifest: UiManifest | undefined): string {\n return (\n [\n \"Fill fields of a form the user sees, as a proposal: the user reviews it and submits it themselves. Call the matching action instead only when the user explicitly asks you to submit.\",\n \"value is merged into the view's current value field by field; fields you omit keep what the user typed.\",\n \"Returns the view's value read back from the screen and agentFields, the fields that still hold what you wrote; a field missing from agentFields was changed by the user.\",\n \"Refuses with not_mounted, not_writable, user_editing (the user is typing in that field: wait or ask), invalid_value (issues name the fields), or ambiguous_client.\",\n \"Returns reachable: false when the app is not open.\",\n ].join(\" \") + writableCatalog(manifest)\n );\n}\n\nfunction highlightDescription(): string {\n return [\n \"Point at something on the user's screen: scrolls a view (a keyed item by key) or one field inside it into the middle of the screen, focuses the field (not on a touch screen, where that opens the keyboard), and marks it for two seconds.\",\n \"Use it to show the user what you mean or to ask which one they meant.\",\n \"Returns shown, the visible fraction after scrolling, or not_mounted when it is not on screen, or reachable: false when the app is not open.\",\n \"Refuses with user_editing when the user is typing in another field: wait or ask, and it moves nothing.\",\n ].join(\" \");\n}\n\nfunction routeEnum(manifest: UiManifest | undefined) {\n const paths = manifest?.routes.map((route) => route.path) ?? [];\n const [first, ...rest] = paths;\n return first === undefined ? z.string() : z.enum([first, ...rest]);\n}\n\nfunction defineTool<I extends z.ZodObject>(tool: AgentTool<I>): AgentTool {\n return tool as unknown as AgentTool;\n}\n\nfunction withClients(\n directory: ClientDirectory,\n scope: string,\n selection: Selection,\n snapshot: ScreenSnapshot,\n): ScreenToolResult {\n const chosen = selection.target.client;\n return {\n client: directory.summary(chosen),\n otherClients: directory.summaries(scope).filter((c) => c.id !== chosen.id),\n ...(selection.tied.length > 0 ? { tiedWith: selection.tied.map((c) => c.id) } : {}),\n ...snapshot,\n };\n}\n\nfunction missingParams(\n route: RouteEntry,\n params: Readonly<Record<string, string>> | undefined,\n): void {\n const missing = route.params.filter((name) => !params?.[name]);\n if (missing.length === 0) return;\n throw new UiFailure({\n code: \"unknown_route\",\n message: `${route.path} needs params: ${missing.join(\", \")}.`,\n issues: missing.map((name) => ({ path: `params.${name}`, message: \"Required\" })),\n });\n}\n\nfunction hrefFor(href: string, webOrigin: string | undefined): string {\n return webOrigin ? new URL(href, webOrigin).href : href;\n}\n\nexport function createUiTools(\n deps: UiToolDeps,\n): (manifest: UiManifest | undefined) => readonly AgentTool[] {\n const { directory, broker } = deps;\n const refuseTie = (selection: Selection) => {\n if (selection.tied.length === 0) return;\n const candidates = [selection.target.client, ...selection.tied];\n throw new UiFailure({\n code: \"ambiguous_client\",\n message:\n \"The user has several app clients open and none stands out. Ask which one, then retry with clientId.\",\n issues: candidates.map((client) => {\n const summary = directory.summary(client);\n return {\n path: \"clientId\",\n message: `${summary.id} (${summary.platform}, ${summary.focused ? \"focused\" : \"not focused\"}, ${summary.visible ? \"visible\" : \"hidden\"}, seen ${summary.seenAgoMs} ms ago)`,\n };\n }),\n });\n };\n const requireOp = (selection: Selection, op: UiOp) => {\n const { client } = selection.target;\n if (client.ops.includes(op)) return;\n throw new UiFailure({\n code: \"unsupported_op\",\n message: `The app client ${client.id} (${client.platform}${client.buildId ? `, build ${client.buildId}` : \"\"}) is too old for ui_${op}. Ask the user to update the app; ui_screen and ui_navigate still work.`,\n });\n };\n const select = (ctx: AgentToolContext, clientId: string | undefined) => {\n if (ctx.clientId !== undefined) return selectBound(ctx, ctx.clientId, clientId);\n if (clientId !== undefined && !directory.connected(ctx.scope, clientId)) {\n const connected = directory.summaries(ctx.scope).map((client) => client.id);\n throw new UiFailure({\n code: \"unknown_client\",\n message: `No app client ${clientId} is connected. Connected clients: ${connected.join(\", \") || \"none\"}.`,\n issues: connected.map((id) => ({ path: \"clientId\", message: id })),\n });\n }\n return directory.select(ctx.scope, clientId);\n };\n const selectBound = (\n ctx: AgentToolContext,\n bound: string,\n requested: string | undefined,\n ) => {\n if (requested !== undefined && requested !== bound) {\n throw new UiFailure({\n code: \"unknown_client\",\n message: `This chat acts on the app client its prompt came from, not on ${requested}.`,\n });\n }\n if (!directory.connected(ctx.scope, bound)) {\n throw new UiFailure({\n code: \"unknown_client\",\n message: \"The app client this chat was sent from is no longer connected.\",\n });\n }\n return directory.select(ctx.scope, bound);\n };\n\n const build = (manifest: UiManifest | undefined): readonly AgentTool[] => {\n const screen = defineTool({\n name: \"ui_screen\",\n description: screenDescription(manifest),\n input: uiOpInputs.screen.extend({ clientId: clientIdInput }),\n readOnly: uiOpReadOnly.screen,\n async run({ clientId }, ctx) {\n const selection = select(ctx, clientId);\n if (!selection) return UNREACHABLE;\n const snapshot = await broker.request(\n selection.target,\n \"screen\",\n {},\n ctx.origin,\n ctx.signal,\n );\n return withClients(directory, ctx.scope, selection, snapshot);\n },\n });\n\n const navigate = defineTool({\n name: \"ui_navigate\",\n description: navigateDescription(manifest),\n input: uiOpInputs.navigate.extend({\n to: routeEnum(manifest).describe(\"The page's route path, exactly as listed.\"),\n clientId: clientIdInput,\n }),\n readOnly: uiOpReadOnly.navigate,\n async run({ to, params, search, replace, clientId }, ctx) {\n const selection = select(ctx, clientId);\n const route = manifest?.routes.find((entry) => entry.path === to);\n if (manifest && manifest.routes.length > 0 && !route) {\n throw new UiFailure({ code: \"unknown_route\", message: `No page at ${to}.` });\n }\n if (route) missingParams(route, params);\n if (!selection) {\n const href = routeHref(\n route ?? { path: to, params: [], views: [] },\n params,\n search,\n );\n return { ...UNREACHABLE, href: hrefFor(href, ctx.webOrigin) };\n }\n refuseTie(selection);\n const input = {\n to,\n ...(params ? { params } : {}),\n ...(search ? { search } : {}),\n ...(replace === undefined ? {} : { replace }),\n };\n const result = await broker.request(\n selection.target,\n \"navigate\",\n input,\n ctx.origin,\n ctx.signal,\n );\n const navigated: NavigateToolResult = {\n client: directory.summary(selection.target.client),\n screen: result.screen,\n };\n return navigated;\n },\n });\n\n const set = defineTool({\n name: toolName(\"set\"),\n description: setDescription(manifest),\n input: uiOpInputs.set.extend({ clientId: clientIdInput }),\n readOnly: uiOpReadOnly.set,\n async run({ view, key, value, clientId }, ctx) {\n const selection = select(ctx, clientId);\n if (!selection) return UNREACHABLE;\n refuseTie(selection);\n requireOp(selection, \"set\");\n const result = await broker.request(\n selection.target,\n \"set\",\n { view, ...(key === undefined ? {} : { key }), value },\n ctx.origin,\n ctx.signal,\n );\n const written: SetToolResult = {\n client: directory.summary(selection.target.client),\n ...result,\n };\n return written;\n },\n });\n\n const highlight = defineTool({\n name: toolName(\"highlight\"),\n description: highlightDescription(),\n input: uiOpInputs.highlight.extend({ clientId: clientIdInput }),\n readOnly: uiOpReadOnly.highlight,\n async run({ view, key, field, clientId }, ctx) {\n const selection = select(ctx, clientId);\n if (!selection) return UNREACHABLE;\n refuseTie(selection);\n requireOp(selection, \"highlight\");\n const result = await broker.request(\n selection.target,\n \"highlight\",\n {\n view,\n ...(key === undefined ? {} : { key }),\n ...(field === undefined ? {} : { field }),\n },\n ctx.origin,\n ctx.signal,\n );\n const pointed: HighlightToolResult = {\n client: directory.summary(selection.target.client),\n ...result,\n };\n return pointed;\n },\n });\n\n const byOp: { readonly [O in UiOp]: AgentTool } = {\n screen,\n navigate,\n set,\n highlight,\n };\n return UI_OPS.map((op) => byOp[op]);\n };\n\n let cachedFor: UiManifest | undefined;\n let cached = build(undefined);\n return (manifest) => {\n if (manifest !== cachedFor) {\n cached = build(manifest);\n cachedFor = manifest;\n }\n return cached;\n };\n}\n\nexport function uiInstructions(): string {\n return [\n \"This app's screen is visible to you through the ui_ tools, next to the app's actions.\",\n 'Call ui_screen to see what the user is looking at before acting on words like \"this\", \"that\" or \"here\".',\n \"Resolve them from attention in this order: focus, selection, lastInteracted, focal.\",\n \"A keyed view's key is the entity id that the app's actions take, so pass it straight to the action.\",\n \"Do the work through actions; the screen updates by itself.\",\n \"To show the user a page, call ui_navigate with a path from its list.\",\n \"You fill forms and the user submits them: use ui_set to fill a form, and call the action that submits it only when the user explicitly asks you to.\",\n \"Some actions ask the user to approve them in the app before they run: call them as usual and wait. If one fails with declined, do not retry unless the user asks again; if it fails with confirmation_unavailable, ask the user to do it in the app themselves.\",\n \"Use ui_highlight to point at what you mean, or at candidates when you need the user to pick one.\",\n \"If a ui_ tool returns reachable: false, the app is not open: tell the user, and for navigation hand them the href.\",\n ].join(\"\\n\");\n}\n"]}
package/dist/view.d.ts ADDED
@@ -0,0 +1,54 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ export type ViewSchema = StandardSchemaV1<unknown, Readonly<Record<string, unknown>>>;
3
+ export type ViewField<S extends ViewSchema> = keyof StandardSchemaV1.InferOutput<S> & string;
4
+ export type ViewWritable<S extends ViewSchema> = boolean | readonly ViewField<S>[];
5
+ export interface AgentViewConfig<N extends string, S extends ViewSchema, K extends boolean, W extends ViewWritable<S>> {
6
+ readonly name: N;
7
+ readonly description: string;
8
+ readonly schema: S;
9
+ readonly keyed?: K | undefined;
10
+ /** `true` opens every top-level field to `ui_set`, a list opens only those. Default `false`. */
11
+ readonly writable?: W | undefined;
12
+ }
13
+ declare const kView: unique symbol;
14
+ export interface AgentViewDefinition<N extends string = string, S extends ViewSchema = ViewSchema, K extends boolean = boolean, W extends boolean | readonly string[] = boolean | readonly string[]> {
15
+ readonly [kView]: true;
16
+ readonly name: N;
17
+ readonly description: string;
18
+ readonly schema: S;
19
+ readonly keyed: K;
20
+ readonly writable: W;
21
+ }
22
+ export type AnyAgentView = AgentViewDefinition<string, ViewSchema, boolean, boolean | readonly string[]>;
23
+ export declare function defineAgentView<const N extends string, S extends ViewSchema, const K extends boolean = false, const W extends ViewWritable<S> = false>(config: AgentViewConfig<N, S, K, W>): AgentViewDefinition<N, S, K, W>;
24
+ export declare function isAgentView(value: unknown): value is AnyAgentView;
25
+ export type ViewValue<D extends AnyAgentView> = StandardSchemaV1.InferOutput<D["schema"]>;
26
+ type FieldsOf<W, D extends AnyAgentView> = W extends true ? ViewField<D["schema"]> : W extends readonly (infer F)[] ? F : never;
27
+ export type WritableField<D extends AnyAgentView> = FieldsOf<D["writable"], D>;
28
+ export type IsWritable<D extends AnyAgentView> = [WritableField<D>] extends [never] ? false : true;
29
+ type KeyBinding<D extends AnyAgentView> = D["keyed"] extends true ? {
30
+ readonly key: string;
31
+ } : {
32
+ readonly key?: undefined;
33
+ };
34
+ /**
35
+ * Applies an agent's write. `next` is the whole value, already validated by the view's
36
+ * schema; `changed` lists the fields the agent sent. Contract: once `set` returns (or its
37
+ * promise resolves), `get()` reflects the write. `useAgentView` keeps it for React state by
38
+ * running `set` inside `flushSync`.
39
+ */
40
+ export type ViewSetter<D extends AnyAgentView> = (next: ViewValue<D>, changed: readonly WritableField<D>[]) => void | Promise<void>;
41
+ type SetBinding<D extends AnyAgentView> = IsWritable<D> extends true ? {
42
+ readonly set: ViewSetter<D>;
43
+ } : {
44
+ readonly set?: undefined;
45
+ };
46
+ export type AgentViewBinding<D extends AnyAgentView> = {
47
+ readonly get: () => ViewValue<D>;
48
+ } & KeyBinding<D> & SetBinding<D>;
49
+ export interface ViewRef {
50
+ readonly view: string;
51
+ readonly key?: string | undefined;
52
+ }
53
+ export {};
54
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAEtF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,UAAU,IAAI,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,GACjF,MAAM,CAAC;AAET,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,UAAU,IAAI,OAAO,GAAG,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;AAEnF,MAAM,WAAW,eAAe,CAC9B,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC;IAEzB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;IAC/B,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;CACnC;AAED,QAAA,MAAM,KAAK,EAAE,OAAO,MAAuC,CAAC;AAE5D,MAAM,WAAW,mBAAmB,CAClC,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,CAAC,SAAS,UAAU,GAAG,UAAU,EACjC,CAAC,SAAS,OAAO,GAAG,OAAO,EAC3B,CAAC,SAAS,OAAO,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,MAAM,EAAE;IAEnE,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GAAG,mBAAmB,CAC5C,MAAM,EACN,UAAU,EACV,OAAO,EACP,OAAO,GAAG,SAAS,MAAM,EAAE,CAC5B,CAAC;AAEF,wBAAgB,eAAe,CAC7B,KAAK,CAAC,CAAC,SAAS,MAAM,EACtB,CAAC,SAAS,UAAU,EACpB,KAAK,CAAC,CAAC,SAAS,OAAO,GAAG,KAAK,EAC/B,KAAK,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,EACvC,MAAM,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAStE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEjE;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,YAAY,IAAI,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE1F,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,YAAY,IAAI,CAAC,SAAS,IAAI,GACrD,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GACtB,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC5B,CAAC,GACD,KAAK,CAAC;AAEZ,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,YAAY,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AAE/E,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,YAAY,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC/E,KAAK,GACL,IAAI,CAAC;AAET,KAAK,UAAU,CAAC,CAAC,SAAS,YAAY,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,GAC7D;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxB;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,YAAY,IAAI,CAC/C,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAClB,OAAO,EAAE,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,KACjC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,KAAK,UAAU,CAAC,CAAC,SAAS,YAAY,IACpC,UAAU,CAAC,CAAC,CAAC,SAAS,IAAI,GACtB;IAAE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAEnC,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,YAAY,IAAI;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;CAClC,GAAG,UAAU,CAAC,CAAC,CAAC,GACf,UAAU,CAAC,CAAC,CAAC,CAAC;AAEhB,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC"}
package/dist/view.js ADDED
@@ -0,0 +1,15 @@
1
+ const kView = Symbol.for("parlor.agentView");
2
+ export function defineAgentView(config) {
3
+ return {
4
+ name: config.name,
5
+ description: config.description,
6
+ schema: config.schema,
7
+ keyed: (config.keyed ?? false),
8
+ writable: (config.writable ?? false),
9
+ [kView]: true,
10
+ };
11
+ }
12
+ export function isAgentView(value) {
13
+ return typeof value === "object" && value !== null && kView in value;
14
+ }
15
+ //# sourceMappingURL=view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.js","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAuBA,MAAM,KAAK,GAAkB,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAuB5D,MAAM,UAAU,eAAe,CAK7B,MAAmC;IACnC,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAM;QACnC,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAM;QACzC,CAAC,KAAK,CAAC,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,CAAC;AACvE,CAAC","sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport type ViewSchema = StandardSchemaV1<unknown, Readonly<Record<string, unknown>>>;\n\nexport type ViewField<S extends ViewSchema> = keyof StandardSchemaV1.InferOutput<S> &\n string;\n\nexport type ViewWritable<S extends ViewSchema> = boolean | readonly ViewField<S>[];\n\nexport interface AgentViewConfig<\n N extends string,\n S extends ViewSchema,\n K extends boolean,\n W extends ViewWritable<S>,\n> {\n readonly name: N;\n readonly description: string;\n readonly schema: S;\n readonly keyed?: K | undefined;\n /** `true` opens every top-level field to `ui_set`, a list opens only those. Default `false`. */\n readonly writable?: W | undefined;\n}\n\nconst kView: unique symbol = Symbol.for(\"parlor.agentView\");\n\nexport interface AgentViewDefinition<\n N extends string = string,\n S extends ViewSchema = ViewSchema,\n K extends boolean = boolean,\n W extends boolean | readonly string[] = boolean | readonly string[],\n> {\n readonly [kView]: true;\n readonly name: N;\n readonly description: string;\n readonly schema: S;\n readonly keyed: K;\n readonly writable: W;\n}\n\nexport type AnyAgentView = AgentViewDefinition<\n string,\n ViewSchema,\n boolean,\n boolean | readonly string[]\n>;\n\nexport function defineAgentView<\n const N extends string,\n S extends ViewSchema,\n const K extends boolean = false,\n const W extends ViewWritable<S> = false,\n>(config: AgentViewConfig<N, S, K, W>): AgentViewDefinition<N, S, K, W> {\n return {\n name: config.name,\n description: config.description,\n schema: config.schema,\n keyed: (config.keyed ?? false) as K,\n writable: (config.writable ?? false) as W,\n [kView]: true,\n };\n}\n\nexport function isAgentView(value: unknown): value is AnyAgentView {\n return typeof value === \"object\" && value !== null && kView in value;\n}\n\nexport type ViewValue<D extends AnyAgentView> = StandardSchemaV1.InferOutput<D[\"schema\"]>;\n\ntype FieldsOf<W, D extends AnyAgentView> = W extends true\n ? ViewField<D[\"schema\"]>\n : W extends readonly (infer F)[]\n ? F\n : never;\n\nexport type WritableField<D extends AnyAgentView> = FieldsOf<D[\"writable\"], D>;\n\nexport type IsWritable<D extends AnyAgentView> = [WritableField<D>] extends [never]\n ? false\n : true;\n\ntype KeyBinding<D extends AnyAgentView> = D[\"keyed\"] extends true\n ? { readonly key: string }\n : { readonly key?: undefined };\n\n/**\n * Applies an agent's write. `next` is the whole value, already validated by the view's\n * schema; `changed` lists the fields the agent sent. Contract: once `set` returns (or its\n * promise resolves), `get()` reflects the write. `useAgentView` keeps it for React state by\n * running `set` inside `flushSync`.\n */\nexport type ViewSetter<D extends AnyAgentView> = (\n next: ViewValue<D>,\n changed: readonly WritableField<D>[],\n) => void | Promise<void>;\n\ntype SetBinding<D extends AnyAgentView> =\n IsWritable<D> extends true\n ? { readonly set: ViewSetter<D> }\n : { readonly set?: undefined };\n\nexport type AgentViewBinding<D extends AnyAgentView> = {\n readonly get: () => ViewValue<D>;\n} & KeyBinding<D> &\n SetBinding<D>;\n\nexport interface ViewRef {\n readonly view: string;\n readonly key?: string | undefined;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { agentManifest, type AgentManifestApi, type AgentManifestOptions, DEFAULT_ROUTE_TREE, manifestFromModule, } from "./plugin.js";
2
+ export { buildUiManifest, describeView } from "./manifest.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { agentManifest, DEFAULT_ROUTE_TREE, manifestFromModule, } from "./plugin.js";
2
+ export { buildUiManifest, describeView } from "./manifest.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAGb,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export {\n agentManifest,\n type AgentManifestApi,\n type AgentManifestOptions,\n DEFAULT_ROUTE_TREE,\n manifestFromModule,\n} from \"./plugin.js\";\nexport { buildUiManifest, describeView } from \"./manifest.js\";\n"]}
@@ -0,0 +1,5 @@
1
+ import type { ManifestBuild, UiAppInfo, ViewEntry } from "../manifest.js";
2
+ import { type AnyAgentView } from "../view.js";
3
+ export declare function describeView(view: AnyAgentView): ViewEntry;
4
+ export declare function buildUiManifest(app: UiAppInfo, routeTree: unknown): ManifestBuild;
5
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/vite/manifest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,aAAa,EAEb,SAAS,EACT,SAAS,EACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,YAAY,EAAe,MAAM,YAAY,CAAC;AAwD5D,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAS1D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,GAAG,aAAa,CAwDjF"}
@@ -0,0 +1,107 @@
1
+ import { $ZodType, toJSONSchema } from "zod/v4/core";
2
+ import { isAgentView } from "../view.js";
3
+ function childrenOf(route) {
4
+ const { children } = route;
5
+ if (!children || typeof children !== "object")
6
+ return [];
7
+ return (Array.isArray(children) ? children : Object.values(children));
8
+ }
9
+ function joinPath(parent, path) {
10
+ const segments = [...parent.split("/"), ...(path ?? "").split("/")].filter(Boolean);
11
+ return `/${segments.join("/")}`;
12
+ }
13
+ function paramsOf(path) {
14
+ return path
15
+ .split("/")
16
+ .filter((segment) => segment.startsWith("$"))
17
+ .map((segment) => (segment === "$" ? "_splat" : segment.slice(1)));
18
+ }
19
+ function jsonSchemaOf(schema, io) {
20
+ if (schema instanceof $ZodType)
21
+ return toJSONSchema(schema, { io });
22
+ const converter = schema?.["~standard"]
23
+ ?.jsonSchema;
24
+ if (!converter)
25
+ return undefined;
26
+ try {
27
+ return converter[io]({ target: "draft-2020-12" });
28
+ }
29
+ catch {
30
+ return undefined;
31
+ }
32
+ }
33
+ function writableFields(view, schema) {
34
+ if (view.writable === true) {
35
+ const properties = schema?.properties;
36
+ return typeof properties === "object" && properties !== null
37
+ ? Object.keys(properties)
38
+ : [];
39
+ }
40
+ return view.writable === false ? [] : [...view.writable];
41
+ }
42
+ export function describeView(view) {
43
+ const schema = jsonSchemaOf(view.schema, "output");
44
+ return {
45
+ name: view.name,
46
+ description: view.description,
47
+ keyed: view.keyed,
48
+ ...(schema ? { schema } : {}),
49
+ writable: writableFields(view, schema),
50
+ };
51
+ }
52
+ export function buildUiManifest(app, routeTree) {
53
+ const warnings = [];
54
+ const routes = [];
55
+ const views = new Map();
56
+ const viewsOf = (route) => {
57
+ const listed = route.options?.staticData?.views;
58
+ if (!Array.isArray(listed))
59
+ return [];
60
+ const found = listed.filter(isAgentView);
61
+ for (const view of found) {
62
+ const known = views.get(view.name);
63
+ if (known && known !== view) {
64
+ throw new Error(`Two different agent views are named "${view.name}".`);
65
+ }
66
+ views.set(view.name, view);
67
+ }
68
+ return found;
69
+ };
70
+ const walk = (route, parentPath, inherited) => {
71
+ const names = [...new Set([...inherited, ...viewsOf(route).map((v) => v.name)])];
72
+ const path = route.isRoot ? "/" : joinPath(parentPath, route.options?.path);
73
+ const children = childrenOf(route);
74
+ if (children.length > 0 || route.isRoot) {
75
+ for (const child of children)
76
+ walk(child, path, names);
77
+ return;
78
+ }
79
+ if (routes.some((entry) => entry.path === path))
80
+ return;
81
+ const description = route.options?.staticData?.description;
82
+ if (typeof description !== "string" || description === "") {
83
+ warnings.push(`Route "${path}" has no staticData.description.`);
84
+ }
85
+ const search = jsonSchemaOf(route.options?.validateSearch, "input");
86
+ routes.push({
87
+ path,
88
+ ...(typeof description === "string" && description !== "" ? { description } : {}),
89
+ params: paramsOf(path),
90
+ ...(search ? { search } : {}),
91
+ views: names,
92
+ });
93
+ };
94
+ if (routeTree && typeof routeTree === "object")
95
+ walk(routeTree, "/", []);
96
+ const entries = [...views.values()].map(describeView);
97
+ for (const entry of entries) {
98
+ if (entry.schema)
99
+ continue;
100
+ warnings.push(`View "${entry.name}" has a schema that cannot be converted to JSON Schema, so the manifest lists it without one.`);
101
+ }
102
+ return {
103
+ manifest: { protocol: 1, app, routes, views: entries },
104
+ warnings,
105
+ };
106
+ }
107
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/vite/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StandardJSONSchemaV1 } from \"@standard-schema/spec\";\nimport { $ZodType, toJSONSchema } from \"zod/v4/core\";\n\nimport type {\n JsonSchema,\n ManifestBuild,\n RouteEntry,\n UiAppInfo,\n ViewEntry,\n} from \"../manifest.js\";\nimport { type AnyAgentView, isAgentView } from \"../view.js\";\n\ninterface RouteLike {\n readonly isRoot?: boolean | undefined;\n readonly options?:\n | {\n readonly path?: string | undefined;\n readonly staticData?:\n | { readonly description?: unknown; readonly views?: unknown }\n | undefined;\n readonly validateSearch?: unknown;\n }\n | undefined;\n readonly children?: unknown;\n}\n\nfunction childrenOf(route: RouteLike): RouteLike[] {\n const { children } = route;\n if (!children || typeof children !== \"object\") return [];\n return (Array.isArray(children) ? children : Object.values(children)) as RouteLike[];\n}\n\nfunction joinPath(parent: string, path: string | undefined): string {\n const segments = [...parent.split(\"/\"), ...(path ?? \"\").split(\"/\")].filter(Boolean);\n return `/${segments.join(\"/\")}`;\n}\n\nfunction paramsOf(path: string): string[] {\n return path\n .split(\"/\")\n .filter((segment) => segment.startsWith(\"$\"))\n .map((segment) => (segment === \"$\" ? \"_splat\" : segment.slice(1)));\n}\n\nfunction jsonSchemaOf(schema: unknown, io: \"input\" | \"output\"): JsonSchema | undefined {\n if (schema instanceof $ZodType) return toJSONSchema(schema, { io }) as JsonSchema;\n const converter = (schema as Partial<StandardJSONSchemaV1> | undefined)?.[\"~standard\"]\n ?.jsonSchema;\n if (!converter) return undefined;\n try {\n return converter[io]({ target: \"draft-2020-12\" });\n } catch {\n return undefined;\n }\n}\n\nfunction writableFields(view: AnyAgentView, schema: JsonSchema | undefined): string[] {\n if (view.writable === true) {\n const properties = schema?.properties;\n return typeof properties === \"object\" && properties !== null\n ? Object.keys(properties)\n : [];\n }\n return view.writable === false ? [] : [...view.writable];\n}\n\nexport function describeView(view: AnyAgentView): ViewEntry {\n const schema = jsonSchemaOf(view.schema, \"output\");\n return {\n name: view.name,\n description: view.description,\n keyed: view.keyed,\n ...(schema ? { schema } : {}),\n writable: writableFields(view, schema),\n };\n}\n\nexport function buildUiManifest(app: UiAppInfo, routeTree: unknown): ManifestBuild {\n const warnings: string[] = [];\n const routes: RouteEntry[] = [];\n const views = new Map<string, AnyAgentView>();\n\n const viewsOf = (route: RouteLike): AnyAgentView[] => {\n const listed = route.options?.staticData?.views;\n if (!Array.isArray(listed)) return [];\n const found = listed.filter(isAgentView);\n for (const view of found) {\n const known = views.get(view.name);\n if (known && known !== view) {\n throw new Error(`Two different agent views are named \"${view.name}\".`);\n }\n views.set(view.name, view);\n }\n return found;\n };\n\n const walk = (route: RouteLike, parentPath: string, inherited: readonly string[]) => {\n const names = [...new Set([...inherited, ...viewsOf(route).map((v) => v.name)])];\n const path = route.isRoot ? \"/\" : joinPath(parentPath, route.options?.path);\n const children = childrenOf(route);\n if (children.length > 0 || route.isRoot) {\n for (const child of children) walk(child, path, names);\n return;\n }\n if (routes.some((entry) => entry.path === path)) return;\n const description = route.options?.staticData?.description;\n if (typeof description !== \"string\" || description === \"\") {\n warnings.push(`Route \"${path}\" has no staticData.description.`);\n }\n const search = jsonSchemaOf(route.options?.validateSearch, \"input\");\n routes.push({\n path,\n ...(typeof description === \"string\" && description !== \"\" ? { description } : {}),\n params: paramsOf(path),\n ...(search ? { search } : {}),\n views: names,\n });\n };\n\n if (routeTree && typeof routeTree === \"object\") walk(routeTree as RouteLike, \"/\", []);\n\n const entries = [...views.values()].map(describeView);\n for (const entry of entries) {\n if (entry.schema) continue;\n warnings.push(\n `View \"${entry.name}\" has a schema that cannot be converted to JSON Schema, so the manifest lists it without one.`,\n );\n }\n\n return {\n manifest: { protocol: 1, app, routes, views: entries },\n warnings,\n };\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { type Plugin } from "vite";
2
+ import { type ManifestBuild, type UiAppInfo, type UiManifest } from "../manifest.js";
3
+ export declare const DEFAULT_ROUTE_TREE = "src/routeTree.gen.ts";
4
+ export interface AgentManifestOptions {
5
+ readonly app: UiAppInfo;
6
+ readonly routeTree?: string | undefined;
7
+ /** Where the manifest is written, absolute or relative to the root. Defaults to `.parlor`. */
8
+ readonly generatedDir?: string | undefined;
9
+ }
10
+ export declare function manifestFromModule(app: UiAppInfo, module: unknown): ManifestBuild;
11
+ export interface AgentManifestApi {
12
+ /** The manifest last generated, until the route tree fails to load. */
13
+ manifest(): UiManifest | undefined;
14
+ }
15
+ export declare function agentManifest(options: AgentManifestOptions): Plugin<AgentManifestApi>;
16
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/vite/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,MAAM,EAIZ,MAAM,MAAM,CAAC;AAEd,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,SAAS,EAEd,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AAIzD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,aAAa,CAEjF;AAiFD,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,QAAQ,IAAI,UAAU,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAAC,gBAAgB,CAAC,CA8HrF"}
@@ -0,0 +1,192 @@
1
+ import { access, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
2
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { build as viteBuild, isRunnableDevEnvironment, runnerImport, } from "vite";
5
+ import { UI_MANIFEST_FILE, } from "../manifest.js";
6
+ import { buildUiManifest } from "./manifest.js";
7
+ export const DEFAULT_ROUTE_TREE = "src/routeTree.gen.ts";
8
+ const GENERATED_DIR = ".parlor";
9
+ const REGENERATE_DEBOUNCE_MS = 50;
10
+ export function manifestFromModule(app, module) {
11
+ return buildUiManifest(app, module?.routeTree);
12
+ }
13
+ const STYLE_IMPORT = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:\?|$)/;
14
+ const EMPTY_STYLE = "\0parlor-empty-style";
15
+ /**
16
+ * The manifest needs route modules, never their stylesheets, and Vite's CSS plugin cannot
17
+ * run outside a build (8.3.5 throws), so every style import loads as an empty module.
18
+ */
19
+ function withoutStyles() {
20
+ return {
21
+ name: "parlor:manifest-without-styles",
22
+ enforce: "pre",
23
+ resolveId: (source) => (STYLE_IMPORT.test(source) ? EMPTY_STYLE : undefined),
24
+ load: (id) => (id === EMPTY_STYLE ? "export default {};" : undefined),
25
+ };
26
+ }
27
+ /**
28
+ * Imports the route tree as one tree-shaken bundle of it and its dependencies, so Node loads
29
+ * one module instead of every file of every library the routes import.
30
+ */
31
+ async function importBundled(entry, root, alias, outDir) {
32
+ const built = (await viteBuild({
33
+ root,
34
+ configFile: false,
35
+ logLevel: "silent",
36
+ publicDir: false,
37
+ resolve: { alias },
38
+ plugins: [withoutStyles()],
39
+ ssr: { noExternal: true },
40
+ build: {
41
+ ssr: entry,
42
+ write: false,
43
+ minify: false,
44
+ copyPublicDir: false,
45
+ rolldownOptions: { output: { codeSplitting: false } },
46
+ },
47
+ }));
48
+ const chunk = built.output.find((output) => output.type === "chunk" && output.isEntry);
49
+ if (!chunk)
50
+ throw new Error(`Bundling ${entry} produced no entry chunk.`);
51
+ await mkdir(outDir, { recursive: true });
52
+ const file = join(outDir, `route-tree.${process.pid}.${Date.now()}.mjs`);
53
+ await writeFile(file, chunk.code);
54
+ try {
55
+ return await import(pathToFileURL(file).href);
56
+ }
57
+ finally {
58
+ await rm(file, { force: true });
59
+ }
60
+ }
61
+ const STACK_FILE = /(?:\(|at )((?:file:\/\/)?\/[^\s()]+?):\d+:\d+\)?$/;
62
+ function throwingFile(error) {
63
+ const stack = error instanceof Error ? (error.stack ?? "") : "";
64
+ for (const line of stack.split("\n")) {
65
+ const file = STACK_FILE.exec(line.trim())?.[1];
66
+ if (file)
67
+ return file.startsWith("file:") ? fileURLToPath(file) : file;
68
+ }
69
+ return undefined;
70
+ }
71
+ function routeTreeImportFailure(root, routeTree, error) {
72
+ const file = throwingFile(error);
73
+ const module = relative(root, file && isAbsolute(file) ? file : routeTree);
74
+ const thrown = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
75
+ return `${module} threw "${thrown}" while the route tree was loaded in Node`;
76
+ }
77
+ export function agentManifest(options) {
78
+ let root = process.cwd();
79
+ let logger;
80
+ let lastWritten;
81
+ let current;
82
+ const routeTreePath = () => resolve(root, options.routeTree ?? DEFAULT_ROUTE_TREE);
83
+ const generatedDir = () => resolve(root, options.generatedDir ?? GENERATED_DIR);
84
+ const outFile = () => join(generatedDir(), UI_MANIFEST_FILE);
85
+ const write = async (build) => {
86
+ current = build.manifest;
87
+ for (const warning of build.warnings)
88
+ logger?.warn(`[parlor] ${warning}`);
89
+ const json = `${JSON.stringify(build.manifest, null, 2)}\n`;
90
+ lastWritten ??= await readFile(outFile(), "utf8").catch(() => undefined);
91
+ if (json === lastWritten)
92
+ return;
93
+ await mkdir(dirname(outFile()), { recursive: true });
94
+ const partial = `${outFile()}.${process.pid}.tmp`;
95
+ await writeFile(partial, json);
96
+ await rename(partial, outFile());
97
+ lastWritten = json;
98
+ };
99
+ const exists = (path) => access(path).then(() => true, () => false);
100
+ const loadRouteTree = async (load) => {
101
+ const entry = routeTreePath();
102
+ try {
103
+ return { ok: true, module: (await exists(entry)) ? await load(entry) : undefined };
104
+ }
105
+ catch (error) {
106
+ return { ok: false, failure: routeTreeImportFailure(root, entry, error) };
107
+ }
108
+ };
109
+ const watchInDev = (server) => {
110
+ const environment = server.environments.ssr;
111
+ if (!environment || !isRunnableDevEnvironment(environment))
112
+ return;
113
+ const runner = environment.runner;
114
+ const generated = generatedDir() + sep;
115
+ let timer;
116
+ let running = Promise.resolve();
117
+ const generate = () => {
118
+ running = running.then(async () => {
119
+ try {
120
+ runner.clearCache();
121
+ const loaded = await loadRouteTree((entry) => runner.import(entry));
122
+ if (!loaded.ok) {
123
+ logger?.error(`[parlor] Could not generate the agent UI manifest: ${loaded.failure}.`);
124
+ return;
125
+ }
126
+ await write(manifestFromModule(options.app, loaded.module));
127
+ }
128
+ catch (error) {
129
+ logger?.error(`[parlor] Could not generate the agent UI manifest: ${error.message}`);
130
+ }
131
+ });
132
+ };
133
+ const schedule = () => {
134
+ clearTimeout(timer);
135
+ timer = setTimeout(generate, REGENERATE_DEBOUNCE_MS);
136
+ };
137
+ const onFile = (file) => {
138
+ if (file.startsWith(generated))
139
+ return;
140
+ if (file === routeTreePath() || runner.evaluatedModules.getModulesByFile(file)) {
141
+ schedule();
142
+ }
143
+ };
144
+ server.watcher.on("change", onFile);
145
+ server.watcher.on("add", onFile);
146
+ server.watcher.on("unlink", onFile);
147
+ if (server.httpServer)
148
+ server.httpServer.once("listening", generate);
149
+ else
150
+ generate();
151
+ };
152
+ return {
153
+ name: "parlor:agent-manifest",
154
+ api: { manifest: () => current },
155
+ configResolved(config) {
156
+ root = config.root;
157
+ logger = config.logger;
158
+ },
159
+ configureServer(server) {
160
+ watchInDev(server);
161
+ },
162
+ async buildStart() {
163
+ if (this.environment.mode !== "build" || this.environment.name !== "client")
164
+ return;
165
+ const { alias } = this.environment.config.resolve;
166
+ const loaded = await loadRouteTree(async (entry) => {
167
+ try {
168
+ return await importBundled(entry, root, alias, dirname(outFile()));
169
+ }
170
+ catch {
171
+ // The runner loads module by module, so its failure names the module that threw.
172
+ return (await runnerImport(entry, {
173
+ root,
174
+ configFile: false,
175
+ logLevel: "error",
176
+ resolve: { alias },
177
+ plugins: [withoutStyles()],
178
+ })).module;
179
+ }
180
+ });
181
+ if (!loaded.ok) {
182
+ logger?.warn(`[parlor] Building without the agent UI manifest: ${loaded.failure}. Keep browser-only code out of the top level of route modules.`);
183
+ await rm(outFile(), { force: true });
184
+ lastWritten = undefined;
185
+ current = undefined;
186
+ return;
187
+ }
188
+ await write(manifestFromModule(options.app, loaded.module));
189
+ },
190
+ };
191
+ }
192
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/vite/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\n\nimport {\n type AliasOptions,\n build as viteBuild,\n isRunnableDevEnvironment,\n type Logger,\n type Plugin,\n type Rolldown,\n runnerImport,\n type ViteDevServer,\n} from \"vite\";\n\nimport {\n type ManifestBuild,\n type UiAppInfo,\n UI_MANIFEST_FILE,\n type UiManifest,\n} from \"../manifest.js\";\nimport { buildUiManifest } from \"./manifest.js\";\n\nexport const DEFAULT_ROUTE_TREE = \"src/routeTree.gen.ts\";\nconst GENERATED_DIR = \".parlor\";\nconst REGENERATE_DEBOUNCE_MS = 50;\n\nexport interface AgentManifestOptions {\n readonly app: UiAppInfo;\n readonly routeTree?: string | undefined;\n /** Where the manifest is written, absolute or relative to the root. Defaults to `.parlor`. */\n readonly generatedDir?: string | undefined;\n}\n\nexport function manifestFromModule(app: UiAppInfo, module: unknown): ManifestBuild {\n return buildUiManifest(app, (module as { routeTree?: unknown } | undefined)?.routeTree);\n}\n\nconst STYLE_IMPORT = /\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:\\?|$)/;\nconst EMPTY_STYLE = \"\\0parlor-empty-style\";\n\n/**\n * The manifest needs route modules, never their stylesheets, and Vite's CSS plugin cannot\n * run outside a build (8.3.5 throws), so every style import loads as an empty module.\n */\nfunction withoutStyles(): Plugin {\n return {\n name: \"parlor:manifest-without-styles\",\n enforce: \"pre\",\n resolveId: (source) => (STYLE_IMPORT.test(source) ? EMPTY_STYLE : undefined),\n load: (id) => (id === EMPTY_STYLE ? \"export default {};\" : undefined),\n };\n}\n\n/**\n * Imports the route tree as one tree-shaken bundle of it and its dependencies, so Node loads\n * one module instead of every file of every library the routes import.\n */\nasync function importBundled(\n entry: string,\n root: string,\n alias: AliasOptions,\n outDir: string,\n): Promise<unknown> {\n const built = (await viteBuild({\n root,\n configFile: false,\n logLevel: \"silent\",\n publicDir: false,\n resolve: { alias },\n plugins: [withoutStyles()],\n ssr: { noExternal: true },\n build: {\n ssr: entry,\n write: false,\n minify: false,\n copyPublicDir: false,\n rolldownOptions: { output: { codeSplitting: false } },\n },\n })) as Rolldown.RolldownOutput;\n const chunk = built.output.find(\n (output): output is Rolldown.OutputChunk => output.type === \"chunk\" && output.isEntry,\n );\n if (!chunk) throw new Error(`Bundling ${entry} produced no entry chunk.`);\n await mkdir(outDir, { recursive: true });\n const file = join(outDir, `route-tree.${process.pid}.${Date.now()}.mjs`);\n await writeFile(file, chunk.code);\n try {\n return await import(pathToFileURL(file).href);\n } finally {\n await rm(file, { force: true });\n }\n}\n\nconst STACK_FILE = /(?:\\(|at )((?:file:\\/\\/)?\\/[^\\s()]+?):\\d+:\\d+\\)?$/;\n\nfunction throwingFile(error: unknown): string | undefined {\n const stack = error instanceof Error ? (error.stack ?? \"\") : \"\";\n for (const line of stack.split(\"\\n\")) {\n const file = STACK_FILE.exec(line.trim())?.[1];\n if (file) return file.startsWith(\"file:\") ? fileURLToPath(file) : file;\n }\n return undefined;\n}\n\nfunction routeTreeImportFailure(root: string, routeTree: string, error: unknown): string {\n const file = throwingFile(error);\n const module = relative(root, file && isAbsolute(file) ? file : routeTree);\n const thrown =\n error instanceof Error ? `${error.name}: ${error.message}` : String(error);\n return `${module} threw \"${thrown}\" while the route tree was loaded in Node`;\n}\n\ntype RouteTreeLoad =\n | { readonly ok: true; readonly module: unknown }\n | { readonly ok: false; readonly failure: string };\n\nexport interface AgentManifestApi {\n /** The manifest last generated, until the route tree fails to load. */\n manifest(): UiManifest | undefined;\n}\n\nexport function agentManifest(options: AgentManifestOptions): Plugin<AgentManifestApi> {\n let root = process.cwd();\n let logger: Logger | undefined;\n let lastWritten: string | undefined;\n let current: UiManifest | undefined;\n\n const routeTreePath = () => resolve(root, options.routeTree ?? DEFAULT_ROUTE_TREE);\n const generatedDir = () => resolve(root, options.generatedDir ?? GENERATED_DIR);\n const outFile = () => join(generatedDir(), UI_MANIFEST_FILE);\n\n const write = async (build: ManifestBuild) => {\n current = build.manifest;\n for (const warning of build.warnings) logger?.warn(`[parlor] ${warning}`);\n const json = `${JSON.stringify(build.manifest, null, 2)}\\n`;\n lastWritten ??= await readFile(outFile(), \"utf8\").catch(() => undefined);\n if (json === lastWritten) return;\n await mkdir(dirname(outFile()), { recursive: true });\n const partial = `${outFile()}.${process.pid}.tmp`;\n await writeFile(partial, json);\n await rename(partial, outFile());\n lastWritten = json;\n };\n\n const exists = (path: string) =>\n access(path).then(\n () => true,\n () => false,\n );\n\n const loadRouteTree = async (\n load: (entry: string) => Promise<unknown>,\n ): Promise<RouteTreeLoad> => {\n const entry = routeTreePath();\n try {\n return { ok: true, module: (await exists(entry)) ? await load(entry) : undefined };\n } catch (error) {\n return { ok: false, failure: routeTreeImportFailure(root, entry, error) };\n }\n };\n\n const watchInDev = (server: ViteDevServer) => {\n const environment = server.environments.ssr;\n if (!environment || !isRunnableDevEnvironment(environment)) return;\n const runner = environment.runner;\n const generated = generatedDir() + sep;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let running: Promise<void> = Promise.resolve();\n\n const generate = () => {\n running = running.then(async () => {\n try {\n runner.clearCache();\n const loaded = await loadRouteTree((entry) => runner.import(entry));\n if (!loaded.ok) {\n logger?.error(\n `[parlor] Could not generate the agent UI manifest: ${loaded.failure}.`,\n );\n return;\n }\n await write(manifestFromModule(options.app, loaded.module));\n } catch (error) {\n logger?.error(\n `[parlor] Could not generate the agent UI manifest: ${(error as Error).message}`,\n );\n }\n });\n };\n const schedule = () => {\n clearTimeout(timer);\n timer = setTimeout(generate, REGENERATE_DEBOUNCE_MS);\n };\n const onFile = (file: string) => {\n if (file.startsWith(generated)) return;\n if (file === routeTreePath() || runner.evaluatedModules.getModulesByFile(file)) {\n schedule();\n }\n };\n server.watcher.on(\"change\", onFile);\n server.watcher.on(\"add\", onFile);\n server.watcher.on(\"unlink\", onFile);\n\n if (server.httpServer) server.httpServer.once(\"listening\", generate);\n else generate();\n };\n\n return {\n name: \"parlor:agent-manifest\",\n api: { manifest: () => current },\n configResolved(config) {\n root = config.root;\n logger = config.logger;\n },\n configureServer(server) {\n watchInDev(server);\n },\n async buildStart() {\n if (this.environment.mode !== \"build\" || this.environment.name !== \"client\") return;\n const { alias } = this.environment.config.resolve;\n const loaded = await loadRouteTree(async (entry) => {\n try {\n return await importBundled(entry, root, alias, dirname(outFile()));\n } catch {\n // The runner loads module by module, so its failure names the module that threw.\n return (\n await runnerImport(entry, {\n root,\n configFile: false,\n logLevel: \"error\",\n resolve: { alias },\n plugins: [withoutStyles()],\n })\n ).module;\n }\n });\n if (!loaded.ok) {\n logger?.warn(\n `[parlor] Building without the agent UI manifest: ${loaded.failure}. Keep browser-only code out of the top level of route modules.`,\n );\n await rm(outFile(), { force: true });\n lastWritten = undefined;\n current = undefined;\n return;\n }\n await write(manifestFromModule(options.app, loaded.module));\n },\n };\n}\n"]}