web-remarq 0.2.5 → 0.3.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/dist/core/index.cjs +149 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +54 -1
- package/dist/core/index.d.ts +54 -1
- package/dist/core/index.js +146 -1
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +164 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -3
- package/dist/index.d.ts +40 -3
- package/dist/index.js +164 -4
- package/dist/index.js.map +1 -1
- package/dist/web-remarq.global.global.js +164 -4
- package/dist/web-remarq.global.global.js.map +1 -1
- package/package.json +1 -1
|
@@ -217,12 +217,54 @@ var WebRemarq = (() => {
|
|
|
217
217
|
return result;
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
// src/core/source-detect.ts
|
|
221
|
+
function detectRemarqPlugin(el) {
|
|
222
|
+
const source = el.getAttribute("data-remarq-source");
|
|
223
|
+
if (!source) return { source: null, component: null };
|
|
224
|
+
return {
|
|
225
|
+
source,
|
|
226
|
+
component: el.getAttribute("data-remarq-component")
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function detectExternalSource(el) {
|
|
230
|
+
var _a;
|
|
231
|
+
const source = (_a = el.dataset.source) != null ? _a : el.getAttribute("data-locator");
|
|
232
|
+
if (!source) return { source: null, component: null };
|
|
233
|
+
return { source, component: null };
|
|
234
|
+
}
|
|
235
|
+
function detectReactFiber(el) {
|
|
236
|
+
var _a, _b, _c, _d;
|
|
237
|
+
const key = Object.keys(el).find((k) => k.startsWith("__reactFiber$"));
|
|
238
|
+
if (!key) return { source: null, component: null };
|
|
239
|
+
let current = el[key];
|
|
240
|
+
let depth = 0;
|
|
241
|
+
while (current && depth < 15) {
|
|
242
|
+
const debugSource = current._debugSource;
|
|
243
|
+
if (debugSource == null ? void 0 : debugSource.fileName) {
|
|
244
|
+
const source = `${debugSource.fileName}:${(_a = debugSource.lineNumber) != null ? _a : 0}:${(_b = debugSource.columnNumber) != null ? _b : 0}`;
|
|
245
|
+
const fiberType = current.type;
|
|
246
|
+
const component = typeof fiberType === "object" && fiberType ? (_d = (_c = fiberType.displayName) != null ? _c : fiberType.name) != null ? _d : null : null;
|
|
247
|
+
return { source, component };
|
|
248
|
+
}
|
|
249
|
+
current = current.return;
|
|
250
|
+
depth++;
|
|
251
|
+
}
|
|
252
|
+
return { source: null, component: null };
|
|
253
|
+
}
|
|
254
|
+
function detectSource(el) {
|
|
255
|
+
const external = detectExternalSource(el);
|
|
256
|
+
if (external.source) return external;
|
|
257
|
+
const fiber = detectReactFiber(el);
|
|
258
|
+
if (fiber.source) return fiber;
|
|
259
|
+
return { source: null, component: null };
|
|
260
|
+
}
|
|
261
|
+
|
|
220
262
|
// src/core/fingerprint.ts
|
|
221
263
|
var TEXT_MAX_LENGTH = 50;
|
|
222
264
|
function createFingerprint(el, options2) {
|
|
223
265
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
224
266
|
const dataAttr = (_a = options2 == null ? void 0 : options2.dataAttribute) != null ? _a : "data-annotate";
|
|
225
|
-
return {
|
|
267
|
+
return __spreadValues({
|
|
226
268
|
dataAnnotate: (_b = el.getAttribute(dataAttr)) != null ? _b : null,
|
|
227
269
|
dataTestId: (_e = (_d = (_c = el.getAttribute("data-testid")) != null ? _c : el.getAttribute("data-test")) != null ? _d : el.getAttribute("data-cy")) != null ? _e : null,
|
|
228
270
|
id: getStableId(el),
|
|
@@ -239,6 +281,24 @@ var WebRemarq = (() => {
|
|
|
239
281
|
parentAnchor: findParentAnchor(el, dataAttr),
|
|
240
282
|
rawClasses: Array.from(el.classList),
|
|
241
283
|
cssModules: decomposeCSSModules(Array.from(el.classList))
|
|
284
|
+
}, resolveSourceFields(el));
|
|
285
|
+
}
|
|
286
|
+
function resolveSourceFields(el) {
|
|
287
|
+
const plugin = detectRemarqPlugin(el);
|
|
288
|
+
if (plugin.source) {
|
|
289
|
+
return {
|
|
290
|
+
sourceLocation: plugin.source,
|
|
291
|
+
componentName: plugin.component,
|
|
292
|
+
detectedSource: null,
|
|
293
|
+
detectedComponent: null
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
const detected = detectSource(el);
|
|
297
|
+
return {
|
|
298
|
+
sourceLocation: null,
|
|
299
|
+
componentName: null,
|
|
300
|
+
detectedSource: detected.source,
|
|
301
|
+
detectedComponent: detected.component
|
|
242
302
|
};
|
|
243
303
|
}
|
|
244
304
|
function getStableId(el) {
|
|
@@ -424,6 +484,88 @@ var WebRemarq = (() => {
|
|
|
424
484
|
return bestScore >= MATCH_THRESHOLD ? bestEl : null;
|
|
425
485
|
}
|
|
426
486
|
|
|
487
|
+
// src/core/agent-export.ts
|
|
488
|
+
function parseSourceLocation(raw) {
|
|
489
|
+
const parts = raw.split(":");
|
|
490
|
+
if (parts.length < 2) return null;
|
|
491
|
+
const column = parseInt(parts.pop(), 10);
|
|
492
|
+
const line = parseInt(parts.pop(), 10);
|
|
493
|
+
const file = parts.join(":");
|
|
494
|
+
if (!file || isNaN(line)) return null;
|
|
495
|
+
return { file, line, column: isNaN(column) ? 0 : column };
|
|
496
|
+
}
|
|
497
|
+
function resolveSource(fp) {
|
|
498
|
+
var _a, _b;
|
|
499
|
+
if (fp.sourceLocation) {
|
|
500
|
+
const parsed = parseSourceLocation(fp.sourceLocation);
|
|
501
|
+
if (parsed) return __spreadProps(__spreadValues({}, parsed), { component: (_a = fp.componentName) != null ? _a : null });
|
|
502
|
+
}
|
|
503
|
+
if (fp.detectedSource) {
|
|
504
|
+
const parsed = parseSourceLocation(fp.detectedSource);
|
|
505
|
+
if (parsed) return __spreadProps(__spreadValues({}, parsed), { component: (_b = fp.detectedComponent) != null ? _b : null });
|
|
506
|
+
}
|
|
507
|
+
return null;
|
|
508
|
+
}
|
|
509
|
+
var TEMPLATE_GLOB = "*.{tsx,jsx,vue,svelte,html}";
|
|
510
|
+
var CSS_MODULE_GLOB = "*.module.{css,scss,less}";
|
|
511
|
+
var COMPONENT_GLOB = "*.{tsx,jsx,vue,ts,js}";
|
|
512
|
+
function buildSearchHints(fp) {
|
|
513
|
+
var _a, _b;
|
|
514
|
+
const grepQueries = [];
|
|
515
|
+
if (fp.dataAnnotate) {
|
|
516
|
+
grepQueries.push({ query: `data-annotate="${fp.dataAnnotate}"`, glob: TEMPLATE_GLOB, confidence: "high" });
|
|
517
|
+
}
|
|
518
|
+
if (fp.dataTestId) {
|
|
519
|
+
grepQueries.push({ query: `data-testid="${fp.dataTestId}"`, glob: TEMPLATE_GLOB, confidence: "high" });
|
|
520
|
+
}
|
|
521
|
+
if (fp.id) {
|
|
522
|
+
grepQueries.push({ query: `id="${fp.id}"`, glob: TEMPLATE_GLOB, confidence: "high" });
|
|
523
|
+
}
|
|
524
|
+
if (fp.ariaLabel) {
|
|
525
|
+
grepQueries.push({ query: `aria-label="${fp.ariaLabel}"`, glob: TEMPLATE_GLOB, confidence: "high" });
|
|
526
|
+
}
|
|
527
|
+
if (fp.textContent) {
|
|
528
|
+
grepQueries.push({ query: `"${fp.textContent}"`, glob: TEMPLATE_GLOB, confidence: "medium" });
|
|
529
|
+
}
|
|
530
|
+
if (fp.role) {
|
|
531
|
+
grepQueries.push({ query: `role="${fp.role}"`, glob: TEMPLATE_GLOB, confidence: "medium" });
|
|
532
|
+
}
|
|
533
|
+
if ((_a = fp.cssModules) == null ? void 0 : _a.length) {
|
|
534
|
+
for (const mod of fp.cssModules) {
|
|
535
|
+
grepQueries.push({ query: `.${mod.localName}`, glob: CSS_MODULE_GLOB, confidence: "medium" });
|
|
536
|
+
grepQueries.push({ query: `styles.${mod.localName}`, glob: COMPONENT_GLOB, confidence: "medium" });
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (fp.stableClasses.length) {
|
|
540
|
+
for (const cls of fp.stableClasses.slice(0, 3)) {
|
|
541
|
+
grepQueries.push({ query: `"${cls}"`, glob: TEMPLATE_GLOB, confidence: "low" });
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return {
|
|
545
|
+
grepQueries,
|
|
546
|
+
domContext: fp.domPath,
|
|
547
|
+
tagName: fp.tagName,
|
|
548
|
+
classes: (_b = fp.rawClasses) != null ? _b : fp.stableClasses
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
function generateAgentExport(annotations, viewportBucket) {
|
|
552
|
+
const agentAnnotations = annotations.map((ann) => ({
|
|
553
|
+
id: ann.id,
|
|
554
|
+
route: ann.route,
|
|
555
|
+
comment: ann.comment,
|
|
556
|
+
status: ann.status,
|
|
557
|
+
timestamp: ann.timestamp,
|
|
558
|
+
source: resolveSource(ann.fingerprint),
|
|
559
|
+
searchHints: buildSearchHints(ann.fingerprint)
|
|
560
|
+
}));
|
|
561
|
+
return {
|
|
562
|
+
version: 1,
|
|
563
|
+
format: "agent",
|
|
564
|
+
viewportBucket,
|
|
565
|
+
annotations: agentAnnotations
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
|
|
427
569
|
// src/ui/styles.ts
|
|
428
570
|
var STYLES_ID = "data-remarq-styles";
|
|
429
571
|
var CSS = `
|
|
@@ -1978,6 +2120,22 @@ var WebRemarq = (() => {
|
|
|
1978
2120
|
console.warn("[web-remarq] Clipboard write failed");
|
|
1979
2121
|
});
|
|
1980
2122
|
}
|
|
2123
|
+
function exportAgent() {
|
|
2124
|
+
const anns = storage.getAll();
|
|
2125
|
+
if (!anns.length) return;
|
|
2126
|
+
const data = generateAgentExport(anns, toBucket(window.innerWidth));
|
|
2127
|
+
const json = JSON.stringify(data, null, 2);
|
|
2128
|
+
downloadFile(json, `remarq-agent-${Date.now()}.json`, "application/json");
|
|
2129
|
+
}
|
|
2130
|
+
function copyAgentToClipboard() {
|
|
2131
|
+
const anns = storage.getAll();
|
|
2132
|
+
if (!anns.length) return;
|
|
2133
|
+
const data = generateAgentExport(anns, toBucket(window.innerWidth));
|
|
2134
|
+
const json = JSON.stringify(data, null, 2);
|
|
2135
|
+
navigator.clipboard.writeText(json).catch(() => {
|
|
2136
|
+
console.warn("[web-remarq] Clipboard write failed");
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
1981
2139
|
function setupMutationObserver() {
|
|
1982
2140
|
mutationObserver = new MutationObserver((mutations) => {
|
|
1983
2141
|
for (const m of mutations) {
|
|
@@ -2083,10 +2241,12 @@ var WebRemarq = (() => {
|
|
|
2083
2241
|
},
|
|
2084
2242
|
export(format) {
|
|
2085
2243
|
if (format === "md") exportMarkdown();
|
|
2086
|
-
else exportJSON();
|
|
2244
|
+
else if (format === "json") exportJSON();
|
|
2245
|
+
else exportAgent();
|
|
2087
2246
|
},
|
|
2088
|
-
copy() {
|
|
2089
|
-
|
|
2247
|
+
copy(format) {
|
|
2248
|
+
if (format === "agent") copyAgentToClipboard();
|
|
2249
|
+
else copyToClipboard();
|
|
2090
2250
|
},
|
|
2091
2251
|
async import(file) {
|
|
2092
2252
|
const text = await file.text();
|