@artooi/ag-ui-web-component 0.1.0 → 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 (109) hide show
  1. package/CHANGELOG.md +102 -2
  2. package/README.md +235 -47
  3. package/dist/ag-ui-web-component.bundle.js +451 -46
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/constants.d.ts +34 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/{ag_ui_chat.d.ts → core/ag_ui_chat.d.ts} +63 -6
  8. package/dist/core/ag_ui_chat.d.ts.map +1 -0
  9. package/dist/core/agui_client.d.ts.map +1 -0
  10. package/dist/core/conversation_store.d.ts.map +1 -0
  11. package/dist/core/create_http_agent.d.ts.map +1 -0
  12. package/dist/core/define_ag_ui_chat.d.ts.map +1 -0
  13. package/dist/dom/animations.d.ts +71 -0
  14. package/dist/dom/animations.d.ts.map +1 -0
  15. package/dist/{dom_driver.d.ts → dom/dom_driver.d.ts} +7 -1
  16. package/dist/dom/dom_driver.d.ts.map +1 -0
  17. package/dist/dom/native_setter.d.ts +5 -0
  18. package/dist/dom/native_setter.d.ts.map +1 -0
  19. package/dist/index.d.ts +19 -16
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3886 -388
  22. package/dist/index.js.map +4 -4
  23. package/dist/skills/fill_template.d.ts +17 -0
  24. package/dist/skills/fill_template.d.ts.map +1 -0
  25. package/dist/skills/parse_skills.d.ts +8 -0
  26. package/dist/skills/parse_skills.d.ts.map +1 -0
  27. package/dist/skills/skill.d.ts +24 -0
  28. package/dist/skills/skill.d.ts.map +1 -0
  29. package/dist/{client_tool_registry.d.ts → tools/client_tool_registry.d.ts} +6 -1
  30. package/dist/tools/client_tool_registry.d.ts.map +1 -0
  31. package/dist/tools/is_destructive.d.ts.map +1 -0
  32. package/dist/tools/is_navigates.d.ts.map +1 -0
  33. package/dist/tools/page_map.d.ts.map +1 -0
  34. package/dist/tools/route_map.d.ts +40 -0
  35. package/dist/tools/route_map.d.ts.map +1 -0
  36. package/dist/tools/state_hook.d.ts.map +1 -0
  37. package/dist/ui/confirmation_card.d.ts +22 -0
  38. package/dist/ui/confirmation_card.d.ts.map +1 -0
  39. package/dist/ui/render_markdown.d.ts +13 -0
  40. package/dist/ui/render_markdown.d.ts.map +1 -0
  41. package/dist/ui/reveal_words.d.ts +8 -0
  42. package/dist/ui/reveal_words.d.ts.map +1 -0
  43. package/dist/ui/skills_menu.d.ts +35 -0
  44. package/dist/ui/skills_menu.d.ts.map +1 -0
  45. package/dist/ui/styles.d.ts +2 -0
  46. package/dist/ui/styles.d.ts.map +1 -0
  47. package/dist/ui/tool_call_card.d.ts +35 -0
  48. package/dist/ui/tool_call_card.d.ts.map +1 -0
  49. package/package.json +5 -3
  50. package/src/constants.ts +38 -0
  51. package/src/core/ag_ui_chat.ts +786 -0
  52. package/src/{agui_client.ts → core/agui_client.ts} +1 -1
  53. package/src/{define_ag_ui_chat.ts → core/define_ag_ui_chat.ts} +1 -1
  54. package/src/dom/animations.ts +201 -0
  55. package/src/{dom_driver.ts → dom/dom_driver.ts} +35 -2
  56. package/src/dom/native_setter.ts +42 -0
  57. package/src/index.ts +61 -32
  58. package/src/skills/fill_template.ts +32 -0
  59. package/src/skills/parse_skills.ts +26 -0
  60. package/src/skills/skill.ts +23 -0
  61. package/src/{client_tool_registry.ts → tools/client_tool_registry.ts} +6 -4
  62. package/src/{is_destructive.ts → tools/is_destructive.ts} +1 -1
  63. package/src/{is_navigates.ts → tools/is_navigates.ts} +1 -1
  64. package/src/tools/route_map.ts +140 -0
  65. package/src/{state_hook.ts → tools/state_hook.ts} +1 -1
  66. package/src/ui/confirmation_card.ts +71 -0
  67. package/src/ui/render_markdown.ts +68 -0
  68. package/src/ui/reveal_words.ts +41 -0
  69. package/src/ui/skills_menu.ts +171 -0
  70. package/src/ui/styles.ts +631 -0
  71. package/src/{tool_call_card.ts → ui/tool_call_card.ts} +50 -19
  72. package/src/version.ts +1 -1
  73. package/dist/ag_ui_chat.d.ts.map +0 -1
  74. package/dist/agui_client.d.ts.map +0 -1
  75. package/dist/animations.d.ts +0 -33
  76. package/dist/animations.d.ts.map +0 -1
  77. package/dist/client_tool_registry.d.ts.map +0 -1
  78. package/dist/confirmation_modal.d.ts +0 -14
  79. package/dist/confirmation_modal.d.ts.map +0 -1
  80. package/dist/conversation_store.d.ts.map +0 -1
  81. package/dist/create_http_agent.d.ts.map +0 -1
  82. package/dist/define_ag_ui_chat.d.ts.map +0 -1
  83. package/dist/dom_driver.d.ts.map +0 -1
  84. package/dist/is_destructive.d.ts.map +0 -1
  85. package/dist/is_navigates.d.ts.map +0 -1
  86. package/dist/page_map.d.ts.map +0 -1
  87. package/dist/route_map.d.ts +0 -27
  88. package/dist/route_map.d.ts.map +0 -1
  89. package/dist/state_hook.d.ts.map +0 -1
  90. package/dist/styles.d.ts +0 -2
  91. package/dist/styles.d.ts.map +0 -1
  92. package/dist/tool_call_card.d.ts +0 -29
  93. package/dist/tool_call_card.d.ts.map +0 -1
  94. package/src/ag_ui_chat.ts +0 -411
  95. package/src/animations.ts +0 -86
  96. package/src/confirmation_modal.ts +0 -69
  97. package/src/route_map.ts +0 -83
  98. package/src/styles.ts +0 -296
  99. /package/dist/{agui_client.d.ts → core/agui_client.d.ts} +0 -0
  100. /package/dist/{conversation_store.d.ts → core/conversation_store.d.ts} +0 -0
  101. /package/dist/{create_http_agent.d.ts → core/create_http_agent.d.ts} +0 -0
  102. /package/dist/{define_ag_ui_chat.d.ts → core/define_ag_ui_chat.d.ts} +0 -0
  103. /package/dist/{is_destructive.d.ts → tools/is_destructive.d.ts} +0 -0
  104. /package/dist/{is_navigates.d.ts → tools/is_navigates.d.ts} +0 -0
  105. /package/dist/{page_map.d.ts → tools/page_map.d.ts} +0 -0
  106. /package/dist/{state_hook.d.ts → tools/state_hook.d.ts} +0 -0
  107. /package/src/{conversation_store.ts → core/conversation_store.ts} +0 -0
  108. /package/src/{create_http_agent.ts → core/create_http_agent.ts} +0 -0
  109. /package/src/{page_map.ts → tools/page_map.ts} +0 -0
