web-remarq 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,10 +44,15 @@ WebRemarq.init({ theme: 'light' })
44
44
  Initialize the tool. Idempotent — safe to call multiple times.
45
45
 
46
46
  ```ts
47
+ import { WebRemarq, LocalStorageAdapter } from 'web-remarq'
48
+
47
49
  WebRemarq.init({
48
50
  theme: 'light', // 'light' | 'dark'
49
51
  classFilter: (name) => boolean, // custom class filter for fingerprinting
50
52
  dataAttribute: 'data-annotate', // which data-attr to use as stable anchor
53
+ position: 'bottom-right', // toolbar anchor
54
+ shortcuts: true, // enable keyboard shortcuts (default true)
55
+ storage: new LocalStorageAdapter() // pluggable storage backend (default)
51
56
  })
52
57
  ```
53
58
 
@@ -90,6 +95,54 @@ Get all annotations, or filter by route.
90
95
 
91
96
  Remove all annotations.
92
97
 
98
+ ## Storage
99
+
100
+ Annotations persist via a pluggable `StorageAdapter` interface. Default = `LocalStorageAdapter` (localStorage, key `remarq:annotations`, automatic in-memory fallback on quota errors).
101
+
102
+ ### Custom adapters
103
+
104
+ ```ts
105
+ import { WebRemarq, type StorageAdapter, type Annotation, type AnnotationStore } from 'web-remarq'
106
+
107
+ const myAdapter: StorageAdapter = {
108
+ async load(): Promise<AnnotationStore | null> { /* ... */ },
109
+ async save(annotation: Annotation): Promise<void> { /* upsert by id */ },
110
+ async remove(id: string): Promise<void> { /* ... */ },
111
+ async clear(): Promise<void> { /* ... */ },
112
+ }
113
+
114
+ WebRemarq.init({ storage: myAdapter })
115
+ ```
116
+
117
+ The interface is async by design — supports remote backends (Supabase, REST, IndexedDB) without changing the public WebRemarq API. The domain layer (`AnnotationStorage`) keeps an in-memory cache, so synchronous getters like `WebRemarq.getAnnotations()` stay sync.
118
+
119
+ `@web-remarq/cloud` (planned) will ship a Supabase-backed `StorageAdapter` implementation for team collaboration.
120
+
121
+ ## Lifecycle states
122
+
123
+ Annotations follow a 5-state lifecycle with a verification gate between AI-claimed fixes and human confirmation. Every transition is recorded in `annotation.lifecycle: AnnotationEvent[]` (`{ type, actor, actorName?, timestamp, reason? }`).
124
+
125
+ | Status | Semantics |
126
+ |---|---|
127
+ | `pending` | Newly created — needs attention |
128
+ | `in_progress` | Acknowledged, work started |
129
+ | `fixed_unverified` | Agent claims it's fixed, awaiting human verification |
130
+ | `verified` | Human confirmed the fix |
131
+ | `dismissed` | Won't fix (terminal) |
132
+
133
+ ### Lifecycle API
134
+
135
+ ```ts
136
+ WebRemarq.acknowledge(id, opts?) // → in_progress
137
+ WebRemarq.claimFix(id, opts?) // → fixed_unverified (agent-only — no UI button)
138
+ WebRemarq.verify(id, opts?) // → verified (from in_progress or fixed_unverified)
139
+ WebRemarq.reject(id, opts?: { reason?: string }) // fixed_unverified → pending
140
+ WebRemarq.dismiss(id, opts?: { reason?: string }) // → dismissed
141
+ WebRemarq.reopen(id, opts?) // verified | dismissed → pending
142
+ ```
143
+
144
+ `opts?: { actor?: 'designer' | 'agent' | 'developer', actorName?: string }`. `claimFix` is intended for agents over MCP; humans skip it and call `verify` directly from `in_progress` for manual fixes. Legacy `'resolved'` status migrates to `'verified'` on load with a synthetic `migrated` event appended to `lifecycle`.
145
+
93
146
  ## Agent Export Format
94
147
 
95
148
  The `export('agent')` format is optimized for AI coding agents:
@@ -134,7 +187,13 @@ Source detection uses a 3-level fallback:
134
187
  For programmatic access without UI:
135
188
 
136
189
  ```ts
137
- import { createFingerprint, matchElement, AnnotationStorage } from 'web-remarq/core'
190
+ import {
191
+ createFingerprint,
192
+ matchElement,
193
+ AnnotationStorage,
194
+ LocalStorageAdapter,
195
+ type StorageAdapter,
196
+ } from 'web-remarq/core'
138
197
  ```
139
198
 
140
199
  ## How It Works
