@runtypelabs/persona 1.48.0 → 2.0.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 (69) hide show
  1. package/README.md +140 -8
  2. package/dist/index.cjs +90 -39
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +1055 -24
  5. package/dist/index.d.ts +1055 -24
  6. package/dist/index.global.js +111 -60
  7. package/dist/index.global.js.map +1 -1
  8. package/dist/index.js +90 -39
  9. package/dist/index.js.map +1 -1
  10. package/dist/install.global.js +1 -1
  11. package/dist/install.global.js.map +1 -1
  12. package/dist/widget.css +836 -513
  13. package/package.json +1 -1
  14. package/src/artifacts-session.test.ts +80 -0
  15. package/src/client.test.ts +20 -21
  16. package/src/client.ts +153 -4
  17. package/src/components/approval-bubble.ts +45 -42
  18. package/src/components/artifact-card.ts +91 -0
  19. package/src/components/artifact-pane.ts +501 -0
  20. package/src/components/composer-builder.ts +32 -27
  21. package/src/components/event-stream-view.ts +40 -40
  22. package/src/components/feedback.ts +36 -36
  23. package/src/components/forms.ts +11 -11
  24. package/src/components/header-builder.test.ts +32 -0
  25. package/src/components/header-builder.ts +55 -36
  26. package/src/components/header-layouts.ts +58 -125
  27. package/src/components/launcher.ts +36 -21
  28. package/src/components/message-bubble.ts +92 -65
  29. package/src/components/messages.ts +2 -2
  30. package/src/components/panel.ts +42 -11
  31. package/src/components/reasoning-bubble.ts +23 -23
  32. package/src/components/registry.ts +4 -0
  33. package/src/components/suggestions.ts +1 -1
  34. package/src/components/tool-bubble.ts +32 -32
  35. package/src/defaults.ts +30 -4
  36. package/src/index.ts +80 -2
  37. package/src/install.ts +22 -0
  38. package/src/plugins/types.ts +23 -0
  39. package/src/postprocessors.ts +2 -2
  40. package/src/runtime/host-layout.ts +174 -0
  41. package/src/runtime/init.test.ts +236 -0
  42. package/src/runtime/init.ts +114 -55
  43. package/src/session.ts +135 -2
  44. package/src/styles/tailwind.css +1 -1
  45. package/src/styles/widget.css +836 -513
  46. package/src/types/theme.ts +354 -0
  47. package/src/types.ts +314 -15
  48. package/src/ui.docked.test.ts +104 -0
  49. package/src/ui.ts +940 -227
  50. package/src/utils/artifact-gate.test.ts +255 -0
  51. package/src/utils/artifact-gate.ts +142 -0
  52. package/src/utils/artifact-resize.test.ts +64 -0
  53. package/src/utils/artifact-resize.ts +67 -0
  54. package/src/utils/attachment-manager.ts +10 -10
  55. package/src/utils/code-generators.test.ts +52 -0
  56. package/src/utils/code-generators.ts +40 -36
  57. package/src/utils/dock.ts +17 -0
  58. package/src/utils/dom-context.test.ts +504 -0
  59. package/src/utils/dom-context.ts +896 -0
  60. package/src/utils/dom.ts +12 -1
  61. package/src/utils/message-fingerprint.test.ts +187 -0
  62. package/src/utils/message-fingerprint.ts +105 -0
  63. package/src/utils/migration.ts +179 -0
  64. package/src/utils/morph.ts +1 -1
  65. package/src/utils/plugins.ts +175 -0
  66. package/src/utils/positioning.ts +4 -4
  67. package/src/utils/theme.test.ts +125 -0
  68. package/src/utils/theme.ts +216 -60
  69. package/src/utils/tokens.ts +682 -0
@@ -24,6 +24,18 @@ const fullConfig = {
24
24
  },
25
25
  };
26
26
 
27
+ const dockedConfig = {
28
+ apiUrl: "https://api.example.com/chat",
29
+ launcher: {
30
+ mountMode: "docked",
31
+ dock: {
32
+ side: "left",
33
+ width: "480px",
34
+ collapsedWidth: "84px",
35
+ },
36
+ },
37
+ };
38
+
27
39
  // =============================================================================
28
40
  // Hook Serialization Tests
29
41
  // =============================================================================
