@agent-native/pinpoint 0.1.8 → 0.1.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.
@@ -310,129 +310,16 @@ function freezeCSS() {
310
310
  };
311
311
  }
312
312
 
313
- // src/freeze/waapi-freeze.ts
314
- function freezeWAAPI() {
315
- const animations = document.getAnimations();
316
- const playing = animations.filter((a) => a.playState === "running");
317
- playing.forEach((a) => a.pause());
318
- return () => {
319
- playing.forEach((a) => {
320
- try {
321
- a.play();
322
- } catch {
323
- }
324
- });
325
- };
326
- }
327
-
328
- // src/freeze/react-freeze.ts
329
- var frozen = false;
330
- var originalDispatcher = null;
331
- var queuedUpdates = [];
332
- function getInternals() {
333
- const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
334
- if (!hook) return null;
335
- const renderers = hook.renderers;
336
- if (!renderers || renderers.size === 0) return null;
337
- const renderer = renderers.values().next().value;
338
- return renderer?.currentDispatcherRef || null;
339
- }
340
- function freezeReact() {
341
- if (frozen) return () => {
342
- };
343
- const internals = getInternals();
344
- if (!internals) return () => {
345
- };
346
- frozen = true;
347
- originalDispatcher = internals.current;
348
- queuedUpdates = [];
349
- const proxyDispatcher = new Proxy(originalDispatcher, {
350
- get(target, prop) {
351
- if (prop === "useState" || prop === "useReducer") {
352
- return (...args) => {
353
- const result = target[prop](...args);
354
- if (Array.isArray(result) && typeof result[1] === "function") {
355
- const originalSetter = result[1];
356
- result[1] = (action) => {
357
- queuedUpdates.push({
358
- fiber: null,
359
- queue: null,
360
- update: { setter: originalSetter, action }
361
- });
362
- };
363
- }
364
- return result;
365
- };
366
- }
367
- return target[prop];
368
- }
369
- });
370
- internals.current = proxyDispatcher;
371
- return () => {
372
- if (!frozen) return;
373
- frozen = false;
374
- if (internals && originalDispatcher) {
375
- internals.current = originalDispatcher;
376
- }
377
- for (const { update } of queuedUpdates) {
378
- try {
379
- update.setter(update.action);
380
- } catch {
381
- }
382
- }
383
- queuedUpdates = [];
384
- originalDispatcher = null;
385
- };
386
- }
387
-
388
- // src/freeze/media-freeze.ts
389
- function freezeMedia() {
390
- const mediaElements = document.querySelectorAll("video, audio");
391
- const playing = [];
392
- mediaElements.forEach((el) => {
393
- const media = el;
394
- if (!media.paused) {
395
- media.pause();
396
- playing.push(media);
397
- }
398
- });
399
- const svgElements = document.querySelectorAll("svg");
400
- const pausedSVGs = [];
401
- svgElements.forEach((svg) => {
402
- if (typeof svg.pauseAnimations === "function") {
403
- try {
404
- svg.pauseAnimations();
405
- pausedSVGs.push(svg);
406
- } catch {
407
- }
408
- }
409
- });
410
- return () => {
411
- playing.forEach((media) => {
412
- try {
413
- media.play();
414
- } catch {
415
- }
416
- });
417
- pausedSVGs.forEach((svg) => {
418
- try {
419
- svg.unpauseAnimations();
420
- } catch {
421
- }
422
- });
423
- };
424
- }
425
-
426
313
  // src/freeze/js-freeze.ts
427
314
  var PINPOINT_SYMBOL = /* @__PURE__ */ Symbol.for("pinpoint-internal");
428
315
  var MAX_QUEUE = 1e3;
429
- var frozen2 = false;
316
+ var frozen = false;
430
317
  var queue = [];
431
318
  var originals = null;
