@replohq/sandbox-runtime 1.24.1 → 1.24.3
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/buildMetadata.js +3 -3
- package/comments-overlay/overlay.d.ts +2 -1
- package/comments-overlay/overlay.js +62 -49
- package/package.json +4 -4
package/buildMetadata.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const BUILD_METADATA = {
|
|
2
2
|
"packageName": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.3",
|
|
4
4
|
"branch": "HEAD",
|
|
5
|
-
"commit": "
|
|
6
|
-
"builtAt": "2026-11-
|
|
5
|
+
"commit": "e1eeef82df82036e9d623fccf943736d34fb994d",
|
|
6
|
+
"builtAt": "2026-11-04T19:25:11.953Z"
|
|
7
7
|
};
|
|
@@ -3,7 +3,7 @@ import type { CommentOverlayAnchorStatus, CommentOverlayPin, CommentOverlayRect
|
|
|
3
3
|
import type { DisplayMode } from "../_vendor/schemas/generated/selectMode";
|
|
4
4
|
import type { ElementSource } from "./capture";
|
|
5
5
|
export declare const OVERLAY_Z_INDEX = 2147483645;
|
|
6
|
-
export declare const HIGHLIGHT_BACKGROUND = "
|
|
6
|
+
export declare const HIGHLIGHT_BACKGROUND = "color-mix(in srgb, var(--replo-comment-accent) 12%, transparent)";
|
|
7
7
|
export declare const BADGE_SIZE_PX = 32;
|
|
8
8
|
export declare const RERESOLVE_DEBOUNCE_MS = 250;
|
|
9
9
|
export type CommentsOverlayCallbacks = {
|
|
@@ -20,6 +20,7 @@ export type CommentsOverlayCallbacks = {
|
|
|
20
20
|
onComposeFromSelection: (input: {
|
|
21
21
|
anchor: CommentAnchorElement;
|
|
22
22
|
}) => void;
|
|
23
|
+
/** Esc, or a click on empty page, closed the pending pick or open thread. */
|
|
23
24
|
onPickCancelled: () => void;
|
|
24
25
|
/** C or Esc pressed in the frame; the host owns the mode. */
|
|
25
26
|
onModeShortcut: (input: {
|
|
@@ -2,8 +2,9 @@ import { captureAnchor, getAnchorElement } from "./capture";
|
|
|
2
2
|
import { isResolutionVisible, resolveAnchor } from "./resolve";
|
|
3
3
|
import { OVERLAY_ROOT_ATTRIBUTE } from "./textQuote";
|
|
4
4
|
const OVERLAY_Z_INDEX = 2147483645;
|
|
5
|
-
const HIGHLIGHT_BACKGROUND = "
|
|
6
|
-
const
|
|
5
|
+
const HIGHLIGHT_BACKGROUND = "color-mix(in srgb, var(--replo-comment-accent) 12%, transparent)";
|
|
6
|
+
const SOFT_OUTLINE_COLOR = "color-mix(in srgb, var(--replo-comment-accent) 55%, transparent)";
|
|
7
|
+
const HIGHLIGHT_OUTLINE = "1.5px solid var(--replo-comment-accent)";
|
|
7
8
|
const BADGE_SIZE_PX = 32;
|
|
8
9
|
const BADGE_HIT_TARGET_PX = 44;
|
|
9
10
|
const BADGE_HIT_TARGET_WIDTH_PX = 64;
|
|
@@ -11,7 +12,7 @@ const COMPACT_GUTTER_MAX_WIDTH_PX = 600;
|
|
|
11
12
|
const RERESOLVE_DEBOUNCE_MS = 250;
|
|
12
13
|
const SELECTION_PROMPT_DEBOUNCE_MS = 150;
|
|
13
14
|
const TEXT_PICK_CLICK_SUPPRESS_MS = 750;
|
|
14
|
-
const HOVER_OUTLINE_STYLE =
|
|
15
|
+
const HOVER_OUTLINE_STYLE = `position:absolute;pointer-events:none;box-sizing:border-box;border:${HIGHLIGHT_OUTLINE};background:transparent;border-radius:4px`;
|
|
15
16
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
16
17
|
const EDITABLE_SELECTOR = "input, textarea, select, [contenteditable]:not([contenteditable='false'])";
|
|
17
18
|
function getReportedStatus(resolution) {
|
|
@@ -31,11 +32,8 @@ function createCommentsOverlay(options) {
|
|
|
31
32
|
let pins = [];
|
|
32
33
|
let resolutions = /* @__PURE__ */ new Map();
|
|
33
34
|
const boundElements = /* @__PURE__ */ new Map();
|
|
34
|
-
let
|
|
35
|
+
let selection = null;
|
|
35
36
|
let hoveredBadgeThreadId = null;
|
|
36
|
-
let draftAnchor = null;
|
|
37
|
-
let draftResolution = null;
|
|
38
|
-
let draftElement = null;
|
|
39
37
|
let statusesKey = "";
|
|
40
38
|
let hoveredElement = null;
|
|
41
39
|
let hoverOutline = null;
|
|
@@ -52,7 +50,7 @@ function createCommentsOverlay(options) {
|
|
|
52
50
|
let isDestroyed = false;
|
|
53
51
|
const root = document.createElement("div");
|
|
54
52
|
root.setAttribute(OVERLAY_ROOT_ATTRIBUTE, "true");
|
|
55
|
-
root.style.cssText = `position:fixed;inset:0;z-index:${OVERLAY_Z_INDEX};pointer-events:none;overflow:hidden`;
|
|
53
|
+
root.style.cssText = `position:fixed;inset:0;z-index:${OVERLAY_Z_INDEX};pointer-events:none;overflow:hidden;--replo-comment-accent:light-dark(#7861bf,#b09be8);--replo-comment-surface:light-dark(#f0eafa,#372e4d);--replo-comment-text:light-dark(#7058b4,#b09be8);--replo-comment-on-accent:light-dark(#fff,#20182f)`;
|
|
56
54
|
document.documentElement.append(root);
|
|
57
55
|
const isInOverlay = (node) => {
|
|
58
56
|
return node instanceof Node && root.contains(node);
|
|
@@ -66,22 +64,22 @@ function createCommentsOverlay(options) {
|
|
|
66
64
|
const isPageElement = (node) => {
|
|
67
65
|
return node instanceof Element && node !== document.body && node !== document.documentElement && !isInOverlay(node);
|
|
68
66
|
};
|
|
69
|
-
const isEditableSelection = (
|
|
70
|
-
const node =
|
|
67
|
+
const isEditableSelection = (selection2) => {
|
|
68
|
+
const node = selection2.anchorNode;
|
|
71
69
|
const element = node instanceof Element ? node : node?.parentElement;
|
|
72
70
|
return Boolean(
|
|
73
71
|
element?.closest(EDITABLE_SELECTOR) || document.activeElement?.matches(EDITABLE_SELECTOR)
|
|
74
72
|
);
|
|
75
73
|
};
|
|
76
74
|
const getUsableSelectionRange = () => {
|
|
77
|
-
const
|
|
78
|
-
if (!
|
|
75
|
+
const selection2 = window.getSelection();
|
|
76
|
+
if (!selection2 || selection2.isCollapsed || selection2.rangeCount === 0) {
|
|
79
77
|
return null;
|
|
80
78
|
}
|
|
81
|
-
if (isEditableSelection(
|
|
79
|
+
if (isEditableSelection(selection2)) {
|
|
82
80
|
return null;
|
|
83
81
|
}
|
|
84
|
-
const range =
|
|
82
|
+
const range = selection2.getRangeAt(0);
|
|
85
83
|
if (!range.toString().trim() || isInOverlay(range.commonAncestorContainer)) {
|
|
86
84
|
return null;
|
|
87
85
|
}
|
|
@@ -132,11 +130,12 @@ function createCommentsOverlay(options) {
|
|
|
132
130
|
}
|
|
133
131
|
}
|
|
134
132
|
resolutions = next;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
133
|
+
if (selection?.kind === "draft") {
|
|
134
|
+
selection.resolution = resolveAnchor(selection.anchor, document, {
|
|
135
|
+
previous: selection.resolution?.element ?? null,
|
|
136
|
+
getSource: cachedGetSource
|
|
137
|
+
});
|
|
138
|
+
}
|
|
140
139
|
const statuses = getElementAnchors().map(({ pin }) => {
|
|
141
140
|
return {
|
|
142
141
|
threadId: pin.threadId,
|
|
@@ -157,7 +156,7 @@ function createCommentsOverlay(options) {
|
|
|
157
156
|
resolveTimer = setTimeout(resolveAll, RERESOLVE_DEBOUNCE_MS);
|
|
158
157
|
};
|
|
159
158
|
const paintHighlight = (resolution, threadId) => {
|
|
160
|
-
const
|
|
159
|
+
const isOutlined = threadId === null || threadId === hoveredBadgeThreadId || selection?.kind === "thread" && threadId === selection.threadId;
|
|
161
160
|
for (const rect of getResolutionRects(resolution)) {
|
|
162
161
|
if (rect.width <= 0 || rect.height <= 0 || rect.bottom < 0 || rect.top > window.innerHeight) {
|
|
163
162
|
continue;
|
|
@@ -168,10 +167,7 @@ function createCommentsOverlay(options) {
|
|
|
168
167
|
} else {
|
|
169
168
|
highlight.dataset.commentDraft = "true";
|
|
170
169
|
}
|
|
171
|
-
highlight.style.cssText = `position:absolute;pointer-events:none;background:${HIGHLIGHT_BACKGROUND};border-radius:
|
|
172
|
-
if (isQuote) {
|
|
173
|
-
highlight.style.borderBottom = QUOTE_UNDERLINE;
|
|
174
|
-
}
|
|
170
|
+
highlight.style.cssText = `position:absolute;pointer-events:none;background:${threadId ? HIGHLIGHT_BACKGROUND : "transparent"};border:${isOutlined ? HIGHLIGHT_OUTLINE : "0"};border-radius:4px;box-sizing:border-box`;
|
|
175
171
|
highlight.style.left = `${rect.left}px`;
|
|
176
172
|
highlight.style.top = `${rect.top}px`;
|
|
177
173
|
highlight.style.width = `${rect.width}px`;
|
|
@@ -180,7 +176,7 @@ function createCommentsOverlay(options) {
|
|
|
180
176
|
}
|
|
181
177
|
};
|
|
182
178
|
const isHighlightShown = (threadId) => {
|
|
183
|
-
return mode === "comment" || threadId ===
|
|
179
|
+
return mode === "comment" || selection?.kind === "thread" && threadId === selection.threadId || threadId === hoveredBadgeThreadId;
|
|
184
180
|
};
|
|
185
181
|
const createIcon = (size, path) => {
|
|
186
182
|
const icon = document.createElementNS(SVG_NAMESPACE, "svg");
|
|
@@ -320,7 +316,7 @@ function createCommentsOverlay(options) {
|
|
|
320
316
|
};
|
|
321
317
|
for (const pin of pins) {
|
|
322
318
|
const resolution = resolutions.get(pin.threadId);
|
|
323
|
-
const isFocused = pin.threadId ===
|
|
319
|
+
const isFocused = selection?.kind === "thread" && pin.threadId === selection.threadId;
|
|
324
320
|
if (!resolution || pin.status === "resolved" && !isFocused || !isResolutionVisible(resolution)) {
|
|
325
321
|
continue;
|
|
326
322
|
}
|
|
@@ -350,12 +346,16 @@ function createCommentsOverlay(options) {
|
|
|
350
346
|
badge.style.top = `${position.top}px`;
|
|
351
347
|
const isActive = isFocused || pin.threadId === hoveredBadgeThreadId;
|
|
352
348
|
const dot = document.createElement("span");
|
|
353
|
-
dot.style.cssText = `display:flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;min-width:48px;height:${BADGE_SIZE_PX}px;padding:0 6px;border-radius:
|
|
349
|
+
dot.style.cssText = `display:flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;min-width:48px;height:${BADGE_SIZE_PX}px;padding:0 6px;border-radius:999px;border:1px solid ${SOFT_OUTLINE_COLOR};background:var(--replo-comment-surface);color:var(--replo-comment-text);box-shadow:0 1px 3px rgba(0,0,0,.08);font:600 14px/1 system-ui,-apple-system,sans-serif;font-variant-numeric:tabular-nums;white-space:nowrap`;
|
|
354
350
|
if (isCompact) {
|
|
355
351
|
dot.style.marginRight = "3px";
|
|
356
352
|
}
|
|
357
353
|
if (isActive) {
|
|
358
|
-
dot.style.borderColor = "
|
|
354
|
+
dot.style.borderColor = "var(--replo-comment-accent)";
|
|
355
|
+
}
|
|
356
|
+
if (isFocused) {
|
|
357
|
+
dot.style.background = "var(--replo-comment-accent)";
|
|
358
|
+
dot.style.color = "var(--replo-comment-on-accent)";
|
|
359
359
|
}
|
|
360
360
|
if (resolution.status === "ambiguous") {
|
|
361
361
|
dot.style.borderStyle = "dashed";
|
|
@@ -380,8 +380,8 @@ function createCommentsOverlay(options) {
|
|
|
380
380
|
child.remove();
|
|
381
381
|
}
|
|
382
382
|
}
|
|
383
|
-
if (
|
|
384
|
-
paintHighlight(
|
|
383
|
+
if (selection?.kind === "draft" && selection.resolution && isResolutionVisible(selection.resolution)) {
|
|
384
|
+
paintHighlight(selection.resolution, null);
|
|
385
385
|
}
|
|
386
386
|
paintBadges();
|
|
387
387
|
paintHover();
|
|
@@ -409,21 +409,32 @@ function createCommentsOverlay(options) {
|
|
|
409
409
|
const anchor = captureAnchor(target, point);
|
|
410
410
|
const range = "tagName" in target ? void 0 : target;
|
|
411
411
|
const rect = (range ?? element).getBoundingClientRect();
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
412
|
+
selection = {
|
|
413
|
+
kind: "draft",
|
|
414
|
+
anchor,
|
|
415
|
+
resolution: {
|
|
416
|
+
status: "attached",
|
|
417
|
+
element,
|
|
418
|
+
...range ? { range } : {}
|
|
419
|
+
}
|
|
418
420
|
};
|
|
419
421
|
hoveredElement = null;
|
|
420
422
|
void finishAnchor(anchor).then((prepared) => report(prepared, rect));
|
|
421
423
|
schedulePaint();
|
|
422
424
|
};
|
|
423
425
|
const clearDraft = () => {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
426
|
+
if (selection?.kind === "draft") {
|
|
427
|
+
selection = null;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
const dismissSelection = () => {
|
|
431
|
+
if (!selection) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
selection = null;
|
|
435
|
+
options.onPickCancelled();
|
|
436
|
+
schedulePaint();
|
|
437
|
+
return true;
|
|
427
438
|
};
|
|
428
439
|
const refreshSelectionPrompt = () => {
|
|
429
440
|
selectionTimer = null;
|
|
@@ -579,7 +590,7 @@ function createCommentsOverlay(options) {
|
|
|
579
590
|
return;
|
|
580
591
|
}
|
|
581
592
|
if (!isPageElement(target)) {
|
|
582
|
-
|
|
593
|
+
dismissSelection();
|
|
583
594
|
return;
|
|
584
595
|
}
|
|
585
596
|
pick(target, { x: event.clientX, y: event.clientY }, reportPicked);
|
|
@@ -595,16 +606,12 @@ function createCommentsOverlay(options) {
|
|
|
595
606
|
if (event.key !== "Escape") {
|
|
596
607
|
return;
|
|
597
608
|
}
|
|
598
|
-
if (mode === "comment" ||
|
|
609
|
+
if (mode === "comment" || selection?.kind === "draft") {
|
|
599
610
|
if (mode === "comment") {
|
|
600
611
|
event.preventDefault();
|
|
601
612
|
event.stopImmediatePropagation();
|
|
602
613
|
}
|
|
603
|
-
if (
|
|
604
|
-
clearDraft();
|
|
605
|
-
options.onPickCancelled();
|
|
606
|
-
schedulePaint();
|
|
607
|
-
} else {
|
|
614
|
+
if (!dismissSelection()) {
|
|
608
615
|
options.onModeShortcut({ mode: "browse" });
|
|
609
616
|
}
|
|
610
617
|
return;
|
|
@@ -713,7 +720,9 @@ function createCommentsOverlay(options) {
|
|
|
713
720
|
mode = nextMode;
|
|
714
721
|
selectionPrompt = null;
|
|
715
722
|
hoveredElement = null;
|
|
716
|
-
|
|
723
|
+
if (selection?.kind === "thread") {
|
|
724
|
+
selection = null;
|
|
725
|
+
}
|
|
717
726
|
setCursor(nextMode, previousMode);
|
|
718
727
|
if (previousMode === "comment") {
|
|
719
728
|
window.getSelection()?.removeAllRanges();
|
|
@@ -731,7 +740,7 @@ function createCommentsOverlay(options) {
|
|
|
731
740
|
resolveAll();
|
|
732
741
|
},
|
|
733
742
|
focusThread: (threadId) => {
|
|
734
|
-
|
|
743
|
+
selection = { kind: "thread", threadId };
|
|
735
744
|
const resolution = resolutions.get(threadId);
|
|
736
745
|
const target = resolution?.range?.startContainer.parentElement ?? resolution?.element ?? null;
|
|
737
746
|
if (resolution && isResolutionVisible(resolution)) {
|
|
@@ -748,7 +757,11 @@ function createCommentsOverlay(options) {
|
|
|
748
757
|
schedulePaint();
|
|
749
758
|
},
|
|
750
759
|
setDraftAnchor: (anchor) => {
|
|
751
|
-
|
|
760
|
+
if (anchor?.type === "element") {
|
|
761
|
+
selection = { kind: "draft", anchor, resolution: null };
|
|
762
|
+
} else {
|
|
763
|
+
clearDraft();
|
|
764
|
+
}
|
|
752
765
|
resolveAll();
|
|
753
766
|
},
|
|
754
767
|
refresh: resolveAll,
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.3",
|
|
4
4
|
"reploBuild": {
|
|
5
5
|
"packageName": "@replohq/sandbox-runtime",
|
|
6
|
-
"version": "1.24.
|
|
6
|
+
"version": "1.24.3",
|
|
7
7
|
"branch": "HEAD",
|
|
8
|
-
"commit": "
|
|
9
|
-
"builtAt": "2026-11-
|
|
8
|
+
"commit": "e1eeef82df82036e9d623fccf943736d34fb994d",
|
|
9
|
+
"builtAt": "2026-11-04T19:25:11.953Z"
|
|
10
10
|
},
|
|
11
11
|
"description": "Replo sandbox runtime — editor integration for agent-built Next.js sites.",
|
|
12
12
|
"license": "SEE LICENSE IN LICENSE",
|