@@ -0,0 +1,17 @@
1
+ /** Result of {@link fillTemplate}: the filled text plus any unresolved keys. */
2
+ export interface TemplateResult {
3
+ /** The prompt with resolved `{placeholder}`s substituted. */
4
+ readonly text: string;
5
+ /** Placeholder names with no value available (deduped, in first-seen order). */
6
+ readonly missing: readonly string[];
7
+ }
8
+ /**
9
+ * Substitute `{name}` placeholders in ``template`` from ``values``.
10
+ *
11
+ * A placeholder whose value is missing, ``null``, or an empty string is left
12
+ * verbatim and reported in ``missing`` — the caller blocks send and tells the
13
+ * user what's needed (e.g. "select rows first") rather than sending a
14
+ * half-filled prompt.
15
+ */
16
+ export declare function fillTemplate(template: string, values: Record<string, unknown>): TemplateResult;
17
+ //# sourceMappingURL=fill_template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill_template.d.ts","sourceRoot":"","sources":["../../src/skills/fill_template.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAID;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAa9F"}
@@ -0,0 +1,8 @@
1
+ import type { Skill } from "./skill.js";
2
+ /**
3
+ * Parse an untrusted value (parsed JSON from `data-skills` or a skills
4
+ * endpoint) into a list of {@link Skill}s, dropping anything malformed. Never
5
+ * throws — a bad payload yields an empty list.
6
+ */
7
+ export declare function parseSkills(value: unknown): Skill[];
8
+ //# sourceMappingURL=parse_skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse_skills.d.ts","sourceRoot":"","sources":["../../src/skills/parse_skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAexC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,CAKnD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A pre-defined prompt the user can launch from the chat — surfaced as a chip
3
+ * and/or in the `/`-command palette. One catalog feeds both surfaces; the host
4
+ * provides skills via the `skills` property / `data-skills` attribute / a
5
+ * fetched endpoint (see {@link AgUiChat}).
6
+ */
7
+ export interface Skill {
8
+ /** Stable id; the `/token` (kebab-case) in the palette. */
9
+ readonly name: string;
10
+ /** Label shown in chips and the palette. */
11
+ readonly title: string;
12
+ /** Secondary line shown in the palette. */
13
+ readonly description?: string;
14
+ /**
15
+ * The prompt inserted (or sent). May contain `{placeholder}`s filled from the
16
+ * host's skill context before send; an unfilled placeholder blocks send.
17
+ */
18
+ readonly prompt: string;
19
+ /** Send immediately on pick instead of pre-filling the input (default false). */
20
+ readonly sendImmediately?: boolean;
21
+ /** Also surface this skill as a chip (default false; the palette shows all). */
22
+ readonly chip?: boolean;
23
+ }
24
+ //# sourceMappingURL=skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/skills/skill.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACpB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,gFAAgF;IAChF,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB"}
@@ -21,7 +21,12 @@ export interface ClientTool {
21
21
  */
22
22
  export declare class ClientToolRegistry {
23
23
  #private;
24
- /** Register a tool. Throws if the name is already taken. */
24
+ /**
25
+ * Register a tool, replacing any existing one with the same name.
26
+ *
27
+ * Idempotent on the name so re-fired host refs / React StrictMode's
28
+ * double-invoke don't throw — re-registering is a replace, not an error.
29
+ */
25
30
  register(tool: ClientTool): void;
26
31
  has(name: string): boolean;
27
32
  /** Return a registered tool or throw. */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client_tool_registry.d.ts","sourceRoot":"","sources":["../../src/tools/client_tool_registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;;IAG7B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAIhC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,yCAAyC;IACzC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAQ7B,wDAAwD;IACxD,KAAK,IAAI,IAAI,EAAE;CAOhB"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is_destructive.d.ts","sourceRoot":"","sources":["../../src/tools/is_destructive.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAE1E"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is_navigates.d.ts","sourceRoot":"","sources":["../../src/tools/is_navigates.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAExE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page_map.d.ts","sourceRoot":"","sources":["../../src/tools/page_map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,IAAI,EAClC,UAAU,EAAE,OAAO,GAClB,OAAO,EAAE,CAKX"}
@@ -0,0 +1,40 @@
1
+ import type { ClientTool } from "./client_tool_registry.js";
2
+ /** A single navigable route the host declares for the agent. */
3
+ export interface Route {
4
+ /** Stable id the agent uses with `navigate_to_route`. */
5
+ readonly id: string;
6
+ /**
7
+ * The URL path to navigate to. May contain `:name` placeholders for dynamic
8
+ * segments (e.g. `/admin/shop/book/:pk/change/`); the agent fills them via
9
+ * the `navigate_to_route` `params` argument. Real apps are mostly
10
+ * parameterised — few pages have a truly static path.
11
+ */
12
+ readonly path: string;
13
+ /** Human label shown to the agent. */
14
+ readonly title?: string;
15
+ /** Optional grouping (e.g. an app or section). */
16
+ readonly group?: string;
17
+ /** Optional longer description of when to use the route. */
18
+ readonly description?: string;
19
+ }
20
+ /** The host-declared catalog of navigable routes. */
21
+ export type RouteMap = readonly Route[];
22
+ /** A route enriched with its derived dynamic-segment parameter names. */
23
+ export interface RouteWithParams extends Route {
24
+ /** Names of the `:name` placeholders in {@link Route.path} (may be empty). */
25
+ readonly pathParams: readonly string[];
26
+ }
27
+ /**
28
+ * The built-in `route.*` tools, bound to live getters so a host can set
29
+ * `routeMap` / `navigate` before or after mount.
30
+ *
31
+ * `list_routes` is read-only and advertises each route's dynamic
32
+ * `pathParams` so the model knows what to supply. `navigate_to_route` is marked
33
+ * `x-navigates` so an MPA reload checkpoints + resumes; it substitutes path
34
+ * params into the template and appends any remaining params as a query string.
35
+ * When the host supplies a `navigate(path)` callback (an SPA), the element
36
+ * routes client-side instead and the run loop simply continues — see
37
+ * `AgUiChat`'s execute path.
38
+ */
39
+ export declare function createRouteTools(getRouteMap: () => RouteMap, getNavigate: () => ((path: string) => void) | null): ClientTool[];
40
+ //# sourceMappingURL=route_map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route_map.d.ts","sourceRoot":"","sources":["../../src/tools/route_map.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,gEAAgE;AAChE,MAAM,WAAW,KAAK;IACpB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qDAAqD;AACrD,MAAM,MAAM,QAAQ,GAAG,SAAS,KAAK,EAAE,CAAC;AAExC,yEAAyE;AACzE,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC5C,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAmDD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,QAAQ,EAC3B,WAAW,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,GACjD,UAAU,EAAE,CA4Cd"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state_hook.d.ts","sourceRoot":"","sources":["../../src/tools/state_hook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IAC5D,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,EAAE,CAmBlE"}
@@ -0,0 +1,22 @@
1
+ /** What the inline confirmation card displays. */
2
+ export interface ConfirmationRequest {
3
+ toolName: string;
4
+ args: Record<string, unknown>;
5
+ /**
6
+ * Human-readable prompt (from the tool's `x-confirm` metadata), e.g.
7
+ * "Activate this project?". Falls back to a generic `Run "<tool>"?`.
8
+ */
9
+ message?: string;
10
+ }
11
+ /**
12
+ * Append an inline confirmation card to ``host`` (the chat message list) and
13
+ * resolve when the user decides.
14
+ *
15
+ * Unlike a modal overlay, the card lives in the transcript right where the
16
+ * action is — it reads naturally after the assistant's explanation and never
17
+ * steals focus from the page. Resolves ``true`` on confirm, ``false`` on
18
+ * cancel. The card stays in the transcript as a resolved record (buttons
19
+ * disabled, `data-resolved` set) rather than vanishing.
20
+ */
21
+ export declare function requestConfirmation(host: Node & ParentNode, request: ConfirmationRequest): Promise<boolean>;
22
+ //# sourceMappingURL=confirmation_card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirmation_card.d.ts","sourceRoot":"","sources":["../../src/ui/confirmation_card.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,GAAG,UAAU,EACvB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAqClB"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Render markdown (and any embedded raw HTML) to a sanitised HTML string.
3
+ *
4
+ * Both markdown syntax and literal HTML flow through one path: `marked` emits
5
+ * HTML, then DOMPurify strips everything outside {@link ALLOWED_TAGS} /
6
+ * {@link ALLOWED_ATTR} (scripts, event handlers, `javascript:` URLs, etc.).
7
+ * Links are hardened with `target="_blank"` + `rel="noopener noreferrer"`.
8
+ *
9
+ * The result is trimmed so a single-paragraph message round-trips to clean
10
+ * `textContent` (no trailing newline from the wrapping `<p>`).
11
+ */
12
+ export declare function renderMarkdown(text: string): string;
13
+ //# sourceMappingURL=render_markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render_markdown.d.ts","sourceRoot":"","sources":["../../src/ui/render_markdown.ts"],"names":[],"mappings":"AA8CA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUnD"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Wrap each word under ``root`` in `<span class="word" style="--ag-ui-word-index: N">`
3
+ * so CSS can reveal them one-by-one (staggered by the index). Whitespace is
4
+ * preserved as plain text. Used for the `word` text-animation mode on a
5
+ * completed assistant message; pure DOM, idempotent enough to re-run.
6
+ */
7
+ export declare function wrapWords(root: HTMLElement): void;
8
+ //# sourceMappingURL=reveal_words.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reveal_words.d.ts","sourceRoot":"","sources":["../../src/ui/reveal_words.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAuBjD"}
@@ -0,0 +1,35 @@
1
+ import type { Skill } from "../skills/skill.js";
2
+ /**
3
+ * The two skill surfaces over a single catalog: a **chips** row (the
4
+ * `chip: true` subset) and a **`/`-command palette** (all skills, filtered).
5
+ * Both are opt-in. Pure DOM; the host ({@link AgUiChat}) appends
6
+ * {@link chips} + {@link palette}, feeds input via {@link onInput} /
7
+ * {@link onKeydown}, and acts on the {@link onPick} callback.
8
+ */
9
+ export declare class SkillsMenu {
10
+ #private;
11
+ /** Chips row — append above the input. Hidden unless chips are enabled and present. */
12
+ readonly chips: HTMLDivElement;
13
+ /** The `/`-command dropdown — append in the input area. Hidden until opened. */
14
+ readonly palette: HTMLDivElement;
15
+ constructor(onPick: (skill: Skill) => void);
16
+ /** Replace the catalog (both surfaces re-derive from it). */
17
+ setSkills(skills: readonly Skill[]): void;
18
+ enableChips(enabled: boolean): void;
19
+ enableSlash(enabled: boolean): void;
20
+ /** Whether the palette is currently open. */
21
+ isOpen(): boolean;
22
+ /**
23
+ * React to an input value change: open + filter the palette when slash mode
24
+ * is on and the value starts with `/`, otherwise close it.
25
+ */
26
+ onInput(value: string): void;
27
+ /**
28
+ * Handle a keydown while the palette is open. Returns ``true`` when consumed
29
+ * (the host should `preventDefault` and skip its own handling).
30
+ */
31
+ onKeydown(event: KeyboardEvent): boolean;
32
+ /** Close the palette. */
33
+ close(): void;
34
+ }
35
+ //# sourceMappingURL=skills_menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills_menu.d.ts","sourceRoot":"","sources":["../../src/ui/skills_menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD;;;;;;GAMG;AACH,qBAAa,UAAU;;IACrB,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;gBASrB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;IAW1C,6DAA6D;IAC7D,SAAS,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,IAAI;IAKzC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKnC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAInC,6CAA6C;IAC7C,MAAM,IAAI,OAAO;IAIjB;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ5B;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IA2BxC,yBAAyB;IACzB,KAAK,IAAI,IAAI;CAyEd"}
@@ -0,0 +1,2 @@
1
+ export declare const STYLES = "\n:host {\n /* Colors */\n --ag-ui-bg: #ffffff;\n --ag-ui-fg: #1a1a2e;\n --ag-ui-accent: #4f46e5;\n --ag-ui-user-bg: #4f46e5;\n --ag-ui-user-fg: #ffffff;\n --ag-ui-assistant-bg: #f1f1f6;\n --ag-ui-input-bg: var(--ag-ui-bg);\n --ag-ui-tool-bg: var(--ag-ui-assistant-bg);\n --ag-ui-tool-fg: var(--ag-ui-accent);\n --ag-ui-header-bg: var(--ag-ui-accent);\n --ag-ui-header-fg: #ffffff;\n --ag-ui-border: #e2e2ec;\n --ag-ui-radius: 12px;\n\n /* Status accents for tool-call cards. */\n --ag-ui-success: #15803d;\n --ag-ui-danger: #b91c1c;\n --ag-ui-muted: #6b7280;\n\n /* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */\n --ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);\n --ag-ui-font: inherit;\n --ag-ui-font-size: 14px;\n --ag-ui-code-font: ui-monospace, \"SF Mono\", Menlo, monospace;\n\n /* Spacing \u2014 the density preset overrides these. */\n --ag-ui-space: 10px;\n --ag-ui-pad: 16px;\n --ag-ui-msg-pad: 8px 12px;\n --ag-ui-msg-radius: 14px;\n\n /* Layout \u2014 override from outside to dock the widget anywhere.\n Set --ag-ui-position: static (and place this element in your own\n grid/flex layout) to embed it in the page flow instead of floating. */\n --ag-ui-position: fixed;\n --ag-ui-z-index: 2147483000;\n --ag-ui-width: 380px;\n --ag-ui-height: 560px;\n --ag-ui-inset: auto 24px 24px auto;\n --ag-ui-max-width: calc(100vw - 48px);\n --ag-ui-max-height: calc(100vh - 48px);\n\n position: var(--ag-ui-position);\n inset: var(--ag-ui-inset);\n z-index: var(--ag-ui-z-index);\n width: var(--ag-ui-width);\n max-width: var(--ag-ui-max-width);\n height: var(--ag-ui-height);\n max-height: var(--ag-ui-max-height);\n display: flex;\n font-family: var(--ag-ui-font);\n font-size: var(--ag-ui-font-size);\n color: var(--ag-ui-fg);\n}\n\n/* \u2500\u2500 Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Themes only re-set the colour variables; layout/spacing are unaffected.\n theme=\"auto\" follows the OS via prefers-color-scheme. */\n:host([theme=\"dark\"]) {\n --ag-ui-bg: #15151f;\n --ag-ui-fg: #e8e8f2;\n --ag-ui-assistant-bg: #25253a;\n --ag-ui-header-bg: #1f1f30;\n --ag-ui-header-fg: #e8e8f2;\n --ag-ui-border: #33334a;\n --ag-ui-muted: #9aa0b4;\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);\n}\n\n@media (prefers-color-scheme: dark) {\n :host([theme=\"auto\"]) {\n --ag-ui-bg: #15151f;\n --ag-ui-fg: #e8e8f2;\n --ag-ui-assistant-bg: #25253a;\n --ag-ui-header-bg: #1f1f30;\n --ag-ui-header-fg: #e8e8f2;\n --ag-ui-border: #33334a;\n --ag-ui-muted: #9aa0b4;\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);\n }\n}\n\n/* A terminal-flavoured \"code\" theme: dark, monospace, green accent. */\n:host([theme=\"code\"]) {\n --ag-ui-bg: #0d1117;\n --ag-ui-fg: #c9d1d9;\n --ag-ui-accent: #3fb950;\n --ag-ui-user-bg: #238636;\n --ag-ui-assistant-bg: #161b22;\n --ag-ui-header-bg: #010409;\n --ag-ui-header-fg: #c9d1d9;\n --ag-ui-border: #30363d;\n --ag-ui-muted: #8b949e;\n --ag-ui-font: var(--ag-ui-code-font);\n --ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);\n}\n\n/* \u2500\u2500 Density \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([density=\"compact\"]) {\n --ag-ui-font-size: 13px;\n --ag-ui-space: 6px;\n --ag-ui-pad: 10px;\n --ag-ui-msg-pad: 5px 9px;\n --ag-ui-msg-radius: 10px;\n}\n\n/* \u2500\u2500 Placement presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([placement=\"bottom-left\"]) {\n --ag-ui-inset: auto auto 24px 24px;\n}\n\n:host([placement=\"side\"]) {\n --ag-ui-inset: 0 0 0 auto;\n --ag-ui-width: 420px;\n --ag-ui-height: 100vh;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n}\n\n:host([placement=\"full\"]) {\n --ag-ui-inset: 0;\n --ag-ui-width: 100vw;\n --ag-ui-height: 100vh;\n --ag-ui-max-width: 100vw;\n --ag-ui-max-height: 100vh;\n --ag-ui-radius: 0;\n}\n\n/* Embedded: drop the floating chrome and the high z-index stacking context so\n the widget lives in the host's own layout (fixes overlay/z-index clashes). */\n:host([placement=\"embedded\"]) {\n --ag-ui-position: static;\n --ag-ui-width: 100%;\n --ag-ui-height: 100%;\n --ag-ui-max-width: 100%;\n --ag-ui-max-height: 100%;\n --ag-ui-shadow: none;\n --ag-ui-z-index: auto;\n}\n\n.chat {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: var(--ag-ui-radius);\n box-shadow: var(--ag-ui-shadow);\n overflow: hidden;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--ag-ui-border);\n background: var(--ag-ui-header-bg);\n color: var(--ag-ui-header-fg);\n}\n\n.header-title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.header-controls {\n display: flex;\n gap: 2px;\n flex: none;\n}\n\n.header-btn {\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n padding: 4px 7px;\n border-radius: 6px;\n cursor: pointer;\n opacity: 0.85;\n}\n\n.header-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.18);\n}\n\n/* Collapsed: keep just the header bar \u2014 hide the whole body, and let the host\n shrink to the header. (A host can also fully hide the element itself.) */\n:host([collapsed]) {\n height: auto;\n max-height: none;\n}\n\n:host([collapsed]) .messages,\n:host([collapsed]) .input-row,\n:host([collapsed]) .skill-chips,\n:host([collapsed]) .skill-palette,\n:host([collapsed]) .skill-hint {\n display: none;\n}\n\n/* Edge-docked placements pin top *and* bottom, which would otherwise keep the\n panel full-height when collapsed; unpin the bottom so it shrinks to the\n header. (Floating/bottom-left pin only the bottom, so they already shrink.) */\n:host([collapsed][placement=\"side\"]),\n:host([collapsed][placement=\"full\"]) {\n bottom: auto;\n}\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: var(--ag-ui-pad);\n display: flex;\n flex-direction: column;\n gap: var(--ag-ui-space);\n}\n\n.message {\n max-width: 80%;\n padding: var(--ag-ui-msg-pad);\n border-radius: var(--ag-ui-msg-radius);\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* \u2500\u2500 Incoming-text animations (data-text-animation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host([data-text-animation=\"fade\"]) .message--assistant {\n animation: ag-ui-msg-fade 0.25s ease both;\n}\n\n@keyframes ag-ui-msg-fade {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n}\n\n.message--assistant .word {\n animation: ag-ui-word-in 0.3s ease both;\n animation-delay: calc(var(--ag-ui-word-index, 0) * 35ms);\n}\n\n@keyframes ag-ui-word-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host([data-text-animation=\"fade\"]) .message--assistant,\n .message--assistant .word {\n animation: none;\n }\n}\n\n.message--user {\n align-self: flex-end;\n background: var(--ag-ui-user-bg);\n color: var(--ag-ui-user-fg);\n border-bottom-right-radius: 4px;\n}\n\n.message--assistant {\n align-self: flex-start;\n background: var(--ag-ui-assistant-bg);\n border-bottom-left-radius: 4px;\n /* Assistant bubbles hold rendered markdown/HTML, so collapse the source\n whitespace the renderer leaves between block tags. */\n white-space: normal;\n}\n\n/* Rendered-markdown elements inside an assistant bubble. */\n.message--assistant > :first-child {\n margin-top: 0;\n}\n\n.message--assistant > :last-child {\n margin-bottom: 0;\n}\n\n.message--assistant p,\n.message--assistant ul,\n.message--assistant ol,\n.message--assistant blockquote,\n.message--assistant pre {\n margin: 0.5em 0;\n}\n\n.message--assistant ul,\n.message--assistant ol {\n padding-left: 1.3em;\n}\n\n.message--assistant a {\n color: var(--ag-ui-accent);\n text-decoration: underline;\n}\n\n.message--assistant code {\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n font-size: 0.92em;\n background: rgba(127, 127, 127, 0.16);\n padding: 1px 4px;\n border-radius: 4px;\n}\n\n.message--assistant pre {\n padding: 8px 10px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n}\n\n.message--assistant pre code {\n background: none;\n padding: 0;\n}\n\n.message--assistant blockquote {\n padding-left: 10px;\n border-left: 3px solid var(--ag-ui-border);\n color: var(--ag-ui-muted);\n}\n\n.pending {\n align-self: flex-start;\n display: inline-flex;\n gap: 4px;\n align-items: center;\n padding: 12px 14px;\n background: var(--ag-ui-assistant-bg);\n border-radius: 14px;\n border-bottom-left-radius: 4px;\n}\n\n.pending-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--ag-ui-muted);\n animation: ag-ui-pending 1.2s infinite ease-in-out both;\n}\n\n.pending-dot:nth-child(2) {\n animation-delay: 0.16s;\n}\n\n.pending-dot:nth-child(3) {\n animation-delay: 0.32s;\n}\n\n@keyframes ag-ui-pending {\n 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pending-dot {\n animation: none;\n opacity: 0.6;\n }\n}\n\n.tool-call {\n align-self: flex-start;\n max-width: 80%;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--ag-ui-tool-bg);\n border: 1px solid var(--ag-ui-border);\n color: var(--ag-ui-tool-fg);\n}\n\n.tool-call-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.tool-call-name {\n font-weight: 600;\n word-break: break-word;\n}\n\n.tool-call-status {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: rgba(127, 127, 127, 0.16);\n color: var(--ag-ui-muted);\n}\n\n.tool-call[data-status=\"done\"] .tool-call-status {\n color: var(--ag-ui-success);\n}\n\n.tool-call[data-status=\"error\"] .tool-call-status {\n color: var(--ag-ui-danger);\n}\n\n.tool-call[data-status=\"declined\"] .tool-call-status {\n color: var(--ag-ui-muted);\n}\n\n.tool-call-args,\n.tool-call-result {\n margin: 0;\n padding: 6px 8px;\n max-height: 160px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--ag-ui-fg);\n}\n\n.tool-call-toggle {\n align-self: flex-start;\n border: none;\n padding: 0;\n background: none;\n font: inherit;\n font-weight: 600;\n color: var(--ag-ui-accent);\n cursor: pointer;\n}\n\n.tool-call-toggle::before {\n content: \"\u25B8 \";\n}\n\n.tool-call-toggle[aria-expanded=\"true\"]::before {\n content: \"\u25BE \";\n}\n\n.input-row {\n display: flex;\n gap: 8px;\n padding: 12px;\n border-top: 1px solid var(--ag-ui-border);\n}\n\n.input {\n flex: 1;\n resize: none;\n background: var(--ag-ui-input-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 10px;\n font: inherit;\n color: inherit;\n outline: none;\n}\n\n.input:focus {\n border-color: var(--ag-ui-accent);\n}\n\n.send {\n border: none;\n border-radius: 8px;\n padding: 0 16px;\n background: var(--ag-ui-accent);\n color: #ffffff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.send:disabled {\n opacity: 0.5;\n cursor: default;\n}\n\n/* Inline confirmation card \u2014 lives in the transcript, no focus-stealing overlay. */\n.confirm {\n align-self: stretch;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-accent);\n border-radius: 10px;\n}\n\n.confirm[data-resolved] {\n opacity: 0.7;\n border-color: var(--ag-ui-border);\n}\n\n.confirm-body {\n font-weight: 600;\n}\n\n.confirm-args {\n margin: 0;\n padding: 8px 10px;\n max-height: 140px;\n overflow: auto;\n font-size: 12px;\n font-family: ui-monospace, \"SF Mono\", Menlo, monospace;\n background: var(--ag-ui-assistant-bg);\n border-radius: 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.confirm-btn {\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n padding: 8px 14px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n background: var(--ag-ui-bg);\n color: var(--ag-ui-fg);\n}\n\n.confirm-btn:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.confirm-btn--confirm {\n border-color: var(--ag-ui-accent);\n background: var(--ag-ui-accent);\n color: #ffffff;\n}\n\n/* Skills \u2014 chips row + the /-command palette, above the input. */\n.skill-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 10px 12px;\n}\n\n.skill-chip {\n border: 1px solid var(--ag-ui-border);\n border-radius: 999px;\n padding: 4px 12px;\n font: inherit;\n font-size: 0.9em;\n cursor: pointer;\n background: var(--ag-ui-assistant-bg);\n color: var(--ag-ui-fg);\n}\n\n.skill-chip:hover {\n border-color: var(--ag-ui-accent);\n}\n\n.skill-palette {\n margin: 8px 12px 0;\n display: flex;\n flex-direction: column;\n max-height: 220px;\n overflow: auto;\n background: var(--ag-ui-bg);\n border: 1px solid var(--ag-ui-border);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);\n}\n\n.skill-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n align-items: flex-start;\n padding: 8px 12px;\n border: none;\n background: none;\n font: inherit;\n text-align: left;\n cursor: pointer;\n color: var(--ag-ui-fg);\n}\n\n.skill-item[aria-selected=\"true\"] {\n background: var(--ag-ui-assistant-bg);\n}\n\n.skill-item-title {\n font-weight: 600;\n}\n\n.skill-item-desc {\n font-size: 0.85em;\n color: var(--ag-ui-muted);\n}\n\n.skill-hint {\n margin: 8px 12px 0;\n font-size: 0.85em;\n color: var(--ag-ui-danger);\n}\n";
2
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM,k/dAknBlB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { TOOL_CALL_STATUS, TOOL_DISPLAY } from "../constants.js";
2
+ /** Any state a tool-call card can be in. */
3
+ export type ToolCallStatus = (typeof TOOL_CALL_STATUS)[keyof typeof TOOL_CALL_STATUS];
4
+ /** How much detail a card renders. */
5
+ export type ToolDisplayMode = (typeof TOOL_DISPLAY)[keyof typeof TOOL_DISPLAY];
6
+ /** The terminal states a card settles into (everything but `pending`). */
7
+ export type SettledStatus = Exclude<ToolCallStatus, typeof TOOL_CALL_STATUS.PENDING>;
8
+ /**
9
+ * A live tool-call card for the chat transcript.
10
+ *
11
+ * Construction renders the tool name and a `running…` status pill; in `full`
12
+ * mode it also shows the pretty-printed arguments inline. {@link settle} later
13
+ * flips the pill to the outcome and — depending on the {@link ToolDisplayMode} —
14
+ * appends a collapsible body:
15
+ *
16
+ * - `minimal` — pill only; nothing to expand.
17
+ * - `compact` — one "Details" toggle revealing args *and* result together.
18
+ * - `full` — the result (or error / decline message) behind its own toggle.
19
+ *
20
+ * Pure DOM (no framework); the host appends {@link element} into its shadow
21
+ * root and themes it via the `--ag-ui-*` custom properties.
22
+ */
23
+ export declare class ToolCallCard {
24
+ #private;
25
+ /** The card's root element; append this into the message list. */
26
+ readonly element: HTMLDivElement;
27
+ constructor(name: string, args: Record<string, unknown>, mode?: ToolDisplayMode, summary?: string);
28
+ /**
29
+ * Flip the status pill to ``status`` and, unless in `minimal` mode, append a
30
+ * collapsed body behind a click-to-expand toggle: the result alone (`full`),
31
+ * or the args + result together (`compact`).
32
+ */
33
+ settle(status: SettledStatus, text: string): void;
34
+ }
35
+ //# sourceMappingURL=tool_call_card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool_call_card.d.ts","sourceRoot":"","sources":["../../src/ui/tool_call_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEjE,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAEtF,sCAAsC;AACtC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE/E,0EAA0E;AAC1E,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAiBrF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY;;IACvB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;gBAO/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,eAAmC,EACzC,OAAO,CAAC,EAAE,MAAM;IAkClB;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAiClD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artooi/ag-ui-web-component",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Framework-free <ag-ui-chat> Web Component over the AG-UI protocol. Drop-in chat sidebar with a pluggable client-side tool registry, DOM driver primitives, animations, and destructive-action confirmation modal.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,11 +52,13 @@
52
52
  "provenance": true
53
53
  },
54
54
  "engines": {
55
- "node": ">=20"
55
+ "node": ">=22"
56
56
  },
57
57
  "dependencies": {
58
58
  "@ag-ui/client": ">=0.0.54 <0.1",
59
- "@ag-ui/core": ">=0.0.54 <0.1"
59
+ "@ag-ui/core": ">=0.0.54 <0.1",
60
+ "dompurify": "^3.4.7",
61
+ "marked": "^18.0.4"
60
62
  },
61
63
  "devDependencies": {
62
64
  "@biomejs/biome": "^2.4.0",
package/src/constants.ts CHANGED
@@ -11,6 +11,14 @@ export const ELEMENT_TAG = "ag-ui-chat";
11
11
  */
12
12
  export const SUBMIT_EVENT = "ag-ui-submit";
13
13
 
14
+ /**
15
+ * Event dispatched by `<ag-ui-chat>` when its collapsed state changes (via the
16
+ * built-in toggle or {@link setCollapsed}). `detail` carries
17
+ * `{ collapsed: boolean }`. A host can listen to drive its own chrome, or hide
18
+ * the built-in toggle and drive the `collapsed` attribute itself.
19
+ */
20
+ export const TOGGLE_EVENT = "ag-ui-toggle";
21
+
14
22
  /** Roles a chat message can take. */
15
23
  export const MESSAGE_ROLE = {
16
24
  USER: "user",
@@ -25,6 +33,21 @@ export const MESSAGE_ROLE = {
25
33
  */
26
34
  export const X_DESTRUCTIVE_KEY = "x-destructive";
27
35
 
36
+ /**
37
+ * JSON-Schema extension key carrying a human-readable confirmation prompt for a
38
+ * destructive tool (e.g. `"Activate this project?"`). Mirrors the `django-ag-ui`
39
+ * server side. When present, the inline confirmation card shows this instead of
40
+ * the generic `Run "<tool>"?`.
41
+ */
42
+ export const X_CONFIRM_KEY = "x-confirm";
43
+
44
+ /**
45
+ * JSON-Schema extension key carrying a short human-readable label for a tool
46
+ * (e.g. `"Query orders"` for `query_model`). Mirrors the `django-ag-ui` server
47
+ * side; the tool-call card shows it instead of the raw tool name when present.
48
+ */
49
+ export const X_SUMMARY_KEY = "x-summary";
50
+
28
51
  /**
29
52
  * JSON-Schema extension key marking a tool as navigating — its handler triggers
30
53
  * a full page reload (an MPA navigation). When a tool's `parameters` carries
@@ -46,3 +69,18 @@ export const TOOL_CALL_STATUS = {
46
69
  ERROR: "error",
47
70
  DECLINED: "declined",
48
71
  } as const;
72
+
73
+ /**
74
+ * How much detail a tool-call card shows. Set via the `data-tool-display`
75
+ * attribute on `<ag-ui-chat>`; defaults to `full` (back-compatible).
76
+ *
77
+ * - `minimal` — just the tool name + status pill. No args, no result body.
78
+ * - `compact` — name + status, with args *and* result tucked behind a single
79
+ * collapsed "Details" toggle. The light default for dense UIs.
80
+ * - `full` — args shown inline, result behind its own toggle (the original).
81
+ */
82
+ export const TOOL_DISPLAY = {
83
+ MINIMAL: "minimal",
84
+ COMPACT: "compact",
85
+ FULL: "full",
86
+ } as const;