@percena/weft 0.4.0-next.0 → 0.4.0-next.10

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 (114) hide show
  1. package/dist/action-bridge.cjs +323 -0
  2. package/dist/action-bridge.d.cts +8 -0
  3. package/dist/action-bridge.d.ts +8 -0
  4. package/dist/action-bridge.js +291 -0
  5. package/dist/chat.cjs +3851 -36
  6. package/dist/chat.d.cts +1 -874
  7. package/dist/chat.d.ts +1 -874
  8. package/dist/chat.js +3870 -36
  9. package/dist/index.cjs +12085 -1488
  10. package/dist/index.d.cts +553 -240
  11. package/dist/index.d.ts +553 -240
  12. package/dist/index.js +12118 -1447
  13. package/dist/providers-flitro.cjs +50 -307
  14. package/dist/providers-flitro.d.cts +75 -52
  15. package/dist/providers-flitro.d.ts +75 -52
  16. package/dist/providers-flitro.js +45 -287
  17. package/dist/styles/fonts/KaTeX_AMS-Regular.ttf +0 -0
  18. package/dist/styles/fonts/KaTeX_AMS-Regular.woff +0 -0
  19. package/dist/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  20. package/dist/styles/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  21. package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  22. package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  23. package/dist/styles/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  24. package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  25. package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  26. package/dist/styles/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  27. package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  28. package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  29. package/dist/styles/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  30. package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  31. package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  32. package/dist/styles/fonts/KaTeX_Main-Bold.ttf +0 -0
  33. package/dist/styles/fonts/KaTeX_Main-Bold.woff +0 -0
  34. package/dist/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
  35. package/dist/styles/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  36. package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  37. package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  38. package/dist/styles/fonts/KaTeX_Main-Italic.ttf +0 -0
  39. package/dist/styles/fonts/KaTeX_Main-Italic.woff +0 -0
  40. package/dist/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
  41. package/dist/styles/fonts/KaTeX_Main-Regular.ttf +0 -0
  42. package/dist/styles/fonts/KaTeX_Main-Regular.woff +0 -0
  43. package/dist/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
  44. package/dist/styles/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  45. package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  46. package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  47. package/dist/styles/fonts/KaTeX_Math-Italic.ttf +0 -0
  48. package/dist/styles/fonts/KaTeX_Math-Italic.woff +0 -0
  49. package/dist/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
  50. package/dist/styles/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  51. package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  52. package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  53. package/dist/styles/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  54. package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  55. package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  56. package/dist/styles/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  57. package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  58. package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  59. package/dist/styles/fonts/KaTeX_Script-Regular.ttf +0 -0
  60. package/dist/styles/fonts/KaTeX_Script-Regular.woff +0 -0
  61. package/dist/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
  62. package/dist/styles/fonts/KaTeX_Size1-Regular.ttf +0 -0
  63. package/dist/styles/fonts/KaTeX_Size1-Regular.woff +0 -0
  64. package/dist/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  65. package/dist/styles/fonts/KaTeX_Size2-Regular.ttf +0 -0
  66. package/dist/styles/fonts/KaTeX_Size2-Regular.woff +0 -0
  67. package/dist/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  68. package/dist/styles/fonts/KaTeX_Size3-Regular.ttf +0 -0
  69. package/dist/styles/fonts/KaTeX_Size3-Regular.woff +0 -0
  70. package/dist/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  71. package/dist/styles/fonts/KaTeX_Size4-Regular.ttf +0 -0
  72. package/dist/styles/fonts/KaTeX_Size4-Regular.woff +0 -0
  73. package/dist/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  74. package/dist/styles/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  75. package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  76. package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  77. package/dist/styles/index.css +2 -212
  78. package/package.json +23 -49
  79. package/dist/auth.cjs +0 -241
  80. package/dist/auth.d.cts +0 -21
  81. package/dist/auth.d.ts +0 -21
  82. package/dist/auth.js +0 -208
  83. package/dist/automations.cjs +0 -3044
  84. package/dist/automations.d.cts +0 -4774
  85. package/dist/automations.d.ts +0 -4774
  86. package/dist/automations.js +0 -2965
  87. package/dist/factory.cjs +0 -5057
  88. package/dist/factory.d.cts +0 -7909
  89. package/dist/factory.d.ts +0 -7909
  90. package/dist/factory.js +0 -5008
  91. package/dist/local-runtime.cjs +0 -1387
  92. package/dist/local-runtime.d.cts +0 -3314
  93. package/dist/local-runtime.d.ts +0 -3314
  94. package/dist/local-runtime.js +0 -1345
  95. package/dist/providers.cjs +0 -6154
  96. package/dist/providers.d.cts +0 -6024
  97. package/dist/providers.d.ts +0 -6024
  98. package/dist/providers.js +0 -6110
  99. package/dist/server.cjs +0 -9137
  100. package/dist/server.d.cts +0 -9868
  101. package/dist/server.d.ts +0 -9868
  102. package/dist/server.js +0 -9118
  103. package/dist/skills-browser.cjs +0 -118
  104. package/dist/skills-browser.d.cts +0 -105
  105. package/dist/skills-browser.d.ts +0 -105
  106. package/dist/skills-browser.js +0 -88
  107. package/dist/skills.cjs +0 -505
  108. package/dist/skills.d.cts +0 -218
  109. package/dist/skills.d.ts +0 -218
  110. package/dist/skills.js +0 -458
  111. package/dist/sources.cjs +0 -1710
  112. package/dist/sources.d.cts +0 -3978
  113. package/dist/sources.d.ts +0 -3978
  114. package/dist/sources.js +0 -1675
