@jami-studio/pinpoint 0.1.12

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 (47) hide show
  1. package/.agents/skills/pinpoint/SKILL.md +77 -0
  2. package/README.md +412 -0
  3. package/dist/agent-context-HBCZ4MBN.js +13 -0
  4. package/dist/agent-context-HBCZ4MBN.js.map +1 -0
  5. package/dist/chunk-B7TY4FPP.js +569 -0
  6. package/dist/chunk-B7TY4FPP.js.map +1 -0
  7. package/dist/chunk-CGJZ7BOM.js +88 -0
  8. package/dist/chunk-CGJZ7BOM.js.map +1 -0
  9. package/dist/chunk-DGUM43GV.js +11 -0
  10. package/dist/chunk-DGUM43GV.js.map +1 -0
  11. package/dist/chunk-HAEYE6KB.js +25 -0
  12. package/dist/chunk-HAEYE6KB.js.map +1 -0
  13. package/dist/chunk-J5PXKVTM.js +53 -0
  14. package/dist/chunk-J5PXKVTM.js.map +1 -0
  15. package/dist/chunk-XBX2J7WU.js +94 -0
  16. package/dist/chunk-XBX2J7WU.js.map +1 -0
  17. package/dist/chunk-ZW7IO3EW.js +4927 -0
  18. package/dist/chunk-ZW7IO3EW.js.map +1 -0
  19. package/dist/cli.js +71 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/formatter-CR4COA5Z.js +8 -0
  22. package/dist/formatter-CR4COA5Z.js.map +1 -0
  23. package/dist/index-NvFcZ4SO.d.ts +200 -0
  24. package/dist/index.browser.d.ts +377 -0
  25. package/dist/index.browser.js +620 -0
  26. package/dist/index.browser.js.map +1 -0
  27. package/dist/index.js +936 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/open-file-WR2JHI4P.js +8 -0
  30. package/dist/open-file-WR2JHI4P.js.map +1 -0
  31. package/dist/primitives/index.js +28 -0
  32. package/dist/primitives/index.js.map +1 -0
  33. package/dist/react.d.ts +23 -0
  34. package/dist/react.js +20 -0
  35. package/dist/react.js.map +1 -0
  36. package/dist/server/index.js +457 -0
  37. package/dist/server/index.js.map +1 -0
  38. package/dist/types/index.js +1 -0
  39. package/dist/types/index.js.map +1 -0
  40. package/package.json +88 -0
  41. package/src/scripts/create-pin.ts +43 -0
  42. package/src/scripts/delete-pin.ts +16 -0
  43. package/src/scripts/get-pins.ts +36 -0
  44. package/src/scripts/list-sessions.ts +33 -0
  45. package/src/scripts/resolve-pin.ts +27 -0
  46. package/src/scripts/run.ts +8 -0
  47. package/src/scripts/update-pin.ts +32 -0