@@ -179,8 +238,8 @@ Works without any markup changes, but for guaranteed stable matching add `data-a
179
238
  - **Toolbar** — fixed bottom-right panel with inspect, spacing, copy, export, import, clear, theme, minimize
180
239
  - **Inspect mode** — hover to highlight, click to annotate
181
240
  - **Spacing inspector** — visualizes margin, padding, content, flex gap on hover
182
- - **Markers** — numbered circles (orange = pending, green = resolved)
183
- - **Popup** — comment input / detail view with Resolve/Delete
241
+ - **Markers** — numbered circles, color per lifecycle state (orange = pending, yellow = in_progress, blue = fixed_unverified, green = verified, gray = dismissed)
242
+ - **Popup** — comment input / detail view with dynamic lifecycle actions + history viewer
184
243
 
185
244
  ## License
186
245
 
@@ -50,11 +50,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
50
50
  var core_exports = {};
51
51
  __export(core_exports, {
52
52
  AnnotationStorage: () => AnnotationStorage,
53
+ InvalidTransitionError: () => InvalidTransitionError,
54
+ LocalStorageAdapter: () => LocalStorageAdapter,
55
+ createEvent: () => createEvent,
53
56
  createFingerprint: () => createFingerprint,
54
57
  detectRemarqPlugin: () => detectRemarqPlugin,
55
58
  detectSource: () => detectSource,
56
59
  generateAgentExport: () => generateAgentExport,
57
- matchElement: () => matchElement
60
+ matchElement: () => matchElement,
61
+ migrateAnnotation: () => migrateAnnotation,
62
+ transition: () => transition
58
63
  });
59
64
  module.exports = __toCommonJS(core_exports);
60
65
 
@@ -379,79 +384,151 @@ function toBucket(width) {
379
384
  }
380
385
 
381
386
  // src/core/storage.ts
382
- var STORAGE_KEY = "remarq:annotations";
387
+ function migrateAnnotation(legacy) {
388
+ const rawStatus = legacy.status;
389
+ const status = rawStatus === "resolved" ? "verified" : rawStatus;
390
+ if (Array.isArray(legacy.lifecycle) && legacy.lifecycle.length > 0) {
391
+ return __spreadProps(__spreadValues({}, legacy), { status, lifecycle: legacy.lifecycle });
392
+ }
393
+ const createdTs = typeof legacy.timestamp === "number" ? legacy.timestamp : Date.now();
394
+ const lifecycle = [
395
+ { type: "created", actor: "designer", timestamp: createdTs }
396
+ ];
397
+ if (rawStatus === "resolved") {
398
+ lifecycle.push({ type: "migrated", actor: null, timestamp: Date.now() });
399
+ }
400
+ return __spreadProps(__spreadValues({}, legacy), { status, lifecycle });
401
+ }
383
402
  var AnnotationStorage = class {
384
- constructor() {
385
- this.annotations = [];
386
- this.extraFields = {};
387
- this.isMemoryOnly = false;
388
- this.load();
403
+ constructor(adapter) {
404
+ this.adapter = adapter;
405
+ this.cache = [];
406
+ this.ready = this.init();
407
+ }
408
+ get isMemoryOnly() {
409
+ var _a;
410
+ return (_a = this.adapter.isMemoryOnly) != null ? _a : false;
389
411
  }
390
412
  getAll() {
391
- return [...this.annotations];
413
+ return [...this.cache];
392
414
  }
393
415
  getByRoute(route) {
394
- return this.annotations.filter((a) => a.route === route);
416
+ return this.cache.filter((a) => a.route === route);
395
417
  }
396
- add(annotation) {
397
- this.annotations.push(annotation);
398
- this.save();
418
+ getById(id) {
419
+ return this.cache.find((a) => a.id === id);
399
420
  }
400
- remove(id) {
401
- this.annotations = this.annotations.filter((a) => a.id !== id);
402
- this.save();
421
+ async add(annotation) {
422
+ this.cache.push(annotation);
423
+ await this.adapter.save(annotation);
403
424
  }
404
- update(id, changes) {
405
- const idx = this.annotations.findIndex((a) => a.id === id);
406
- if (idx !== -1) {
407
- this.annotations[idx] = __spreadValues(__spreadValues({}, this.annotations[idx]), changes);
408
- this.save();
409
- }
425
+ async remove(id) {
426
+ this.cache = this.cache.filter((a) => a.id !== id);
427
+ await this.adapter.remove(id);
428
+ }
429
+ async update(id, changes) {
430
+ const idx = this.cache.findIndex((a) => a.id === id);
431
+ if (idx === -1) return;
432
+ const updated = __spreadValues(__spreadValues({}, this.cache[idx]), changes);
433
+ this.cache[idx] = updated;
434
+ await this.adapter.save(updated);
410
435
  }
411
- clearAll() {
412
- this.annotations = [];
413
- this.save();
436
+ async clearAll() {
437
+ this.cache = [];
438
+ await this.adapter.clear();
414
439
  }
415
440
  exportJSON() {
416
441
  return {
417
442
  version: 1,
418
- annotations: [...this.annotations]
443
+ annotations: [...this.cache]
419
444
  };
420
445
  }
421
- importJSON(data) {
422
- this.annotations = [...data.annotations];
446
+ async importJSON(data) {
447
+ this.cache = data.annotations.map(migrateAnnotation);
423
448
  this.migrateViewportBuckets();
424
- this.save();
449
+ await this.adapter.clear();
450
+ for (const ann of this.cache) {
451
+ await this.adapter.save(ann);
452
+ }
453
+ }
454
+ async init() {
455
+ const data = await this.adapter.load();
456
+ if (data) {
457
+ this.cache = data.annotations.map(migrateAnnotation);
458
+ this.migrateViewportBuckets();
459
+ }
425
460
  }
426
461
  migrateViewportBuckets() {
427
- for (const ann of this.annotations) {
462
+ for (const ann of this.cache) {
428
463
  if (ann.viewportBucket == null && ann.viewport) {
429
464
  const width = parseInt(ann.viewport.split("x")[0], 10);
430
465
  ann.viewportBucket = toBucket(width);
431
466
  }
432
467
  }
433
468
  }
434
- load() {
469
+ };
470
+
471
+ // src/core/local-storage-adapter.ts
472
+ var STORAGE_KEY = "remarq:annotations";
473
+ var LocalStorageAdapter = class {
474
+ constructor() {
475
+ this.isMemoryOnly = false;
476
+ this.extraFields = {};
477
+ this.memoryStore = null;
478
+ }
479
+ async load() {
480
+ if (this.isMemoryOnly) return this.memoryStore;
435
481
  try {
436
482
  const raw = localStorage.getItem(STORAGE_KEY);
437
- if (raw) {
438
- const parsed = JSON.parse(raw);
439
- const _a = parsed, { version, annotations } = _a, rest = __objRest(_a, ["version", "annotations"]);
440
- this.annotations = annotations != null ? annotations : [];
441
- this.extraFields = rest;
442
- this.migrateViewportBuckets();
443
- }
483
+ if (!raw) return null;
484
+ const parsed = JSON.parse(raw);
485
+ const _a = parsed, { version, annotations } = _a, rest = __objRest(_a, ["version", "annotations"]);
486
+ this.extraFields = rest;
487
+ const store = {
488
+ version: 1,
489
+ annotations: Array.isArray(annotations) ? annotations : []
490
+ };
491
+ this.memoryStore = store;
492
+ return store;
444
493
  } catch (e) {
445
494
  this.isMemoryOnly = true;
495
+ return this.memoryStore;
446
496
  }
447
497
  }
448
- save() {
498
+ async save(annotation) {
499
+ const store = await this.ensureStore();
500
+ const idx = store.annotations.findIndex((a) => a.id === annotation.id);
501
+ if (idx === -1) {
502
+ store.annotations.push(annotation);
503
+ } else {
504
+ store.annotations[idx] = annotation;
505
+ }
506
+ this.persist(store);
507
+ }
508
+ async remove(id) {
509
+ const store = await this.ensureStore();
510
+ store.annotations = store.annotations.filter((a) => a.id !== id);
511
+ this.persist(store);
512
+ }
513
+ async clear() {
514
+ const store = await this.ensureStore();
515
+ store.annotations = [];
516
+ this.persist(store);
517
+ }
518
+ async ensureStore() {
519
+ if (this.memoryStore) return this.memoryStore;
520
+ const loaded = await this.load();
521
+ if (loaded) return loaded;
522
+ this.memoryStore = { version: 1, annotations: [] };
523
+ return this.memoryStore;
524
+ }
525
+ persist(store) {
449
526
  if (this.isMemoryOnly) return;
450
527
  try {
451
528
  const data = __spreadProps(__spreadValues({
452
529
  version: 1
453
530
  }, this.extraFields), {
454
- annotations: this.annotations
531
+ annotations: store.annotations
455
532
  });
456
533
  localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
457
534
  } catch (e) {
@@ -532,7 +609,16 @@ function generateAgentExport(annotations, viewportBucket) {
532
609
  status: ann.status,
533
610
  timestamp: ann.timestamp,
534
611
  source: resolveSource(ann.fingerprint),
535
- searchHints: buildSearchHints(ann.fingerprint)
612
+ searchHints: buildSearchHints(ann.fingerprint),
613
+ lifecycle: ann.lifecycle.map((ev) => {
614
+ const out = {
615
+ type: ev.type,
616
+ actor: ev.actor,
617
+ timestamp: ev.timestamp
618
+ };
619
+ if (ev.reason !== void 0) out.reason = ev.reason;
620
+ return out;
621
+ })
536
622
  }));
537
623
  return {
538
624
  version: 1,
@@ -541,13 +627,79 @@ function generateAgentExport(annotations, viewportBucket) {
541
627
  annotations: agentAnnotations
542
628
  };
543
629
  }
630
+
631
+ // src/core/lifecycle.ts
632
+ var InvalidTransitionError = class extends Error {
633
+ constructor(from, action) {
634
+ super(`Cannot ${action} from status "${from}"`);
635
+ this.name = "InvalidTransitionError";
636
+ }
637
+ };
638
+ var ACTION_TO_EVENT = {
639
+ acknowledge: "acknowledged",
640
+ claimFix: "fix_claimed",
641
+ verify: "verified",
642
+ reject: "rejected",
643
+ dismiss: "dismissed",
644
+ reopen: "reopened"
645
+ };
646
+ var DEFAULT_ACTOR_BY_EVENT = {
647
+ created: "designer",
648
+ acknowledged: "developer",
649
+ fix_claimed: "agent",
650
+ verified: "developer",
651
+ rejected: "developer",
652
+ dismissed: "developer",
653
+ reopened: "developer",
654
+ migrated: null
655
+ };
656
+ function createEvent(type, opts = {}) {
657
+ var _a, _b;
658
+ const event = {
659
+ type,
660
+ actor: (_a = opts.actor) != null ? _a : DEFAULT_ACTOR_BY_EVENT[type],
661
+ timestamp: (_b = opts.timestamp) != null ? _b : Date.now()
662
+ };
663
+ if (opts.actorName !== void 0) event.actorName = opts.actorName;
664
+ if (opts.reason !== void 0) event.reason = opts.reason;
665
+ return event;
666
+ }
667
+ function nextStatus(from, action) {
668
+ switch (action) {
669
+ case "acknowledge":
670
+ return from === "pending" ? "in_progress" : null;
671
+ case "claimFix":
672
+ return from === "pending" || from === "in_progress" ? "fixed_unverified" : null;
673
+ case "verify":
674
+ return from === "fixed_unverified" || from === "in_progress" ? "verified" : null;
675
+ case "reject":
676
+ return from === "fixed_unverified" ? "pending" : null;
677
+ case "dismiss":
678
+ return from === "pending" || from === "in_progress" || from === "fixed_unverified" ? "dismissed" : null;
679
+ case "reopen":
680
+ return from === "dismissed" || from === "verified" ? "pending" : null;
681
+ }
682
+ }
683
+ function transition(annotation, action, opts = {}) {
684
+ const next = nextStatus(annotation.status, action);
685
+ if (next === null) {
686
+ throw new InvalidTransitionError(annotation.status, action);
687
+ }
688
+ const event = createEvent(ACTION_TO_EVENT[action], opts);
689
+ return { status: next, event };
690
+ }
544
691
  // Annotate the CommonJS export names for ESM import in node:
545
692
  0 && (module.exports = {
546
693
  AnnotationStorage,
694
+ InvalidTransitionError,
695
+ LocalStorageAdapter,
696
+ createEvent,
547
697
  createFingerprint,
548
698
  detectRemarqPlugin,
549
699
  detectSource,
550
700
  generateAgentExport,
551
- matchElement
701
+ matchElement,
702
+ migrateAnnotation,
703
+ transition
552
704
  });
553
705
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/index.ts","../../src/core/hash-detect.ts","../../src/core/source-detect.ts","../../src/core/fingerprint.ts","../../src/core/matcher.ts","../../src/core/viewport.ts","../../src/core/storage.ts","../../src/core/agent-export.ts"],"sourcesContent":["export type { Annotation, AnnotationStore, ElementFingerprint, CSSModuleClass, SourceDetectionResult, SearchConfidence, GrepQuery, AgentSearchHints, AgentAnnotationSource, AgentAnnotation, AgentExport, ToolbarPosition } from './types'\nexport { createFingerprint } from './fingerprint'\nexport { matchElement } from './matcher'\nexport { AnnotationStorage } from './storage'\nexport { detectRemarqPlugin, detectSource } from './source-detect'\nexport { generateAgentExport } from './agent-export'\n","import type { CSSModuleClass } from './types'\n\nconst CSS_MODULES_RE = /^(.+)__([a-zA-Z0-9]{3,})$/\nconst CSS_MODULES_3SEG_RE = /^([^_]+(?:[_-][^_]+)*)__([a-zA-Z][a-zA-Z0-9]*)__([a-zA-Z0-9]{3,})$/\nconst STYLED_COMPONENTS_RE = /^sc-/\nconst EMOTION_RE = /^css-[a-zA-Z0-9]+$/\nconst PURE_HASH_RE = /^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z0-9]{8,}$/\n\nexport function isHashedClass(className: string): boolean {\n if (STYLED_COMPONENTS_RE.test(className)) return true\n if (EMOTION_RE.test(className)) return true\n if (CSS_MODULES_RE.test(className)) return true\n if (PURE_HASH_RE.test(className)) return true\n return false\n}\n\nexport function stripHash(className: string): string {\n const match = className.match(CSS_MODULES_RE)\n if (match) {\n const prefix = className.slice(0, className.lastIndexOf('__'))\n return prefix\n }\n return className\n}\n\nexport function filterClasses(\n classes: string[],\n classFilter?: (className: string) => boolean,\n): string[] {\n const result: string[] = []\n\n for (const cls of classes) {\n if (STYLED_COMPONENTS_RE.test(cls)) continue\n if (EMOTION_RE.test(cls)) continue\n if (PURE_HASH_RE.test(cls)) continue\n\n let stable = stripHash(cls)\n\n if (classFilter && !classFilter(stable)) continue\n\n result.push(stable)\n }\n\n return result\n}\n\nexport function decomposeCSSModules(classes: string[]): CSSModuleClass[] {\n const result: CSSModuleClass[] = []\n for (const cls of classes) {\n const match = cls.match(CSS_MODULES_3SEG_RE)\n if (match) {\n result.push({\n raw: cls,\n moduleHint: match[1],\n localName: match[2],\n })\n }\n }\n return result\n}\n","import type { SourceDetectionResult } from './types'\n\n/**\n * Level 1: Read data-remarq-source/data-remarq-component attrs\n * injected by @web-remarq/babel-plugin or @web-remarq/unplugin.\n */\nexport function detectRemarqPlugin(el: HTMLElement): SourceDetectionResult {\n const source = el.getAttribute('data-remarq-source')\n if (!source) return { source: null, component: null }\n return {\n source,\n component: el.getAttribute('data-remarq-component'),\n }\n}\n\n/**\n * Level 2a: Read data-source or data-locator attrs\n * from locator.js or similar external tools.\n */\nexport function detectExternalSource(el: HTMLElement): SourceDetectionResult {\n const source = el.dataset.source ?? el.getAttribute('data-locator')\n if (!source) return { source: null, component: null }\n return { source, component: null }\n}\n\n/**\n * Level 2b: Read React fiber _debugSource (dev mode only).\n * Unstable/best-effort — React internals are not public API.\n * Walks up the fiber tree because _debugSource lives on component fibers,\n * not on host (DOM element) fibers.\n */\nexport function detectReactFiber(el: HTMLElement): SourceDetectionResult {\n const key = Object.keys(el).find(k => k.startsWith('__reactFiber$'))\n if (!key) return { source: null, component: null }\n\n let current = (el as unknown as Record<string, unknown>)[key] as Record<string, unknown> | null\n // Walk up fiber tree to find nearest fiber with _debugSource (max 15 levels)\n let depth = 0\n while (current && depth < 15) {\n const debugSource = current._debugSource as { fileName?: string; lineNumber?: number; columnNumber?: number } | undefined\n if (debugSource?.fileName) {\n const source = `${debugSource.fileName}:${debugSource.lineNumber ?? 0}:${debugSource.columnNumber ?? 0}`\n\n // Try to get component name from fiber.type\n const fiberType = current.type as { displayName?: string; name?: string } | string | undefined\n const component = typeof fiberType === 'object' && fiberType\n ? (fiberType.displayName ?? fiberType.name ?? null)\n : null\n\n return { source, component }\n }\n current = current.return as Record<string, unknown> | null\n depth++\n }\n\n return { source: null, component: null }\n}\n\n/**\n * Runs Level 2 detectors in order. Returns first non-null result.\n */\nexport function detectSource(el: HTMLElement): SourceDetectionResult {\n const external = detectExternalSource(el)\n if (external.source) return external\n\n const fiber = detectReactFiber(el)\n if (fiber.source) return fiber\n\n return { source: null, component: null }\n}\n","import type { ElementFingerprint, WebRemarqOptions } from './types'\nimport { filterClasses, isHashedClass, decomposeCSSModules } from './hash-detect'\nimport { detectRemarqPlugin, detectSource } from './source-detect'\n\nconst TEXT_MAX_LENGTH = 50\n\nexport function createFingerprint(\n el: HTMLElement,\n options?: Pick<WebRemarqOptions, 'classFilter' | 'dataAttribute'>,\n): ElementFingerprint {\n const dataAttr = options?.dataAttribute ?? 'data-annotate'\n\n return {\n dataAnnotate: el.getAttribute(dataAttr) ?? null,\n dataTestId: el.getAttribute('data-testid')\n ?? el.getAttribute('data-test')\n ?? el.getAttribute('data-cy')\n ?? null,\n id: getStableId(el),\n tagName: el.tagName.toLowerCase(),\n textContent: getTextContent(el),\n role: el.getAttribute('role') ?? null,\n ariaLabel: el.getAttribute('aria-label') ?? null,\n stableClasses: filterClasses(\n Array.from(el.classList),\n options?.classFilter,\n ),\n domPath: buildDomPath(el),\n siblingIndex: getSiblingIndex(el),\n parentAnchor: findParentAnchor(el, dataAttr),\n rawClasses: Array.from(el.classList),\n cssModules: decomposeCSSModules(Array.from(el.classList)),\n ...resolveSourceFields(el),\n }\n}\n\nfunction resolveSourceFields(el: HTMLElement): {\n sourceLocation: string | null\n componentName: string | null\n detectedSource: string | null\n detectedComponent: string | null\n} {\n const plugin = detectRemarqPlugin(el)\n if (plugin.source) {\n return {\n sourceLocation: plugin.source,\n componentName: plugin.component,\n detectedSource: null,\n detectedComponent: null,\n }\n }\n\n const detected = detectSource(el)\n return {\n sourceLocation: null,\n componentName: null,\n detectedSource: detected.source,\n detectedComponent: detected.component,\n }\n}\n\nfunction getStableId(el: HTMLElement): string | null {\n const id = el.id\n if (!id) return null\n if (isHashedClass(id)) return null\n return id\n}\n\nfunction getTextContent(el: HTMLElement): string | null {\n // Use only direct text nodes, not nested children's text\n let text = ''\n for (const node of Array.from(el.childNodes)) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent ?? ''\n }\n }\n text = text.trim()\n\n // If no direct text, try first meaningful child's text (for wrappers like <span><b>Text</b></span>)\n if (!text && el.children.length <= 3) {\n text = el.textContent?.trim() ?? ''\n }\n\n if (!text) return null\n return text.length > TEXT_MAX_LENGTH ? text.slice(0, TEXT_MAX_LENGTH) : text\n}\n\nfunction buildDomPath(el: HTMLElement): string {\n const parts: string[] = []\n let current: HTMLElement | null = el\n\n while (current && current !== document.body && parts.length < 5) {\n let segment = current.tagName.toLowerCase()\n const stable = filterClasses(Array.from(current.classList))\n if (stable.length > 0) {\n segment += '.' + stable.slice(0, 2).join('.')\n }\n parts.unshift(segment)\n current = current.parentElement\n }\n\n return parts.join(' > ')\n}\n\nfunction getSiblingIndex(el: HTMLElement): number {\n const parent = el.parentElement\n if (!parent) return 0\n const children = Array.from(parent.children)\n return children.indexOf(el)\n}\n\nfunction findParentAnchor(el: HTMLElement, dataAttr: string): string | null {\n let current = el.parentElement\n while (current && current !== document.body) {\n const value = current.getAttribute(dataAttr)\n if (value) return value\n current = current.parentElement\n }\n return null\n}\n","import type { ElementFingerprint, WebRemarqOptions } from './types'\nimport { filterClasses } from './hash-detect'\n\nconst MATCH_THRESHOLD = 50\n\nexport function levenshteinSimilarity(a: string, b: string): number {\n if (a === b) return 1\n if (!a.length || !b.length) return 0\n\n const matrix: number[][] = []\n for (let i = 0; i <= a.length; i++) {\n matrix[i] = [i]\n }\n for (let j = 0; j <= b.length; j++) {\n matrix[0][j] = j\n }\n\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1\n matrix[i][j] = Math.min(\n matrix[i - 1][j] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j - 1] + cost,\n )\n }\n }\n\n const distance = matrix[a.length][b.length]\n return 1 - distance / Math.max(a.length, b.length)\n}\n\nfunction textSimilarity(a: string | null, b: string | null): number {\n if (!a || !b) return 0\n const na = a.trim().toLowerCase()\n const nb = b.trim().toLowerCase()\n if (na === nb) return 1\n if (na.includes(nb) || nb.includes(na)) return 1\n return levenshteinSimilarity(na, nb)\n}\n\nfunction jaccardSimilarity(a: string[], b: string[]): number {\n if (!a.length && !b.length) return 0\n const setA = new Set(a)\n const setB = new Set(b)\n let intersection = 0\n for (const item of setA) {\n if (setB.has(item)) intersection++\n }\n const union = new Set([...a, ...b]).size\n return union === 0 ? 0 : intersection / union\n}\n\nfunction scoreCandidate(el: HTMLElement, fp: ElementFingerprint, dataAttr: string): number {\n let score = 0\n\n // dataAnnotate match (+100)\n const elAnnotate = el.getAttribute(dataAttr)\n if (fp.dataAnnotate && elAnnotate === fp.dataAnnotate) {\n score += 100\n }\n\n // textContent match (+35 scaled)\n const elText = el.textContent?.trim().slice(0, 50) ?? null\n const textSim = textSimilarity(fp.textContent, elText)\n if (textSim > 0.7) {\n score += textSim * 35\n }\n\n // role + ariaLabel match (+30)\n if (fp.role && el.getAttribute('role') === fp.role &&\n fp.ariaLabel && el.getAttribute('aria-label') === fp.ariaLabel) {\n score += 30\n }\n\n // parentAnchor match (+15)\n if (fp.parentAnchor) {\n let parent = el.parentElement\n while (parent && parent !== document.body) {\n if (parent.getAttribute(dataAttr) === fp.parentAnchor) {\n score += 15\n break\n }\n parent = parent.parentElement\n }\n }\n\n // stableClasses overlap (+30 scaled)\n if (fp.stableClasses.length > 0) {\n const elClasses = filterClasses(Array.from(el.classList))\n const jaccard = jaccardSimilarity(fp.stableClasses, elClasses)\n score += jaccard * 30\n }\n\n // domPath match (+20 scaled)\n if (fp.domPath) {\n const elPath = buildDomPath(el)\n const pathSim = levenshteinSimilarity(fp.domPath, elPath)\n score += pathSim * 20\n }\n\n // siblingIndex match (+5)\n const parent = el.parentElement\n if (parent) {\n const idx = Array.from(parent.children).indexOf(el)\n if (idx === fp.siblingIndex) {\n score += 5\n }\n }\n\n return score\n}\n\nfunction buildDomPath(el: HTMLElement): string {\n const parts: string[] = []\n let current: HTMLElement | null = el\n while (current && current !== document.body && parts.length < 5) {\n let segment = current.tagName.toLowerCase()\n const stable = filterClasses(Array.from(current.classList))\n if (stable.length > 0) {\n segment += '.' + stable.slice(0, 2).join('.')\n }\n parts.unshift(segment)\n current = current.parentElement\n }\n return parts.join(' > ')\n}\n\nexport function matchElement(\n fp: ElementFingerprint,\n options?: Pick<WebRemarqOptions, 'dataAttribute'>,\n): HTMLElement | null {\n const dataAttr = options?.dataAttribute ?? 'data-annotate'\n\n // 1. Exact match by data-annotate\n if (fp.dataAnnotate) {\n const el = document.querySelector<HTMLElement>(`[${dataAttr}=\"${fp.dataAnnotate}\"]`)\n if (el) return el\n }\n\n // 2. Exact match by data-testid\n if (fp.dataTestId) {\n const el = document.querySelector<HTMLElement>(\n `[data-testid=\"${fp.dataTestId}\"], [data-test=\"${fp.dataTestId}\"], [data-cy=\"${fp.dataTestId}\"]`,\n )\n if (el) return el\n }\n\n // 3. Exact match by id\n if (fp.id) {\n const el = document.getElementById(fp.id) as HTMLElement | null\n if (el) return el\n }\n\n // 4. Fuzzy match by tagName + weighted scoring\n const candidates = document.querySelectorAll<HTMLElement>(fp.tagName)\n let bestEl: HTMLElement | null = null\n let bestScore = 0\n\n for (const candidate of candidates) {\n const score = scoreCandidate(candidate, fp, dataAttr)\n if (score > bestScore) {\n bestScore = score\n bestEl = candidate\n }\n }\n\n return bestScore >= MATCH_THRESHOLD ? bestEl : null\n}\n","type BucketChangeCallback = () => void\n\nlet currentBucket: number = 0\nlet onBucketChange: BucketChangeCallback | null = null\nlet resizeHandler: (() => void) | null = null\n\nexport function toBucket(width: number): number {\n return Math.floor(width / 100) * 100\n}\n\nfunction debounce(fn: () => void, ms: number): () => void {\n let timer: ReturnType<typeof setTimeout>\n return () => {\n clearTimeout(timer)\n timer = setTimeout(fn, ms)\n }\n}\n\nexport function initViewportListener(callback: BucketChangeCallback): void {\n currentBucket = toBucket(window.innerWidth)\n onBucketChange = callback\n\n resizeHandler = debounce(() => {\n const newBucket = toBucket(window.innerWidth)\n if (newBucket !== currentBucket) {\n currentBucket = newBucket\n onBucketChange?.()\n }\n }, 300)\n\n window.addEventListener('resize', resizeHandler)\n}\n\nexport function destroyViewportListener(): void {\n if (resizeHandler) {\n window.removeEventListener('resize', resizeHandler)\n resizeHandler = null\n }\n onBucketChange = null\n}\n","import type { Annotation, AnnotationStore } from './types'\nimport { toBucket } from './viewport'\n\nconst STORAGE_KEY = 'remarq:annotations'\n\nexport class AnnotationStorage {\n private annotations: Annotation[] = []\n private extraFields: Record<string, unknown> = {}\n isMemoryOnly = false\n\n constructor() {\n this.load()\n }\n\n getAll(): Annotation[] {\n return [...this.annotations]\n }\n\n getByRoute(route: string): Annotation[] {\n return this.annotations.filter((a) => a.route === route)\n }\n\n add(annotation: Annotation): void {\n this.annotations.push(annotation)\n this.save()\n }\n\n remove(id: string): void {\n this.annotations = this.annotations.filter((a) => a.id !== id)\n this.save()\n }\n\n update(id: string, changes: Partial<Annotation>): void {\n const idx = this.annotations.findIndex((a) => a.id === id)\n if (idx !== -1) {\n this.annotations[idx] = { ...this.annotations[idx], ...changes }\n this.save()\n }\n }\n\n clearAll(): void {\n this.annotations = []\n this.save()\n }\n\n exportJSON(): AnnotationStore {\n return {\n version: 1,\n annotations: [...this.annotations],\n }\n }\n\n importJSON(data: AnnotationStore): void {\n this.annotations = [...data.annotations]\n this.migrateViewportBuckets()\n this.save()\n }\n\n private migrateViewportBuckets(): void {\n for (const ann of this.annotations) {\n if (ann.viewportBucket == null && ann.viewport) {\n const width = parseInt(ann.viewport.split('x')[0], 10)\n ann.viewportBucket = toBucket(width)\n }\n }\n }\n\n private load(): void {\n try {\n const raw = localStorage.getItem(STORAGE_KEY)\n if (raw) {\n const parsed = JSON.parse(raw)\n const { version, annotations, ...rest } = parsed\n this.annotations = annotations ?? []\n this.extraFields = rest\n this.migrateViewportBuckets()\n }\n } catch {\n this.isMemoryOnly = true\n }\n }\n\n private save(): void {\n if (this.isMemoryOnly) return\n try {\n const data = {\n version: 1,\n ...this.extraFields,\n annotations: this.annotations,\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data))\n } catch {\n this.isMemoryOnly = true\n }\n }\n}\n","import type {\n Annotation,\n AgentExport,\n AgentAnnotation,\n AgentAnnotationSource,\n AgentSearchHints,\n GrepQuery,\n ElementFingerprint,\n} from './types'\n\nfunction parseSourceLocation(raw: string): { file: string; line: number; column: number } | null {\n const parts = raw.split(':')\n if (parts.length < 2) return null\n // file path may contain \":\" on Windows (C:\\...), so rejoin all but last 2\n const column = parseInt(parts.pop()!, 10)\n const line = parseInt(parts.pop()!, 10)\n const file = parts.join(':')\n if (!file || isNaN(line)) return null\n return { file, line, column: isNaN(column) ? 0 : column }\n}\n\nfunction resolveSource(fp: ElementFingerprint): AgentAnnotationSource | null {\n // Level 1: plugin source\n if (fp.sourceLocation) {\n const parsed = parseSourceLocation(fp.sourceLocation)\n if (parsed) return { ...parsed, component: fp.componentName ?? null }\n }\n\n // Level 2: detected source\n if (fp.detectedSource) {\n const parsed = parseSourceLocation(fp.detectedSource)\n if (parsed) return { ...parsed, component: fp.detectedComponent ?? null }\n }\n\n return null\n}\n\nconst TEMPLATE_GLOB = '*.{tsx,jsx,vue,svelte,html}'\nconst CSS_MODULE_GLOB = '*.module.{css,scss,less}'\nconst COMPONENT_GLOB = '*.{tsx,jsx,vue,ts,js}'\n\nfunction buildSearchHints(fp: ElementFingerprint): AgentSearchHints {\n const grepQueries: GrepQuery[] = []\n\n // High confidence — unique selectors\n if (fp.dataAnnotate) {\n grepQueries.push({ query: `data-annotate=\"${fp.dataAnnotate}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n if (fp.dataTestId) {\n grepQueries.push({ query: `data-testid=\"${fp.dataTestId}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n if (fp.id) {\n grepQueries.push({ query: `id=\"${fp.id}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n if (fp.ariaLabel) {\n grepQueries.push({ query: `aria-label=\"${fp.ariaLabel}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n\n // Medium confidence — text, CSS modules, role\n if (fp.textContent) {\n grepQueries.push({ query: `\"${fp.textContent}\"`, glob: TEMPLATE_GLOB, confidence: 'medium' })\n }\n if (fp.role) {\n grepQueries.push({ query: `role=\"${fp.role}\"`, glob: TEMPLATE_GLOB, confidence: 'medium' })\n }\n if (fp.cssModules?.length) {\n for (const mod of fp.cssModules) {\n grepQueries.push({ query: `.${mod.localName}`, glob: CSS_MODULE_GLOB, confidence: 'medium' })\n grepQueries.push({ query: `styles.${mod.localName}`, glob: COMPONENT_GLOB, confidence: 'medium' })\n }\n }\n\n // Low confidence — classes, domPath\n if (fp.stableClasses.length) {\n for (const cls of fp.stableClasses.slice(0, 3)) {\n grepQueries.push({ query: `\"${cls}\"`, glob: TEMPLATE_GLOB, confidence: 'low' })\n }\n }\n\n return {\n grepQueries,\n domContext: fp.domPath,\n tagName: fp.tagName,\n classes: fp.rawClasses ?? fp.stableClasses,\n }\n}\n\nexport function generateAgentExport(annotations: Annotation[], viewportBucket: number): AgentExport {\n const agentAnnotations: AgentAnnotation[] = annotations.map(ann => ({\n id: ann.id,\n route: ann.route,\n comment: ann.comment,\n status: ann.status,\n timestamp: ann.timestamp,\n source: resolveSource(ann.fingerprint),\n searchHints: buildSearchHints(ann.fingerprint),\n }))\n\n return {\n version: 1,\n format: 'agent',\n viewportBucket,\n annotations: agentAnnotations,\n }\n}\n"],"mappings":"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","names":["parent","buildDomPath"]}
1
+ {"version":3,"sources":["../../src/core/index.ts","../../src/core/hash-detect.ts","../../src/core/source-detect.ts","../../src/core/fingerprint.ts","../../src/core/matcher.ts","../../src/core/viewport.ts","../../src/core/storage.ts","../../src/core/local-storage-adapter.ts","../../src/core/agent-export.ts","../../src/core/lifecycle.ts"],"sourcesContent":["export type {\n Annotation,\n AnnotationStatus,\n AnnotationEvent,\n AnnotationEventType,\n Actor,\n AnnotationStore,\n ElementFingerprint,\n CSSModuleClass,\n SourceDetectionResult,\n SearchConfidence,\n GrepQuery,\n AgentSearchHints,\n AgentAnnotationSource,\n AgentAnnotation,\n AgentLifecycleEvent,\n AgentExport,\n ToolbarPosition,\n StorageAdapter,\n StorageChangeEvent,\n} from './types'\nexport { createFingerprint } from './fingerprint'\nexport { matchElement } from './matcher'\nexport { AnnotationStorage, migrateAnnotation } from './storage'\nexport { LocalStorageAdapter } from './local-storage-adapter'\nexport { detectRemarqPlugin, detectSource } from './source-detect'\nexport { generateAgentExport } from './agent-export'\nexport { transition, createEvent, InvalidTransitionError } from './lifecycle'\nexport type { LifecycleAction, EventOpts } from './lifecycle'\n","import type { CSSModuleClass } from './types'\n\nconst CSS_MODULES_RE = /^(.+)__([a-zA-Z0-9]{3,})$/\nconst CSS_MODULES_3SEG_RE = /^([^_]+(?:[_-][^_]+)*)__([a-zA-Z][a-zA-Z0-9]*)__([a-zA-Z0-9]{3,})$/\nconst STYLED_COMPONENTS_RE = /^sc-/\nconst EMOTION_RE = /^css-[a-zA-Z0-9]+$/\nconst PURE_HASH_RE = /^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z0-9]{8,}$/\n\nexport function isHashedClass(className: string): boolean {\n if (STYLED_COMPONENTS_RE.test(className)) return true\n if (EMOTION_RE.test(className)) return true\n if (CSS_MODULES_RE.test(className)) return true\n if (PURE_HASH_RE.test(className)) return true\n return false\n}\n\nexport function stripHash(className: string): string {\n const match = className.match(CSS_MODULES_RE)\n if (match) {\n const prefix = className.slice(0, className.lastIndexOf('__'))\n return prefix\n }\n return className\n}\n\nexport function filterClasses(\n classes: string[],\n classFilter?: (className: string) => boolean,\n): string[] {\n const result: string[] = []\n\n for (const cls of classes) {\n if (STYLED_COMPONENTS_RE.test(cls)) continue\n if (EMOTION_RE.test(cls)) continue\n if (PURE_HASH_RE.test(cls)) continue\n\n let stable = stripHash(cls)\n\n if (classFilter && !classFilter(stable)) continue\n\n result.push(stable)\n }\n\n return result\n}\n\nexport function decomposeCSSModules(classes: string[]): CSSModuleClass[] {\n const result: CSSModuleClass[] = []\n for (const cls of classes) {\n const match = cls.match(CSS_MODULES_3SEG_RE)\n if (match) {\n result.push({\n raw: cls,\n moduleHint: match[1],\n localName: match[2],\n })\n }\n }\n return result\n}\n","import type { SourceDetectionResult } from './types'\n\n/**\n * Level 1: Read data-remarq-source/data-remarq-component attrs\n * injected by @web-remarq/babel-plugin or @web-remarq/unplugin.\n */\nexport function detectRemarqPlugin(el: HTMLElement): SourceDetectionResult {\n const source = el.getAttribute('data-remarq-source')\n if (!source) return { source: null, component: null }\n return {\n source,\n component: el.getAttribute('data-remarq-component'),\n }\n}\n\n/**\n * Level 2a: Read data-source or data-locator attrs\n * from locator.js or similar external tools.\n */\nexport function detectExternalSource(el: HTMLElement): SourceDetectionResult {\n const source = el.dataset.source ?? el.getAttribute('data-locator')\n if (!source) return { source: null, component: null }\n return { source, component: null }\n}\n\n/**\n * Level 2b: Read React fiber _debugSource (dev mode only).\n * Unstable/best-effort — React internals are not public API.\n * Walks up the fiber tree because _debugSource lives on component fibers,\n * not on host (DOM element) fibers.\n */\nexport function detectReactFiber(el: HTMLElement): SourceDetectionResult {\n const key = Object.keys(el).find(k => k.startsWith('__reactFiber$'))\n if (!key) return { source: null, component: null }\n\n let current = (el as unknown as Record<string, unknown>)[key] as Record<string, unknown> | null\n // Walk up fiber tree to find nearest fiber with _debugSource (max 15 levels)\n let depth = 0\n while (current && depth < 15) {\n const debugSource = current._debugSource as { fileName?: string; lineNumber?: number; columnNumber?: number } | undefined\n if (debugSource?.fileName) {\n const source = `${debugSource.fileName}:${debugSource.lineNumber ?? 0}:${debugSource.columnNumber ?? 0}`\n\n // Try to get component name from fiber.type\n const fiberType = current.type as { displayName?: string; name?: string } | string | undefined\n const component = typeof fiberType === 'object' && fiberType\n ? (fiberType.displayName ?? fiberType.name ?? null)\n : null\n\n return { source, component }\n }\n current = current.return as Record<string, unknown> | null\n depth++\n }\n\n return { source: null, component: null }\n}\n\n/**\n * Runs Level 2 detectors in order. Returns first non-null result.\n */\nexport function detectSource(el: HTMLElement): SourceDetectionResult {\n const external = detectExternalSource(el)\n if (external.source) return external\n\n const fiber = detectReactFiber(el)\n if (fiber.source) return fiber\n\n return { source: null, component: null }\n}\n","import type { ElementFingerprint, WebRemarqOptions } from './types'\nimport { filterClasses, isHashedClass, decomposeCSSModules } from './hash-detect'\nimport { detectRemarqPlugin, detectSource } from './source-detect'\n\nconst TEXT_MAX_LENGTH = 50\n\nexport function createFingerprint(\n el: HTMLElement,\n options?: Pick<WebRemarqOptions, 'classFilter' | 'dataAttribute'>,\n): ElementFingerprint {\n const dataAttr = options?.dataAttribute ?? 'data-annotate'\n\n return {\n dataAnnotate: el.getAttribute(dataAttr) ?? null,\n dataTestId: el.getAttribute('data-testid')\n ?? el.getAttribute('data-test')\n ?? el.getAttribute('data-cy')\n ?? null,\n id: getStableId(el),\n tagName: el.tagName.toLowerCase(),\n textContent: getTextContent(el),\n role: el.getAttribute('role') ?? null,\n ariaLabel: el.getAttribute('aria-label') ?? null,\n stableClasses: filterClasses(\n Array.from(el.classList),\n options?.classFilter,\n ),\n domPath: buildDomPath(el),\n siblingIndex: getSiblingIndex(el),\n parentAnchor: findParentAnchor(el, dataAttr),\n rawClasses: Array.from(el.classList),\n cssModules: decomposeCSSModules(Array.from(el.classList)),\n ...resolveSourceFields(el),\n }\n}\n\nfunction resolveSourceFields(el: HTMLElement): {\n sourceLocation: string | null\n componentName: string | null\n detectedSource: string | null\n detectedComponent: string | null\n} {\n const plugin = detectRemarqPlugin(el)\n if (plugin.source) {\n return {\n sourceLocation: plugin.source,\n componentName: plugin.component,\n detectedSource: null,\n detectedComponent: null,\n }\n }\n\n const detected = detectSource(el)\n return {\n sourceLocation: null,\n componentName: null,\n detectedSource: detected.source,\n detectedComponent: detected.component,\n }\n}\n\nfunction getStableId(el: HTMLElement): string | null {\n const id = el.id\n if (!id) return null\n if (isHashedClass(id)) return null\n return id\n}\n\nfunction getTextContent(el: HTMLElement): string | null {\n // Use only direct text nodes, not nested children's text\n let text = ''\n for (const node of Array.from(el.childNodes)) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent ?? ''\n }\n }\n text = text.trim()\n\n // If no direct text, try first meaningful child's text (for wrappers like <span><b>Text</b></span>)\n if (!text && el.children.length <= 3) {\n text = el.textContent?.trim() ?? ''\n }\n\n if (!text) return null\n return text.length > TEXT_MAX_LENGTH ? text.slice(0, TEXT_MAX_LENGTH) : text\n}\n\nfunction buildDomPath(el: HTMLElement): string {\n const parts: string[] = []\n let current: HTMLElement | null = el\n\n while (current && current !== document.body && parts.length < 5) {\n let segment = current.tagName.toLowerCase()\n const stable = filterClasses(Array.from(current.classList))\n if (stable.length > 0) {\n segment += '.' + stable.slice(0, 2).join('.')\n }\n parts.unshift(segment)\n current = current.parentElement\n }\n\n return parts.join(' > ')\n}\n\nfunction getSiblingIndex(el: HTMLElement): number {\n const parent = el.parentElement\n if (!parent) return 0\n const children = Array.from(parent.children)\n return children.indexOf(el)\n}\n\nfunction findParentAnchor(el: HTMLElement, dataAttr: string): string | null {\n let current = el.parentElement\n while (current && current !== document.body) {\n const value = current.getAttribute(dataAttr)\n if (value) return value\n current = current.parentElement\n }\n return null\n}\n","import type { ElementFingerprint, WebRemarqOptions } from './types'\nimport { filterClasses } from './hash-detect'\n\nconst MATCH_THRESHOLD = 50\n\nexport function levenshteinSimilarity(a: string, b: string): number {\n if (a === b) return 1\n if (!a.length || !b.length) return 0\n\n const matrix: number[][] = []\n for (let i = 0; i <= a.length; i++) {\n matrix[i] = [i]\n }\n for (let j = 0; j <= b.length; j++) {\n matrix[0][j] = j\n }\n\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1\n matrix[i][j] = Math.min(\n matrix[i - 1][j] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j - 1] + cost,\n )\n }\n }\n\n const distance = matrix[a.length][b.length]\n return 1 - distance / Math.max(a.length, b.length)\n}\n\nfunction textSimilarity(a: string | null, b: string | null): number {\n if (!a || !b) return 0\n const na = a.trim().toLowerCase()\n const nb = b.trim().toLowerCase()\n if (na === nb) return 1\n if (na.includes(nb) || nb.includes(na)) return 1\n return levenshteinSimilarity(na, nb)\n}\n\nfunction jaccardSimilarity(a: string[], b: string[]): number {\n if (!a.length && !b.length) return 0\n const setA = new Set(a)\n const setB = new Set(b)\n let intersection = 0\n for (const item of setA) {\n if (setB.has(item)) intersection++\n }\n const union = new Set([...a, ...b]).size\n return union === 0 ? 0 : intersection / union\n}\n\nfunction scoreCandidate(el: HTMLElement, fp: ElementFingerprint, dataAttr: string): number {\n let score = 0\n\n // dataAnnotate match (+100)\n const elAnnotate = el.getAttribute(dataAttr)\n if (fp.dataAnnotate && elAnnotate === fp.dataAnnotate) {\n score += 100\n }\n\n // textContent match (+35 scaled)\n const elText = el.textContent?.trim().slice(0, 50) ?? null\n const textSim = textSimilarity(fp.textContent, elText)\n if (textSim > 0.7) {\n score += textSim * 35\n }\n\n // role + ariaLabel match (+30)\n if (fp.role && el.getAttribute('role') === fp.role &&\n fp.ariaLabel && el.getAttribute('aria-label') === fp.ariaLabel) {\n score += 30\n }\n\n // parentAnchor match (+15)\n if (fp.parentAnchor) {\n let parent = el.parentElement\n while (parent && parent !== document.body) {\n if (parent.getAttribute(dataAttr) === fp.parentAnchor) {\n score += 15\n break\n }\n parent = parent.parentElement\n }\n }\n\n // stableClasses overlap (+30 scaled)\n if (fp.stableClasses.length > 0) {\n const elClasses = filterClasses(Array.from(el.classList))\n const jaccard = jaccardSimilarity(fp.stableClasses, elClasses)\n score += jaccard * 30\n }\n\n // domPath match (+20 scaled)\n if (fp.domPath) {\n const elPath = buildDomPath(el)\n const pathSim = levenshteinSimilarity(fp.domPath, elPath)\n score += pathSim * 20\n }\n\n // siblingIndex match (+5)\n const parent = el.parentElement\n if (parent) {\n const idx = Array.from(parent.children).indexOf(el)\n if (idx === fp.siblingIndex) {\n score += 5\n }\n }\n\n return score\n}\n\nfunction buildDomPath(el: HTMLElement): string {\n const parts: string[] = []\n let current: HTMLElement | null = el\n while (current && current !== document.body && parts.length < 5) {\n let segment = current.tagName.toLowerCase()\n const stable = filterClasses(Array.from(current.classList))\n if (stable.length > 0) {\n segment += '.' + stable.slice(0, 2).join('.')\n }\n parts.unshift(segment)\n current = current.parentElement\n }\n return parts.join(' > ')\n}\n\nexport function matchElement(\n fp: ElementFingerprint,\n options?: Pick<WebRemarqOptions, 'dataAttribute'>,\n): HTMLElement | null {\n const dataAttr = options?.dataAttribute ?? 'data-annotate'\n\n // 1. Exact match by data-annotate\n if (fp.dataAnnotate) {\n const el = document.querySelector<HTMLElement>(`[${dataAttr}=\"${fp.dataAnnotate}\"]`)\n if (el) return el\n }\n\n // 2. Exact match by data-testid\n if (fp.dataTestId) {\n const el = document.querySelector<HTMLElement>(\n `[data-testid=\"${fp.dataTestId}\"], [data-test=\"${fp.dataTestId}\"], [data-cy=\"${fp.dataTestId}\"]`,\n )\n if (el) return el\n }\n\n // 3. Exact match by id\n if (fp.id) {\n const el = document.getElementById(fp.id) as HTMLElement | null\n if (el) return el\n }\n\n // 4. Fuzzy match by tagName + weighted scoring\n const candidates = document.querySelectorAll<HTMLElement>(fp.tagName)\n let bestEl: HTMLElement | null = null\n let bestScore = 0\n\n for (const candidate of candidates) {\n const score = scoreCandidate(candidate, fp, dataAttr)\n if (score > bestScore) {\n bestScore = score\n bestEl = candidate\n }\n }\n\n return bestScore >= MATCH_THRESHOLD ? bestEl : null\n}\n","type BucketChangeCallback = () => void\n\nlet currentBucket: number = 0\nlet onBucketChange: BucketChangeCallback | null = null\nlet resizeHandler: (() => void) | null = null\n\nexport function toBucket(width: number): number {\n return Math.floor(width / 100) * 100\n}\n\nfunction debounce(fn: () => void, ms: number): () => void {\n let timer: ReturnType<typeof setTimeout>\n return () => {\n clearTimeout(timer)\n timer = setTimeout(fn, ms)\n }\n}\n\nexport function initViewportListener(callback: BucketChangeCallback): void {\n currentBucket = toBucket(window.innerWidth)\n onBucketChange = callback\n\n resizeHandler = debounce(() => {\n const newBucket = toBucket(window.innerWidth)\n if (newBucket !== currentBucket) {\n currentBucket = newBucket\n onBucketChange?.()\n }\n }, 300)\n\n window.addEventListener('resize', resizeHandler)\n}\n\nexport function destroyViewportListener(): void {\n if (resizeHandler) {\n window.removeEventListener('resize', resizeHandler)\n resizeHandler = null\n }\n onBucketChange = null\n}\n","import type { Annotation, AnnotationEvent, AnnotationStatus, AnnotationStore, StorageAdapter } from './types'\nimport { toBucket } from './viewport'\n\nexport function migrateAnnotation(legacy: any): Annotation {\n const rawStatus = legacy.status\n const status: AnnotationStatus =\n rawStatus === 'resolved' ? 'verified' : rawStatus\n\n if (Array.isArray(legacy.lifecycle) && legacy.lifecycle.length > 0) {\n return { ...legacy, status, lifecycle: legacy.lifecycle }\n }\n\n const createdTs = typeof legacy.timestamp === 'number' ? legacy.timestamp : Date.now()\n const lifecycle: AnnotationEvent[] = [\n { type: 'created', actor: 'designer', timestamp: createdTs },\n ]\n if (rawStatus === 'resolved') {\n lifecycle.push({ type: 'migrated', actor: null, timestamp: Date.now() })\n }\n\n return { ...legacy, status, lifecycle }\n}\n\nexport class AnnotationStorage {\n private cache: Annotation[] = []\n readonly ready: Promise<void>\n\n constructor(private adapter: StorageAdapter) {\n this.ready = this.init()\n }\n\n get isMemoryOnly(): boolean {\n return this.adapter.isMemoryOnly ?? false\n }\n\n getAll(): Annotation[] {\n return [...this.cache]\n }\n\n getByRoute(route: string): Annotation[] {\n return this.cache.filter((a) => a.route === route)\n }\n\n getById(id: string): Annotation | undefined {\n return this.cache.find((a) => a.id === id)\n }\n\n async add(annotation: Annotation): Promise<void> {\n this.cache.push(annotation)\n await this.adapter.save(annotation)\n }\n\n async remove(id: string): Promise<void> {\n this.cache = this.cache.filter((a) => a.id !== id)\n await this.adapter.remove(id)\n }\n\n async update(id: string, changes: Partial<Annotation>): Promise<void> {\n const idx = this.cache.findIndex((a) => a.id === id)\n if (idx === -1) return\n const updated = { ...this.cache[idx], ...changes }\n this.cache[idx] = updated\n await this.adapter.save(updated)\n }\n\n async clearAll(): Promise<void> {\n this.cache = []\n await this.adapter.clear()\n }\n\n exportJSON(): AnnotationStore {\n return {\n version: 1,\n annotations: [...this.cache],\n }\n }\n\n async importJSON(data: AnnotationStore): Promise<void> {\n this.cache = data.annotations.map(migrateAnnotation)\n this.migrateViewportBuckets()\n await this.adapter.clear()\n for (const ann of this.cache) {\n await this.adapter.save(ann)\n }\n }\n\n private async init(): Promise<void> {\n const data = await this.adapter.load()\n if (data) {\n this.cache = data.annotations.map(migrateAnnotation)\n this.migrateViewportBuckets()\n }\n }\n\n private migrateViewportBuckets(): void {\n for (const ann of this.cache) {\n if (ann.viewportBucket == null && ann.viewport) {\n const width = parseInt(ann.viewport.split('x')[0], 10)\n ann.viewportBucket = toBucket(width)\n }\n }\n }\n}\n","import type { Annotation, AnnotationStore, StorageAdapter } from './types';\n\nconst STORAGE_KEY = 'remarq:annotations';\n\nexport class LocalStorageAdapter implements StorageAdapter {\n isMemoryOnly = false;\n private extraFields: Record<string, unknown> = {};\n private memoryStore: AnnotationStore | null = null;\n\n async load(): Promise<AnnotationStore | null> {\n if (this.isMemoryOnly) return this.memoryStore;\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n const { version, annotations, ...rest } = parsed;\n this.extraFields = rest;\n const store: AnnotationStore = {\n version: 1,\n annotations: Array.isArray(annotations) ? annotations : [],\n };\n this.memoryStore = store;\n return store;\n } catch {\n this.isMemoryOnly = true;\n return this.memoryStore;\n }\n }\n\n async save(annotation: Annotation): Promise<void> {\n const store = await this.ensureStore();\n const idx = store.annotations.findIndex((a) => a.id === annotation.id);\n if (idx === -1) {\n store.annotations.push(annotation);\n } else {\n store.annotations[idx] = annotation;\n }\n this.persist(store);\n }\n\n async remove(id: string): Promise<void> {\n const store = await this.ensureStore();\n store.annotations = store.annotations.filter((a) => a.id !== id);\n this.persist(store);\n }\n\n async clear(): Promise<void> {\n const store = await this.ensureStore();\n store.annotations = [];\n this.persist(store);\n }\n\n private async ensureStore(): Promise<AnnotationStore> {\n if (this.memoryStore) return this.memoryStore;\n const loaded = await this.load();\n if (loaded) return loaded;\n this.memoryStore = { version: 1, annotations: [] };\n return this.memoryStore;\n }\n\n private persist(store: AnnotationStore): void {\n if (this.isMemoryOnly) return;\n try {\n const data = {\n version: 1,\n ...this.extraFields,\n annotations: store.annotations,\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n } catch {\n this.isMemoryOnly = true;\n }\n }\n}\n","import type {\n Annotation,\n AgentExport,\n AgentAnnotation,\n AgentAnnotationSource,\n AgentSearchHints,\n GrepQuery,\n ElementFingerprint,\n} from './types'\n\nfunction parseSourceLocation(raw: string): { file: string; line: number; column: number } | null {\n const parts = raw.split(':')\n if (parts.length < 2) return null\n // file path may contain \":\" on Windows (C:\\...), so rejoin all but last 2\n const column = parseInt(parts.pop()!, 10)\n const line = parseInt(parts.pop()!, 10)\n const file = parts.join(':')\n if (!file || isNaN(line)) return null\n return { file, line, column: isNaN(column) ? 0 : column }\n}\n\nfunction resolveSource(fp: ElementFingerprint): AgentAnnotationSource | null {\n // Level 1: plugin source\n if (fp.sourceLocation) {\n const parsed = parseSourceLocation(fp.sourceLocation)\n if (parsed) return { ...parsed, component: fp.componentName ?? null }\n }\n\n // Level 2: detected source\n if (fp.detectedSource) {\n const parsed = parseSourceLocation(fp.detectedSource)\n if (parsed) return { ...parsed, component: fp.detectedComponent ?? null }\n }\n\n return null\n}\n\nconst TEMPLATE_GLOB = '*.{tsx,jsx,vue,svelte,html}'\nconst CSS_MODULE_GLOB = '*.module.{css,scss,less}'\nconst COMPONENT_GLOB = '*.{tsx,jsx,vue,ts,js}'\n\nfunction buildSearchHints(fp: ElementFingerprint): AgentSearchHints {\n const grepQueries: GrepQuery[] = []\n\n // High confidence — unique selectors\n if (fp.dataAnnotate) {\n grepQueries.push({ query: `data-annotate=\"${fp.dataAnnotate}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n if (fp.dataTestId) {\n grepQueries.push({ query: `data-testid=\"${fp.dataTestId}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n if (fp.id) {\n grepQueries.push({ query: `id=\"${fp.id}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n if (fp.ariaLabel) {\n grepQueries.push({ query: `aria-label=\"${fp.ariaLabel}\"`, glob: TEMPLATE_GLOB, confidence: 'high' })\n }\n\n // Medium confidence — text, CSS modules, role\n if (fp.textContent) {\n grepQueries.push({ query: `\"${fp.textContent}\"`, glob: TEMPLATE_GLOB, confidence: 'medium' })\n }\n if (fp.role) {\n grepQueries.push({ query: `role=\"${fp.role}\"`, glob: TEMPLATE_GLOB, confidence: 'medium' })\n }\n if (fp.cssModules?.length) {\n for (const mod of fp.cssModules) {\n grepQueries.push({ query: `.${mod.localName}`, glob: CSS_MODULE_GLOB, confidence: 'medium' })\n grepQueries.push({ query: `styles.${mod.localName}`, glob: COMPONENT_GLOB, confidence: 'medium' })\n }\n }\n\n // Low confidence — classes, domPath\n if (fp.stableClasses.length) {\n for (const cls of fp.stableClasses.slice(0, 3)) {\n grepQueries.push({ query: `\"${cls}\"`, glob: TEMPLATE_GLOB, confidence: 'low' })\n }\n }\n\n return {\n grepQueries,\n domContext: fp.domPath,\n tagName: fp.tagName,\n classes: fp.rawClasses ?? fp.stableClasses,\n }\n}\n\nexport function generateAgentExport(annotations: Annotation[], viewportBucket: number): AgentExport {\n const agentAnnotations: AgentAnnotation[] = annotations.map(ann => ({\n id: ann.id,\n route: ann.route,\n comment: ann.comment,\n status: ann.status,\n timestamp: ann.timestamp,\n source: resolveSource(ann.fingerprint),\n searchHints: buildSearchHints(ann.fingerprint),\n lifecycle: ann.lifecycle.map((ev) => {\n const out: { type: typeof ev.type; actor: typeof ev.actor; timestamp: number; reason?: string } = {\n type: ev.type,\n actor: ev.actor,\n timestamp: ev.timestamp,\n }\n if (ev.reason !== undefined) out.reason = ev.reason\n return out\n }),\n }))\n\n return {\n version: 1,\n format: 'agent',\n viewportBucket,\n annotations: agentAnnotations,\n }\n}\n","import type {\n Annotation,\n AnnotationEvent,\n AnnotationEventType,\n AnnotationStatus,\n Actor,\n} from './types'\n\nexport type LifecycleAction =\n | 'acknowledge'\n | 'claimFix'\n | 'verify'\n | 'reject'\n | 'dismiss'\n | 'reopen'\n\nexport class InvalidTransitionError extends Error {\n constructor(from: AnnotationStatus, action: LifecycleAction) {\n super(`Cannot ${action} from status \"${from}\"`)\n this.name = 'InvalidTransitionError'\n }\n}\n\nexport interface EventOpts {\n actor?: Actor\n actorName?: string\n reason?: string\n timestamp?: number\n}\n\nconst ACTION_TO_EVENT: Record<LifecycleAction, AnnotationEventType> = {\n acknowledge: 'acknowledged',\n claimFix: 'fix_claimed',\n verify: 'verified',\n reject: 'rejected',\n dismiss: 'dismissed',\n reopen: 'reopened',\n}\n\nconst DEFAULT_ACTOR_BY_EVENT: Record<AnnotationEventType, Actor | null> = {\n created: 'designer',\n acknowledged: 'developer',\n fix_claimed: 'agent',\n verified: 'developer',\n rejected: 'developer',\n dismissed: 'developer',\n reopened: 'developer',\n migrated: null,\n}\n\nexport function createEvent(type: AnnotationEventType, opts: EventOpts = {}): AnnotationEvent {\n const event: AnnotationEvent = {\n type,\n actor: opts.actor ?? DEFAULT_ACTOR_BY_EVENT[type],\n timestamp: opts.timestamp ?? Date.now(),\n }\n if (opts.actorName !== undefined) event.actorName = opts.actorName\n if (opts.reason !== undefined) event.reason = opts.reason\n return event\n}\n\nfunction nextStatus(\n from: AnnotationStatus,\n action: LifecycleAction,\n): AnnotationStatus | null {\n switch (action) {\n case 'acknowledge':\n return from === 'pending' ? 'in_progress' : null\n case 'claimFix':\n return from === 'pending' || from === 'in_progress' ? 'fixed_unverified' : null\n case 'verify':\n return from === 'fixed_unverified' || from === 'in_progress' ? 'verified' : null\n case 'reject':\n return from === 'fixed_unverified' ? 'pending' : null\n case 'dismiss':\n return from === 'pending' || from === 'in_progress' || from === 'fixed_unverified'\n ? 'dismissed'\n : null\n case 'reopen':\n return from === 'dismissed' || from === 'verified' ? 'pending' : null\n }\n}\n\nexport function transition(\n annotation: Annotation,\n action: LifecycleAction,\n opts: EventOpts = {},\n): { status: AnnotationStatus; event: AnnotationEvent } {\n const next = nextStatus(annotation.status, action)\n if (next === null) {\n throw new InvalidTransitionError(annotation.status, action)\n }\n const event = createEvent(ACTION_TO_EVENT[action], opts)\n return { status: next, event }\n}\n"],"mappings":"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","names":["parent","buildDomPath"]}