@agent-native/pinpoint 0.1.1
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.
- package/.agents/skills/pinpoint/SKILL.md +77 -0
- package/README.md +408 -0
- package/dist/agent-context-76ZW6ODH.js +13 -0
- package/dist/agent-context-76ZW6ODH.js.map +1 -0
- package/dist/chunk-5OW42OKO.js +4897 -0
- package/dist/chunk-5OW42OKO.js.map +1 -0
- package/dist/chunk-BB7X7W3H.js +94 -0
- package/dist/chunk-BB7X7W3H.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-EPXBFDY6.js +88 -0
- package/dist/chunk-EPXBFDY6.js.map +1 -0
- package/dist/chunk-JCYY4S7A.js +53 -0
- package/dist/chunk-JCYY4S7A.js.map +1 -0
- package/dist/chunk-W7IKAJ3P.js +569 -0
- package/dist/chunk-W7IKAJ3P.js.map +1 -0
- package/dist/chunk-Y7IWDHIU.js +25 -0
- package/dist/chunk-Y7IWDHIU.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/formatter-25JPHXYA.js +8 -0
- package/dist/formatter-25JPHXYA.js.map +1 -0
- package/dist/index-5or67wLi.d.ts +193 -0
- package/dist/index-CJGmgMCD.d.ts +79 -0
- package/dist/index.browser.d.ts +381 -0
- package/dist/index.browser.js +657 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.d.ts +269 -0
- package/dist/index.js +973 -0
- package/dist/index.js.map +1 -0
- package/dist/open-file-RQVHOCXI.js +8 -0
- package/dist/open-file-RQVHOCXI.js.map +1 -0
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.js +28 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/react.d.ts +23 -0
- package/dist/react.js +20 -0
- package/dist/react.js.map +1 -0
- package/dist/server/index.d.ts +161 -0
- package/dist/server/index.js +457 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types/index.d.ts +193 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +83 -0
- package/src/scripts/create-pin.ts +41 -0
- package/src/scripts/delete-pin.ts +15 -0
- package/src/scripts/get-pins.ts +35 -0
- package/src/scripts/list-sessions.ts +33 -0
- package/src/scripts/resolve-pin.ts +26 -0
- package/src/scripts/run.ts +8 -0
- package/src/scripts/update-pin.ts +31 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/frameworks/react-adapter.ts","../src/frameworks/vue-adapter.ts","../src/frameworks/generic-adapter.ts","../src/plugins/registry.ts","../src/plugins/agent-native-plugin.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/security/input-sanitization.ts","../src/security/origin-validation.ts","../src/index.browser.ts"],"sourcesContent":["// @agent-native/pinpoint — React adapter using bippy + element-source\n// MIT License\n\nimport type {\n FrameworkAdapter,\n ComponentInfo,\n SourceLocation,\n} from \"../types/index.js\";\n\n// bippy provides React fiber introspection (MIT)\n// These are imported dynamically to avoid hard dependency when React isn't present\nlet bippy: typeof import(\"bippy\") | null = null;\nlet elementSource: typeof import(\"element-source\") | null = null;\n\nasync function loadBippy() {\n if (!bippy) {\n try {\n bippy = await import(\"bippy\");\n } catch {\n bippy = null;\n }\n }\n return bippy;\n}\n\nasync function loadElementSource() {\n if (!elementSource) {\n try {\n elementSource = await import(\"element-source\");\n } catch {\n elementSource = null;\n }\n }\n return elementSource;\n}\n\n/** React internal component names to filter from the component path */\nconst FRAMEWORK_INTERNALS = new Set([\n \"Fragment\",\n \"Suspense\",\n \"StrictMode\",\n \"Profiler\",\n \"Provider\",\n \"Consumer\",\n \"ForwardRef\",\n \"Memo\",\n // Next.js internals\n \"InnerLayoutRouter\",\n \"OuterLayoutRouter\",\n \"RenderFromTemplateContext\",\n \"ScrollAndFocusHandler\",\n \"RedirectBoundary\",\n \"NotFoundBoundary\",\n \"LoadingBoundary\",\n \"ErrorBoundary\",\n \"HotReload\",\n \"Router\",\n \"ServerRoot\",\n \"AppRouter\",\n \"ServerInsertedHTMLProvider\",\n // React Router internals\n \"Routes\",\n \"RenderedRoute\",\n \"Navigate\",\n \"Outlet\",\n]);\n\nfunction getRDTHook(): any {\n return typeof window !== \"undefined\"\n ? (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__\n : null;\n}\n\nexport const reactAdapter: FrameworkAdapter = {\n name: \"react\",\n\n detect(): boolean {\n return !!getRDTHook();\n },\n\n getComponentInfo(element: Element): ComponentInfo | null {\n const b = bippy;\n if (!b) return null;\n\n try {\n const fiber = b.getFiberFromHostInstance(element);\n if (!fiber) return null;\n\n // Build component path by traversing up the fiber tree\n const components: string[] = [];\n let current: any = fiber;\n\n while (current) {\n const name = b.getDisplayName(current);\n if (name && !FRAMEWORK_INTERNALS.has(name)) {\n components.unshift(name);\n }\n current = current.return ?? null;\n if (components.length > 20) break;\n }\n\n // Get the immediate component name\n let componentFiber: any = fiber;\n while (componentFiber && typeof componentFiber.type === \"string\") {\n componentFiber = componentFiber.return ?? null;\n }\n\n const displayName = componentFiber\n ? b.getDisplayName(componentFiber)\n : null;\n\n const sourceInfo = getSourceFromFiber(componentFiber);\n\n return {\n name: displayName || components[components.length - 1] || \"Unknown\",\n displayName: displayName || undefined,\n filePath: sourceInfo?.file,\n lineNumber: sourceInfo?.line,\n };\n } catch {\n return null;\n }\n },\n\n getSourceLocation(element: Element): SourceLocation | null {\n const b = bippy;\n if (!b) return null;\n\n try {\n const fiber = b.getFiberFromHostInstance(element);\n if (!fiber) return null;\n\n let componentFiber: any = fiber;\n while (componentFiber && typeof componentFiber.type === \"string\") {\n componentFiber = componentFiber.return ?? null;\n }\n\n return getSourceFromFiber(componentFiber);\n } catch {\n return null;\n }\n },\n\n freeze(): void {\n // React update freezing handled by freeze/react-freeze.ts\n },\n\n unfreeze(): void {\n // Restore handled by freeze/react-freeze.ts\n },\n};\n\nfunction getSourceFromFiber(fiber: any): SourceLocation | null {\n if (!fiber) return null;\n\n // React 18: _debugSource contains file/line info\n if (fiber._debugSource) {\n return {\n file: fiber._debugSource.fileName,\n line: fiber._debugSource.lineNumber,\n column: fiber._debugSource.columnNumber,\n };\n }\n\n // React 19: _debugSource was removed, use element-source library\n // element-source returns Promise<ElementSourceInfo[]> — we use it sync from cache if available\n // For synchronous adapter API, we only use _debugSource. Async source resolution\n // is handled at a higher level when building ElementContext.\n\n return null;\n}\n\n/**\n * Build a component path string like: <App> <Layout> <Sidebar> <NavLink>\n */\nexport function buildComponentPath(element: Element): string {\n const b = bippy;\n if (!b) return \"\";\n\n try {\n const fiber = b.getFiberFromHostInstance(element);\n if (!fiber) return \"\";\n\n const components: string[] = [];\n let current: any = fiber;\n\n while (current) {\n const name = b.getDisplayName(current);\n if (name && !FRAMEWORK_INTERNALS.has(name)) {\n components.unshift(`<${name}>`);\n }\n current = current.return ?? null;\n if (components.length > 10) break;\n }\n\n return components.join(\" \");\n } catch {\n return \"\";\n }\n}\n\n// Initialize bippy and element-source lazily\nif (typeof window !== \"undefined\") {\n const init = () => {\n loadBippy();\n loadElementSource();\n };\n if (typeof requestIdleCallback !== \"undefined\") {\n requestIdleCallback(init);\n } else {\n setTimeout(init, 100);\n }\n}\n","// @agent-native/pinpoint — Vue 3 adapter\n// MIT License\n//\n// Detects Vue 3 apps via window.__VUE__ or [data-v-] attributes.\n// Walks component tree via __vueParentComponent DOM properties.\n\nimport type {\n FrameworkAdapter,\n ComponentInfo,\n SourceLocation,\n} from \"../types/index.js\";\n\nexport const vueAdapter: FrameworkAdapter = {\n name: \"vue\",\n\n detect(): boolean {\n if (typeof window === \"undefined\") return false;\n // Vue 3 devtools hook\n if ((window as any).__VUE__) return true;\n // Vue 3 scoped style attributes\n if (document.querySelector(\"[data-v-]\")) return true;\n // Check for Vue 3 app instance\n return !!document.querySelector(\"[__vue_app__]\");\n },\n\n getComponentInfo(element: Element): ComponentInfo | null {\n const instance = getVueInstance(element);\n if (!instance) return null;\n\n const name = getComponentName(instance);\n const components = buildVueComponentPath(element);\n\n return {\n name: name || \"Unknown\",\n displayName: name || undefined,\n filePath: instance.$options?.__file || instance.type?.__file,\n lineNumber: undefined, // Vue doesn't expose line numbers like React\n };\n },\n\n getSourceLocation(element: Element): SourceLocation | null {\n const instance = getVueInstance(element);\n if (!instance) return null;\n\n const file =\n instance.$options?.__file ||\n instance.type?.__file ||\n instance.type?.__name;\n\n if (!file) return null;\n\n return { file };\n },\n};\n\n/**\n * Get the Vue component instance associated with a DOM element.\n */\nfunction getVueInstance(element: Element): any {\n // Vue 3: __vueParentComponent or __vue_app__\n const el = element as any;\n\n if (el.__vueParentComponent) {\n return el.__vueParentComponent;\n }\n\n // Walk up to find the nearest Vue component\n let current: Element | null = element;\n while (current) {\n if ((current as any).__vueParentComponent) {\n return (current as any).__vueParentComponent;\n }\n // Vue 2 compatibility\n if ((current as any).__vue__) {\n return (current as any).__vue__;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n\n/**\n * Get the display name of a Vue component instance.\n */\nfunction getComponentName(instance: any): string | null {\n if (!instance) return null;\n\n // Vue 3 Composition API\n if (instance.type?.name) return instance.type.name;\n if (instance.type?.__name) return instance.type.__name;\n\n // Vue 3 Options API\n if (instance.$options?.name) return instance.$options.name;\n\n // Infer from __file\n const file = instance.type?.__file || instance.$options?.__file;\n if (file) {\n const match = file.match(/([^/\\\\]+)\\.\\w+$/);\n if (match) return match[1];\n }\n\n return null;\n}\n\n/**\n * Build a component path for Vue by walking up the component tree.\n */\nfunction buildVueComponentPath(element: Element): string {\n const components: string[] = [];\n let current: Element | null = element;\n\n while (current && components.length < 10) {\n const instance = (current as any).__vueParentComponent;\n if (instance) {\n const name = getComponentName(instance);\n if (name) {\n components.unshift(`<${name}>`);\n }\n }\n current = current.parentElement;\n }\n\n return components.join(\" \");\n}\n","// @agent-native/pinpoint — Generic fallback adapter\n// MIT License\n//\n// For non-framework pages. DOM-only info, no component tree, no source files.\n\nimport type {\n FrameworkAdapter,\n ComponentInfo,\n SourceLocation,\n} from \"../types/index.js\";\n\nexport const genericAdapter: FrameworkAdapter = {\n name: \"generic\",\n\n detect(): boolean {\n // Always matches as the last resort\n return true;\n },\n\n getComponentInfo(_element: Element): ComponentInfo | null {\n // No framework = no component info\n return null;\n },\n\n getSourceLocation(_element: Element): SourceLocation | null {\n // No framework = no source location\n return null;\n },\n};\n","// @agent-native/pinpoint — Plugin registration and hook dispatch\n// MIT License\n\nimport type {\n Plugin,\n PluginHooks,\n PinpointAPI,\n PluginHookRegistry,\n} from \"../types/index.js\";\n\nconst plugins: Map<string, Plugin> = new Map();\nconst hookHandlers: Map<keyof PluginHooks, Set<Function>> = new Map();\n\n/**\n * Register a plugin.\n */\nexport function registerPlugin(plugin: Plugin, api?: PinpointAPI): void {\n if (plugins.has(plugin.name)) {\n unregisterPlugin(plugin.name);\n }\n\n plugins.set(plugin.name, plugin);\n\n // Register hook handlers\n if (plugin.hooks) {\n for (const [hookName, handler] of Object.entries(plugin.hooks)) {\n if (typeof handler === \"function\") {\n const key = hookName as keyof PluginHooks;\n if (!hookHandlers.has(key)) {\n hookHandlers.set(key, new Set());\n }\n hookHandlers.get(key)!.add(handler);\n }\n }\n }\n\n // Call setup if provided\n if (plugin.setup && api) {\n const registry: PluginHookRegistry = {\n register(hookName, handler) {\n if (!hookHandlers.has(hookName)) {\n hookHandlers.set(hookName, new Set());\n }\n hookHandlers.get(hookName)!.add(handler);\n },\n unregister(hookName, handler) {\n hookHandlers.get(hookName)?.delete(handler);\n },\n };\n plugin.setup(api, registry);\n }\n}\n\n/**\n * Unregister a plugin by name.\n */\nexport function unregisterPlugin(name: string): void {\n const plugin = plugins.get(name);\n if (!plugin) return;\n\n // Remove hook handlers\n if (plugin.hooks) {\n for (const [hookName, handler] of Object.entries(plugin.hooks)) {\n if (typeof handler === \"function\") {\n hookHandlers.get(hookName as keyof PluginHooks)?.delete(handler);\n }\n }\n }\n\n plugins.delete(name);\n}\n\n/**\n * Get all registered plugin names.\n */\nexport function getPlugins(): string[] {\n return Array.from(plugins.keys());\n}\n\n/**\n * Dispatch a hook to all registered handlers.\n */\nexport function dispatchHook(name: keyof PluginHooks, ...args: any[]): void {\n const handlers = hookHandlers.get(name);\n if (!handlers) return;\n\n for (const handler of handlers) {\n try {\n handler(...args);\n } catch (err) {\n console.warn(`[pinpoint] Plugin hook ${name} error:`, err);\n }\n }\n}\n\n/**\n * Dispatch a hook that can transform data (pipeline pattern).\n * Returns the transformed value, or false to cancel.\n */\nexport function dispatchTransformHook<T>(\n name: keyof PluginHooks,\n initial: T,\n): T | false {\n const handlers = hookHandlers.get(name);\n if (!handlers) return initial;\n\n let current: T | false = initial;\n for (const handler of handlers) {\n try {\n const result: any = handler(current);\n if (result === false) return false;\n if (result !== undefined) current = result as T;\n } catch (err) {\n console.warn(`[pinpoint] Plugin hook ${name} error:`, err);\n }\n }\n\n return current;\n}\n\n/**\n * Get context menu actions from all plugins.\n */\nexport function getPluginActions() {\n const actions = [];\n for (const plugin of plugins.values()) {\n if (plugin.actions) {\n actions.push(...plugin.actions);\n }\n }\n return actions;\n}\n","// @agent-native/pinpoint — Built-in agent-native plugin\n// MIT License\n//\n// Wires sendToAgentChat(), SSE sync, and file persistence.\n// Default plugin — makes Pinpoint agent-native out of the box.\n// Can be disabled for standalone/clipboard-only mode.\n\nimport type { Plugin, Pin } from \"../types/index.js\";\n\nexport const agentNativePlugin: Plugin = {\n name: \"agent-native\",\n\n setup(_api, hooks) {\n hooks.register(\"onPinCreate\", (_pin: Pin) => {\n // Pin created — the main app handles storage via the configured adapter\n });\n\n hooks.register(\"onPinResolve\", (_pin: Pin) => {\n // Pin resolved — could notify the agent\n });\n },\n\n hooks: {\n onPinCreate(pin: Pin) {\n if (typeof console !== \"undefined\") {\n console.debug(\"[pinpoint] Pin created:\", pin.id);\n }\n },\n\n onPinResolve(pin: Pin) {\n if (typeof console !== \"undefined\") {\n console.debug(\"[pinpoint] Pin resolved:\", pin.id);\n }\n },\n\n transformOutput(output: string) {\n return output;\n },\n },\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 — Input sanitization for DOM-derived strings\n// MIT License\n\nconst HTML_ENTITIES: Record<string, string> = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n};\n\n/**\n * Escape HTML entities in a string.\n * Use on all DOM-derived strings before rendering or including in output.\n */\nexport function escapeHtml(str: string): string {\n return str.replace(/[&<>\"']/g, (char) => HTML_ENTITIES[char] || char);\n}\n\n/**\n * Sanitize a string by removing control characters and limiting length.\n */\nexport function sanitizeString(str: string, maxLength = 1000): string {\n // Remove control characters (except newline, tab)\n const cleaned = str.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, \"\");\n return cleaned.slice(0, maxLength);\n}\n\n/**\n * Sanitize an object's string values recursively.\n */\nexport function sanitizeObject<T extends Record<string, any>>(\n obj: T,\n maxStringLength = 1000,\n): T {\n const result: any = {};\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === \"string\") {\n result[key] = sanitizeString(value, maxStringLength);\n } else if (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n result[key] = sanitizeObject(value, maxStringLength);\n } else if (Array.isArray(value)) {\n result[key] = value.map((item) =>\n typeof item === \"string\"\n ? sanitizeString(item, maxStringLength)\n : typeof item === \"object\" && item !== null\n ? sanitizeObject(item, maxStringLength)\n : item,\n );\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n","// @agent-native/pinpoint — Origin validation for cross-frame communication\n// MIT License\n\n/**\n * Validate that a message origin is allowed.\n * Used for postMessage security when communicating with frames.\n */\nexport function isAllowedOrigin(\n origin: string,\n allowedOrigins?: string[],\n): boolean {\n // Always allow same-origin\n if (origin === window.location.origin) return true;\n\n // Always allow localhost variants\n if (\n origin.startsWith(\"http://localhost\") ||\n origin.startsWith(\"http://127.0.0.1\") ||\n origin.startsWith(\"https://localhost\")\n ) {\n return true;\n }\n\n // Check explicit allowlist\n if (allowedOrigins && allowedOrigins.length > 0) {\n return allowedOrigins.includes(origin);\n }\n\n // Default: deny unknown origins\n return false;\n}\n\n/**\n * Create a MessageChannel port pair for secure bi-directional communication.\n * Avoids broadcasting via postMessage('*').\n */\nexport function createSecureChannel(): {\n port: MessagePort;\n remotePort: MessagePort;\n} {\n const channel = new MessageChannel();\n return {\n port: channel.port1,\n remotePort: channel.port2,\n };\n}\n","// @agent-native/pinpoint — Browser entry point (includes SolidJS UI)\n// MIT License\n\n// Re-export everything from main entry\nexport * from \"./index.js\";\n\n// UI-specific exports\nexport { mountPinpoint, unmountPinpoint } from \"./ui/mount.js\";\nexport { PinMarkerManager } from \"./ui/components/PinMarker.js\";\n\n// Auto-register framework adapters\nimport { registerAdapter } from \"./frameworks/adapter.js\";\nimport { reactAdapter } from \"./frameworks/react-adapter.js\";\nimport { vueAdapter } from \"./frameworks/vue-adapter.js\";\n\nregisterAdapter(reactAdapter);\nregisterAdapter(vueAdapter);\n"],"mappings":"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","names":["frozen"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { PinStorage, Pin, PinStatus, FrameworkAdapter, OutputFormat, QueuedAnnotation, PluginHooks, Plugin, PinpointAPI } from './types/index.js';
|
|
2
|
+
export { ComponentInfo, ContextMenuAction, CopyContext, DrawStroke, DrawToolType, ElementContext, ElementInfo, FrameworkInfo, PinEvent, PinpointConfig, SourceLocation, TextNote, ToolbarMode } from './types/index.js';
|
|
3
|
+
export { M as MemoryStore, b as buildElementContext, a as buildSelector, d as detectFramework, e as extractElementInfo, f as freeze, g as getComponentInfo, c as getSourceLocation, i as isFreezeActive, o as openFile, r as registerAdapter, u as unfreeze } from './index-CJGmgMCD.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
declare class RestClient implements PinStorage {
|
|
7
|
+
private endpoint;
|
|
8
|
+
constructor(endpoint: string);
|
|
9
|
+
load(pageUrl: string): Promise<Pin[]>;
|
|
10
|
+
save(pin: Pin): Promise<void>;
|
|
11
|
+
update(id: string, patch: Partial<Pin>): Promise<void>;
|
|
12
|
+
delete(id: string): Promise<void>;
|
|
13
|
+
list(filter?: {
|
|
14
|
+
pageUrl?: string;
|
|
15
|
+
status?: PinStatus;
|
|
16
|
+
}): Promise<Pin[]>;
|
|
17
|
+
clear(pageUrl?: string): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare const ElementInfoSchema: z.ZodObject<{
|
|
21
|
+
tagName: z.ZodString;
|
|
22
|
+
id: z.ZodOptional<z.ZodString>;
|
|
23
|
+
classNames: z.ZodArray<z.ZodString>;
|
|
24
|
+
selector: z.ZodString;
|
|
25
|
+
textContent: z.ZodOptional<z.ZodString>;
|
|
26
|
+
boundingRect: z.ZodObject<{
|
|
27
|
+
x: z.ZodNumber;
|
|
28
|
+
y: z.ZodNumber;
|
|
29
|
+
width: z.ZodNumber;
|
|
30
|
+
height: z.ZodNumber;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
computedStyles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
33
|
+
ariaAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
34
|
+
dataAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
35
|
+
domPath: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
declare const FrameworkInfoSchema: z.ZodObject<{
|
|
38
|
+
framework: z.ZodString;
|
|
39
|
+
componentPath: z.ZodString;
|
|
40
|
+
sourceFile: z.ZodOptional<z.ZodString>;
|
|
41
|
+
frameworkVersion: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
declare const PinSchema: z.ZodObject<{
|
|
44
|
+
id: z.ZodString;
|
|
45
|
+
pageUrl: z.ZodString;
|
|
46
|
+
createdAt: z.ZodString;
|
|
47
|
+
updatedAt: z.ZodString;
|
|
48
|
+
author: z.ZodOptional<z.ZodString>;
|
|
49
|
+
comment: z.ZodString;
|
|
50
|
+
element: z.ZodObject<{
|
|
51
|
+
tagName: z.ZodString;
|
|
52
|
+
id: z.ZodOptional<z.ZodString>;
|
|
53
|
+
classNames: z.ZodArray<z.ZodString>;
|
|
54
|
+
selector: z.ZodString;
|
|
55
|
+
textContent: z.ZodOptional<z.ZodString>;
|
|
56
|
+
boundingRect: z.ZodObject<{
|
|
57
|
+
x: z.ZodNumber;
|
|
58
|
+
y: z.ZodNumber;
|
|
59
|
+
width: z.ZodNumber;
|
|
60
|
+
height: z.ZodNumber;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
computedStyles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
63
|
+
ariaAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
64
|
+
dataAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
65
|
+
domPath: z.ZodOptional<z.ZodString>;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
framework: z.ZodOptional<z.ZodObject<{
|
|
68
|
+
framework: z.ZodString;
|
|
69
|
+
componentPath: z.ZodString;
|
|
70
|
+
sourceFile: z.ZodOptional<z.ZodString>;
|
|
71
|
+
frameworkVersion: z.ZodOptional<z.ZodString>;
|
|
72
|
+
}, z.core.$strip>>;
|
|
73
|
+
status: z.ZodObject<{
|
|
74
|
+
state: z.ZodEnum<{
|
|
75
|
+
open: "open";
|
|
76
|
+
acknowledged: "acknowledged";
|
|
77
|
+
resolved: "resolved";
|
|
78
|
+
dismissed: "dismissed";
|
|
79
|
+
}>;
|
|
80
|
+
changedAt: z.ZodString;
|
|
81
|
+
changedBy: z.ZodOptional<z.ZodString>;
|
|
82
|
+
}, z.core.$strip>;
|
|
83
|
+
}, z.core.$strip>;
|
|
84
|
+
|
|
85
|
+
interface ElementPickerOptions {
|
|
86
|
+
/** Called on hover with the element under the cursor */
|
|
87
|
+
onHover?: (element: Element | null, rect: DOMRect | null) => void;
|
|
88
|
+
/** Called after stable hover (100ms) with full element context */
|
|
89
|
+
onStableHover?: (element: Element) => void;
|
|
90
|
+
/** Called when an element is clicked/selected */
|
|
91
|
+
onSelect?: (element: Element) => void;
|
|
92
|
+
/** Elements to ignore (e.g., pinpoint's own UI) */
|
|
93
|
+
ignoreSelector?: string;
|
|
94
|
+
/** Whether to block page interactions during selection */
|
|
95
|
+
blockInteractions?: boolean;
|
|
96
|
+
}
|
|
97
|
+
declare class ElementPicker {
|
|
98
|
+
private active;
|
|
99
|
+
private paused;
|
|
100
|
+
private hoveredElement;
|
|
101
|
+
private rafId;
|
|
102
|
+
private stableTimeout;
|
|
103
|
+
private lastTarget;
|
|
104
|
+
private options;
|
|
105
|
+
private handleMouseMove;
|
|
106
|
+
private handleClick;
|
|
107
|
+
private handleKeyDown;
|
|
108
|
+
constructor(options?: ElementPickerOptions);
|
|
109
|
+
/**
|
|
110
|
+
* Check if an event originates from Pinpoint's own UI.
|
|
111
|
+
* Uses composedPath() to cross Shadow DOM boundaries.
|
|
112
|
+
*/
|
|
113
|
+
private isOwnUI;
|
|
114
|
+
private shouldIgnore;
|
|
115
|
+
private pierceElementFromPoint;
|
|
116
|
+
private processHover;
|
|
117
|
+
private clearStableTimeout;
|
|
118
|
+
activate(): void;
|
|
119
|
+
deactivate(): void;
|
|
120
|
+
/** Update blockInteractions at runtime (called from settings toggle) */
|
|
121
|
+
setBlockInteractions(value: boolean): void;
|
|
122
|
+
/** Pause picking without removing listeners (e.g., while popup is open) */
|
|
123
|
+
pause(): void;
|
|
124
|
+
/** Resume picking after pause */
|
|
125
|
+
resume(): void;
|
|
126
|
+
isPaused(): boolean;
|
|
127
|
+
isActive(): boolean;
|
|
128
|
+
/** Get the currently hovered element */
|
|
129
|
+
getHoveredElement(): Element | null;
|
|
130
|
+
dispose(): void;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface DragSelectOptions {
|
|
134
|
+
/** Minimum coverage threshold (0-1) for an element to be considered selected */
|
|
135
|
+
coverageThreshold?: number;
|
|
136
|
+
/** Called when drag starts */
|
|
137
|
+
onDragStart?: (rect: DOMRect) => void;
|
|
138
|
+
/** Called during drag with the current selection rectangle */
|
|
139
|
+
onDragMove?: (rect: DOMRect) => void;
|
|
140
|
+
/** Called when drag ends with selected elements */
|
|
141
|
+
onDragEnd?: (elements: Element[]) => void;
|
|
142
|
+
/** Elements to ignore */
|
|
143
|
+
ignoreSelector?: string;
|
|
144
|
+
}
|
|
145
|
+
declare class DragSelect {
|
|
146
|
+
private active;
|
|
147
|
+
private dragging;
|
|
148
|
+
private startX;
|
|
149
|
+
private startY;
|
|
150
|
+
private options;
|
|
151
|
+
private handleMouseDown;
|
|
152
|
+
private handleMouseMove;
|
|
153
|
+
private handleMouseUp;
|
|
154
|
+
constructor(options?: DragSelectOptions);
|
|
155
|
+
private buildRect;
|
|
156
|
+
private getElementsInRect;
|
|
157
|
+
activate(): void;
|
|
158
|
+
deactivate(): void;
|
|
159
|
+
isDragging(): boolean;
|
|
160
|
+
dispose(): void;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
interface TextSelection {
|
|
164
|
+
/** The selected text */
|
|
165
|
+
text: string;
|
|
166
|
+
/** The container element */
|
|
167
|
+
container: Element;
|
|
168
|
+
/** Start offset within the container */
|
|
169
|
+
startOffset: number;
|
|
170
|
+
/** End offset within the container */
|
|
171
|
+
endOffset: number;
|
|
172
|
+
/** Surrounding context (text before + selected + text after) */
|
|
173
|
+
context: string;
|
|
174
|
+
/** Bounding rect of the selection */
|
|
175
|
+
rect: DOMRect;
|
|
176
|
+
}
|
|
177
|
+
interface TextSelectOptions {
|
|
178
|
+
/** Called when text selection changes */
|
|
179
|
+
onSelect?: (selection: TextSelection | null) => void;
|
|
180
|
+
/** Minimum characters to trigger selection callback */
|
|
181
|
+
minLength?: number;
|
|
182
|
+
}
|
|
183
|
+
declare class TextSelect {
|
|
184
|
+
private active;
|
|
185
|
+
private options;
|
|
186
|
+
private handleSelectionChange;
|
|
187
|
+
private debounceTimer;
|
|
188
|
+
constructor(options?: TextSelectOptions);
|
|
189
|
+
private getTextSelection;
|
|
190
|
+
activate(): void;
|
|
191
|
+
deactivate(): void;
|
|
192
|
+
/** Get the current text selection, if any */
|
|
193
|
+
getCurrentSelection(): TextSelection | null;
|
|
194
|
+
dispose(): void;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
declare const reactAdapter: FrameworkAdapter;
|
|
198
|
+
|
|
199
|
+
declare const vueAdapter: FrameworkAdapter;
|
|
200
|
+
|
|
201
|
+
declare const genericAdapter: FrameworkAdapter;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Format pins into a human/agent-readable markdown string.
|
|
205
|
+
*/
|
|
206
|
+
declare function formatPins(pins: Pin[], format?: OutputFormat): string;
|
|
207
|
+
|
|
208
|
+
interface AgentOutput {
|
|
209
|
+
message: string;
|
|
210
|
+
context: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Format a single pin into rich context for the agent.
|
|
214
|
+
*
|
|
215
|
+
* ```
|
|
216
|
+
* [Annotation on <button class="primary"> in <Header> component]
|
|
217
|
+
* Comment: "This button should be blue instead of gray"
|
|
218
|
+
* Element: button.primary at (120, 45)
|
|
219
|
+
* Source: src/components/Header.tsx:42
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
declare function formatRichPinContext(pin: Pin): string;
|
|
223
|
+
/**
|
|
224
|
+
* Format pins for agent chat.
|
|
225
|
+
* The full formatted output goes into message (visible in chat UI) so the user
|
|
226
|
+
* can see exactly what context the agent is working with.
|
|
227
|
+
*/
|
|
228
|
+
declare function formatPinsForAgent(pins: Pin[], format?: OutputFormat): AgentOutput;
|
|
229
|
+
/**
|
|
230
|
+
* Format queued annotations for batch sending.
|
|
231
|
+
*/
|
|
232
|
+
declare function formatQueueForAgent(queue: QueuedAnnotation[], format?: OutputFormat): AgentOutput;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Register a plugin.
|
|
236
|
+
*/
|
|
237
|
+
declare function registerPlugin(plugin: Plugin, api?: PinpointAPI): void;
|
|
238
|
+
/**
|
|
239
|
+
* Unregister a plugin by name.
|
|
240
|
+
*/
|
|
241
|
+
declare function unregisterPlugin(name: string): void;
|
|
242
|
+
/**
|
|
243
|
+
* Get all registered plugin names.
|
|
244
|
+
*/
|
|
245
|
+
declare function getPlugins(): string[];
|
|
246
|
+
/**
|
|
247
|
+
* Dispatch a hook to all registered handlers.
|
|
248
|
+
*/
|
|
249
|
+
declare function dispatchHook(name: keyof PluginHooks, ...args: any[]): void;
|
|
250
|
+
|
|
251
|
+
declare const agentNativePlugin: Plugin;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Escape HTML entities in a string.
|
|
255
|
+
* Use on all DOM-derived strings before rendering or including in output.
|
|
256
|
+
*/
|
|
257
|
+
declare function escapeHtml(str: string): string;
|
|
258
|
+
/**
|
|
259
|
+
* Sanitize a string by removing control characters and limiting length.
|
|
260
|
+
*/
|
|
261
|
+
declare function sanitizeString(str: string, maxLength?: number): string;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Validate that a message origin is allowed.
|
|
265
|
+
* Used for postMessage security when communicating with frames.
|
|
266
|
+
*/
|
|
267
|
+
declare function isAllowedOrigin(origin: string, allowedOrigins?: string[]): boolean;
|
|
268
|
+
|
|
269
|
+
export { DragSelect, ElementInfoSchema, ElementPicker, FrameworkAdapter, FrameworkInfoSchema, OutputFormat, Pin, PinSchema, PinStatus, PinStorage, PinpointAPI, Plugin, PluginHooks, QueuedAnnotation, RestClient, TextSelect, agentNativePlugin, dispatchHook, escapeHtml, formatPins, formatPinsForAgent, formatQueueForAgent, formatRichPinContext, genericAdapter, getPlugins, isAllowedOrigin, reactAdapter, registerPlugin, sanitizeString, unregisterPlugin, vueAdapter };
|