gesso-framework 0.6.30 → 0.8.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 (48) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/dist/{FunctionComponent-CHtojpp7.d.ts → FunctionComponent-BDVrANP0.d.ts} +371 -115
  3. package/dist/{serveChannels-BlEag7WU.js → WorkerPorts-m_hLRoPj.js} +8 -240
  4. package/dist/WorkerPorts-m_hLRoPj.js.map +1 -0
  5. package/dist/agent/index.d.ts +55 -2
  6. package/dist/agent/index.js +8 -4
  7. package/dist/agent/index.js.map +1 -1
  8. package/dist/app-De3z58x7.js +638 -0
  9. package/dist/app-De3z58x7.js.map +1 -0
  10. package/dist/computed-DyW9SPpq.js +587 -0
  11. package/dist/computed-DyW9SPpq.js.map +1 -0
  12. package/dist/createComponent-DJads88q.js +47 -0
  13. package/dist/createComponent-DJads88q.js.map +1 -0
  14. package/dist/{index-DZbSb8IN.d.ts → index-DocVauCS.d.ts} +593 -119
  15. package/dist/index.d.ts +4 -5
  16. package/dist/index.js +609 -6641
  17. package/dist/index.js.map +1 -1
  18. package/dist/jsx/jsx-runtime.d.ts +8 -5
  19. package/dist/jsx/jsx-runtime.js +15 -6
  20. package/dist/jsx/jsx-runtime.js.map +1 -1
  21. package/dist/{persisted-fUzIU8FZ.js → persisted-qEBOHDnj.js} +4 -576
  22. package/dist/persisted-qEBOHDnj.js.map +1 -0
  23. package/dist/remote/index.d.ts +2 -2
  24. package/dist/remote/index.js +2 -1
  25. package/dist/remote/index.js.map +1 -1
  26. package/dist/{remote-BoB8zh7z.js → remote-B4bjdTzg.js} +19 -4
  27. package/dist/remote-B4bjdTzg.js.map +1 -0
  28. package/dist/render-W2XO444K.js +7310 -0
  29. package/dist/render-W2XO444K.js.map +1 -0
  30. package/dist/serveChannels-DReCmRxO.js +241 -0
  31. package/dist/serveChannels-DReCmRxO.js.map +1 -0
  32. package/dist/{createComponent-3n1ZSql8.js → show-D0MevHaV.js} +2 -46
  33. package/dist/show-D0MevHaV.js.map +1 -0
  34. package/dist/{ui-CHtNccR8.d.ts → tools-Bl8LZ7LR.d.ts} +351 -8
  35. package/dist/{webmcp-CdDq2nzS.js → webmcp-D7IlA0fu.js} +3 -3
  36. package/dist/webmcp-D7IlA0fu.js.map +1 -0
  37. package/dist/worker/index.d.ts +3 -4
  38. package/dist/worker/index.js +5 -3
  39. package/dist/worker/index.js.map +1 -1
  40. package/package.json +2 -2
  41. package/dist/ChannelProtocol-ByNoHujM.d.ts +0 -247
  42. package/dist/app-Yig59Ygf.js +0 -326
  43. package/dist/app-Yig59Ygf.js.map +0 -1
  44. package/dist/createComponent-3n1ZSql8.js.map +0 -1
  45. package/dist/persisted-fUzIU8FZ.js.map +0 -1
  46. package/dist/remote-BoB8zh7z.js.map +0 -1
  47. package/dist/serveChannels-BlEag7WU.js.map +0 -1
  48. package/dist/webmcp-CdDq2nzS.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-De3z58x7.js","names":["themeTokens","themeTokens"],"sources":["../src/agent/designedTheme.ts","../src/agent/tools.ts","../src/agent/tokens.ts","../src/agent/ui.ts","../src/agent/app.ts"],"sourcesContent":["import { darkTheme, lightTheme, type UiTheme } from 'gesso-core';\n\n/** A theme an agent asks for: the application's own, or the light or dark one it designs in. */\nexport type AgentThemeName = 'app' | 'light' | 'dark';\n\n/**\n * The themes an application designs in, when they are not the ones it\n * is drawn in: a design editor's are the project's, and its own chrome\n * is no business of an agent designing that project.\n */\nexport interface DesignThemes {\n readonly light?: UiTheme;\n readonly dark?: UiTheme;\n}\n\n/**\n * The theme an agent's `theme` names, and what to call it back.\n *\n * `light` and `dark` are the application's design themes, or Gesso's\n * where it has none. `app` is the theme the running application is\n * drawn in. Asked for nothing, an application that has design themes\n * means them, its light one before its dark, since what it is drawn in\n * is not what is being designed; one without them means itself.\n */\nexport function designedTheme(\n asked: AgentThemeName | undefined,\n themes: DesignThemes,\n appTheme: () => UiTheme | undefined\n): { readonly theme: UiTheme; readonly name: AgentThemeName } {\n const name = asked ?? (themes.light !== undefined ? 'light' : themes.dark !== undefined ? 'dark' : 'app');\n if (name === 'dark') {\n return { theme: themes.dark ?? darkTheme, name };\n }\n if (name === 'light') {\n return { theme: themes.light ?? lightTheme, name };\n }\n return { theme: appTheme() ?? lightTheme, name };\n}\n","import type { JsonSchema } from '../channel/ChannelSchema';\nimport {\n WAITS_UP_TO,\n type AgentContent,\n type AgentSurfaceLike,\n type AgentTool,\n type AgentToolResult\n} from './AgentSurface';\nimport { validate } from './validate';\n\n/**\n * Tools an application offers an agent of its own accord, beside the\n * ones its channels and its screen give it.\n *\n * A channel command answers with the view, which is right for \"do this\n * and show me the state\": the agent sees what its call did. Some tools\n * answer with something else: a measurement, a list of problems, a\n * picture composed for the occasion. Those an application writes here,\n * and the render worker serves them with the rest:\n *\n * renderRoot(App).useAgentTools([{\n * name: 'board_check',\n * description: 'What is wrong with a screen, by element.',\n * inputSchema: { type: 'object', properties: { screen: { type: 'string' } }, required: ['screen'] },\n * readOnly: true,\n * run: async ({ screen }) => agentText(await check(screen as string))\n * }]);\n *\n * Arguments are checked against `inputSchema` before `run` is called,\n * and a thrown error becomes a result the agent reads, as every Gesso\n * tool's does: an agent corrects a call it can read the failure of.\n */\nexport interface AgentToolDefinition {\n readonly name: string;\n readonly title?: string;\n readonly description: string;\n /** An object schema: the tool's arguments, by name. */\n readonly inputSchema: JsonSchema;\n /** It changes nothing. */\n readonly readOnly?: boolean;\n /** It may undo or overwrite something a person made. */\n readonly destructive?: boolean;\n /** Calling it twice with the same arguments does what calling it once did. */\n readonly idempotent?: boolean;\n /**\n * How long a call may take, in milliseconds, for a tool that waits on\n * purpose: for a person to answer, or for something to happen (a tool\n * an agent calls to wait for its next task). The bridges between the\n * agent and this thread give it that long, where they would give up on\n * any other call after two minutes.\n */\n readonly waitsUpToMs?: number;\n run(args: Readonly<Record<string, unknown>>): AgentToolResult | Promise<AgentToolResult>;\n}\n\n/** A tool's answer as text, and, given, the same as data. */\nexport function agentText(text: string, structured?: Record<string, unknown>): AgentToolResult {\n return {\n content: [{ type: 'text', text }],\n ...(structured === undefined ? {} : { structuredContent: structured }),\n isError: false\n };\n}\n\n/** A tool's failure, written for the agent to correct its call by. */\nexport function agentError(text: string): AgentToolResult {\n return { content: [{ type: 'text', text }], isError: true };\n}\n\n/** A tool's answer as text and pictures, each a PNG's bytes. */\nexport function agentImages(\n text: string,\n pictures: readonly Uint8Array[],\n structured?: Record<string, unknown>\n): AgentToolResult {\n const content: AgentContent[] = [{ type: 'text', text }];\n for (const png of pictures) {\n content.push({ type: 'image', data: base64(png), mimeType: 'image/png' });\n }\n return { content, ...(structured === undefined ? {} : { structuredContent: structured }), isError: false };\n}\n\n/** Serves a list of tool definitions as a surface, read afresh each time so a list may change. */\nexport function toolSurface(definitions: () => readonly AgentToolDefinition[]): AgentSurfaceLike {\n const listed = (definition: AgentToolDefinition): AgentTool => ({\n name: definition.name,\n ...(definition.title === undefined ? {} : { title: definition.title }),\n description: definition.description,\n inputSchema: definition.inputSchema,\n annotations: {\n ...(definition.title === undefined ? {} : { title: definition.title }),\n readOnlyHint: definition.readOnly === true,\n ...(definition.destructive === undefined ? {} : { destructiveHint: definition.destructive }),\n ...(definition.idempotent === undefined ? {} : { idempotentHint: definition.idempotent }),\n openWorldHint: false\n },\n ...(definition.waitsUpToMs === undefined ? {} : { _meta: { [WAITS_UP_TO]: definition.waitsUpToMs } })\n });\n return {\n tools: () => definitions().map(listed),\n resources: () => [],\n read: () => undefined,\n call: async (name, args) => {\n const definition = definitions().find(each => each.name === name);\n if (definition === undefined) {\n return agentError(`There is no tool called ${name}.`);\n }\n const input = args ?? {};\n const problem = validate(definition.inputSchema, input);\n if (problem !== null) {\n return agentError(`${name}: ${problem}`);\n }\n try {\n return await definition.run(input);\n } catch (error) {\n return agentError(`${name} failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n };\n}\n\nfunction base64(bytes: Uint8Array): string {\n let binary = '';\n const chunk = 0x8000;\n for (let at = 0; at < bytes.length; at += chunk) {\n binary += String.fromCharCode(...bytes.subarray(at, at + chunk));\n }\n return btoa(binary);\n}\n","import { colorToHex, type UiBoxShadow, type UiColor, type UiTheme } from 'gesso-core';\n\n/**\n * A theme, as the design tokens an agent designs with.\n *\n * An agent writing a screen should say `backgroundColor=\"surface\"` and\n * `borderRadius=\"medium\"`, not `#f9fafb` and `8`: the names follow the\n * theme into dark mode, high contrast and a rebrand, and the numbers do\n * not. It can only say the names if it is told what they are, and a\n * theme's palette and scales are values in the running application,\n * which no reading of the source can give. So the page tells it.\n *\n * Colours are hex, because that is what a designer reads and what an\n * agent writes when it has to. The text names the props each group\n * feeds, so the agent learns the spelling along with the values.\n */\n\n/** The theme as plain data: what `tokens_view` returns as structured content. */\nexport interface ThemeTokens {\n readonly colors: Readonly<Record<string, string>>;\n readonly typography: Readonly<Record<string, TextStyleToken>>;\n readonly spacing: Readonly<Record<string, number>>;\n readonly shapes: Readonly<Record<string, unknown>>;\n readonly shadows: Readonly<Record<string, string>>;\n readonly density: string;\n readonly contrast: string;\n /** What an inch and a rem are worth in pixels: every other length here is pixels. */\n readonly units: { readonly pixelsPerInch: number; readonly rootFontSize: number };\n /** Token groups the application or a library added, by the name each was declared with. */\n readonly extensions: Readonly<Record<string, unknown>>;\n}\n\nexport interface TextStyleToken {\n readonly fontFamily: string;\n readonly fontSize: number;\n readonly fontWeight: string | number;\n readonly lineHeight: number;\n readonly letterSpacing: number;\n}\n\nexport function themeTokens(theme: UiTheme): ThemeTokens {\n const typography: Record<string, TextStyleToken> = {};\n for (const [role, style] of Object.entries(theme.typography)) {\n typography[role] = {\n fontFamily: style.fontFamily,\n fontSize: style.fontSize,\n fontWeight: style.fontWeight,\n lineHeight: style.lineHeight,\n letterSpacing: style.letterSpacing\n };\n }\n const shadows: Record<string, string> = {};\n for (const [name, layers] of Object.entries(theme.shadows)) {\n shadows[name] = (layers as readonly UiBoxShadow[]).map(formatShadow).join(', ') || 'none';\n }\n const extensions: Record<string, unknown> = {};\n for (const [key, group] of theme.extensions ?? []) {\n extensions[key.description ?? 'extension'] = plain(group);\n }\n return {\n colors: Object.fromEntries(Object.entries(theme.colors).map(([name, color]) => [name, hex(color)])),\n typography,\n spacing: { ...theme.spacing },\n shapes: plain(theme.shapes) as Record<string, unknown>,\n shadows,\n density: theme.density,\n contrast: theme.contrast,\n units: { pixelsPerInch: theme.units.pixelsPerInch, rootFontSize: theme.units.rootFontSize },\n extensions\n };\n}\n\n/**\n * The tokens as text, a few lines per group, for an agent to read.\n * `which` says which theme they are: \"The theme in force at the\n * application's outermost content\".\n */\nexport function formatThemeTokens(tokens: ThemeTokens, which: string): string {\n const lines = [\n `${which}. Write these names rather than their values, so a screen follows the theme ` +\n 'into dark mode, high contrast and a rebrand.',\n '',\n 'colors: any color prop takes the name (backgroundColor=\"surface\", color=\"primary\").'\n ];\n for (const [name, value] of Object.entries(tokens.colors)) {\n lines.push(` ${name} ${value}`);\n }\n lines.push('', 'typography: the textStyle prop takes the role (textStyle=\"title\"). family size/line-height weight');\n for (const [role, style] of Object.entries(tokens.typography)) {\n lines.push(` ${role} ${style.fontFamily} ${style.fontSize}/${style.lineHeight} ${style.fontWeight}`);\n }\n lines.push(\n '',\n 'shapes: borderRadius takes the name (borderRadius=\"medium\").',\n ` ${inline(tokens.shapes)}`,\n '',\n 'spacing: the scale, in pixels, for gap, padding and margin.',\n ` ${inline(tokens.spacing)}`,\n '',\n 'shadows:'\n );\n for (const [name, value] of Object.entries(tokens.shadows)) {\n lines.push(` ${name} ${value}`);\n }\n lines.push('', `density ${tokens.density}, contrast ${tokens.contrast}`);\n const { pixelsPerInch, rootFontSize } = tokens.units;\n lines.push(\n '',\n `units: every length above is pixels. 1in = ${pixelsPerInch}px, 1pt = ${round(pixelsPerInch / 72)}px, ` +\n `1mm = ${round(pixelsPerInch / 25.4)}px, 1rem = ${rootFontSize}px. To write one in these units, ` +\n \"convert with the theme's: const { rem, inch, pt, mm } = lengths(theme.units) from gesso-core.\"\n );\n const extensions = Object.entries(tokens.extensions);\n if (extensions.length > 0) {\n lines.push('', 'extensions: token groups the application added.');\n for (const [name, group] of extensions) {\n lines.push(` ${name} ${JSON.stringify(group)}`);\n }\n }\n return lines.join('\\n');\n}\n\nfunction round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\n\nfunction inline(record: Readonly<Record<string, unknown>>): string {\n return Object.entries(record)\n .map(([name, value]) => `${name} ${typeof value === 'object' ? JSON.stringify(value) : String(value)}`)\n .join(', ');\n}\n\nfunction formatShadow(shadow: UiBoxShadow): string {\n const color = typeof shadow.color === 'string' ? shadow.color : hex(shadow.color);\n const parts = [shadow.offsetX, shadow.offsetY, shadow.blurRadius, shadow.spreadRadius].join(' ');\n return `${shadow.inset === true ? 'inset ' : ''}${parts} ${color}`;\n}\n\nfunction isColor(value: unknown): value is UiColor {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const color = value as Partial<UiColor>;\n return (\n Object.keys(value).length === 4 &&\n typeof color.r === 'number' &&\n typeof color.g === 'number' &&\n typeof color.b === 'number' &&\n typeof color.a === 'number'\n );\n}\n\nfunction hex(color: UiColor): string {\n return colorToHex(color);\n}\n\n/** A token group as JSON can hold it: colours as hex, and nothing that is not data. */\nfunction plain(value: unknown): unknown {\n if (isColor(value)) {\n return hex(value);\n }\n if (Array.isArray(value)) {\n return value.map(plain);\n }\n if (typeof value === 'object' && value !== null) {\n const out: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry !== 'function') {\n out[key] = plain(entry);\n }\n }\n return out;\n }\n return value;\n}\n","import type { UiKeyModifiers, UiSemanticsAction, UiSemanticsMap, UiSemanticsRecord, UiTheme } from 'gesso-core';\n\nimport type { JsonSchema } from '../channel/ChannelSchema';\nimport type { AgentSurface, AgentTool, AgentToolResult } from './AgentSurface';\nimport { designedTheme, type AgentThemeName, type DesignThemes } from './designedTheme';\nimport type { RenderRequest } from './render';\nimport { formatThemeTokens, themeTokens } from './tokens';\n\n/**\n * The screen, as tools an agent can use.\n *\n * Channels are the application's own vocabulary, and the right way in\n * for anything they cover. Not everything is covered: a dialog's\n * buttons, a tab, a field the person is halfway through filling. For\n * those an agent has to do what a person does, and a canvas gives it\n * nothing to do that with: no DOM to query, no element to click.\n *\n * The semantics tree is the answer a screen reader already gets. Every\n * control has a role and an accessible name, a state, a value, and an\n * id, so an agent can read the screen as an outline and act on a\n * control by naming it. Acting goes through `applySemanticsAction`,\n * the path the accessibility mirror uses, which turns a press into the\n * same click a pointer makes and a value into the same edit a keyboard\n * makes: an agent can do exactly what a person could, no more, and an\n * open focus trap holds it as it holds Tab.\n *\n * ui_snapshot the screen as an outline, each control with a ref\n * ui_press press a control, by ref or by role and name\n * ui_type replace a field's text\n * ui_focus move focus to a control\n * ui_key press a key where focus is: Enter, Escape, Tab, ArrowDown\n * tokens_view the theme's colours, type, radii and spacing, by name\n * render_frame a module of the project drawn to a PNG, at a width\n *\n * Each action answers with the outline as it is afterwards.\n */\n\n/** What the tools need of the running application. */\nexport interface UiHost {\n semanticsTree(): UiSemanticsMap;\n focusedNodeId(): string | null;\n applySemanticsAction(action: UiSemanticsAction): void;\n key(key: string, modifiers: UiKeyModifiers): void;\n /**\n * Runs a pending frame now. A tab in the background is sent no\n * frames, and without one an action's effect never reaches the tree\n * this reads back.\n */\n flush(): void;\n /**\n * The theme in force at a node, by semantics record id, or at the\n * application's outermost content when none is named. Optional, so a\n * host written before it still serves the other tools; without it,\n * `tokens_view` says it cannot answer.\n */\n theme?(at?: string): UiTheme | undefined;\n /** The themes the application designs in, if they are not its own; see `designedTheme`. */\n designThemes?(): DesignThemes;\n /** Draws a module of the project to a PNG; see `renderModule`. Optional, as `theme` is. */\n render?(request: RenderRequest): Promise<AgentToolResult>;\n}\n\nexport interface UiSurfaceOptions {\n /** How long the screen must hold still after an action before it is read back (default 50 ms). */\n quietMs?: number;\n /** The longest an action waits for that (default 1000 ms). */\n settleMs?: number;\n}\n\nconst THEME: JsonSchema = {\n enum: ['app', 'light', 'dark'],\n description:\n \"The light or dark theme of what is being designed, or the running application's own (app). By default the \" +\n 'light one where the application designs in themes of its own, as a design editor does, else its own.'\n};\n\nconst TARGET: Record<string, JsonSchema> = {\n ref: { type: 'string', description: 'The ref ui_snapshot gave the control, such as \"e4\".' },\n role: { type: 'string', description: 'The control\\'s role, such as \"button\" or \"textbox\".' },\n name: { type: 'string', description: \"The control's accessible name, as ui_snapshot shows it in quotes.\" }\n};\n\nconst TOOLS: readonly AgentTool[] = [\n {\n name: 'ui_snapshot',\n title: 'Read the screen',\n description:\n 'The screen as an outline of what a screen reader would announce: each control with its role, name, state, ' +\n 'value and a ref to act on it by. Read it before acting, and again whenever an action did not do what you ' +\n 'expected. Prefer a channel tool when one covers what you want; these act on the interface.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: { readOnlyHint: true, openWorldHint: false }\n },\n {\n name: 'ui_press',\n title: 'Press a control',\n description:\n 'Presses a button, link, checkbox, tab or any other control, as a click would. Name it by ref, or by role and ' +\n 'name. Returns the screen afterwards.',\n inputSchema: { type: 'object', properties: TARGET, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }\n },\n {\n name: 'ui_type',\n title: 'Fill a field',\n description:\n \"Replaces a text field's whole text, as if the person had selected it all and typed. Name the field by ref, or \" +\n 'by role and name. Returns the screen afterwards; press Enter with ui_key to submit.',\n inputSchema: {\n type: 'object',\n properties: { ...TARGET, text: { type: 'string', description: 'The text the field should hold.' } },\n required: ['text'],\n additionalProperties: false\n },\n annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }\n },\n {\n name: 'ui_focus',\n title: 'Focus a control',\n description: 'Moves keyboard focus to a control, by ref or by role and name. Returns the screen afterwards.',\n inputSchema: { type: 'object', properties: TARGET, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false }\n },\n {\n name: 'ui_key',\n title: 'Press a key',\n description:\n 'Presses a key where focus is, as the keyboard would: Enter, Escape, Tab, ArrowDown, a letter. Modifiers are ' +\n 'optional. Returns the screen afterwards.',\n inputSchema: {\n type: 'object',\n properties: {\n key: { type: 'string', description: 'A KeyboardEvent key name, such as \"Enter\", \"Escape\" or \"a\".' },\n shift: { type: 'boolean' },\n ctrl: { type: 'boolean' },\n alt: { type: 'boolean' },\n meta: { type: 'boolean' }\n },\n required: ['key'],\n additionalProperties: false\n },\n annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }\n },\n {\n name: 'tokens_view',\n title: 'Read the design tokens',\n description:\n \"The theme's colours, type styles, corner radii, spacing scale and shadows, by name and value, as the screen \" +\n 'draws them. Read it before designing, and write the names rather than raw values. Name a control, by ref or ' +\n 'by role and name, to read the theme where it is: part of a screen may have a theme of its own.',\n inputSchema: { type: 'object', properties: { ...TARGET, theme: THEME }, additionalProperties: false },\n annotations: { readOnlyHint: true, openWorldHint: false }\n },\n {\n name: 'render_frame',\n title: 'Draw a frame',\n description:\n 'Draws a module of the project to a PNG you can look at: a mock, or a component with inputs, at the width ' +\n \"you ask for, in the theme being designed in. The pixels are the application's own: the same layout, \" +\n 'text and paint. Draw what you build, at a phone width and a desktop one, and look before you call it done. ' +\n 'Without a height it is as tall as its content, which suits a component or a section; give one for a whole ' +\n 'screen, which then fills it.',\n inputSchema: {\n type: 'object',\n properties: {\n module: {\n type: 'string',\n description: 'The module, from the project root, as library_overview gives it: \"src/mocks/Settings\".'\n },\n export: {\n type: 'string',\n description:\n \"The export to draw: a component or an element. By default the module's default, else its only component.\"\n },\n inputs: { type: 'object', description: 'Inputs for a component, by name, as library_get lists them.' },\n width: { type: 'number', description: 'In logical pixels: 390 for a phone, 1280 for a desktop.' },\n height: { type: 'number', description: 'In logical pixels. Leave it out to fit the content.' },\n scale: { type: 'number', description: 'Device pixels per logical pixel, 1 to 3 (default 1).' },\n theme: THEME\n },\n required: ['module', 'width'],\n additionalProperties: false\n },\n annotations: { readOnlyHint: true, openWorldHint: false }\n }\n];\n\n/**\n * The screen's tools, by name: what a relay that carries only the screen\n * (`gesso-electrobun`'s, to a desktop app's main process) lets through.\n * Listed from the tools themselves, so a tool added here is relayed\n * without the relay being told.\n */\nexport const SCREEN_TOOL_NAMES: readonly string[] = TOOLS.map(tool => tool.name);\n\n/**\n * Short names for record ids.\n *\n * A record's id is its path through the tree, `root:0:0:component:1:0:1`,\n * which is exact and long, and an outline repeats one on every line an\n * agent reads. A ref is `e` and a number, given the first time a record\n * is seen and kept for as long as the surface lives, so the ref an agent\n * read in one snapshot still names the same control in the next.\n */\nexport class UiRefs {\n private readonly byId = new Map<string, string>();\n private readonly byRef = new Map<string, string>();\n\n refOf(id: string): string {\n let ref = this.byId.get(id);\n if (ref === undefined) {\n ref = `e${this.byId.size + 1}`;\n this.byId.set(id, ref);\n this.byRef.set(ref, id);\n }\n return ref;\n }\n\n /** The record id a ref names, or the input itself when it is not a ref this surface gave. */\n idOf(ref: string): string {\n return this.byRef.get(ref) ?? ref;\n }\n}\n\n/**\n * The tools, over a host. `host` returns undefined until the\n * application has started, and a tool called before then says so.\n */\nexport function uiSurface(host: () => UiHost | undefined, options: UiSurfaceOptions = {}): AgentSurface {\n const quietMs = options.quietMs ?? 50;\n const settleMs = options.settleMs ?? 1000;\n const refs = new UiRefs();\n\n /** Waits until two readings of the screen agree, then returns the last. */\n const settled = async (ui: UiHost): Promise<string> => {\n const start = Date.now();\n let previous = '';\n for (;;) {\n ui.flush();\n const current = outline(ui.semanticsTree(), ui.focusedNodeId(), refs);\n if (current === previous || Date.now() - start >= settleMs) {\n return current;\n }\n previous = current;\n await new Promise(resolve => setTimeout(resolve, quietMs));\n }\n };\n\n const act = async (\n args: Readonly<Record<string, unknown>>,\n perform: (ui: UiHost, record: UiSemanticsRecord) => string | null\n ): Promise<AgentToolResult> => {\n const ui = host();\n if (ui === undefined) {\n return failure('The application has not started yet.');\n }\n ui.flush();\n const found = resolveTarget(ui.semanticsTree(), args, refs);\n if (typeof found === 'string') {\n return failure(found);\n }\n if (found.disabled === true) {\n return failure(`${describe(found)} is disabled.`);\n }\n const problem = perform(ui, found);\n if (problem !== null) {\n return failure(problem);\n }\n return success(await settled(ui));\n };\n\n return {\n tools: () => TOOLS,\n call: async (name, args = {}) => {\n switch (name) {\n case 'ui_snapshot': {\n const ui = host();\n return ui === undefined ? failure('The application has not started yet.') : success(await settled(ui));\n }\n case 'ui_press':\n return act(args, (ui, record) => (ui.applySemanticsAction({ id: record.id, action: 'click' }), null));\n case 'ui_focus':\n return act(args, (ui, record) => (ui.applySemanticsAction({ id: record.id, action: 'focus' }), null));\n case 'ui_type':\n if (typeof args.text !== 'string') {\n return failure('ui_type needs text: the text the field should hold.');\n }\n return act(args, (ui, record) => {\n if (record.states?.includes('readonly')) {\n return `${describe(record)} is read-only.`;\n }\n ui.applySemanticsAction({ id: record.id, action: 'setValue', value: args.text as string });\n return null;\n });\n case 'ui_key': {\n const ui = host();\n if (ui === undefined) {\n return failure('The application has not started yet.');\n }\n if (typeof args.key !== 'string' || args.key === '') {\n return failure('ui_key needs key: a KeyboardEvent key name, such as \"Enter\".');\n }\n ui.key(args.key, {\n shift: args.shift === true,\n ctrl: args.ctrl === true,\n alt: args.alt === true,\n meta: args.meta === true\n });\n return success(await settled(ui));\n }\n case 'tokens_view': {\n const ui = host();\n if (ui === undefined) {\n return failure('The application has not started yet.');\n }\n if (ui.theme === undefined) {\n return failure('This application does not report its theme to agents.');\n }\n let at: UiSemanticsRecord | undefined;\n if (args.ref !== undefined || args.role !== undefined || args.name !== undefined) {\n ui.flush();\n const found = resolveTarget(ui.semanticsTree(), args, refs);\n if (typeof found === 'string') {\n return failure(found);\n }\n at = found;\n }\n // A control named is read where it is. Otherwise the theme\n // asked for, or the one being designed in, which for a design\n // editor is its project's and not the editor's own.\n let theme: UiTheme | undefined;\n let which: string;\n if (at !== undefined) {\n theme = ui.theme(at.id);\n which = `The theme in force at ${describe(at)}`;\n } else {\n const designed = designedTheme(args.theme as AgentThemeName | undefined, ui.designThemes?.() ?? {}, () =>\n ui.theme?.()\n );\n theme = designed.name === 'app' ? ui.theme() : designed.theme;\n which =\n designed.name === 'app'\n ? \"The theme in force at the application's outermost content\"\n : `The ${designed.name} theme being designed in`;\n }\n if (theme === undefined) {\n return failure('The application has not drawn anything yet, so no theme is in force.');\n }\n const tokens = themeTokens(theme);\n return {\n content: [{ type: 'text', text: formatThemeTokens(tokens, which) }],\n structuredContent: tokens as unknown as Record<string, unknown>,\n isError: false\n };\n }\n case 'render_frame': {\n const ui = host();\n if (ui === undefined) {\n return failure('The application has not started yet.');\n }\n if (ui.render === undefined) {\n return failure('This application cannot draw frames for agents.');\n }\n if (typeof args.module !== 'string' || args.module === '') {\n return failure(\n 'render_frame needs module: the module, from the project root, such as \"src/mocks/Settings\".'\n );\n }\n if (typeof args.width !== 'number' || !(args.width > 0)) {\n return failure('render_frame needs width: a number of logical pixels above zero, such as 390.');\n }\n return ui.render(args as unknown as RenderRequest);\n }\n default:\n return failure(`There is no tool called ${name}.`);\n }\n },\n resources: () => [],\n read: () => undefined,\n dispose: () => {}\n };\n}\n\n/**\n * The tree as an indented outline, one control per line:\n *\n * - button \"Add one\" [e3]\n * - textbox \"Title\" value=\"Groceries\" [e4] (focused)\n *\n * Text, because an agent reads it, and an outline is a third the size\n * of the same tree as JSON. A record with neither a role nor a name is\n * structure, and its children are lifted to its depth.\n */\nexport function outline(tree: UiSemanticsMap, focused: string | null, refs: UiRefs = new UiRefs()): string {\n const depths = new Map<string, number>();\n const lines: string[] = [];\n for (const record of tree.values()) {\n const parentDepth = record.parent === null ? -1 : (depths.get(record.parent) ?? -1);\n const shown = record.role !== undefined || (record.label !== undefined && record.label !== '');\n const depth = shown ? parentDepth + 1 : parentDepth;\n depths.set(record.id, depth);\n if (!shown) {\n continue;\n }\n const parts = [`${' '.repeat(depth)}- ${describe(record)}`];\n if (record.states !== undefined && record.states.length > 0) {\n parts.push(`[${record.states.join(', ')}]`);\n }\n const value = valueOf(record);\n if (value !== null) {\n parts.push(`value=${JSON.stringify(value)}`);\n }\n if (record.disabled === true) {\n parts.push('(disabled)');\n }\n parts.push(`[${refs.refOf(record.id)}]`);\n if (record.id === focused) {\n parts.push('(focused)');\n }\n lines.push(parts.join(' '));\n }\n return lines.length === 0 ? '(the screen announces nothing)' : lines.join('\\n');\n}\n\nfunction describe(record: UiSemanticsRecord): string {\n const name = record.label === undefined || record.label === '' ? '' : ` ${JSON.stringify(record.label)}`;\n return `${record.role ?? 'text'}${name}`;\n}\n\nfunction valueOf(record: UiSemanticsRecord): string | null {\n if (record.valueText !== undefined && record.valueText !== record.label) {\n return record.valueText;\n }\n if (record.valueNow !== undefined) {\n return String(record.valueNow);\n }\n return null;\n}\n\n/**\n * The record an action names: by ref, or by role and name. A name\n * matches exactly before it matches as a part, ignoring case, so\n * \"Save\" finds the button called Save rather than \"Save as\". More than\n * one match is an error listing them, because guessing which of two\n * buttons an agent meant is how the wrong one gets pressed.\n */\nexport function resolveTarget(\n tree: UiSemanticsMap,\n args: Readonly<Record<string, unknown>>,\n refs: UiRefs = new UiRefs()\n): UiSemanticsRecord | string {\n const ref = typeof args.ref === 'string' ? args.ref : undefined;\n const role = typeof args.role === 'string' ? args.role : undefined;\n const name = typeof args.name === 'string' ? args.name : undefined;\n if (ref !== undefined) {\n return (\n tree.get(refs.idOf(ref)) ??\n `Nothing on the screen has the ref ${ref} now. Read ui_snapshot again for current refs.`\n );\n }\n if (role === undefined && name === undefined) {\n return 'Say which control: a ref from ui_snapshot, or a role and a name.';\n }\n const candidates = [...tree.values()].filter(record => role === undefined || record.role === role);\n let matches = candidates;\n if (name !== undefined) {\n const wanted = name.toLowerCase();\n const exact = candidates.filter(record => record.label?.toLowerCase() === wanted);\n matches = exact.length > 0 ? exact : candidates.filter(record => record.label?.toLowerCase().includes(wanted));\n }\n const wanted = [role, name === undefined ? undefined : JSON.stringify(name)].filter(Boolean).join(' ');\n if (matches.length === 1) {\n return matches[0];\n }\n if (matches.length === 0) {\n const nearby = candidates\n .filter(record => record.role !== undefined)\n .slice(0, 10)\n .map(record => `${describe(record)} [${refs.refOf(record.id)}]`);\n return `Nothing on the screen is ${wanted}.${nearby.length > 0 ? ` Some that are: ${nearby.join('; ')}.` : ''}`;\n }\n return `${matches.length} controls are ${wanted}: ${matches\n .slice(0, 10)\n .map(record => `${describe(record)} [${refs.refOf(record.id)}]`)\n .join('; ')}. Use a ref.`;\n}\n\nfunction success(text: string): AgentToolResult {\n return { content: [{ type: 'text', text }], isError: false };\n}\n\nfunction failure(text: string): AgentToolResult {\n return { content: [{ type: 'text', text }], isError: true };\n}\n","import type { ServedChannel } from '../channel/serveChannels';\nimport type { WorkerHandle } from '../worker/WorkerPorts';\nimport { agentSurface } from './AgentSurface';\nimport { AGENT_PORT, combineSurfaces, remoteSurface, serveAgentPort } from './remote';\nimport { toolSurface, type AgentToolDefinition } from './tools';\nimport { uiSurface, type UiHost } from './ui';\n\n/** What a thread that draws the application can offer an agent. */\nexport interface ApplicationAgentParts {\n /** The channels fed from this thread. */\n readonly channels: () => readonly ServedChannel[];\n /** The workers behind it, each asked over an agent port of its own. */\n readonly workers: () => Iterable<WorkerHandle>;\n /** The screen, once the application has started. */\n readonly ui: () => UiHost | undefined;\n /** Tools the application offers of its own accord (`useAgentTools`). */\n readonly tools?: () => readonly AgentToolDefinition[];\n}\n\n/**\n * Answers an agent port with the whole application: the channels this\n * thread feeds, whatever each worker behind it serves, and the screen.\n *\n * The thread that draws is the one that knows all three, which is the\n * render worker in the worker configuration and the page in the single\n * thread one; both answer with this. The screen comes last, so a\n * channel tool keeps its name.\n */\nexport function serveApplicationAgent(port: MessagePort, parts: ApplicationAgentParts): () => void {\n return serveAgentPort(port, confirm => {\n const workers = [...parts.workers()]\n .filter(worker => worker.spawned)\n .map(worker => remoteSurface(worker.open(AGENT_PORT), { confirm }));\n return combineSurfaces([\n agentSurface(parts.channels(), { confirm }),\n ...workers,\n uiSurface(parts.ui),\n ...(parts.tools === undefined ? [] : [toolSurface(parts.tools)])\n ]);\n });\n}\n"],"mappings":"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"}