@@ -0,0 +1,569 @@
1
+ // src/storage/memory-store.ts
2
+ var MemoryStore = class {
3
+ pins = /* @__PURE__ */ new Map();
4
+ async load(pageUrl) {
5
+ return Array.from(this.pins.values()).filter(
6
+ (pin) => pin.pageUrl === pageUrl
7
+ );
8
+ }
9
+ async save(pin) {
10
+ this.pins.set(pin.id, { ...pin });
11
+ }
12
+ async update(id, patch) {
13
+ const existing = this.pins.get(id);
14
+ if (!existing) return;
15
+ this.pins.set(id, {
16
+ ...existing,
17
+ ...patch,
18
+ id: existing.id,
19
+ // never overwrite ID
20
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
21
+ });
22
+ }
23
+ async delete(id) {
24
+ this.pins.delete(id);
25
+ }
26
+ async list(filter) {
27
+ let result = Array.from(this.pins.values());
28
+ if (filter?.pageUrl) {
29
+ result = result.filter((pin) => pin.pageUrl === filter.pageUrl);
30
+ }
31
+ if (filter?.status) {
32
+ result = result.filter((pin) => pin.status.state === filter.status);
33
+ }
34
+ return result;
35
+ }
36
+ async clear(pageUrl) {
37
+ if (pageUrl) {
38
+ for (const [id, pin] of this.pins) {
39
+ if (pin.pageUrl === pageUrl) {
40
+ this.pins.delete(id);
41
+ }
42
+ }
43
+ } else {
44
+ this.pins.clear();
45
+ }
46
+ }
47
+ };
48
+
49
+ // src/detection/selector-builder.ts
50
+ import { finder } from "@medv/finder";
51
+ var DEFAULT_SKIP_CLASSES = [
52
+ /^css-/,
53
+ // CSS-in-JS (Emotion, etc.)
54
+ /^_/,
55
+ // CSS Modules hashes
56
+ /^sc-/,
57
+ // styled-components
58
+ /^go\d/,
59
+ // Goober
60
+ /^tw-/,
61
+ // Tailwind utilities (sometimes hashed)
62
+ /^chakra-/
63
+ // Chakra UI internals
64
+ ];
65
+ var DEFAULT_SKIP_IDS = [
66
+ /^:r[0-9]/,
67
+ // React auto-generated IDs
68
+ /^radix-/,
69
+ // Radix UI auto IDs
70
+ /^headlessui-/
71
+ // HeadlessUI auto IDs
72
+ ];
73
+ function buildSelector(element, options = {}) {
74
+ const { timeoutMs = 200, skipClassPatterns = [] } = options;
75
+ const allSkipClasses = [...DEFAULT_SKIP_CLASSES, ...skipClassPatterns];
76
+ try {
77
+ return finder(element, {
78
+ className: (name) => !allSkipClasses.some((pattern) => pattern.test(name)),
79
+ idName: (name) => !DEFAULT_SKIP_IDS.some((pattern) => pattern.test(name)),
80
+ attr: (name) => name.startsWith("data-testid") || name.startsWith("data-cy"),
81
+ timeoutMs
82
+ });
83
+ } catch {
84
+ return buildFallbackSelector(element);
85
+ }
86
+ }
87
+ function buildFallbackSelector(element) {
88
+ const parts = [];
89
+ if (element.id) {
90
+ return `#${CSS.escape(element.id)}`;
91
+ }
92
+ parts.push(element.tagName.toLowerCase());
93
+ const testId = element.getAttribute("data-testid");
94
+ if (testId) {
95
+ return `[data-testid="${CSS.escape(testId)}"]`;
96
+ }
97
+ const classes = Array.from(element.classList).filter(
98
+ (name) => !DEFAULT_SKIP_CLASSES.some((pattern) => pattern.test(name))
99
+ );
100
+ if (classes.length > 0) {
101
+ parts.push(`.${classes.map((c) => CSS.escape(c)).join(".")}`);
102
+ }
103
+ const parent = element.parentElement;
104
+ if (parent) {
105
+ const siblings = Array.from(parent.children).filter(
106
+ (child) => child.tagName === element.tagName
107
+ );
108
+ if (siblings.length > 1) {
109
+ const index = siblings.indexOf(element) + 1;
110
+ parts.push(`:nth-child(${index})`);
111
+ }
112
+ }
113
+ return parts.join("");
114
+ }
115
+
116
+ // src/detection/element-info.ts
117
+ var STYLE_KEYS = [
118
+ "color",
119
+ "backgroundColor",
120
+ "fontSize",
121
+ "fontFamily",
122
+ "fontWeight",
123
+ "lineHeight",
124
+ "padding",
125
+ "margin",
126
+ "border",
127
+ "borderRadius",
128
+ "display",
129
+ "position",
130
+ "width",
131
+ "height",
132
+ "opacity",
133
+ "zIndex",
134
+ "overflow",
135
+ "textAlign",
136
+ "textDecoration"
137
+ ];
138
+ function extractElementInfo(element) {
139
+ const rect = element.getBoundingClientRect();
140
+ const computed = window.getComputedStyle(element);
141
+ const computedStyles = {};
142
+ for (const key of STYLE_KEYS) {
143
+ const value = computed.getPropertyValue(
144
+ key.replace(/([A-Z])/g, "-$1").toLowerCase()
145
+ );
146
+ if (value) {
147
+ computedStyles[key] = value;
148
+ }
149
+ }
150
+ const ariaAttributes = {};
151
+ for (const attr of element.attributes) {
152
+ if (attr.name.startsWith("aria-") || attr.name === "role") {
153
+ ariaAttributes[attr.name] = attr.value;
154
+ }
155
+ }
156
+ const dataAttributes = {};
157
+ for (const attr of element.attributes) {
158
+ if (attr.name.startsWith("data-")) {
159
+ dataAttributes[attr.name] = attr.value;
160
+ }
161
+ }
162
+ const domPath = buildDomPath(element);
163
+ const textContent = getTextContent(element);
164
+ return {
165
+ tagName: element.tagName.toLowerCase(),
166
+ id: element.id || void 0,
167
+ classNames: Array.from(element.classList),
168
+ selector: buildSelector(element),
169
+ textContent,
170
+ boundingRect: {
171
+ x: Math.round(rect.x),
172
+ y: Math.round(rect.y),
173
+ width: Math.round(rect.width),
174
+ height: Math.round(rect.height)
175
+ },
176
+ computedStyles,
177
+ ariaAttributes: Object.keys(ariaAttributes).length > 0 ? ariaAttributes : void 0,
178
+ dataAttributes: Object.keys(dataAttributes).length > 0 ? dataAttributes : void 0,
179
+ domPath
180
+ };
181
+ }
182
+ function buildElementContext(element, frameworkInfo) {
183
+ const info = extractElementInfo(element);
184
+ const htmlSnippet = getCleanedHtml(element);
185
+ return {
186
+ element: info,
187
+ framework: frameworkInfo,
188
+ htmlSnippet,
189
+ cssSelector: info.selector,
190
+ computedStyles: info.computedStyles || {}
191
+ };
192
+ }
193
+ function getTextContent(element) {
194
+ let text = "";
195
+ for (const node of element.childNodes) {
196
+ if (node.nodeType === Node.TEXT_NODE) {
197
+ text += node.textContent?.trim() || "";
198
+ }
199
+ }
200
+ if (!text) {
201
+ text = element.textContent?.trim() || "";
202
+ }
203
+ if (!text) return void 0;
204
+ return text.length > 200 ? text.slice(0, 200) + "..." : text;
205
+ }
206
+ function buildDomPath(element) {
207
+ const parts = [];
208
+ let current = element;
209
+ while (current && current !== document.documentElement) {
210
+ let part = current.tagName.toLowerCase();
211
+ if (current.id) {
212
+ part += `#${current.id}`;
213
+ } else if (current.classList.length > 0) {
214
+ const firstClass = current.classList[0];
215
+ if (firstClass && !/^(css-|_|sc-)/.test(firstClass)) {
216
+ part += `.${firstClass}`;
217
+ }
218
+ }
219
+ parts.unshift(part);
220
+ current = current.parentElement;
221
+ }
222
+ return parts.join(" > ");
223
+ }
224
+ function getCleanedHtml(element, maxLength = 500) {
225
+ const clone = element.cloneNode(true);
226
+ const allElements = [clone, ...Array.from(clone.querySelectorAll("*"))];
227
+ for (const el of allElements) {
228
+ for (const attr of Array.from(el.attributes)) {
229
+ if (attr.name.startsWith("on")) {
230
+ el.removeAttribute(attr.name);
231
+ }
232
+ }
233
+ }
234
+ let html = clone.outerHTML;
235
+ html = html.replace(/\s+/g, " ").trim();
236
+ if (html.length > maxLength) {
237
+ const openTagEnd = html.indexOf(">") + 1;
238
+ if (openTagEnd > 0 && openTagEnd < maxLength) {
239
+ html = html.slice(0, maxLength) + "...";
240
+ }
241
+ }
242
+ return html;
243
+ }
244
+
245
+ // src/frameworks/adapter.ts
246
+ var adapters = [];
247
+ var detectedAdapter = null;
248
+ var detected = false;
249
+ function registerAdapter(adapter) {
250
+ adapters.push(adapter);
251
+ detected = false;
252
+ detectedAdapter = null;
253
+ }
254
+ function detectFramework() {
255
+ if (detected && detectedAdapter) return detectedAdapter;
256
+ for (const adapter of adapters) {
257
+ try {
258
+ if (adapter.detect()) {
259
+ detectedAdapter = adapter;
260
+ detected = true;
261
+ return adapter;
262
+ }
263
+ } catch {
264
+ }
265
+ }
266
+ detectedAdapter = genericAdapter;
267
+ detected = true;
268
+ return genericAdapter;
269
+ }
270
+ function getComponentInfo(element) {
271
+ const adapter = detectFramework();
272
+ try {
273
+ return adapter.getComponentInfo(element);
274
+ } catch {
275
+ return null;
276
+ }
277
+ }
278
+ function getSourceLocation(element) {
279
+ const adapter = detectFramework();
280
+ try {
281
+ return adapter.getSourceLocation(element);
282
+ } catch {
283
+ return null;
284
+ }
285
+ }
286
+ var genericAdapter = {
287
+ name: "generic",
288
+ detect: () => true,
289
+ // Always matches as fallback
290
+ getComponentInfo: () => null,
291
+ getSourceLocation: () => null
292
+ };
293
+
294
+ // src/freeze/css-freeze.ts
295
+ var FREEZE_STYLE_ID = "__pinpoint-css-freeze";
296
+ function freezeCSS() {
297
+ if (document.getElementById(FREEZE_STYLE_ID)) {
298
+ return () => {
299
+ };
300
+ }
301
+ const style = document.createElement("style");
302
+ style.id = FREEZE_STYLE_ID;
303
+ style.textContent = `*, *::before, *::after {
304
+ animation-play-state: paused !important;
305
+ transition-property: none !important;
306
+ }`;
307
+ document.head.appendChild(style);
308
+ return () => {
309
+ style.remove();
310
+ };
311
+ }
312
+
313
+ // src/freeze/js-freeze.ts
314
+ var PINPOINT_SYMBOL = /* @__PURE__ */ Symbol.for("pinpoint-internal");
315
+ var MAX_QUEUE = 1e3;
316
+ var frozen = false;
317
+ var queue = [];
318
+ var originals = null;
319
+ function freezeJSTimers() {
320
+ if (frozen) return () => {
321
+ };
322
+ frozen = true;
323
+ queue = [];
324
+ originals = {
325
+ setTimeout: window.setTimeout.bind(window),
326
+ setInterval: window.setInterval.bind(window),
327
+ clearTimeout: window.clearTimeout.bind(window),
328
+ clearInterval: window.clearInterval.bind(window),
329
+ requestAnimationFrame: window.requestAnimationFrame.bind(window)
330
+ };
331
+ window.setTimeout = (callback, delay, ...args) => {
332
+ if (typeof callback !== "function") return 0;
333
+ if (callback[PINPOINT_SYMBOL]) {
334
+ return originals.setTimeout(callback, delay, ...args);
335
+ }
336
+ if (queue.length < MAX_QUEUE) {
337
+ queue.push({ type: "timeout", callback, delay, args });
338
+ }
339
+ return 0;
340
+ };
341
+ window.setInterval = (callback, delay, ...args) => {
342
+ if (typeof callback !== "function") return 0;
343
+ if (callback[PINPOINT_SYMBOL]) {
344
+ return originals.setInterval(callback, delay, ...args);
345
+ }
346
+ if (queue.length < MAX_QUEUE) {
347
+ queue.push({ type: "interval", callback, delay, args });
348
+ }
349
+ return 0;
350
+ };
351
+ window.requestAnimationFrame = (callback) => {
352
+ if (callback[PINPOINT_SYMBOL]) {
353
+ return originals.requestAnimationFrame(callback);
354
+ }
355
+ if (queue.length < MAX_QUEUE) {
356
+ queue.push({ type: "raf", callback });
357
+ }
358
+ return 0;
359
+ };
360
+ return () => {
361
+ if (!frozen || !originals) return;
362
+ frozen = false;
363
+ window.setTimeout = originals.setTimeout;
364
+ window.setInterval = originals.setInterval;
365
+ window.clearTimeout = originals.clearTimeout;
366
+ window.clearInterval = originals.clearInterval;
367
+ window.requestAnimationFrame = originals.requestAnimationFrame;
368
+ const replayBatch = () => {
369
+ const batch = queue.splice(0, 50);
370
+ for (const item of batch) {
371
+ try {
372
+ if (item.type === "raf") {
373
+ originals.requestAnimationFrame(
374
+ item.callback
375
+ );
376
+ } else {
377
+ originals.setTimeout(
378
+ item.callback,
379
+ 0,
380
+ ...item.args || []
381
+ );
382
+ }
383
+ } catch {
384
+ }
385
+ }
386
+ if (queue.length > 0) {
387
+ (window.requestIdleCallback || originals.setTimeout)(replayBatch);
388
+ }
389
+ };
390
+ if (queue.length > 0) {
391
+ (window.requestIdleCallback || originals.setTimeout)(replayBatch);
392
+ }
393
+ originals = null;
394
+ };
395
+ }
396
+
397
+ // src/freeze/media-freeze.ts
398
+ function freezeMedia() {
399
+ const mediaElements = document.querySelectorAll("video, audio");
400
+ const playing = [];
401
+ mediaElements.forEach((el) => {
402
+ const media = el;
403
+ if (!media.paused) {
404
+ media.pause();
405
+ playing.push(media);
406
+ }
407
+ });
408
+ const svgElements = document.querySelectorAll("svg");
409
+ const pausedSVGs = [];
410
+ svgElements.forEach((svg) => {
411
+ if (typeof svg.pauseAnimations === "function") {
412
+ try {
413
+ svg.pauseAnimations();
414
+ pausedSVGs.push(svg);
415
+ } catch {
416
+ }
417
+ }
418
+ });
419
+ return () => {
420
+ playing.forEach((media) => {
421
+ try {
422
+ media.play();
423
+ } catch {
424
+ }
425
+ });
426
+ pausedSVGs.forEach((svg) => {
427
+ try {
428
+ svg.unpauseAnimations();
429
+ } catch {
430
+ }
431
+ });
432
+ };
433
+ }
434
+
435
+ // src/freeze/react-freeze.ts
436
+ var frozen2 = false;
437
+ var originalDispatcher = null;
438
+ var queuedUpdates = [];
439
+ function getInternals() {
440
+ const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
441
+ if (!hook) return null;
442
+ const renderers = hook.renderers;
443
+ if (!renderers || renderers.size === 0) return null;
444
+ const renderer = renderers.values().next().value;
445
+ return renderer?.currentDispatcherRef || null;
446
+ }
447
+ function freezeReact() {
448
+ if (frozen2) return () => {
449
+ };
450
+ const internals = getInternals();
451
+ if (!internals) return () => {
452
+ };
453
+ frozen2 = true;
454
+ originalDispatcher = internals.current;
455
+ queuedUpdates = [];
456
+ const proxyDispatcher = new Proxy(originalDispatcher, {
457
+ get(target, prop) {
458
+ if (prop === "useState" || prop === "useReducer") {
459
+ return (...args) => {
460
+ const result = target[prop](...args);
461
+ if (Array.isArray(result) && typeof result[1] === "function") {
462
+ const originalSetter = result[1];
463
+ result[1] = (action) => {
464
+ queuedUpdates.push({
465
+ fiber: null,
466
+ queue: null,
467
+ update: { setter: originalSetter, action }
468
+ });
469
+ };
470
+ }
471
+ return result;
472
+ };
473
+ }
474
+ return target[prop];
475
+ }
476
+ });
477
+ internals.current = proxyDispatcher;
478
+ return () => {
479
+ if (!frozen2) return;
480
+ frozen2 = false;
481
+ if (internals && originalDispatcher) {
482
+ internals.current = originalDispatcher;
483
+ }
484
+ for (const { update } of queuedUpdates) {
485
+ try {
486
+ update.setter(update.action);
487
+ } catch {
488
+ }
489
+ }
490
+ queuedUpdates = [];
491
+ originalDispatcher = null;
492
+ };
493
+ }
494
+
495
+ // src/freeze/waapi-freeze.ts
496
+ function freezeWAAPI() {
497
+ const animations = document.getAnimations();
498
+ const playing = animations.filter((a) => a.playState === "running");
499
+ playing.forEach((a) => a.pause());
500
+ return () => {
501
+ playing.forEach((a) => {
502
+ try {
503
+ a.play();
504
+ } catch {
505
+ }
506
+ });
507
+ };
508
+ }
509
+
510
+ // src/freeze/controller.ts
511
+ var cleanups = [];
512
+ var active = false;
513
+ function freeze(_elements, options = {}) {
514
+ if (active) return;
515
+ active = true;
516
+ cleanups = [freezeCSS(), freezeWAAPI(), freezeReact(), freezeMedia()];
517
+ if (options.jsTimers) {
518
+ cleanups.push(freezeJSTimers());
519
+ }
520
+ }
521
+ function unfreeze() {
522
+ if (!active) return;
523
+ active = false;
524
+ for (const cleanup of cleanups) {
525
+ try {
526
+ cleanup();
527
+ } catch {
528
+ }
529
+ }
530
+ cleanups = [];
531
+ }
532
+ function isFreezeActive() {
533
+ return active;
534
+ }
535
+
536
+ // src/utils/open-file.ts
537
+ async function openFile(filePath, lineNumber) {
538
+ const vsCodeUrl = lineNumber ? `vscode://file/${filePath}:${lineNumber}` : `vscode://file/${filePath}`;
539
+ try {
540
+ window.open(vsCodeUrl, "_blank");
541
+ return;
542
+ } catch {
543
+ }
544
+ try {
545
+ await fetch("/api/open-file", {
546
+ method: "POST",
547
+ headers: { "Content-Type": "application/json" },
548
+ body: JSON.stringify({ filePath, lineNumber })
549
+ });
550
+ } catch {
551
+ console.warn("[pinpoint] Could not open file:", filePath);
552
+ }
553
+ }
554
+
555
+ export {
556
+ MemoryStore,
557
+ buildSelector,
558
+ extractElementInfo,
559
+ buildElementContext,
560
+ registerAdapter,
561
+ detectFramework,
562
+ getComponentInfo,
563
+ getSourceLocation,
564
+ freeze,
565
+ unfreeze,
566
+ isFreezeActive,
567
+ openFile
568
+ };
569
+ //# sourceMappingURL=chunk-B7TY4FPP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/storage/memory-store.ts","../src/detection/selector-builder.ts","../src/detection/element-info.ts","../src/frameworks/adapter.ts","../src/freeze/css-freeze.ts","../src/freeze/js-freeze.ts","../src/freeze/media-freeze.ts","../src/freeze/react-freeze.ts","../src/freeze/waapi-freeze.ts","../src/freeze/controller.ts","../src/utils/open-file.ts"],"sourcesContent":["// @agent-native/pinpoint — In-memory storage adapter\r\n// MIT License\r\n//\r\n// Used for standalone/clipboard-only mode. Pins live in memory for\r\n// the current session. NOT localStorage (violates agent-native Rule 1).\r\n// Pins are lost on page reload — intentional. Connect to a server for persistence.\r\n\r\nimport type { Pin, PinStatus, PinStorage } from \"../types/index.js\";\r\n\r\nexport class MemoryStore implements PinStorage {\r\n private pins: Map<string, Pin> = new Map();\r\n\r\n async load(pageUrl: string): Promise<Pin[]> {\r\n return Array.from(this.pins.values()).filter(\r\n (pin) => pin.pageUrl === pageUrl,\r\n );\r\n }\r\n\r\n async save(pin: Pin): Promise<void> {\r\n this.pins.set(pin.id, { ...pin });\r\n }\r\n\r\n async update(id: string, patch: Partial<Pin>): Promise<void> {\r\n const existing = this.pins.get(id);\r\n if (!existing) return;\r\n this.pins.set(id, {\r\n ...existing,\r\n ...patch,\r\n id: existing.id, // never overwrite ID\r\n updatedAt: new Date().toISOString(),\r\n });\r\n }\r\n\r\n async delete(id: string): Promise<void> {\r\n this.pins.delete(id);\r\n }\r\n\r\n async list(filter?: {\r\n pageUrl?: string;\r\n status?: PinStatus;\r\n }): Promise<Pin[]> {\r\n let result = Array.from(this.pins.values());\r\n if (filter?.pageUrl) {\r\n result = result.filter((pin) => pin.pageUrl === filter.pageUrl);\r\n }\r\n if (filter?.status) {\r\n result = result.filter((pin) => pin.status.state === filter.status);\r\n }\r\n return result;\r\n }\r\n\r\n async clear(pageUrl?: string): Promise<void> {\r\n if (pageUrl) {\r\n for (const [id, pin] of this.pins) {\r\n if (pin.pageUrl === pageUrl) {\r\n this.pins.delete(id);\r\n }\r\n }\r\n } else {\r\n this.pins.clear();\r\n }\r\n }\r\n}\r\n","// @agent-native/pinpoint — CSS selector generation using @medv/finder\r\n// MIT License\r\n\r\nimport { finder } from \"@medv/finder\";\r\n\r\nexport interface SelectorOptions {\r\n /** Timeout for selector generation (ms) */\r\n timeoutMs?: number;\r\n /** Additional class names to skip */\r\n skipClassPatterns?: RegExp[];\r\n}\r\n\r\nconst DEFAULT_SKIP_CLASSES = [\r\n /^css-/, // CSS-in-JS (Emotion, etc.)\r\n /^_/, // CSS Modules hashes\r\n /^sc-/, // styled-components\r\n /^go\\d/, // Goober\r\n /^tw-/, // Tailwind utilities (sometimes hashed)\r\n /^chakra-/, // Chakra UI internals\r\n];\r\n\r\nconst DEFAULT_SKIP_IDS = [\r\n /^:r[0-9]/, // React auto-generated IDs\r\n /^radix-/, // Radix UI auto IDs\r\n /^headlessui-/, // HeadlessUI auto IDs\r\n];\r\n\r\n/**\r\n * Generate a unique, human-readable CSS selector for an element.\r\n * Uses @medv/finder (MIT) with configuration to skip CSS-in-JS hashes.\r\n */\r\nexport function buildSelector(\r\n element: Element,\r\n options: SelectorOptions = {},\r\n): string {\r\n const { timeoutMs = 200, skipClassPatterns = [] } = options;\r\n\r\n const allSkipClasses = [...DEFAULT_SKIP_CLASSES, ...skipClassPatterns];\r\n\r\n try {\r\n return finder(element, {\r\n className: (name: string) =>\r\n !allSkipClasses.some((pattern) => pattern.test(name)),\r\n idName: (name: string) =>\r\n !DEFAULT_SKIP_IDS.some((pattern) => pattern.test(name)),\r\n attr: (name: string) =>\r\n name.startsWith(\"data-testid\") || name.startsWith(\"data-cy\"),\r\n timeoutMs,\r\n });\r\n } catch {\r\n // Fallback: build a basic selector from tag + classes\r\n return buildFallbackSelector(element);\r\n }\r\n}\r\n\r\nfunction buildFallbackSelector(element: Element): string {\r\n const parts: string[] = [];\r\n\r\n if (element.id) {\r\n return `#${CSS.escape(element.id)}`;\r\n }\r\n\r\n parts.push(element.tagName.toLowerCase());\r\n\r\n // Use data-testid if available\r\n const testId = element.getAttribute(\"data-testid\");\r\n if (testId) {\r\n return `[data-testid=\"${CSS.escape(testId)}\"]`;\r\n }\r\n\r\n // Add meaningful class names\r\n const classes = Array.from(element.classList).filter(\r\n (name) => !DEFAULT_SKIP_CLASSES.some((pattern) => pattern.test(name)),\r\n );\r\n if (classes.length > 0) {\r\n parts.push(`.${classes.map((c) => CSS.escape(c)).join(\".\")}`);\r\n }\r\n\r\n // Add nth-child for uniqueness\r\n const parent = element.parentElement;\r\n if (parent) {\r\n const siblings = Array.from(parent.children).filter(\r\n (child) => child.tagName === element.tagName,\r\n );\r\n if (siblings.length > 1) {\r\n const index = siblings.indexOf(element) + 1;\r\n parts.push(`:nth-child(${index})`);\r\n }\r\n }\r\n\r\n return parts.join(\"\");\r\n}\r\n","// @agent-native/pinpoint — Element metadata extraction\r\n// MIT License\r\n\r\nimport type {\r\n ElementInfo,\r\n ElementContext,\r\n FrameworkInfo,\r\n} from \"../types/index.js\";\r\nimport { buildSelector } from \"./selector-builder.js\";\r\n\r\n/** Relevant computed style properties to capture */\r\nconst STYLE_KEYS = [\r\n \"color\",\r\n \"backgroundColor\",\r\n \"fontSize\",\r\n \"fontFamily\",\r\n \"fontWeight\",\r\n \"lineHeight\",\r\n \"padding\",\r\n \"margin\",\r\n \"border\",\r\n \"borderRadius\",\r\n \"display\",\r\n \"position\",\r\n \"width\",\r\n \"height\",\r\n \"opacity\",\r\n \"zIndex\",\r\n \"overflow\",\r\n \"textAlign\",\r\n \"textDecoration\",\r\n] as const;\r\n\r\n/**\r\n * Extract comprehensive metadata from a DOM element.\r\n */\r\nexport function extractElementInfo(element: Element): ElementInfo {\r\n const rect = element.getBoundingClientRect();\r\n const computed = window.getComputedStyle(element);\r\n\r\n // Extract computed styles (relevant subset)\r\n const computedStyles: Record<string, string> = {};\r\n for (const key of STYLE_KEYS) {\r\n const value = computed.getPropertyValue(\r\n key.replace(/([A-Z])/g, \"-$1\").toLowerCase(),\r\n );\r\n if (value) {\r\n computedStyles[key] = value;\r\n }\r\n }\r\n\r\n // Extract ARIA attributes\r\n const ariaAttributes: Record<string, string> = {};\r\n for (const attr of element.attributes) {\r\n if (attr.name.startsWith(\"aria-\") || attr.name === \"role\") {\r\n ariaAttributes[attr.name] = attr.value;\r\n }\r\n }\r\n\r\n // Extract data attributes\r\n const dataAttributes: Record<string, string> = {};\r\n for (const attr of element.attributes) {\r\n if (attr.name.startsWith(\"data-\")) {\r\n dataAttributes[attr.name] = attr.value;\r\n }\r\n }\r\n\r\n // Build DOM path\r\n const domPath = buildDomPath(element);\r\n\r\n // Get text content (truncated)\r\n const textContent = getTextContent(element);\r\n\r\n return {\r\n tagName: element.tagName.toLowerCase(),\r\n id: element.id || undefined,\r\n classNames: Array.from(element.classList),\r\n selector: buildSelector(element),\r\n textContent,\r\n boundingRect: {\r\n x: Math.round(rect.x),\r\n y: Math.round(rect.y),\r\n width: Math.round(rect.width),\r\n height: Math.round(rect.height),\r\n },\r\n computedStyles,\r\n ariaAttributes:\r\n Object.keys(ariaAttributes).length > 0 ? ariaAttributes : undefined,\r\n dataAttributes:\r\n Object.keys(dataAttributes).length > 0 ? dataAttributes : undefined,\r\n domPath,\r\n };\r\n}\r\n\r\n/**\r\n * Build a full ElementContext including HTML snippet and framework info.\r\n */\r\nexport function buildElementContext(\r\n element: Element,\r\n frameworkInfo?: FrameworkInfo,\r\n): ElementContext {\r\n const info = extractElementInfo(element);\r\n const htmlSnippet = getCleanedHtml(element);\r\n\r\n return {\r\n element: info,\r\n framework: frameworkInfo,\r\n htmlSnippet,\r\n cssSelector: info.selector,\r\n computedStyles: info.computedStyles || {},\r\n };\r\n}\r\n\r\n/**\r\n * Get text content of an element, truncated to 200 characters.\r\n * Only includes direct text nodes, not deeply nested text.\r\n */\r\nfunction getTextContent(element: Element): string | undefined {\r\n // Get direct text content only (not children's text)\r\n let text = \"\";\r\n for (const node of element.childNodes) {\r\n if (node.nodeType === Node.TEXT_NODE) {\r\n text += node.textContent?.trim() || \"\";\r\n }\r\n }\r\n\r\n // Fallback to full textContent if no direct text\r\n if (!text) {\r\n text = element.textContent?.trim() || \"\";\r\n }\r\n\r\n if (!text) return undefined;\r\n return text.length > 200 ? text.slice(0, 200) + \"...\" : text;\r\n}\r\n\r\n/**\r\n * Build a DOM path string like: html > body > div#root > main > section.hero\r\n */\r\nfunction buildDomPath(element: Element): string {\r\n const parts: string[] = [];\r\n let current: Element | null = element;\r\n\r\n while (current && current !== document.documentElement) {\r\n let part = current.tagName.toLowerCase();\r\n if (current.id) {\r\n part += `#${current.id}`;\r\n } else if (current.classList.length > 0) {\r\n const firstClass = current.classList[0];\r\n if (firstClass && !/^(css-|_|sc-)/.test(firstClass)) {\r\n part += `.${firstClass}`;\r\n }\r\n }\r\n parts.unshift(part);\r\n current = current.parentElement;\r\n }\r\n\r\n return parts.join(\" > \");\r\n}\r\n\r\n/**\r\n * Get a cleaned HTML snippet of an element.\r\n * Removes inline event handlers and excessive whitespace.\r\n */\r\nfunction getCleanedHtml(element: Element, maxLength = 500): string {\r\n const clone = element.cloneNode(true) as Element;\r\n\r\n // Remove event handler attributes\r\n const allElements = [clone, ...Array.from(clone.querySelectorAll(\"*\"))];\r\n for (const el of allElements) {\r\n for (const attr of Array.from(el.attributes)) {\r\n if (attr.name.startsWith(\"on\")) {\r\n el.removeAttribute(attr.name);\r\n }\r\n }\r\n }\r\n\r\n let html = clone.outerHTML;\r\n // Collapse whitespace\r\n html = html.replace(/\\s+/g, \" \").trim();\r\n\r\n if (html.length > maxLength) {\r\n // Truncate but keep the opening tag intact\r\n const openTagEnd = html.indexOf(\">\") + 1;\r\n if (openTagEnd > 0 && openTagEnd < maxLength) {\r\n html = html.slice(0, maxLength) + \"...\";\r\n }\r\n }\r\n\r\n return html;\r\n}\r\n","// @agent-native/pinpoint — Framework adapter interface and auto-detection\r\n// MIT License\r\n\r\nimport type {\r\n FrameworkAdapter,\r\n ComponentInfo,\r\n SourceLocation,\r\n} from \"../types/index.js\";\r\n\r\n/** Registry of framework adapters, tried in order */\r\nconst adapters: FrameworkAdapter[] = [];\r\n\r\n/** The currently detected adapter (cached after first detection) */\r\nlet detectedAdapter: FrameworkAdapter | null = null;\r\nlet detected = false;\r\n\r\n/**\r\n * Register a framework adapter. Adapters are tried in registration order.\r\n */\r\nexport function registerAdapter(adapter: FrameworkAdapter): void {\r\n adapters.push(adapter);\r\n // Reset detection cache when new adapters are registered\r\n detected = false;\r\n detectedAdapter = null;\r\n}\r\n\r\n/**\r\n * Auto-detect the current framework by trying each adapter's detect() method.\r\n * Returns the first matching adapter, or the generic fallback.\r\n */\r\nexport function detectFramework(): FrameworkAdapter {\r\n if (detected && detectedAdapter) return detectedAdapter;\r\n\r\n for (const adapter of adapters) {\r\n try {\r\n if (adapter.detect()) {\r\n detectedAdapter = adapter;\r\n detected = true;\r\n return adapter;\r\n }\r\n } catch {\r\n // Adapter detection failed, try next\r\n }\r\n }\r\n\r\n // Return generic adapter as fallback\r\n detectedAdapter = genericAdapter;\r\n detected = true;\r\n return genericAdapter;\r\n}\r\n\r\n/**\r\n * Get component info for an element using the detected framework adapter.\r\n */\r\nexport function getComponentInfo(element: Element): ComponentInfo | null {\r\n const adapter = detectFramework();\r\n try {\r\n return adapter.getComponentInfo(element);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get source location for an element using the detected framework adapter.\r\n */\r\nexport function getSourceLocation(element: Element): SourceLocation | null {\r\n const adapter = detectFramework();\r\n try {\r\n return adapter.getSourceLocation(element);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Reset detection cache. Useful for testing or when the page framework changes.\r\n */\r\nexport function resetDetection(): void {\r\n detected = false;\r\n detectedAdapter = null;\r\n}\r\n\r\n/**\r\n * Get all registered adapters.\r\n */\r\nexport function getAdapters(): FrameworkAdapter[] {\r\n return [...adapters];\r\n}\r\n\r\n/** Generic fallback adapter for non-framework pages */\r\nconst genericAdapter: FrameworkAdapter = {\r\n name: \"generic\",\r\n detect: () => true, // Always matches as fallback\r\n getComponentInfo: () => null,\r\n getSourceLocation: () => null,\r\n};\r\n","// @agent-native/pinpoint — CSS animation freezing\r\n// MIT License\r\n\r\nconst FREEZE_STYLE_ID = \"__pinpoint-css-freeze\";\r\n\r\n/**\r\n * Freeze all CSS animations and transitions on the page.\r\n * Returns a cleanup function to restore.\r\n */\r\nexport function freezeCSS(): () => void {\r\n if (document.getElementById(FREEZE_STYLE_ID)) {\r\n return () => {}; // Already frozen\r\n }\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = FREEZE_STYLE_ID;\r\n style.textContent = `*, *::before, *::after {\r\n animation-play-state: paused !important;\r\n transition-property: none !important;\r\n }`;\r\n document.head.appendChild(style);\r\n\r\n return () => {\r\n style.remove();\r\n };\r\n}\r\n","// @agent-native/pinpoint — JS timer monkey-patching (opt-in)\r\n// MIT License\r\n//\r\n// Opt-in: disabled by default, activated via options.freezeJSTimers: true\r\n// Bounded queue (max 1000), staggered replay, Symbol-based exclusion.\r\n\r\nconst PINPOINT_SYMBOL = Symbol.for(\"pinpoint-internal\");\r\nconst MAX_QUEUE = 1000;\r\n\r\ninterface QueuedTimer {\r\n type: \"timeout\" | \"interval\" | \"raf\";\r\n callback: Function;\r\n delay?: number;\r\n args?: any[];\r\n}\r\n\r\nlet frozen = false;\r\nlet queue: QueuedTimer[] = [];\r\nlet originals: {\r\n setTimeout: typeof setTimeout;\r\n setInterval: typeof setInterval;\r\n clearTimeout: typeof clearTimeout;\r\n clearInterval: typeof clearInterval;\r\n requestAnimationFrame: typeof requestAnimationFrame;\r\n} | null = null;\r\n\r\n/**\r\n * Freeze JS timers by monkey-patching setTimeout, setInterval, rAF.\r\n * Queued callbacks are replayed on unfreeze.\r\n *\r\n * **Opt-in only** — call this explicitly when config.freezeJSTimers is true.\r\n */\r\nexport function freezeJSTimers(): () => void {\r\n if (frozen) return () => {};\r\n\r\n frozen = true;\r\n queue = [];\r\n\r\n originals = {\r\n setTimeout: window.setTimeout.bind(window),\r\n setInterval: window.setInterval.bind(window),\r\n clearTimeout: window.clearTimeout.bind(window),\r\n clearInterval: window.clearInterval.bind(window),\r\n requestAnimationFrame: window.requestAnimationFrame.bind(window),\r\n };\r\n\r\n // Patch setTimeout\r\n (window as any).setTimeout = (\r\n callback: Function | string,\r\n delay?: number,\r\n ...args: any[]\r\n ) => {\r\n if (typeof callback !== \"function\") return 0;\r\n // Skip our own callbacks (Symbol-based filter)\r\n if ((callback as any)[PINPOINT_SYMBOL]) {\r\n return originals!.setTimeout(callback, delay, ...args);\r\n }\r\n if (queue.length < MAX_QUEUE) {\r\n queue.push({ type: \"timeout\", callback, delay, args });\r\n }\r\n return 0; // Return fake timer ID\r\n };\r\n\r\n // Patch setInterval\r\n (window as any).setInterval = (\r\n callback: Function | string,\r\n delay?: number,\r\n ...args: any[]\r\n ) => {\r\n if (typeof callback !== \"function\") return 0;\r\n if ((callback as any)[PINPOINT_SYMBOL]) {\r\n return originals!.setInterval(callback, delay, ...args);\r\n }\r\n if (queue.length < MAX_QUEUE) {\r\n queue.push({ type: \"interval\", callback, delay, args });\r\n }\r\n return 0;\r\n };\r\n\r\n // Patch requestAnimationFrame\r\n (window as any).requestAnimationFrame = (callback: FrameRequestCallback) => {\r\n if ((callback as any)[PINPOINT_SYMBOL]) {\r\n return originals!.requestAnimationFrame(callback);\r\n }\r\n if (queue.length < MAX_QUEUE) {\r\n queue.push({ type: \"raf\", callback });\r\n }\r\n return 0;\r\n };\r\n\r\n return () => {\r\n if (!frozen || !originals) return;\r\n frozen = false;\r\n\r\n // Restore originals\r\n window.setTimeout = originals.setTimeout as any;\r\n window.setInterval = originals.setInterval as any;\r\n window.clearTimeout = originals.clearTimeout;\r\n window.clearInterval = originals.clearInterval;\r\n window.requestAnimationFrame = originals.requestAnimationFrame;\r\n\r\n // Staggered replay via requestIdleCallback\r\n const replayBatch = () => {\r\n const batch = queue.splice(0, 50);\r\n for (const item of batch) {\r\n try {\r\n if (item.type === \"raf\") {\r\n originals!.requestAnimationFrame(\r\n item.callback as FrameRequestCallback,\r\n );\r\n } else {\r\n originals!.setTimeout(\r\n item.callback as any,\r\n 0,\r\n ...(item.args || []),\r\n );\r\n }\r\n } catch {\r\n // Callback may no longer be valid\r\n }\r\n }\r\n if (queue.length > 0) {\r\n (window.requestIdleCallback || originals!.setTimeout)(replayBatch);\r\n }\r\n };\r\n\r\n if (queue.length > 0) {\r\n (window.requestIdleCallback || originals.setTimeout)(replayBatch);\r\n }\r\n\r\n originals = null;\r\n };\r\n}\r\n\r\n/**\r\n * Mark a callback as internal to Pinpoint, so it's not frozen.\r\n */\r\nexport function markInternal<T extends Function>(fn: T): T {\r\n (fn as any)[PINPOINT_SYMBOL] = true;\r\n return fn;\r\n}\r\n","// @agent-native/pinpoint — Media element freeze (video, audio, SVG SMIL)\r\n// MIT License\r\n\r\n/**\r\n * Pause all playing media elements on the page.\r\n * Returns a cleanup function to resume.\r\n */\r\nexport function freezeMedia(): () => void {\r\n const mediaElements = document.querySelectorAll(\"video, audio\");\r\n const playing: HTMLMediaElement[] = [];\r\n\r\n mediaElements.forEach((el) => {\r\n const media = el as HTMLMediaElement;\r\n if (!media.paused) {\r\n media.pause();\r\n playing.push(media);\r\n }\r\n });\r\n\r\n // Pause SVG SMIL animations\r\n const svgElements = document.querySelectorAll(\"svg\");\r\n const pausedSVGs: SVGSVGElement[] = [];\r\n svgElements.forEach((svg) => {\r\n if (typeof svg.pauseAnimations === \"function\") {\r\n try {\r\n svg.pauseAnimations();\r\n pausedSVGs.push(svg);\r\n } catch {\r\n // SVG may not support animation\r\n }\r\n }\r\n });\r\n\r\n return () => {\r\n playing.forEach((media) => {\r\n try {\r\n media.play();\r\n } catch {\r\n // Media may have been removed\r\n }\r\n });\r\n\r\n pausedSVGs.forEach((svg) => {\r\n try {\r\n svg.unpauseAnimations();\r\n } catch {\r\n // SVG may have been removed\r\n }\r\n });\r\n };\r\n}\r\n","// @agent-native/pinpoint — React update freezing\r\n// MIT License\r\n//\r\n// Patches React's dispatcher to queue state updates instead of applying them.\r\n// On unfreeze, flush queued updates. This prevents the host app from\r\n// re-rendering while the user is selecting an element.\r\n//\r\n// Based on react-grab pattern (MIT).\r\n\r\ninterface QueuedUpdate {\r\n fiber: any;\r\n queue: any;\r\n update: any;\r\n}\r\n\r\nlet frozen = false;\r\nlet originalDispatcher: any = null;\r\nlet queuedUpdates: QueuedUpdate[] = [];\r\n\r\nfunction getInternals(): any {\r\n const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;\r\n if (!hook) return null;\r\n\r\n // Get the first React renderer\r\n const renderers = hook.renderers;\r\n if (!renderers || renderers.size === 0) return null;\r\n\r\n const renderer = renderers.values().next().value;\r\n return renderer?.currentDispatcherRef || null;\r\n}\r\n\r\n/**\r\n * Freeze React state updates by patching the dispatcher.\r\n * Updates are queued and replayed on unfreeze.\r\n */\r\nexport function freezeReact(): () => void {\r\n if (frozen) return () => {};\r\n\r\n const internals = getInternals();\r\n if (!internals) return () => {};\r\n\r\n frozen = true;\r\n originalDispatcher = internals.current;\r\n queuedUpdates = [];\r\n\r\n // Create a proxy dispatcher that intercepts useState/useReducer\r\n const proxyDispatcher = new Proxy(originalDispatcher, {\r\n get(target, prop) {\r\n if (prop === \"useState\" || prop === \"useReducer\") {\r\n return (...args: any[]) => {\r\n const result = target[prop](...args);\r\n // Wrap the setter to queue updates\r\n if (Array.isArray(result) && typeof result[1] === \"function\") {\r\n const originalSetter = result[1];\r\n result[1] = (action: any) => {\r\n queuedUpdates.push({\r\n fiber: null,\r\n queue: null,\r\n update: { setter: originalSetter, action },\r\n });\r\n };\r\n }\r\n return result;\r\n };\r\n }\r\n return target[prop];\r\n },\r\n });\r\n\r\n internals.current = proxyDispatcher;\r\n\r\n return () => {\r\n if (!frozen) return;\r\n frozen = false;\r\n\r\n // Restore original dispatcher\r\n if (internals && originalDispatcher) {\r\n internals.current = originalDispatcher;\r\n }\r\n\r\n // Flush queued updates\r\n for (const { update } of queuedUpdates) {\r\n try {\r\n update.setter(update.action);\r\n } catch {\r\n // Update may no longer be valid\r\n }\r\n }\r\n\r\n queuedUpdates = [];\r\n originalDispatcher = null;\r\n };\r\n}\r\n\r\nexport function isReactFrozen(): boolean {\r\n return frozen;\r\n}\r\n","// @agent-native/pinpoint — Web Animations API freeze\r\n// MIT License\r\n\r\n/**\r\n * Pause all WAAPI animations on the page.\r\n * Returns a cleanup function to resume.\r\n */\r\nexport function freezeWAAPI(): () => void {\r\n const animations = document.getAnimations();\r\n const playing = animations.filter((a) => a.playState === \"running\");\r\n playing.forEach((a) => a.pause());\r\n\r\n return () => {\r\n playing.forEach((a) => {\r\n try {\r\n a.play();\r\n } catch {\r\n // Animation may have been removed\r\n }\r\n });\r\n };\r\n}\r\n","// @agent-native/pinpoint — Unified freeze controller\r\n// MIT License\r\n//\r\n// Lazy initialization — nothing is patched until first freeze() call.\r\n\r\nimport { freezeCSS } from \"./css-freeze.js\";\r\nimport { freezeJSTimers } from \"./js-freeze.js\";\r\nimport { freezeMedia } from \"./media-freeze.js\";\r\nimport { freezeReact } from \"./react-freeze.js\";\r\nimport { freezeWAAPI } from \"./waapi-freeze.js\";\r\n\r\nlet cleanups: Array<() => void> = [];\r\nlet active = false;\r\n\r\nexport interface FreezeOptions {\r\n /** Freeze JS timers (opt-in, disabled by default) */\r\n jsTimers?: boolean;\r\n}\r\n\r\n/**\r\n * Freeze all animations, transitions, React updates, and media.\r\n * Call unfreeze() to restore.\r\n */\r\nexport function freeze(\r\n _elements?: Element[],\r\n options: FreezeOptions = {},\r\n): void {\r\n if (active) return;\r\n active = true;\r\n\r\n cleanups = [freezeCSS(), freezeWAAPI(), freezeReact(), freezeMedia()];\r\n\r\n if (options.jsTimers) {\r\n cleanups.push(freezeJSTimers());\r\n }\r\n}\r\n\r\n/**\r\n * Unfreeze everything and restore normal behavior.\r\n */\r\nexport function unfreeze(): void {\r\n if (!active) return;\r\n active = false;\r\n\r\n for (const cleanup of cleanups) {\r\n try {\r\n cleanup();\r\n } catch {\r\n // Best-effort cleanup\r\n }\r\n }\r\n cleanups = [];\r\n}\r\n\r\n/**\r\n * Check if freeze is currently active.\r\n */\r\nexport function isFreezeActive(): boolean {\r\n return active;\r\n}\r\n","// @agent-native/pinpoint — Open file in editor\r\n// MIT License\r\n\r\n/**\r\n * Open a file in the user's editor. Tries vscode:// protocol first,\r\n * falls back to a fetch to /api/open-file.\r\n */\r\nexport async function openFile(\r\n filePath: string,\r\n lineNumber?: number,\r\n): Promise<void> {\r\n // Try VS Code protocol\r\n const vsCodeUrl = lineNumber\r\n ? `vscode://file/${filePath}:${lineNumber}`\r\n : `vscode://file/${filePath}`;\r\n\r\n try {\r\n window.open(vsCodeUrl, \"_blank\");\r\n return;\r\n } catch {\r\n // VS Code not available\r\n }\r\n\r\n // Fallback: POST to server endpoint\r\n try {\r\n await fetch(\"/api/open-file\", {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ filePath, lineNumber }),\r\n });\r\n } catch {\r\n // Server endpoint not available\r\n console.warn(\"[pinpoint] Could not open file:\", filePath);\r\n }\r\n}\r\n"],"mappings":"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","names":["frozen"]}