@@ -109,6 +121,16 @@ describe("Hook Serialization", () => {
109
121
  // =============================================================================
110
122
 
111
123
  describe("ESM Format Hooks", () => {
124
+ it("should serialize docked launcher config", () => {
125
+ const code = generateCodeSnippet(dockedConfig, "esm");
126
+
127
+ expect(code).toContain('mountMode: "docked"');
128
+ expect(code).toContain('dock: {');
129
+ expect(code).toContain('side: "left"');
130
+ expect(code).toContain('width: "480px"');
131
+ expect(code).toContain('collapsedWidth: "84px"');
132
+ });
133
+
112
134
  it("should inject getHeaders hook", () => {
113
135
  const code = generateCodeSnippet(minimalConfig, "esm", {
114
136
  hooks: {
@@ -165,6 +187,16 @@ describe("ESM Format Hooks", () => {
165
187
  });
166
188
 
167
189
  describe("React Component Format Hooks", () => {
190
+ it("should serialize docked launcher config in React component format", () => {
191
+ const code = generateCodeSnippet(dockedConfig, "react-component");
192
+
193
+ expect(code).toContain('mountMode: "docked"');
194
+ expect(code).toContain('dock: {');
195
+ expect(code).toContain('side: "left"');
196
+ expect(code).toContain('width: "480px"');
197
+ expect(code).toContain('collapsedWidth: "84px"');
198
+ });
199
+
168
200
  it("should inject hooks in React component format", () => {
169
201
  const code = generateCodeSnippet(minimalConfig, "react-component", {
170
202
  hooks: {
@@ -191,6 +223,16 @@ describe("React Component Format Hooks", () => {
191
223
  });
192
224
 
193
225
  describe("React Advanced Format Hooks", () => {
226
+ it("should serialize docked launcher config in React advanced format", () => {
227
+ const code = generateCodeSnippet(dockedConfig, "react-advanced");
228
+
229
+ expect(code).toContain('mountMode: "docked"');
230
+ expect(code).toContain('dock: {');
231
+ expect(code).toContain('side: "left"');
232
+ expect(code).toContain('width: "480px"');
233
+ expect(code).toContain('collapsedWidth: "84px"');
234
+ });
235
+
194
236
  it("should inject custom action handlers alongside defaults", () => {
195
237
  const code = generateCodeSnippet(minimalConfig, "react-advanced", {
196
238
  hooks: {
@@ -242,6 +284,16 @@ describe("React Advanced Format Hooks", () => {
242
284
  });
243
285
 
244
286
  describe("Script Manual Format Hooks", () => {
287
+ it("should serialize docked launcher config in script-manual format", () => {
288
+ const code = generateCodeSnippet(dockedConfig, "script-manual");
289
+
290
+ expect(code).toContain('mountMode: "docked"');
291
+ expect(code).toContain('dock: {');
292
+ expect(code).toContain('side: "left"');
293
+ expect(code).toContain('width: "480px"');
294
+ expect(code).toContain('collapsedWidth: "84px"');
295
+ });
296
+
245
297
  it("should inject hooks in script-manual format", () => {
246
298
  const code = generateCodeSnippet(minimalConfig, "script-manual", {
247
299
  hooks: {
@@ -497,6 +497,42 @@ function generateHooksConfig(hooks: CodeGeneratorHooks | undefined, indent: stri
497
497
  return lines;
498
498
  }
499
499
 
500
+ function appendSerializableObjectEntries(
501
+ lines: string[],
502
+ value: Record<string, unknown>,
503
+ indent: string
504
+ ): void {
505
+ Object.entries(value).forEach(([key, entryValue]) => {
506
+ if (entryValue === undefined || typeof entryValue === "function") return;
507
+
508
+ if (Array.isArray(entryValue)) {
509
+ lines.push(`${indent}${key}: ${JSON.stringify(entryValue)},`);
510
+ return;
511
+ }
512
+
513
+ if (entryValue && typeof entryValue === "object") {
514
+ lines.push(`${indent}${key}: {`);
515
+ appendSerializableObjectEntries(lines, entryValue as Record<string, unknown>, `${indent} `);
516
+ lines.push(`${indent}},`);
517
+ return;
518
+ }
519
+
520
+ lines.push(`${indent}${key}: ${JSON.stringify(entryValue)},`);
521
+ });
522
+ }
523
+
524
+ function appendSerializableObjectBlock(
525
+ lines: string[],
526
+ key: string,
527
+ value: Record<string, unknown> | undefined,
528
+ indent: string
529
+ ): void {
530
+ if (!value) return;
531
+ lines.push(`${indent}${key}: {`);
532
+ appendSerializableObjectEntries(lines, value, `${indent} `);
533
+ lines.push(`${indent}},`);
534
+ }
535
+
500
536
  export function generateCodeSnippet(
501
537
  config: any,
502
538
  format: CodeFormat = "esm",
@@ -555,15 +591,7 @@ function generateESMCode(config: any, options?: CodeGeneratorOptions): string {
555
591
  }
556
592
 
557
593
  if (config.launcher) {
558
- lines.push(" launcher: {");
559
- Object.entries(config.launcher).forEach(([key, value]) => {
560
- if (typeof value === "string") {
561
- lines.push(` ${key}: "${value}",`);
562
- } else if (typeof value === "boolean") {
563
- lines.push(` ${key}: ${value},`);
564
- }
565
- });
566
- lines.push(" },");
594
+ appendSerializableObjectBlock(lines, "launcher", config.launcher, " ");
567
595
  }
568
596
 
569
597
  if (config.copy) {
@@ -713,15 +741,7 @@ function generateReactComponentCode(config: any, options?: CodeGeneratorOptions)
713
741
  }
714
742
 
715
743
  if (config.launcher) {
716
- lines.push(" launcher: {");
717
- Object.entries(config.launcher).forEach(([key, value]) => {
718
- if (typeof value === "string") {
719
- lines.push(` ${key}: "${value}",`);
720
- } else if (typeof value === "boolean") {
721
- lines.push(` ${key}: ${value},`);
722
- }
723
- });
724
- lines.push(" },");
744
+ appendSerializableObjectBlock(lines, "launcher", config.launcher, " ");
725
745
  }
726
746
 
727
747
  if (config.copy) {
@@ -988,15 +1008,7 @@ function generateReactAdvancedCode(config: any, options?: CodeGeneratorOptions):
988
1008
  }
989
1009
 
990
1010
  if (config.launcher) {
991
- lines.push(" launcher: {");
992
- Object.entries(config.launcher).forEach(([key, value]) => {
993
- if (typeof value === "string") {
994
- lines.push(` ${key}: "${value}",`);
995
- } else if (typeof value === "boolean") {
996
- lines.push(` ${key}: ${value},`);
997
- }
998
- });
999
- lines.push(" },");
1011
+ appendSerializableObjectBlock(lines, "launcher", config.launcher, " ");
1000
1012
  }
1001
1013
 
1002
1014
  if (config.copy) {
@@ -1388,15 +1400,7 @@ function generateScriptManualCode(config: any, options?: CodeGeneratorOptions):
1388
1400
  }
1389
1401
 
1390
1402
  if (config.launcher) {
1391
- lines.push(" launcher: {");
1392
- Object.entries(config.launcher).forEach(([key, value]) => {
1393
- if (typeof value === "string") {
1394
- lines.push(` ${key}: "${value}",`);
1395
- } else if (typeof value === "boolean") {
1396
- lines.push(` ${key}: ${value},`);
1397
- }
1398
- });
1399
- lines.push(" },");
1403
+ appendSerializableObjectBlock(lines, "launcher", config.launcher, " ");
1400
1404
  }
1401
1405
 
1402
1406
  if (config.copy) {
@@ -0,0 +1,17 @@
1
+ import type { AgentWidgetConfig, AgentWidgetDockConfig } from "../types";
2
+
3
+ const DEFAULT_DOCK_CONFIG: Required<AgentWidgetDockConfig> = {
4
+ side: "right",
5
+ width: "420px",
6
+ collapsedWidth: "72px",
7
+ };
8
+
9
+ export const isDockedMountMode = (config?: AgentWidgetConfig): boolean =>
10
+ (config?.launcher?.mountMode ?? "floating") === "docked";
11
+
12
+ export const resolveDockConfig = (
13
+ config?: AgentWidgetConfig
14
+ ): Required<AgentWidgetDockConfig> => ({
15
+ ...DEFAULT_DOCK_CONFIG,
16
+ ...(config?.launcher?.dock ?? {}),
17
+ });