432
319
  function freezeJSTimers() {
433
- if (frozen2) return () => {
320
+ if (frozen) return () => {
434
321
  };
435
- frozen2 = true;
322
+ frozen = true;
436
323
  queue = [];
437
324
  originals = {
438
325
  setTimeout: window.setTimeout.bind(window),
@@ -471,8 +358,8 @@ function freezeJSTimers() {
471
358
  return 0;
472
359
  };
473
360
  return () => {
474
- if (!frozen2 || !originals) return;
475
- frozen2 = false;
361
+ if (!frozen || !originals) return;
362
+ frozen = false;
476
363
  window.setTimeout = originals.setTimeout;
477
364
  window.setInterval = originals.setInterval;
478
365
  window.clearTimeout = originals.clearTimeout;
@@ -507,6 +394,119 @@ function freezeJSTimers() {
507
394
  };
508
395
  }
509
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
510
  // src/freeze/controller.ts
511
511
  var cleanups = [];
512
512
  var active = false;
@@ -566,4 +566,4 @@ export {
566
566
  isFreezeActive,
567
567
  openFile
568
568
  };
569
- //# sourceMappingURL=chunk-W7IKAJ3P.js.map
569
+ //# sourceMappingURL=chunk-PAXU7A5W.js.map
@@ -1 +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/waapi-freeze.ts","../src/freeze/react-freeze.ts","../src/freeze/media-freeze.ts","../src/freeze/js-freeze.ts","../src/freeze/controller.ts","../src/utils/open-file.ts"],"sourcesContent":["// @agent-native/pinpoint — In-memory storage adapter\n// MIT License\n//\n// Used for standalone/clipboard-only mode. Pins live in memory for\n// the current session. NOT localStorage (violates agent-native Rule 1).\n// Pins are lost on page reload — intentional. Connect to a server for persistence.\n\nimport type { Pin, PinStatus, PinStorage } from \"../types/index.js\";\n\nexport class MemoryStore implements PinStorage {\n private pins: Map<string, Pin> = new Map();\n\n async load(pageUrl: string): Promise<Pin[]> {\n return Array.from(this.pins.values()).filter(\n (pin) => pin.pageUrl === pageUrl,\n );\n }\n\n async save(pin: Pin): Promise<void> {\n this.pins.set(pin.id, { ...pin });\n }\n\n async update(id: string, patch: Partial<Pin>): Promise<void> {\n const existing = this.pins.get(id);\n if (!existing) return;\n this.pins.set(id, {\n ...existing,\n ...patch,\n id: existing.id, // never overwrite ID\n updatedAt: new Date().toISOString(),\n });\n }\n\n async delete(id: string): Promise<void> {\n this.pins.delete(id);\n }\n\n async list(filter?: {\n pageUrl?: string;\n status?: PinStatus;\n }): Promise<Pin[]> {\n let result = Array.from(this.pins.values());\n if (filter?.pageUrl) {\n result = result.filter((pin) => pin.pageUrl === filter.pageUrl);\n }\n if (filter?.status) {\n result = result.filter((pin) => pin.status.state === filter.status);\n }\n return result;\n }\n\n async clear(pageUrl?: string): Promise<void> {\n if (pageUrl) {\n for (const [id, pin] of this.pins) {\n if (pin.pageUrl === pageUrl) {\n this.pins.delete(id);\n }\n }\n } else {\n this.pins.clear();\n }\n }\n}\n","// @agent-native/pinpoint — CSS selector generation using @medv/finder\n// MIT License\n\nimport { finder } from \"@medv/finder\";\n\nexport interface SelectorOptions {\n /** Timeout for selector generation (ms) */\n timeoutMs?: number;\n /** Additional class names to skip */\n skipClassPatterns?: RegExp[];\n}\n\nconst DEFAULT_SKIP_CLASSES = [\n /^css-/, // CSS-in-JS (Emotion, etc.)\n /^_/, // CSS Modules hashes\n /^sc-/, // styled-components\n /^go\\d/, // Goober\n /^tw-/, // Tailwind utilities (sometimes hashed)\n /^chakra-/, // Chakra UI internals\n];\n\nconst DEFAULT_SKIP_IDS = [\n /^:r[0-9]/, // React auto-generated IDs\n /^radix-/, // Radix UI auto IDs\n /^headlessui-/, // HeadlessUI auto IDs\n];\n\n/**\n * Generate a unique, human-readable CSS selector for an element.\n * Uses @medv/finder (MIT) with configuration to skip CSS-in-JS hashes.\n */\nexport function buildSelector(\n element: Element,\n options: SelectorOptions = {},\n): string {\n const { timeoutMs = 200, skipClassPatterns = [] } = options;\n\n const allSkipClasses = [...DEFAULT_SKIP_CLASSES, ...skipClassPatterns];\n\n try {\n return finder(element, {\n className: (name: string) =>\n !allSkipClasses.some((pattern) => pattern.test(name)),\n idName: (name: string) =>\n !DEFAULT_SKIP_IDS.some((pattern) => pattern.test(name)),\n attr: (name: string) =>\n name.startsWith(\"data-testid\") || name.startsWith(\"data-cy\"),\n timeoutMs,\n });\n } catch {\n // Fallback: build a basic selector from tag + classes\n return buildFallbackSelector(element);\n }\n}\n\nfunction buildFallbackSelector(element: Element): string {\n const parts: string[] = [];\n\n if (element.id) {\n return `#${CSS.escape(element.id)}`;\n }\n\n parts.push(element.tagName.toLowerCase());\n\n // Use data-testid if available\n const testId = element.getAttribute(\"data-testid\");\n if (testId) {\n return `[data-testid=\"${CSS.escape(testId)}\"]`;\n }\n\n // Add meaningful class names\n const classes = Array.from(element.classList).filter(\n (name) => !DEFAULT_SKIP_CLASSES.some((pattern) => pattern.test(name)),\n );\n if (classes.length > 0) {\n parts.push(`.${classes.map((c) => CSS.escape(c)).join(\".\")}`);\n }\n\n // Add nth-child for uniqueness\n const parent = element.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (child) => child.tagName === element.tagName,\n );\n if (siblings.length > 1) {\n const index = siblings.indexOf(element) + 1;\n parts.push(`:nth-child(${index})`);\n }\n }\n\n return parts.join(\"\");\n}\n","// @agent-native/pinpoint — Element metadata extraction\n// MIT License\n\nimport type {\n ElementInfo,\n ElementContext,\n FrameworkInfo,\n} from \"../types/index.js\";\nimport { buildSelector } from \"./selector-builder.js\";\n\n/** Relevant computed style properties to capture */\nconst STYLE_KEYS = [\n \"color\",\n \"backgroundColor\",\n \"fontSize\",\n \"fontFamily\",\n \"fontWeight\",\n \"lineHeight\",\n \"padding\",\n \"margin\",\n \"border\",\n \"borderRadius\",\n \"display\",\n \"position\",\n \"width\",\n \"height\",\n \"opacity\",\n \"zIndex\",\n \"overflow\",\n \"textAlign\",\n \"textDecoration\",\n] as const;\n\n/**\n * Extract comprehensive metadata from a DOM element.\n */\nexport function extractElementInfo(element: Element): ElementInfo {\n const rect = element.getBoundingClientRect();\n const computed = window.getComputedStyle(element);\n\n // Extract computed styles (relevant subset)\n const computedStyles: Record<string, string> = {};\n for (const key of STYLE_KEYS) {\n const value = computed.getPropertyValue(\n key.replace(/([A-Z])/g, \"-$1\").toLowerCase(),\n );\n if (value) {\n computedStyles[key] = value;\n }\n }\n\n // Extract ARIA attributes\n const ariaAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"aria-\") || attr.name === \"role\") {\n ariaAttributes[attr.name] = attr.value;\n }\n }\n\n // Extract data attributes\n const dataAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"data-\")) {\n dataAttributes[attr.name] = attr.value;\n }\n }\n\n // Build DOM path\n const domPath = buildDomPath(element);\n\n // Get text content (truncated)\n const textContent = getTextContent(element);\n\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id || undefined,\n classNames: Array.from(element.classList),\n selector: buildSelector(element),\n textContent,\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n },\n computedStyles,\n ariaAttributes:\n Object.keys(ariaAttributes).length > 0 ? ariaAttributes : undefined,\n dataAttributes:\n Object.keys(dataAttributes).length > 0 ? dataAttributes : undefined,\n domPath,\n };\n}\n\n/**\n * Build a full ElementContext including HTML snippet and framework info.\n */\nexport function buildElementContext(\n element: Element,\n frameworkInfo?: FrameworkInfo,\n): ElementContext {\n const info = extractElementInfo(element);\n const htmlSnippet = getCleanedHtml(element);\n\n return {\n element: info,\n framework: frameworkInfo,\n htmlSnippet,\n cssSelector: info.selector,\n computedStyles: info.computedStyles || {},\n };\n}\n\n/**\n * Get text content of an element, truncated to 200 characters.\n * Only includes direct text nodes, not deeply nested text.\n */\nfunction getTextContent(element: Element): string | undefined {\n // Get direct text content only (not children's text)\n let text = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent?.trim() || \"\";\n }\n }\n\n // Fallback to full textContent if no direct text\n if (!text) {\n text = element.textContent?.trim() || \"\";\n }\n\n if (!text) return undefined;\n return text.length > 200 ? text.slice(0, 200) + \"...\" : text;\n}\n\n/**\n * Build a DOM path string like: html > body > div#root > main > section.hero\n */\nfunction buildDomPath(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current !== document.documentElement) {\n let part = current.tagName.toLowerCase();\n if (current.id) {\n part += `#${current.id}`;\n } else if (current.classList.length > 0) {\n const firstClass = current.classList[0];\n if (firstClass && !/^(css-|_|sc-)/.test(firstClass)) {\n part += `.${firstClass}`;\n }\n }\n parts.unshift(part);\n current = current.parentElement;\n }\n\n return parts.join(\" > \");\n}\n\n/**\n * Get a cleaned HTML snippet of an element.\n * Removes inline event handlers and excessive whitespace.\n */\nfunction getCleanedHtml(element: Element, maxLength = 500): string {\n const clone = element.cloneNode(true) as Element;\n\n // Remove event handler attributes\n const allElements = [clone, ...Array.from(clone.querySelectorAll(\"*\"))];\n for (const el of allElements) {\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) {\n el.removeAttribute(attr.name);\n }\n }\n }\n\n let html = clone.outerHTML;\n // Collapse whitespace\n html = html.replace(/\\s+/g, \" \").trim();\n\n if (html.length > maxLength) {\n // Truncate but keep the opening tag intact\n const openTagEnd = html.indexOf(\">\") + 1;\n if (openTagEnd > 0 && openTagEnd < maxLength) {\n html = html.slice(0, maxLength) + \"...\";\n }\n }\n\n return html;\n}\n","// @agent-native/pinpoint — Framework adapter interface and auto-detection\n// MIT License\n\nimport type {\n FrameworkAdapter,\n ComponentInfo,\n SourceLocation,\n} from \"../types/index.js\";\n\n/** Registry of framework adapters, tried in order */\nconst adapters: FrameworkAdapter[] = [];\n\n/** The currently detected adapter (cached after first detection) */\nlet detectedAdapter: FrameworkAdapter | null = null;\nlet detected = false;\n\n/**\n * Register a framework adapter. Adapters are tried in registration order.\n */\nexport function registerAdapter(adapter: FrameworkAdapter): void {\n adapters.push(adapter);\n // Reset detection cache when new adapters are registered\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Auto-detect the current framework by trying each adapter's detect() method.\n * Returns the first matching adapter, or the generic fallback.\n */\nexport function detectFramework(): FrameworkAdapter {\n if (detected && detectedAdapter) return detectedAdapter;\n\n for (const adapter of adapters) {\n try {\n if (adapter.detect()) {\n detectedAdapter = adapter;\n detected = true;\n return adapter;\n }\n } catch {\n // Adapter detection failed, try next\n }\n }\n\n // Return generic adapter as fallback\n detectedAdapter = genericAdapter;\n detected = true;\n return genericAdapter;\n}\n\n/**\n * Get component info for an element using the detected framework adapter.\n */\nexport function getComponentInfo(element: Element): ComponentInfo | null {\n const adapter = detectFramework();\n try {\n return adapter.getComponentInfo(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Get source location for an element using the detected framework adapter.\n */\nexport function getSourceLocation(element: Element): SourceLocation | null {\n const adapter = detectFramework();\n try {\n return adapter.getSourceLocation(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Reset detection cache. Useful for testing or when the page framework changes.\n */\nexport function resetDetection(): void {\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Get all registered adapters.\n */\nexport function getAdapters(): FrameworkAdapter[] {\n return [...adapters];\n}\n\n/** Generic fallback adapter for non-framework pages */\nconst genericAdapter: FrameworkAdapter = {\n name: \"generic\",\n detect: () => true, // Always matches as fallback\n getComponentInfo: () => null,\n getSourceLocation: () => null,\n};\n","// @agent-native/pinpoint — CSS animation freezing\n// MIT License\n\nconst FREEZE_STYLE_ID = \"__pinpoint-css-freeze\";\n\n/**\n * Freeze all CSS animations and transitions on the page.\n * Returns a cleanup function to restore.\n */\nexport function freezeCSS(): () => void {\n if (document.getElementById(FREEZE_STYLE_ID)) {\n return () => {}; // Already frozen\n }\n\n const style = document.createElement(\"style\");\n style.id = FREEZE_STYLE_ID;\n style.textContent = `*, *::before, *::after {\n animation-play-state: paused !important;\n transition-property: none !important;\n }`;\n document.head.appendChild(style);\n\n return () => {\n style.remove();\n };\n}\n","// @agent-native/pinpoint — Web Animations API freeze\n// MIT License\n\n/**\n * Pause all WAAPI animations on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeWAAPI(): () => void {\n const animations = document.getAnimations();\n const playing = animations.filter((a) => a.playState === \"running\");\n playing.forEach((a) => a.pause());\n\n return () => {\n playing.forEach((a) => {\n try {\n a.play();\n } catch {\n // Animation may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — React update freezing\n// MIT License\n//\n// Patches React's dispatcher to queue state updates instead of applying them.\n// On unfreeze, flush queued updates. This prevents the host app from\n// re-rendering while the user is selecting an element.\n//\n// Based on react-grab pattern (MIT).\n\ninterface QueuedUpdate {\n fiber: any;\n queue: any;\n update: any;\n}\n\nlet frozen = false;\nlet originalDispatcher: any = null;\nlet queuedUpdates: QueuedUpdate[] = [];\n\nfunction getInternals(): any {\n const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook) return null;\n\n // Get the first React renderer\n const renderers = hook.renderers;\n if (!renderers || renderers.size === 0) return null;\n\n const renderer = renderers.values().next().value;\n return renderer?.currentDispatcherRef || null;\n}\n\n/**\n * Freeze React state updates by patching the dispatcher.\n * Updates are queued and replayed on unfreeze.\n */\nexport function freezeReact(): () => void {\n if (frozen) return () => {};\n\n const internals = getInternals();\n if (!internals) return () => {};\n\n frozen = true;\n originalDispatcher = internals.current;\n queuedUpdates = [];\n\n // Create a proxy dispatcher that intercepts useState/useReducer\n const proxyDispatcher = new Proxy(originalDispatcher, {\n get(target, prop) {\n if (prop === \"useState\" || prop === \"useReducer\") {\n return (...args: any[]) => {\n const result = target[prop](...args);\n // Wrap the setter to queue updates\n if (Array.isArray(result) && typeof result[1] === \"function\") {\n const originalSetter = result[1];\n result[1] = (action: any) => {\n queuedUpdates.push({\n fiber: null,\n queue: null,\n update: { setter: originalSetter, action },\n });\n };\n }\n return result;\n };\n }\n return target[prop];\n },\n });\n\n internals.current = proxyDispatcher;\n\n return () => {\n if (!frozen) return;\n frozen = false;\n\n // Restore original dispatcher\n if (internals && originalDispatcher) {\n internals.current = originalDispatcher;\n }\n\n // Flush queued updates\n for (const { update } of queuedUpdates) {\n try {\n update.setter(update.action);\n } catch {\n // Update may no longer be valid\n }\n }\n\n queuedUpdates = [];\n originalDispatcher = null;\n };\n}\n\nexport function isReactFrozen(): boolean {\n return frozen;\n}\n","// @agent-native/pinpoint — Media element freeze (video, audio, SVG SMIL)\n// MIT License\n\n/**\n * Pause all playing media elements on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeMedia(): () => void {\n const mediaElements = document.querySelectorAll(\"video, audio\");\n const playing: HTMLMediaElement[] = [];\n\n mediaElements.forEach((el) => {\n const media = el as HTMLMediaElement;\n if (!media.paused) {\n media.pause();\n playing.push(media);\n }\n });\n\n // Pause SVG SMIL animations\n const svgElements = document.querySelectorAll(\"svg\");\n const pausedSVGs: SVGSVGElement[] = [];\n svgElements.forEach((svg) => {\n if (typeof svg.pauseAnimations === \"function\") {\n try {\n svg.pauseAnimations();\n pausedSVGs.push(svg);\n } catch {\n // SVG may not support animation\n }\n }\n });\n\n return () => {\n playing.forEach((media) => {\n try {\n media.play();\n } catch {\n // Media may have been removed\n }\n });\n\n pausedSVGs.forEach((svg) => {\n try {\n svg.unpauseAnimations();\n } catch {\n // SVG may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — JS timer monkey-patching (opt-in)\n// MIT License\n//\n// Opt-in: disabled by default, activated via options.freezeJSTimers: true\n// Bounded queue (max 1000), staggered replay, Symbol-based exclusion.\n\nconst PINPOINT_SYMBOL = Symbol.for(\"pinpoint-internal\");\nconst MAX_QUEUE = 1000;\n\ninterface QueuedTimer {\n type: \"timeout\" | \"interval\" | \"raf\";\n callback: Function;\n delay?: number;\n args?: any[];\n}\n\nlet frozen = false;\nlet queue: QueuedTimer[] = [];\nlet originals: {\n setTimeout: typeof setTimeout;\n setInterval: typeof setInterval;\n clearTimeout: typeof clearTimeout;\n clearInterval: typeof clearInterval;\n requestAnimationFrame: typeof requestAnimationFrame;\n} | null = null;\n\n/**\n * Freeze JS timers by monkey-patching setTimeout, setInterval, rAF.\n * Queued callbacks are replayed on unfreeze.\n *\n * **Opt-in only** — call this explicitly when config.freezeJSTimers is true.\n */\nexport function freezeJSTimers(): () => void {\n if (frozen) return () => {};\n\n frozen = true;\n queue = [];\n\n originals = {\n setTimeout: window.setTimeout.bind(window),\n setInterval: window.setInterval.bind(window),\n clearTimeout: window.clearTimeout.bind(window),\n clearInterval: window.clearInterval.bind(window),\n requestAnimationFrame: window.requestAnimationFrame.bind(window),\n };\n\n // Patch setTimeout\n (window as any).setTimeout = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n // Skip our own callbacks (Symbol-based filter)\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setTimeout(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"timeout\", callback, delay, args });\n }\n return 0; // Return fake timer ID\n };\n\n // Patch setInterval\n (window as any).setInterval = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setInterval(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"interval\", callback, delay, args });\n }\n return 0;\n };\n\n // Patch requestAnimationFrame\n (window as any).requestAnimationFrame = (callback: FrameRequestCallback) => {\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.requestAnimationFrame(callback);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"raf\", callback });\n }\n return 0;\n };\n\n return () => {\n if (!frozen || !originals) return;\n frozen = false;\n\n // Restore originals\n window.setTimeout = originals.setTimeout as any;\n window.setInterval = originals.setInterval as any;\n window.clearTimeout = originals.clearTimeout;\n window.clearInterval = originals.clearInterval;\n window.requestAnimationFrame = originals.requestAnimationFrame;\n\n // Staggered replay via requestIdleCallback\n const replayBatch = () => {\n const batch = queue.splice(0, 50);\n for (const item of batch) {\n try {\n if (item.type === \"raf\") {\n originals!.requestAnimationFrame(\n item.callback as FrameRequestCallback,\n );\n } else {\n originals!.setTimeout(\n item.callback as any,\n 0,\n ...(item.args || []),\n );\n }\n } catch {\n // Callback may no longer be valid\n }\n }\n if (queue.length > 0) {\n (window.requestIdleCallback || originals!.setTimeout)(replayBatch);\n }\n };\n\n if (queue.length > 0) {\n (window.requestIdleCallback || originals.setTimeout)(replayBatch);\n }\n\n originals = null;\n };\n}\n\n/**\n * Mark a callback as internal to Pinpoint, so it's not frozen.\n */\nexport function markInternal<T extends Function>(fn: T): T {\n (fn as any)[PINPOINT_SYMBOL] = true;\n return fn;\n}\n","// @agent-native/pinpoint — Unified freeze controller\n// MIT License\n//\n// Lazy initialization — nothing is patched until first freeze() call.\n\nimport { freezeCSS } from \"./css-freeze.js\";\nimport { freezeWAAPI } from \"./waapi-freeze.js\";\nimport { freezeReact } from \"./react-freeze.js\";\nimport { freezeMedia } from \"./media-freeze.js\";\nimport { freezeJSTimers } from \"./js-freeze.js\";\n\nlet cleanups: Array<() => void> = [];\nlet active = false;\n\nexport interface FreezeOptions {\n /** Freeze JS timers (opt-in, disabled by default) */\n jsTimers?: boolean;\n}\n\n/**\n * Freeze all animations, transitions, React updates, and media.\n * Call unfreeze() to restore.\n */\nexport function freeze(\n _elements?: Element[],\n options: FreezeOptions = {},\n): void {\n if (active) return;\n active = true;\n\n cleanups = [freezeCSS(), freezeWAAPI(), freezeReact(), freezeMedia()];\n\n if (options.jsTimers) {\n cleanups.push(freezeJSTimers());\n }\n}\n\n/**\n * Unfreeze everything and restore normal behavior.\n */\nexport function unfreeze(): void {\n if (!active) return;\n active = false;\n\n for (const cleanup of cleanups) {\n try {\n cleanup();\n } catch {\n // Best-effort cleanup\n }\n }\n cleanups = [];\n}\n\n/**\n * Check if freeze is currently active.\n */\nexport function isFreezeActive(): boolean {\n return active;\n}\n","// @agent-native/pinpoint — Open file in editor\n// MIT License\n\n/**\n * Open a file in the user's editor. Tries vscode:// protocol first,\n * falls back to a fetch to /api/open-file.\n */\nexport async function openFile(\n filePath: string,\n lineNumber?: number,\n): Promise<void> {\n // Try VS Code protocol\n const vsCodeUrl = lineNumber\n ? `vscode://file/${filePath}:${lineNumber}`\n : `vscode://file/${filePath}`;\n\n try {\n window.open(vsCodeUrl, \"_blank\");\n return;\n } catch {\n // VS Code not available\n }\n\n // Fallback: POST to server endpoint\n try {\n await fetch(\"/api/open-file\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ filePath, lineNumber }),\n });\n } catch {\n // Server endpoint not available\n console.warn(\"[pinpoint] Could not open file:\", filePath);\n }\n}\n"],"mappings":"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","names":["frozen"]}
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\n// MIT License\n//\n// Used for standalone/clipboard-only mode. Pins live in memory for\n// the current session. NOT localStorage (violates agent-native Rule 1).\n// Pins are lost on page reload — intentional. Connect to a server for persistence.\n\nimport type { Pin, PinStatus, PinStorage } from \"../types/index.js\";\n\nexport class MemoryStore implements PinStorage {\n private pins: Map<string, Pin> = new Map();\n\n async load(pageUrl: string): Promise<Pin[]> {\n return Array.from(this.pins.values()).filter(\n (pin) => pin.pageUrl === pageUrl,\n );\n }\n\n async save(pin: Pin): Promise<void> {\n this.pins.set(pin.id, { ...pin });\n }\n\n async update(id: string, patch: Partial<Pin>): Promise<void> {\n const existing = this.pins.get(id);\n if (!existing) return;\n this.pins.set(id, {\n ...existing,\n ...patch,\n id: existing.id, // never overwrite ID\n updatedAt: new Date().toISOString(),\n });\n }\n\n async delete(id: string): Promise<void> {\n this.pins.delete(id);\n }\n\n async list(filter?: {\n pageUrl?: string;\n status?: PinStatus;\n }): Promise<Pin[]> {\n let result = Array.from(this.pins.values());\n if (filter?.pageUrl) {\n result = result.filter((pin) => pin.pageUrl === filter.pageUrl);\n }\n if (filter?.status) {\n result = result.filter((pin) => pin.status.state === filter.status);\n }\n return result;\n }\n\n async clear(pageUrl?: string): Promise<void> {\n if (pageUrl) {\n for (const [id, pin] of this.pins) {\n if (pin.pageUrl === pageUrl) {\n this.pins.delete(id);\n }\n }\n } else {\n this.pins.clear();\n }\n }\n}\n","// @agent-native/pinpoint — CSS selector generation using @medv/finder\n// MIT License\n\nimport { finder } from \"@medv/finder\";\n\nexport interface SelectorOptions {\n /** Timeout for selector generation (ms) */\n timeoutMs?: number;\n /** Additional class names to skip */\n skipClassPatterns?: RegExp[];\n}\n\nconst DEFAULT_SKIP_CLASSES = [\n /^css-/, // CSS-in-JS (Emotion, etc.)\n /^_/, // CSS Modules hashes\n /^sc-/, // styled-components\n /^go\\d/, // Goober\n /^tw-/, // Tailwind utilities (sometimes hashed)\n /^chakra-/, // Chakra UI internals\n];\n\nconst DEFAULT_SKIP_IDS = [\n /^:r[0-9]/, // React auto-generated IDs\n /^radix-/, // Radix UI auto IDs\n /^headlessui-/, // HeadlessUI auto IDs\n];\n\n/**\n * Generate a unique, human-readable CSS selector for an element.\n * Uses @medv/finder (MIT) with configuration to skip CSS-in-JS hashes.\n */\nexport function buildSelector(\n element: Element,\n options: SelectorOptions = {},\n): string {\n const { timeoutMs = 200, skipClassPatterns = [] } = options;\n\n const allSkipClasses = [...DEFAULT_SKIP_CLASSES, ...skipClassPatterns];\n\n try {\n return finder(element, {\n className: (name: string) =>\n !allSkipClasses.some((pattern) => pattern.test(name)),\n idName: (name: string) =>\n !DEFAULT_SKIP_IDS.some((pattern) => pattern.test(name)),\n attr: (name: string) =>\n name.startsWith(\"data-testid\") || name.startsWith(\"data-cy\"),\n timeoutMs,\n });\n } catch {\n // Fallback: build a basic selector from tag + classes\n return buildFallbackSelector(element);\n }\n}\n\nfunction buildFallbackSelector(element: Element): string {\n const parts: string[] = [];\n\n if (element.id) {\n return `#${CSS.escape(element.id)}`;\n }\n\n parts.push(element.tagName.toLowerCase());\n\n // Use data-testid if available\n const testId = element.getAttribute(\"data-testid\");\n if (testId) {\n return `[data-testid=\"${CSS.escape(testId)}\"]`;\n }\n\n // Add meaningful class names\n const classes = Array.from(element.classList).filter(\n (name) => !DEFAULT_SKIP_CLASSES.some((pattern) => pattern.test(name)),\n );\n if (classes.length > 0) {\n parts.push(`.${classes.map((c) => CSS.escape(c)).join(\".\")}`);\n }\n\n // Add nth-child for uniqueness\n const parent = element.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (child) => child.tagName === element.tagName,\n );\n if (siblings.length > 1) {\n const index = siblings.indexOf(element) + 1;\n parts.push(`:nth-child(${index})`);\n }\n }\n\n return parts.join(\"\");\n}\n","// @agent-native/pinpoint — Element metadata extraction\n// MIT License\n\nimport type {\n ElementInfo,\n ElementContext,\n FrameworkInfo,\n} from \"../types/index.js\";\nimport { buildSelector } from \"./selector-builder.js\";\n\n/** Relevant computed style properties to capture */\nconst STYLE_KEYS = [\n \"color\",\n \"backgroundColor\",\n \"fontSize\",\n \"fontFamily\",\n \"fontWeight\",\n \"lineHeight\",\n \"padding\",\n \"margin\",\n \"border\",\n \"borderRadius\",\n \"display\",\n \"position\",\n \"width\",\n \"height\",\n \"opacity\",\n \"zIndex\",\n \"overflow\",\n \"textAlign\",\n \"textDecoration\",\n] as const;\n\n/**\n * Extract comprehensive metadata from a DOM element.\n */\nexport function extractElementInfo(element: Element): ElementInfo {\n const rect = element.getBoundingClientRect();\n const computed = window.getComputedStyle(element);\n\n // Extract computed styles (relevant subset)\n const computedStyles: Record<string, string> = {};\n for (const key of STYLE_KEYS) {\n const value = computed.getPropertyValue(\n key.replace(/([A-Z])/g, \"-$1\").toLowerCase(),\n );\n if (value) {\n computedStyles[key] = value;\n }\n }\n\n // Extract ARIA attributes\n const ariaAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"aria-\") || attr.name === \"role\") {\n ariaAttributes[attr.name] = attr.value;\n }\n }\n\n // Extract data attributes\n const dataAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"data-\")) {\n dataAttributes[attr.name] = attr.value;\n }\n }\n\n // Build DOM path\n const domPath = buildDomPath(element);\n\n // Get text content (truncated)\n const textContent = getTextContent(element);\n\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id || undefined,\n classNames: Array.from(element.classList),\n selector: buildSelector(element),\n textContent,\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n },\n computedStyles,\n ariaAttributes:\n Object.keys(ariaAttributes).length > 0 ? ariaAttributes : undefined,\n dataAttributes:\n Object.keys(dataAttributes).length > 0 ? dataAttributes : undefined,\n domPath,\n };\n}\n\n/**\n * Build a full ElementContext including HTML snippet and framework info.\n */\nexport function buildElementContext(\n element: Element,\n frameworkInfo?: FrameworkInfo,\n): ElementContext {\n const info = extractElementInfo(element);\n const htmlSnippet = getCleanedHtml(element);\n\n return {\n element: info,\n framework: frameworkInfo,\n htmlSnippet,\n cssSelector: info.selector,\n computedStyles: info.computedStyles || {},\n };\n}\n\n/**\n * Get text content of an element, truncated to 200 characters.\n * Only includes direct text nodes, not deeply nested text.\n */\nfunction getTextContent(element: Element): string | undefined {\n // Get direct text content only (not children's text)\n let text = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent?.trim() || \"\";\n }\n }\n\n // Fallback to full textContent if no direct text\n if (!text) {\n text = element.textContent?.trim() || \"\";\n }\n\n if (!text) return undefined;\n return text.length > 200 ? text.slice(0, 200) + \"...\" : text;\n}\n\n/**\n * Build a DOM path string like: html > body > div#root > main > section.hero\n */\nfunction buildDomPath(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current !== document.documentElement) {\n let part = current.tagName.toLowerCase();\n if (current.id) {\n part += `#${current.id}`;\n } else if (current.classList.length > 0) {\n const firstClass = current.classList[0];\n if (firstClass && !/^(css-|_|sc-)/.test(firstClass)) {\n part += `.${firstClass}`;\n }\n }\n parts.unshift(part);\n current = current.parentElement;\n }\n\n return parts.join(\" > \");\n}\n\n/**\n * Get a cleaned HTML snippet of an element.\n * Removes inline event handlers and excessive whitespace.\n */\nfunction getCleanedHtml(element: Element, maxLength = 500): string {\n const clone = element.cloneNode(true) as Element;\n\n // Remove event handler attributes\n const allElements = [clone, ...Array.from(clone.querySelectorAll(\"*\"))];\n for (const el of allElements) {\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) {\n el.removeAttribute(attr.name);\n }\n }\n }\n\n let html = clone.outerHTML;\n // Collapse whitespace\n html = html.replace(/\\s+/g, \" \").trim();\n\n if (html.length > maxLength) {\n // Truncate but keep the opening tag intact\n const openTagEnd = html.indexOf(\">\") + 1;\n if (openTagEnd > 0 && openTagEnd < maxLength) {\n html = html.slice(0, maxLength) + \"...\";\n }\n }\n\n return html;\n}\n","// @agent-native/pinpoint — Framework adapter interface and auto-detection\n// MIT License\n\nimport type {\n FrameworkAdapter,\n ComponentInfo,\n SourceLocation,\n} from \"../types/index.js\";\n\n/** Registry of framework adapters, tried in order */\nconst adapters: FrameworkAdapter[] = [];\n\n/** The currently detected adapter (cached after first detection) */\nlet detectedAdapter: FrameworkAdapter | null = null;\nlet detected = false;\n\n/**\n * Register a framework adapter. Adapters are tried in registration order.\n */\nexport function registerAdapter(adapter: FrameworkAdapter): void {\n adapters.push(adapter);\n // Reset detection cache when new adapters are registered\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Auto-detect the current framework by trying each adapter's detect() method.\n * Returns the first matching adapter, or the generic fallback.\n */\nexport function detectFramework(): FrameworkAdapter {\n if (detected && detectedAdapter) return detectedAdapter;\n\n for (const adapter of adapters) {\n try {\n if (adapter.detect()) {\n detectedAdapter = adapter;\n detected = true;\n return adapter;\n }\n } catch {\n // Adapter detection failed, try next\n }\n }\n\n // Return generic adapter as fallback\n detectedAdapter = genericAdapter;\n detected = true;\n return genericAdapter;\n}\n\n/**\n * Get component info for an element using the detected framework adapter.\n */\nexport function getComponentInfo(element: Element): ComponentInfo | null {\n const adapter = detectFramework();\n try {\n return adapter.getComponentInfo(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Get source location for an element using the detected framework adapter.\n */\nexport function getSourceLocation(element: Element): SourceLocation | null {\n const adapter = detectFramework();\n try {\n return adapter.getSourceLocation(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Reset detection cache. Useful for testing or when the page framework changes.\n */\nexport function resetDetection(): void {\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Get all registered adapters.\n */\nexport function getAdapters(): FrameworkAdapter[] {\n return [...adapters];\n}\n\n/** Generic fallback adapter for non-framework pages */\nconst genericAdapter: FrameworkAdapter = {\n name: \"generic\",\n detect: () => true, // Always matches as fallback\n getComponentInfo: () => null,\n getSourceLocation: () => null,\n};\n","// @agent-native/pinpoint — CSS animation freezing\n// MIT License\n\nconst FREEZE_STYLE_ID = \"__pinpoint-css-freeze\";\n\n/**\n * Freeze all CSS animations and transitions on the page.\n * Returns a cleanup function to restore.\n */\nexport function freezeCSS(): () => void {\n if (document.getElementById(FREEZE_STYLE_ID)) {\n return () => {}; // Already frozen\n }\n\n const style = document.createElement(\"style\");\n style.id = FREEZE_STYLE_ID;\n style.textContent = `*, *::before, *::after {\n animation-play-state: paused !important;\n transition-property: none !important;\n }`;\n document.head.appendChild(style);\n\n return () => {\n style.remove();\n };\n}\n","// @agent-native/pinpoint — JS timer monkey-patching (opt-in)\n// MIT License\n//\n// Opt-in: disabled by default, activated via options.freezeJSTimers: true\n// Bounded queue (max 1000), staggered replay, Symbol-based exclusion.\n\nconst PINPOINT_SYMBOL = Symbol.for(\"pinpoint-internal\");\nconst MAX_QUEUE = 1000;\n\ninterface QueuedTimer {\n type: \"timeout\" | \"interval\" | \"raf\";\n callback: Function;\n delay?: number;\n args?: any[];\n}\n\nlet frozen = false;\nlet queue: QueuedTimer[] = [];\nlet originals: {\n setTimeout: typeof setTimeout;\n setInterval: typeof setInterval;\n clearTimeout: typeof clearTimeout;\n clearInterval: typeof clearInterval;\n requestAnimationFrame: typeof requestAnimationFrame;\n} | null = null;\n\n/**\n * Freeze JS timers by monkey-patching setTimeout, setInterval, rAF.\n * Queued callbacks are replayed on unfreeze.\n *\n * **Opt-in only** — call this explicitly when config.freezeJSTimers is true.\n */\nexport function freezeJSTimers(): () => void {\n if (frozen) return () => {};\n\n frozen = true;\n queue = [];\n\n originals = {\n setTimeout: window.setTimeout.bind(window),\n setInterval: window.setInterval.bind(window),\n clearTimeout: window.clearTimeout.bind(window),\n clearInterval: window.clearInterval.bind(window),\n requestAnimationFrame: window.requestAnimationFrame.bind(window),\n };\n\n // Patch setTimeout\n (window as any).setTimeout = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n // Skip our own callbacks (Symbol-based filter)\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setTimeout(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"timeout\", callback, delay, args });\n }\n return 0; // Return fake timer ID\n };\n\n // Patch setInterval\n (window as any).setInterval = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setInterval(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"interval\", callback, delay, args });\n }\n return 0;\n };\n\n // Patch requestAnimationFrame\n (window as any).requestAnimationFrame = (callback: FrameRequestCallback) => {\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.requestAnimationFrame(callback);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"raf\", callback });\n }\n return 0;\n };\n\n return () => {\n if (!frozen || !originals) return;\n frozen = false;\n\n // Restore originals\n window.setTimeout = originals.setTimeout as any;\n window.setInterval = originals.setInterval as any;\n window.clearTimeout = originals.clearTimeout;\n window.clearInterval = originals.clearInterval;\n window.requestAnimationFrame = originals.requestAnimationFrame;\n\n // Staggered replay via requestIdleCallback\n const replayBatch = () => {\n const batch = queue.splice(0, 50);\n for (const item of batch) {\n try {\n if (item.type === \"raf\") {\n originals!.requestAnimationFrame(\n item.callback as FrameRequestCallback,\n );\n } else {\n originals!.setTimeout(\n item.callback as any,\n 0,\n ...(item.args || []),\n );\n }\n } catch {\n // Callback may no longer be valid\n }\n }\n if (queue.length > 0) {\n (window.requestIdleCallback || originals!.setTimeout)(replayBatch);\n }\n };\n\n if (queue.length > 0) {\n (window.requestIdleCallback || originals.setTimeout)(replayBatch);\n }\n\n originals = null;\n };\n}\n\n/**\n * Mark a callback as internal to Pinpoint, so it's not frozen.\n */\nexport function markInternal<T extends Function>(fn: T): T {\n (fn as any)[PINPOINT_SYMBOL] = true;\n return fn;\n}\n","// @agent-native/pinpoint — Media element freeze (video, audio, SVG SMIL)\n// MIT License\n\n/**\n * Pause all playing media elements on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeMedia(): () => void {\n const mediaElements = document.querySelectorAll(\"video, audio\");\n const playing: HTMLMediaElement[] = [];\n\n mediaElements.forEach((el) => {\n const media = el as HTMLMediaElement;\n if (!media.paused) {\n media.pause();\n playing.push(media);\n }\n });\n\n // Pause SVG SMIL animations\n const svgElements = document.querySelectorAll(\"svg\");\n const pausedSVGs: SVGSVGElement[] = [];\n svgElements.forEach((svg) => {\n if (typeof svg.pauseAnimations === \"function\") {\n try {\n svg.pauseAnimations();\n pausedSVGs.push(svg);\n } catch {\n // SVG may not support animation\n }\n }\n });\n\n return () => {\n playing.forEach((media) => {\n try {\n media.play();\n } catch {\n // Media may have been removed\n }\n });\n\n pausedSVGs.forEach((svg) => {\n try {\n svg.unpauseAnimations();\n } catch {\n // SVG may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — React update freezing\n// MIT License\n//\n// Patches React's dispatcher to queue state updates instead of applying them.\n// On unfreeze, flush queued updates. This prevents the host app from\n// re-rendering while the user is selecting an element.\n//\n// Based on react-grab pattern (MIT).\n\ninterface QueuedUpdate {\n fiber: any;\n queue: any;\n update: any;\n}\n\nlet frozen = false;\nlet originalDispatcher: any = null;\nlet queuedUpdates: QueuedUpdate[] = [];\n\nfunction getInternals(): any {\n const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook) return null;\n\n // Get the first React renderer\n const renderers = hook.renderers;\n if (!renderers || renderers.size === 0) return null;\n\n const renderer = renderers.values().next().value;\n return renderer?.currentDispatcherRef || null;\n}\n\n/**\n * Freeze React state updates by patching the dispatcher.\n * Updates are queued and replayed on unfreeze.\n */\nexport function freezeReact(): () => void {\n if (frozen) return () => {};\n\n const internals = getInternals();\n if (!internals) return () => {};\n\n frozen = true;\n originalDispatcher = internals.current;\n queuedUpdates = [];\n\n // Create a proxy dispatcher that intercepts useState/useReducer\n const proxyDispatcher = new Proxy(originalDispatcher, {\n get(target, prop) {\n if (prop === \"useState\" || prop === \"useReducer\") {\n return (...args: any[]) => {\n const result = target[prop](...args);\n // Wrap the setter to queue updates\n if (Array.isArray(result) && typeof result[1] === \"function\") {\n const originalSetter = result[1];\n result[1] = (action: any) => {\n queuedUpdates.push({\n fiber: null,\n queue: null,\n update: { setter: originalSetter, action },\n });\n };\n }\n return result;\n };\n }\n return target[prop];\n },\n });\n\n internals.current = proxyDispatcher;\n\n return () => {\n if (!frozen) return;\n frozen = false;\n\n // Restore original dispatcher\n if (internals && originalDispatcher) {\n internals.current = originalDispatcher;\n }\n\n // Flush queued updates\n for (const { update } of queuedUpdates) {\n try {\n update.setter(update.action);\n } catch {\n // Update may no longer be valid\n }\n }\n\n queuedUpdates = [];\n originalDispatcher = null;\n };\n}\n\nexport function isReactFrozen(): boolean {\n return frozen;\n}\n","// @agent-native/pinpoint — Web Animations API freeze\n// MIT License\n\n/**\n * Pause all WAAPI animations on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeWAAPI(): () => void {\n const animations = document.getAnimations();\n const playing = animations.filter((a) => a.playState === \"running\");\n playing.forEach((a) => a.pause());\n\n return () => {\n playing.forEach((a) => {\n try {\n a.play();\n } catch {\n // Animation may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — Unified freeze controller\n// MIT License\n//\n// Lazy initialization — nothing is patched until first freeze() call.\n\nimport { freezeCSS } from \"./css-freeze.js\";\nimport { freezeJSTimers } from \"./js-freeze.js\";\nimport { freezeMedia } from \"./media-freeze.js\";\nimport { freezeReact } from \"./react-freeze.js\";\nimport { freezeWAAPI } from \"./waapi-freeze.js\";\n\nlet cleanups: Array<() => void> = [];\nlet active = false;\n\nexport interface FreezeOptions {\n /** Freeze JS timers (opt-in, disabled by default) */\n jsTimers?: boolean;\n}\n\n/**\n * Freeze all animations, transitions, React updates, and media.\n * Call unfreeze() to restore.\n */\nexport function freeze(\n _elements?: Element[],\n options: FreezeOptions = {},\n): void {\n if (active) return;\n active = true;\n\n cleanups = [freezeCSS(), freezeWAAPI(), freezeReact(), freezeMedia()];\n\n if (options.jsTimers) {\n cleanups.push(freezeJSTimers());\n }\n}\n\n/**\n * Unfreeze everything and restore normal behavior.\n */\nexport function unfreeze(): void {\n if (!active) return;\n active = false;\n\n for (const cleanup of cleanups) {\n try {\n cleanup();\n } catch {\n // Best-effort cleanup\n }\n }\n cleanups = [];\n}\n\n/**\n * Check if freeze is currently active.\n */\nexport function isFreezeActive(): boolean {\n return active;\n}\n","// @agent-native/pinpoint — Open file in editor\n// MIT License\n\n/**\n * Open a file in the user's editor. Tries vscode:// protocol first,\n * falls back to a fetch to /api/open-file.\n */\nexport async function openFile(\n filePath: string,\n lineNumber?: number,\n): Promise<void> {\n // Try VS Code protocol\n const vsCodeUrl = lineNumber\n ? `vscode://file/${filePath}:${lineNumber}`\n : `vscode://file/${filePath}`;\n\n try {\n window.open(vsCodeUrl, \"_blank\");\n return;\n } catch {\n // VS Code not available\n }\n\n // Fallback: POST to server endpoint\n try {\n await fetch(\"/api/open-file\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ filePath, lineNumber }),\n });\n } catch {\n // Server endpoint not available\n console.warn(\"[pinpoint] Could not open file:\", filePath);\n }\n}\n"],"mappings":"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","names":["frozen"]}
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ var command = process.argv[2];
9
9
  if (command === "init") {
10
10
  init();
11
11
  } else {
12
- console.log("Usage: npx @agent-native/pinpoint init");
12
+ console.log("Usage: npx @agent-native/pinpoint@latest init");
13
13
  console.log("");
14
14
  console.log("Commands:");
15
15
  console.log(" init Copy agent scripts and skill to your project");
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n// @agent-native/pinpoint — CLI for project setup\n// MIT License\n//\n// Usage: npx @agent-native/pinpoint init\n\nimport { existsSync, mkdirSync, cpSync, readdirSync } from \"node:fs\";\nimport { resolve, dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst command = process.argv[2];\n\nif (command === \"init\") {\n init();\n} else {\n console.log(\"Usage: npx @agent-native/pinpoint init\");\n console.log(\"\");\n console.log(\"Commands:\");\n console.log(\" init Copy agent scripts and skill to your project\");\n process.exit(0);\n}\n\nfunction init() {\n const projectRoot = process.cwd();\n\n // 1. Copy agent scripts to scripts/\n const scriptsSource = resolve(__dirname, \"../src/scripts\");\n const scriptsDest = resolve(projectRoot, \"scripts\");\n\n if (!existsSync(scriptsDest)) {\n mkdirSync(scriptsDest, { recursive: true });\n }\n\n const scriptFiles = readdirSync(scriptsSource).filter((f) =>\n f.endsWith(\".ts\"),\n );\n let copiedScripts = 0;\n\n for (const file of scriptFiles) {\n const dest = join(scriptsDest, file);\n if (existsSync(dest)) {\n console.log(` skip scripts/${file} (already exists)`);\n } else {\n cpSync(join(scriptsSource, file), dest);\n console.log(` added scripts/${file}`);\n copiedScripts++;\n }\n }\n\n // 2. Copy agent skill if .agents/ directory pattern exists\n const skillSource = resolve(__dirname, \"../.agents/skills/pinpoint\");\n const skillDest = resolve(projectRoot, \".agents/skills/pinpoint\");\n\n if (existsSync(skillSource)) {\n if (!existsSync(skillDest)) {\n mkdirSync(skillDest, { recursive: true });\n }\n const skillFile = join(skillSource, \"SKILL.md\");\n const skillDestFile = join(skillDest, \"SKILL.md\");\n if (existsSync(skillFile)) {\n if (existsSync(skillDestFile)) {\n console.log(\n \" skip .agents/skills/pinpoint/SKILL.md (already exists)\",\n );\n } else {\n cpSync(skillFile, skillDestFile);\n console.log(\" added .agents/skills/pinpoint/SKILL.md\");\n }\n }\n }\n\n console.log(\"\");\n console.log(\n copiedScripts > 0\n ? \"Pinpoint initialized. Agent scripts are in scripts/.\"\n : \"Pinpoint already initialized. No new files copied.\",\n );\n console.log(\"\");\n console.log(\"Next steps:\");\n console.log(\n \" 1. Add <Pinpoint /> to your client: import { Pinpoint } from '@agent-native/pinpoint/react'\",\n );\n console.log(\n ' 2. Add middleware to your server: app.use(\"/api/pins\", pagePinRoutes())',\n );\n}\n"],"mappings":";;;AAMA,SAAS,YAAY,WAAW,QAAQ,mBAAmB;AAC3D,SAAS,SAAS,SAAS,YAAY;AACvC,SAAS,qBAAqB;AAE9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,UAAU,QAAQ,KAAK,CAAC;AAE9B,IAAI,YAAY,QAAQ;AACtB,OAAK;AACP,OAAO;AACL,UAAQ,IAAI,wCAAwC;AACpD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW;AACvB,UAAQ,IAAI,wDAAwD;AACpE,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,OAAO;AACd,QAAM,cAAc,QAAQ,IAAI;AAGhC,QAAM,gBAAgB,QAAQ,WAAW,gBAAgB;AACzD,QAAM,cAAc,QAAQ,aAAa,SAAS;AAElD,MAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,cAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AAEA,QAAM,cAAc,YAAY,aAAa,EAAE;AAAA,IAAO,CAAC,MACrD,EAAE,SAAS,KAAK;AAAA,EAClB;AACA,MAAI,gBAAgB;AAEpB,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,KAAK,aAAa,IAAI;AACnC,QAAI,WAAW,IAAI,GAAG;AACpB,cAAQ,IAAI,mBAAmB,IAAI,mBAAmB;AAAA,IACxD,OAAO;AACL,aAAO,KAAK,eAAe,IAAI,GAAG,IAAI;AACtC,cAAQ,IAAI,mBAAmB,IAAI,EAAE;AACrC;AAAA,IACF;AAAA,EACF;AAGA,QAAM,cAAc,QAAQ,WAAW,4BAA4B;AACnE,QAAM,YAAY,QAAQ,aAAa,yBAAyB;AAEhE,MAAI,WAAW,WAAW,GAAG;AAC3B,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,gBAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC1C;AACA,UAAM,YAAY,KAAK,aAAa,UAAU;AAC9C,UAAM,gBAAgB,KAAK,WAAW,UAAU;AAChD,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI,WAAW,aAAa,GAAG;AAC7B,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF,OAAO;AACL,eAAO,WAAW,aAAa;AAC/B,gBAAQ,IAAI,0CAA0C;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ;AAAA,IACN,gBAAgB,IACZ,yDACA;AAAA,EACN;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa;AACzB,UAAQ;AAAA,IACN;AAAA,EACF;AACA,UAAQ;AAAA,IACN;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n// @agent-native/pinpoint — CLI for project setup\n// MIT License\n//\n// Usage: npx @agent-native/pinpoint@latest init\n\nimport { existsSync, mkdirSync, cpSync, readdirSync } from \"node:fs\";\nimport { resolve, dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst command = process.argv[2];\n\nif (command === \"init\") {\n init();\n} else {\n console.log(\"Usage: npx @agent-native/pinpoint@latest init\");\n console.log(\"\");\n console.log(\"Commands:\");\n console.log(\" init Copy agent scripts and skill to your project\");\n process.exit(0);\n}\n\nfunction init() {\n const projectRoot = process.cwd();\n\n // 1. Copy agent scripts to scripts/\n const scriptsSource = resolve(__dirname, \"../src/scripts\");\n const scriptsDest = resolve(projectRoot, \"scripts\");\n\n if (!existsSync(scriptsDest)) {\n mkdirSync(scriptsDest, { recursive: true });\n }\n\n const scriptFiles = readdirSync(scriptsSource).filter((f) =>\n f.endsWith(\".ts\"),\n );\n let copiedScripts = 0;\n\n for (const file of scriptFiles) {\n const dest = join(scriptsDest, file);\n if (existsSync(dest)) {\n console.log(` skip scripts/${file} (already exists)`);\n } else {\n cpSync(join(scriptsSource, file), dest);\n console.log(` added scripts/${file}`);\n copiedScripts++;\n }\n }\n\n // 2. Copy agent skill if .agents/ directory pattern exists\n const skillSource = resolve(__dirname, \"../.agents/skills/pinpoint\");\n const skillDest = resolve(projectRoot, \".agents/skills/pinpoint\");\n\n if (existsSync(skillSource)) {\n if (!existsSync(skillDest)) {\n mkdirSync(skillDest, { recursive: true });\n }\n const skillFile = join(skillSource, \"SKILL.md\");\n const skillDestFile = join(skillDest, \"SKILL.md\");\n if (existsSync(skillFile)) {\n if (existsSync(skillDestFile)) {\n console.log(\n \" skip .agents/skills/pinpoint/SKILL.md (already exists)\",\n );\n } else {\n cpSync(skillFile, skillDestFile);\n console.log(\" added .agents/skills/pinpoint/SKILL.md\");\n }\n }\n }\n\n console.log(\"\");\n console.log(\n copiedScripts > 0\n ? \"Pinpoint initialized. Agent scripts are in scripts/.\"\n : \"Pinpoint already initialized. No new files copied.\",\n );\n console.log(\"\");\n console.log(\"Next steps:\");\n console.log(\n \" 1. Add <Pinpoint /> to your client: import { Pinpoint } from '@agent-native/pinpoint/react'\",\n );\n console.log(\n ' 2. Add middleware to your server: app.use(\"/api/pins\", pagePinRoutes())',\n );\n}\n"],"mappings":";;;AAMA,SAAS,YAAY,WAAW,QAAQ,mBAAmB;AAC3D,SAAS,SAAS,SAAS,YAAY;AACvC,SAAS,qBAAqB;AAE9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,UAAU,QAAQ,KAAK,CAAC;AAE9B,IAAI,YAAY,QAAQ;AACtB,OAAK;AACP,OAAO;AACL,UAAQ,IAAI,+CAA+C;AAC3D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW;AACvB,UAAQ,IAAI,wDAAwD;AACpE,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,OAAO;AACd,QAAM,cAAc,QAAQ,IAAI;AAGhC,QAAM,gBAAgB,QAAQ,WAAW,gBAAgB;AACzD,QAAM,cAAc,QAAQ,aAAa,SAAS;AAElD,MAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,cAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AAEA,QAAM,cAAc,YAAY,aAAa,EAAE;AAAA,IAAO,CAAC,MACrD,EAAE,SAAS,KAAK;AAAA,EAClB;AACA,MAAI,gBAAgB;AAEpB,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,KAAK,aAAa,IAAI;AACnC,QAAI,WAAW,IAAI,GAAG;AACpB,cAAQ,IAAI,mBAAmB,IAAI,mBAAmB;AAAA,IACxD,OAAO;AACL,aAAO,KAAK,eAAe,IAAI,GAAG,IAAI;AACtC,cAAQ,IAAI,mBAAmB,IAAI,EAAE;AACrC;AAAA,IACF;AAAA,EACF;AAGA,QAAM,cAAc,QAAQ,WAAW,4BAA4B;AACnE,QAAM,YAAY,QAAQ,aAAa,yBAAyB;AAEhE,MAAI,WAAW,WAAW,GAAG;AAC3B,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,gBAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC1C;AACA,UAAM,YAAY,KAAK,aAAa,UAAU;AAC9C,UAAM,gBAAgB,KAAK,WAAW,UAAU;AAChD,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI,WAAW,aAAa,GAAG;AAC7B,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF,OAAO;AACL,eAAO,WAAW,aAAa;AAC/B,gBAAQ,IAAI,0CAA0C;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ;AAAA,IACN,gBAAgB,IACZ,yDACA;AAAA,EACN;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa;AACzB,UAAQ;AAAA,IACN;AAAA,EACF;AACA,UAAQ;AAAA,IACN;AAAA,EACF;AACF;","names":[]}