@@ -0,0 +1,323 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/action-bridge.ts
21
+ var action_bridge_exports = {};
22
+ __export(action_bridge_exports, {
23
+ ActionReplayLayer: () => ActionReplayLayer,
24
+ DEFAULT_TIMING: () => DEFAULT_TIMING,
25
+ createActionBridge: () => createActionBridge,
26
+ useActionBridge: () => useActionBridge,
27
+ weftAction: () => weftAction,
28
+ weftActionSelector: () => weftActionSelector
29
+ });
30
+ module.exports = __toCommonJS(action_bridge_exports);
31
+
32
+ // ../packages/action-bridge/dist/index.js
33
+ var DEFAULT_TIMING = {
34
+ cursorMoveMs: 550,
35
+ rippleMs: 450,
36
+ flashMs: 900,
37
+ cursorHideMs: 2600,
38
+ settleMs: 180
39
+ };
40
+ function weftAction(action, id) {
41
+ return { "data-weft-action": id === void 0 ? action : `${action}:${id}` };
42
+ }
43
+ function weftActionSelector(target) {
44
+ return `[data-weft-action=${JSON.stringify(target)}]`;
45
+ }
46
+ var FLASH_CLASS = "weft-action-flash";
47
+ var STYLE_ID = "weft-action-bridge-styles";
48
+ function injectStyles(doc, timing) {
49
+ if (doc.getElementById(STYLE_ID)) return;
50
+ const style = doc.createElement("style");
51
+ style.id = STYLE_ID;
52
+ style.textContent = `
53
+ .weft-ghost-cursor{position:fixed;left:0;top:0;z-index:9999;pointer-events:none;transition:transform ${timing.cursorMoveMs}ms cubic-bezier(.22,1,.36,1),opacity .3s ease}
54
+ .weft-ghost-cursor svg{display:block;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35))}
55
+ .weft-ghost-cursor .weft-cursor-label{position:absolute;left:18px;top:18px;white-space:nowrap;background:rgba(30,30,40,.92);color:#fff;font:12px/1.6 system-ui,sans-serif;padding:2px 8px;border-radius:6px}
56
+ .weft-ghost-cursor .weft-cursor-ripple{position:absolute;left:-14px;top:-14px;width:28px;height:28px;border-radius:50%;border:2px solid rgba(120,90,220,.8);opacity:0;transform:scale(.3)}
57
+ .weft-ghost-cursor.weft-clicking .weft-cursor-ripple{animation:weft-cursor-ripple ${timing.rippleMs}ms ease-out}
58
+ @keyframes weft-cursor-ripple{0%{opacity:.9;transform:scale(.3)}100%{opacity:0;transform:scale(1.6)}}
59
+ .${FLASH_CLASS}{animation:weft-action-flash ${timing.flashMs}ms ease-out}
60
+ @keyframes weft-action-flash{0%{box-shadow:0 0 0 3px rgba(120,90,220,.65)}100%{box-shadow:0 0 0 3px rgba(120,90,220,0)}}
61
+ `;
62
+ doc.head.appendChild(style);
63
+ }
64
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
65
+ function createActionBridge(options = {}) {
66
+ const doc = options.document ?? (typeof document !== "undefined" ? document : void 0);
67
+ const cursorMode = options.cursor ?? "ghost";
68
+ const timing = { ...DEFAULT_TIMING, ...options.timing };
69
+ const labelPrefix = options.labelPrefix ?? "AI";
70
+ let queue = Promise.resolve();
71
+ let disposed = false;
72
+ let cursorEl = null;
73
+ let hideTimer;
74
+ const disconnects = [];
75
+ function ensureCursor() {
76
+ if (!doc || cursorMode !== "ghost") return null;
77
+ if (cursorEl) return cursorEl;
78
+ injectStyles(doc, timing);
79
+ cursorEl = doc.createElement("div");
80
+ cursorEl.className = "weft-ghost-cursor";
81
+ cursorEl.style.opacity = "0";
82
+ cursorEl.innerHTML = '<div class="weft-cursor-ripple"></div><svg width="20" height="20" viewBox="0 0 24 24"><path d="M4 2l16 8.5-7 1.8L9.4 19z" fill="#fff" stroke="#333" stroke-width="1.4"/></svg><span class="weft-cursor-label"></span>';
83
+ doc.body.appendChild(cursorEl);
84
+ return cursorEl;
85
+ }
86
+ async function replay(event) {
87
+ if (disposed || !doc) return;
88
+ const el = event.target ? doc.querySelector(weftActionSelector(event.target)) : null;
89
+ if (el && cursorMode !== "off") {
90
+ injectStyles(doc, timing);
91
+ const rect = el.getBoundingClientRect();
92
+ const cursor = ensureCursor();
93
+ if (cursor) {
94
+ const label = cursor.querySelector(".weft-cursor-label");
95
+ label.textContent = event.label ? `${labelPrefix} ${event.label}` : labelPrefix;
96
+ cursor.style.transform = `translate(${rect.left + rect.width / 2}px, ${rect.top + rect.height / 2}px)`;
97
+ cursor.style.opacity = "1";
98
+ await sleep(timing.cursorMoveMs + 70);
99
+ if (disposed) return;
100
+ cursor.classList.add("weft-clicking");
101
+ }
102
+ el.classList.add(FLASH_CLASS);
103
+ setTimeout(() => el.classList.remove(FLASH_CLASS), timing.flashMs + 50);
104
+ await sleep(timing.rippleMs);
105
+ cursor?.classList.remove("weft-clicking");
106
+ }
107
+ await options.onReplayed?.(event);
108
+ await sleep(timing.settleMs);
109
+ if (cursorEl) {
110
+ if (hideTimer) clearTimeout(hideTimer);
111
+ hideTimer = setTimeout(() => {
112
+ if (cursorEl) cursorEl.style.opacity = "0";
113
+ }, timing.cursorHideMs);
114
+ }
115
+ }
116
+ function accepts(event) {
117
+ if (event.actor !== "agent") return false;
118
+ if (options.session && event.session && event.session !== options.session) return false;
119
+ return true;
120
+ }
121
+ return {
122
+ dispatch(event) {
123
+ if (disposed || !accepts(event)) return;
124
+ queue = queue.then(() => replay(event)).catch(() => {
125
+ });
126
+ },
127
+ connect(source, connectOptions) {
128
+ const eventName = connectOptions?.eventName ?? "weft-action";
129
+ const map = connectOptions?.map ?? ((raw) => raw);
130
+ const listener = (e) => {
131
+ let raw;
132
+ try {
133
+ raw = JSON.parse(e.data);
134
+ } catch {
135
+ return;
136
+ }
137
+ const event = map(raw);
138
+ if (event) this.dispatch(event);
139
+ };
140
+ source.addEventListener(eventName, listener);
141
+ const disconnect = () => source.removeEventListener?.(eventName, listener);
142
+ disconnects.push(disconnect);
143
+ return disconnect;
144
+ },
145
+ flush() {
146
+ return queue;
147
+ },
148
+ dispose() {
149
+ disposed = true;
150
+ for (const disconnect of disconnects) disconnect();
151
+ if (hideTimer) clearTimeout(hideTimer);
152
+ cursorEl?.remove();
153
+ cursorEl = null;
154
+ doc?.getElementById(STYLE_ID)?.remove();
155
+ }
156
+ };
157
+ }
158
+
159
+ // ../packages/action-bridge/dist/react.js
160
+ var import_react = require("react");
161
+ var DEFAULT_TIMING2 = {
162
+ cursorMoveMs: 550,
163
+ rippleMs: 450,
164
+ flashMs: 900,
165
+ cursorHideMs: 2600,
166
+ settleMs: 180
167
+ };
168
+ function weftActionSelector2(target) {
169
+ return `[data-weft-action=${JSON.stringify(target)}]`;
170
+ }
171
+ var FLASH_CLASS2 = "weft-action-flash";
172
+ var STYLE_ID2 = "weft-action-bridge-styles";
173
+ function injectStyles2(doc, timing) {
174
+ if (doc.getElementById(STYLE_ID2)) return;
175
+ const style = doc.createElement("style");
176
+ style.id = STYLE_ID2;
177
+ style.textContent = `
178
+ .weft-ghost-cursor{position:fixed;left:0;top:0;z-index:9999;pointer-events:none;transition:transform ${timing.cursorMoveMs}ms cubic-bezier(.22,1,.36,1),opacity .3s ease}
179
+ .weft-ghost-cursor svg{display:block;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35))}
180
+ .weft-ghost-cursor .weft-cursor-label{position:absolute;left:18px;top:18px;white-space:nowrap;background:rgba(30,30,40,.92);color:#fff;font:12px/1.6 system-ui,sans-serif;padding:2px 8px;border-radius:6px}
181
+ .weft-ghost-cursor .weft-cursor-ripple{position:absolute;left:-14px;top:-14px;width:28px;height:28px;border-radius:50%;border:2px solid rgba(120,90,220,.8);opacity:0;transform:scale(.3)}
182
+ .weft-ghost-cursor.weft-clicking .weft-cursor-ripple{animation:weft-cursor-ripple ${timing.rippleMs}ms ease-out}
183
+ @keyframes weft-cursor-ripple{0%{opacity:.9;transform:scale(.3)}100%{opacity:0;transform:scale(1.6)}}
184
+ .${FLASH_CLASS2}{animation:weft-action-flash ${timing.flashMs}ms ease-out}
185
+ @keyframes weft-action-flash{0%{box-shadow:0 0 0 3px rgba(120,90,220,.65)}100%{box-shadow:0 0 0 3px rgba(120,90,220,0)}}
186
+ `;
187
+ doc.head.appendChild(style);
188
+ }
189
+ var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
190
+ function createActionBridge2(options = {}) {
191
+ const doc = options.document ?? (typeof document !== "undefined" ? document : void 0);
192
+ const cursorMode = options.cursor ?? "ghost";
193
+ const timing = { ...DEFAULT_TIMING2, ...options.timing };
194
+ const labelPrefix = options.labelPrefix ?? "AI";
195
+ let queue = Promise.resolve();
196
+ let disposed = false;
197
+ let cursorEl = null;
198
+ let hideTimer;
199
+ const disconnects = [];
200
+ function ensureCursor() {
201
+ if (!doc || cursorMode !== "ghost") return null;
202
+ if (cursorEl) return cursorEl;
203
+ injectStyles2(doc, timing);
204
+ cursorEl = doc.createElement("div");
205
+ cursorEl.className = "weft-ghost-cursor";
206
+ cursorEl.style.opacity = "0";
207
+ cursorEl.innerHTML = '<div class="weft-cursor-ripple"></div><svg width="20" height="20" viewBox="0 0 24 24"><path d="M4 2l16 8.5-7 1.8L9.4 19z" fill="#fff" stroke="#333" stroke-width="1.4"/></svg><span class="weft-cursor-label"></span>';
208
+ doc.body.appendChild(cursorEl);
209
+ return cursorEl;
210
+ }
211
+ async function replay(event) {
212
+ if (disposed || !doc) return;
213
+ const el = event.target ? doc.querySelector(weftActionSelector2(event.target)) : null;
214
+ if (el && cursorMode !== "off") {
215
+ injectStyles2(doc, timing);
216
+ const rect = el.getBoundingClientRect();
217
+ const cursor = ensureCursor();
218
+ if (cursor) {
219
+ const label = cursor.querySelector(".weft-cursor-label");
220
+ label.textContent = event.label ? `${labelPrefix} ${event.label}` : labelPrefix;
221
+ cursor.style.transform = `translate(${rect.left + rect.width / 2}px, ${rect.top + rect.height / 2}px)`;
222
+ cursor.style.opacity = "1";
223
+ await sleep2(timing.cursorMoveMs + 70);
224
+ if (disposed) return;
225
+ cursor.classList.add("weft-clicking");
226
+ }
227
+ el.classList.add(FLASH_CLASS2);
228
+ setTimeout(() => el.classList.remove(FLASH_CLASS2), timing.flashMs + 50);
229
+ await sleep2(timing.rippleMs);
230
+ cursor?.classList.remove("weft-clicking");
231
+ }
232
+ await options.onReplayed?.(event);
233
+ await sleep2(timing.settleMs);
234
+ if (cursorEl) {
235
+ if (hideTimer) clearTimeout(hideTimer);
236
+ hideTimer = setTimeout(() => {
237
+ if (cursorEl) cursorEl.style.opacity = "0";
238
+ }, timing.cursorHideMs);
239
+ }
240
+ }
241
+ function accepts(event) {
242
+ if (event.actor !== "agent") return false;
243
+ if (options.session && event.session && event.session !== options.session) return false;
244
+ return true;
245
+ }
246
+ return {
247
+ dispatch(event) {
248
+ if (disposed || !accepts(event)) return;
249
+ queue = queue.then(() => replay(event)).catch(() => {
250
+ });
251
+ },
252
+ connect(source, connectOptions) {
253
+ const eventName = connectOptions?.eventName ?? "weft-action";
254
+ const map = connectOptions?.map ?? ((raw) => raw);
255
+ const listener = (e) => {
256
+ let raw;
257
+ try {
258
+ raw = JSON.parse(e.data);
259
+ } catch {
260
+ return;
261
+ }
262
+ const event = map(raw);
263
+ if (event) this.dispatch(event);
264
+ };
265
+ source.addEventListener(eventName, listener);
266
+ const disconnect = () => source.removeEventListener?.(eventName, listener);
267
+ disconnects.push(disconnect);
268
+ return disconnect;
269
+ },
270
+ flush() {
271
+ return queue;
272
+ },
273
+ dispose() {
274
+ disposed = true;
275
+ for (const disconnect of disconnects) disconnect();
276
+ if (hideTimer) clearTimeout(hideTimer);
277
+ cursorEl?.remove();
278
+ cursorEl = null;
279
+ doc?.getElementById(STYLE_ID2)?.remove();
280
+ }
281
+ };
282
+ }
283
+ function useActionBridge(options = {}) {
284
+ const bridgeRef = (0, import_react.useRef)(null);
285
+ const optionsRef = (0, import_react.useRef)(options);
286
+ optionsRef.current = options;
287
+ if (!bridgeRef.current) {
288
+ bridgeRef.current = createActionBridge2({
289
+ ...options,
290
+ onReplayed: (event) => optionsRef.current.onReplayed?.(event)
291
+ });
292
+ }
293
+ (0, import_react.useEffect)(() => {
294
+ return () => {
295
+ bridgeRef.current?.dispose();
296
+ bridgeRef.current = null;
297
+ };
298
+ }, []);
299
+ return bridgeRef.current;
300
+ }
301
+ function ActionReplayLayer(props) {
302
+ const { source, eventName, map, ...bridgeOptions } = props;
303
+ const bridge = useActionBridge(bridgeOptions);
304
+ const mapRef = (0, import_react.useRef)(map);
305
+ mapRef.current = map;
306
+ (0, import_react.useEffect)(() => {
307
+ if (!source) return;
308
+ return bridge.connect(source, {
309
+ eventName,
310
+ map: mapRef.current ? (raw) => mapRef.current?.(raw) ?? null : void 0
311
+ });
312
+ }, [bridge, source, eventName]);
313
+ return null;
314
+ }
315
+ // Annotate the CommonJS export names for ESM import in node:
316
+ 0 && (module.exports = {
317
+ ActionReplayLayer,
318
+ DEFAULT_TIMING,
319
+ createActionBridge,
320
+ useActionBridge,
321
+ weftAction,
322
+ weftActionSelector
323
+ });
@@ -0,0 +1,8 @@
1
+ export { ActionReplayLayer, ActionReplayLayerProps, useActionBridge };
2
+ import '@weft/ui';
3
+ import '@weft/chat';
4
+ import '@weft/ui/lib/en-fallback';
5
+ import '@weft/react';
6
+ import '@weft/runtime-core';
7
+ import '@weft/timeline';
8
+ import '@weft/provider-flitro';
@@ -0,0 +1,8 @@
1
+ export { ActionReplayLayer, ActionReplayLayerProps, useActionBridge };
2
+ import '@weft/ui';
3
+ import '@weft/chat';
4
+ import '@weft/ui/lib/en-fallback';
5
+ import '@weft/react';
6
+ import '@weft/runtime-core';
7
+ import '@weft/timeline';
8
+ import '@weft/provider-flitro';
@@ -0,0 +1,291 @@
1
+ // ../packages/action-bridge/dist/index.js
2
+ var DEFAULT_TIMING = {
3
+ cursorMoveMs: 550,
4
+ rippleMs: 450,
5
+ flashMs: 900,
6
+ cursorHideMs: 2600,
7
+ settleMs: 180
8
+ };
9
+ function weftAction(action, id) {
10
+ return { "data-weft-action": id === void 0 ? action : `${action}:${id}` };
11
+ }
12
+ function weftActionSelector(target) {
13
+ return `[data-weft-action=${JSON.stringify(target)}]`;
14
+ }
15
+ var FLASH_CLASS = "weft-action-flash";
16
+ var STYLE_ID = "weft-action-bridge-styles";
17
+ function injectStyles(doc, timing) {
18
+ if (doc.getElementById(STYLE_ID)) return;
19
+ const style = doc.createElement("style");
20
+ style.id = STYLE_ID;
21
+ style.textContent = `
22
+ .weft-ghost-cursor{position:fixed;left:0;top:0;z-index:9999;pointer-events:none;transition:transform ${timing.cursorMoveMs}ms cubic-bezier(.22,1,.36,1),opacity .3s ease}
23
+ .weft-ghost-cursor svg{display:block;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35))}
24
+ .weft-ghost-cursor .weft-cursor-label{position:absolute;left:18px;top:18px;white-space:nowrap;background:rgba(30,30,40,.92);color:#fff;font:12px/1.6 system-ui,sans-serif;padding:2px 8px;border-radius:6px}
25
+ .weft-ghost-cursor .weft-cursor-ripple{position:absolute;left:-14px;top:-14px;width:28px;height:28px;border-radius:50%;border:2px solid rgba(120,90,220,.8);opacity:0;transform:scale(.3)}
26
+ .weft-ghost-cursor.weft-clicking .weft-cursor-ripple{animation:weft-cursor-ripple ${timing.rippleMs}ms ease-out}
27
+ @keyframes weft-cursor-ripple{0%{opacity:.9;transform:scale(.3)}100%{opacity:0;transform:scale(1.6)}}
28
+ .${FLASH_CLASS}{animation:weft-action-flash ${timing.flashMs}ms ease-out}
29
+ @keyframes weft-action-flash{0%{box-shadow:0 0 0 3px rgba(120,90,220,.65)}100%{box-shadow:0 0 0 3px rgba(120,90,220,0)}}
30
+ `;
31
+ doc.head.appendChild(style);
32
+ }
33
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
34
+ function createActionBridge(options = {}) {
35
+ const doc = options.document ?? (typeof document !== "undefined" ? document : void 0);
36
+ const cursorMode = options.cursor ?? "ghost";
37
+ const timing = { ...DEFAULT_TIMING, ...options.timing };
38
+ const labelPrefix = options.labelPrefix ?? "AI";
39
+ let queue = Promise.resolve();
40
+ let disposed = false;
41
+ let cursorEl = null;
42
+ let hideTimer;
43
+ const disconnects = [];
44
+ function ensureCursor() {
45
+ if (!doc || cursorMode !== "ghost") return null;
46
+ if (cursorEl) return cursorEl;
47
+ injectStyles(doc, timing);
48
+ cursorEl = doc.createElement("div");
49
+ cursorEl.className = "weft-ghost-cursor";
50
+ cursorEl.style.opacity = "0";
51
+ cursorEl.innerHTML = '<div class="weft-cursor-ripple"></div><svg width="20" height="20" viewBox="0 0 24 24"><path d="M4 2l16 8.5-7 1.8L9.4 19z" fill="#fff" stroke="#333" stroke-width="1.4"/></svg><span class="weft-cursor-label"></span>';
52
+ doc.body.appendChild(cursorEl);
53
+ return cursorEl;
54
+ }
55
+ async function replay(event) {
56
+ if (disposed || !doc) return;
57
+ const el = event.target ? doc.querySelector(weftActionSelector(event.target)) : null;
58
+ if (el && cursorMode !== "off") {
59
+ injectStyles(doc, timing);
60
+ const rect = el.getBoundingClientRect();
61
+ const cursor = ensureCursor();
62
+ if (cursor) {
63
+ const label = cursor.querySelector(".weft-cursor-label");
64
+ label.textContent = event.label ? `${labelPrefix} ${event.label}` : labelPrefix;
65
+ cursor.style.transform = `translate(${rect.left + rect.width / 2}px, ${rect.top + rect.height / 2}px)`;
66
+ cursor.style.opacity = "1";
67
+ await sleep(timing.cursorMoveMs + 70);
68
+ if (disposed) return;
69
+ cursor.classList.add("weft-clicking");
70
+ }
71
+ el.classList.add(FLASH_CLASS);
72
+ setTimeout(() => el.classList.remove(FLASH_CLASS), timing.flashMs + 50);
73
+ await sleep(timing.rippleMs);
74
+ cursor?.classList.remove("weft-clicking");
75
+ }
76
+ await options.onReplayed?.(event);
77
+ await sleep(timing.settleMs);
78
+ if (cursorEl) {
79
+ if (hideTimer) clearTimeout(hideTimer);
80
+ hideTimer = setTimeout(() => {
81
+ if (cursorEl) cursorEl.style.opacity = "0";
82
+ }, timing.cursorHideMs);
83
+ }
84
+ }
85
+ function accepts(event) {
86
+ if (event.actor !== "agent") return false;
87
+ if (options.session && event.session && event.session !== options.session) return false;
88
+ return true;
89
+ }
90
+ return {
91
+ dispatch(event) {
92
+ if (disposed || !accepts(event)) return;
93
+ queue = queue.then(() => replay(event)).catch(() => {
94
+ });
95
+ },
96
+ connect(source, connectOptions) {
97
+ const eventName = connectOptions?.eventName ?? "weft-action";
98
+ const map = connectOptions?.map ?? ((raw) => raw);
99
+ const listener = (e) => {
100
+ let raw;
101
+ try {
102
+ raw = JSON.parse(e.data);
103
+ } catch {
104
+ return;
105
+ }
106
+ const event = map(raw);
107
+ if (event) this.dispatch(event);
108
+ };
109
+ source.addEventListener(eventName, listener);
110
+ const disconnect = () => source.removeEventListener?.(eventName, listener);
111
+ disconnects.push(disconnect);
112
+ return disconnect;
113
+ },
114
+ flush() {
115
+ return queue;
116
+ },
117
+ dispose() {
118
+ disposed = true;
119
+ for (const disconnect of disconnects) disconnect();
120
+ if (hideTimer) clearTimeout(hideTimer);
121
+ cursorEl?.remove();
122
+ cursorEl = null;
123
+ doc?.getElementById(STYLE_ID)?.remove();
124
+ }
125
+ };
126
+ }
127
+
128
+ // ../packages/action-bridge/dist/react.js
129
+ import { useEffect, useRef } from "react";
130
+ var DEFAULT_TIMING2 = {
131
+ cursorMoveMs: 550,
132
+ rippleMs: 450,
133
+ flashMs: 900,
134
+ cursorHideMs: 2600,
135
+ settleMs: 180
136
+ };
137
+ function weftActionSelector2(target) {
138
+ return `[data-weft-action=${JSON.stringify(target)}]`;
139
+ }
140
+ var FLASH_CLASS2 = "weft-action-flash";
141
+ var STYLE_ID2 = "weft-action-bridge-styles";
142
+ function injectStyles2(doc, timing) {
143
+ if (doc.getElementById(STYLE_ID2)) return;
144
+ const style = doc.createElement("style");
145
+ style.id = STYLE_ID2;
146
+ style.textContent = `
147
+ .weft-ghost-cursor{position:fixed;left:0;top:0;z-index:9999;pointer-events:none;transition:transform ${timing.cursorMoveMs}ms cubic-bezier(.22,1,.36,1),opacity .3s ease}
148
+ .weft-ghost-cursor svg{display:block;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35))}
149
+ .weft-ghost-cursor .weft-cursor-label{position:absolute;left:18px;top:18px;white-space:nowrap;background:rgba(30,30,40,.92);color:#fff;font:12px/1.6 system-ui,sans-serif;padding:2px 8px;border-radius:6px}
150
+ .weft-ghost-cursor .weft-cursor-ripple{position:absolute;left:-14px;top:-14px;width:28px;height:28px;border-radius:50%;border:2px solid rgba(120,90,220,.8);opacity:0;transform:scale(.3)}
151
+ .weft-ghost-cursor.weft-clicking .weft-cursor-ripple{animation:weft-cursor-ripple ${timing.rippleMs}ms ease-out}
152
+ @keyframes weft-cursor-ripple{0%{opacity:.9;transform:scale(.3)}100%{opacity:0;transform:scale(1.6)}}
153
+ .${FLASH_CLASS2}{animation:weft-action-flash ${timing.flashMs}ms ease-out}
154
+ @keyframes weft-action-flash{0%{box-shadow:0 0 0 3px rgba(120,90,220,.65)}100%{box-shadow:0 0 0 3px rgba(120,90,220,0)}}
155
+ `;
156
+ doc.head.appendChild(style);
157
+ }
158
+ var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
159
+ function createActionBridge2(options = {}) {
160
+ const doc = options.document ?? (typeof document !== "undefined" ? document : void 0);
161
+ const cursorMode = options.cursor ?? "ghost";
162
+ const timing = { ...DEFAULT_TIMING2, ...options.timing };
163
+ const labelPrefix = options.labelPrefix ?? "AI";
164
+ let queue = Promise.resolve();
165
+ let disposed = false;
166
+ let cursorEl = null;
167
+ let hideTimer;
168
+ const disconnects = [];
169
+ function ensureCursor() {
170
+ if (!doc || cursorMode !== "ghost") return null;
171
+ if (cursorEl) return cursorEl;
172
+ injectStyles2(doc, timing);
173
+ cursorEl = doc.createElement("div");
174
+ cursorEl.className = "weft-ghost-cursor";
175
+ cursorEl.style.opacity = "0";
176
+ cursorEl.innerHTML = '<div class="weft-cursor-ripple"></div><svg width="20" height="20" viewBox="0 0 24 24"><path d="M4 2l16 8.5-7 1.8L9.4 19z" fill="#fff" stroke="#333" stroke-width="1.4"/></svg><span class="weft-cursor-label"></span>';
177
+ doc.body.appendChild(cursorEl);
178
+ return cursorEl;
179
+ }
180
+ async function replay(event) {
181
+ if (disposed || !doc) return;
182
+ const el = event.target ? doc.querySelector(weftActionSelector2(event.target)) : null;
183
+ if (el && cursorMode !== "off") {
184
+ injectStyles2(doc, timing);
185
+ const rect = el.getBoundingClientRect();
186
+ const cursor = ensureCursor();
187
+ if (cursor) {
188
+ const label = cursor.querySelector(".weft-cursor-label");
189
+ label.textContent = event.label ? `${labelPrefix} ${event.label}` : labelPrefix;
190
+ cursor.style.transform = `translate(${rect.left + rect.width / 2}px, ${rect.top + rect.height / 2}px)`;
191
+ cursor.style.opacity = "1";
192
+ await sleep2(timing.cursorMoveMs + 70);
193
+ if (disposed) return;
194
+ cursor.classList.add("weft-clicking");
195
+ }
196
+ el.classList.add(FLASH_CLASS2);
197
+ setTimeout(() => el.classList.remove(FLASH_CLASS2), timing.flashMs + 50);
198
+ await sleep2(timing.rippleMs);
199
+ cursor?.classList.remove("weft-clicking");
200
+ }
201
+ await options.onReplayed?.(event);
202
+ await sleep2(timing.settleMs);
203
+ if (cursorEl) {
204
+ if (hideTimer) clearTimeout(hideTimer);
205
+ hideTimer = setTimeout(() => {
206
+ if (cursorEl) cursorEl.style.opacity = "0";
207
+ }, timing.cursorHideMs);
208
+ }
209
+ }
210
+ function accepts(event) {
211
+ if (event.actor !== "agent") return false;
212
+ if (options.session && event.session && event.session !== options.session) return false;
213
+ return true;
214
+ }
215
+ return {
216
+ dispatch(event) {
217
+ if (disposed || !accepts(event)) return;
218
+ queue = queue.then(() => replay(event)).catch(() => {
219
+ });
220
+ },
221
+ connect(source, connectOptions) {
222
+ const eventName = connectOptions?.eventName ?? "weft-action";
223
+ const map = connectOptions?.map ?? ((raw) => raw);
224
+ const listener = (e) => {
225
+ let raw;
226
+ try {
227
+ raw = JSON.parse(e.data);
228
+ } catch {
229
+ return;
230
+ }
231
+ const event = map(raw);
232
+ if (event) this.dispatch(event);
233
+ };
234
+ source.addEventListener(eventName, listener);
235
+ const disconnect = () => source.removeEventListener?.(eventName, listener);
236
+ disconnects.push(disconnect);
237
+ return disconnect;
238
+ },
239
+ flush() {
240
+ return queue;
241
+ },
242
+ dispose() {
243
+ disposed = true;
244
+ for (const disconnect of disconnects) disconnect();
245
+ if (hideTimer) clearTimeout(hideTimer);
246
+ cursorEl?.remove();
247
+ cursorEl = null;
248
+ doc?.getElementById(STYLE_ID2)?.remove();
249
+ }
250
+ };
251
+ }
252
+ function useActionBridge(options = {}) {
253
+ const bridgeRef = useRef(null);
254
+ const optionsRef = useRef(options);
255
+ optionsRef.current = options;
256
+ if (!bridgeRef.current) {
257
+ bridgeRef.current = createActionBridge2({
258
+ ...options,
259
+ onReplayed: (event) => optionsRef.current.onReplayed?.(event)
260
+ });
261
+ }
262
+ useEffect(() => {
263
+ return () => {
264
+ bridgeRef.current?.dispose();
265
+ bridgeRef.current = null;
266
+ };
267
+ }, []);
268
+ return bridgeRef.current;
269
+ }
270
+ function ActionReplayLayer(props) {
271
+ const { source, eventName, map, ...bridgeOptions } = props;
272
+ const bridge = useActionBridge(bridgeOptions);
273
+ const mapRef = useRef(map);
274
+ mapRef.current = map;
275
+ useEffect(() => {
276
+ if (!source) return;
277
+ return bridge.connect(source, {
278
+ eventName,
279
+ map: mapRef.current ? (raw) => mapRef.current?.(raw) ?? null : void 0
280
+ });
281
+ }, [bridge, source, eventName]);
282
+ return null;
283
+ }
284
+ export {
285
+ ActionReplayLayer,
286
+ DEFAULT_TIMING,
287
+ createActionBridge,
288
+ useActionBridge,
289
+ weftAction,
290
+ weftActionSelector
291
+ };