@01.works/visual-review 0.13.0 → 0.15.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 +86 -22
- package/THIRD_PARTY_NOTICES.md +0 -9
- package/dist/active-review-mount-BpeCsPqV.js +1941 -0
- package/dist/cli.js +994 -139
- package/dist/{convex-runtime-DY-himGr.js → convex-runtime-D1aPBck9.js} +2 -2
- package/dist/{cursor-chat-repository-Dn3UVmUP.js → cursor-chat-repository-CK86F1lv.js} +1 -1
- package/dist/hosted-runtime-B7YTLu3G.js +13 -0
- package/dist/index.d.ts +191 -8
- package/dist/index.js +1 -1
- package/dist/{install-BXWJcrQ8.js → install-CY72L_bY.js} +2 -2
- package/dist/mcp.js +32 -0
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/review-repository-CAu78oOD.js +1 -0
- package/dist/{source-instrumentation-transform-B23vB7l6.js → source-instrumentation-transform-7yivYljc.js} +16 -6
- package/dist/source-loader.js +1 -1
- package/dist/src-IC5X3zme.js +1 -0
- package/dist/vite.js +1 -1
- package/package.json +10 -5
- package/dist/active-review-mount-BEEKqerS.js +0 -1401
- package/dist/hosted-runtime-BFendO_5.js +0 -1
- package/dist/instant-runtime-UFycxLQ8.js +0 -1
- package/dist/review-repository-xzjM-750.js +0 -1
- package/dist/reviewer-auth-presentation-CAm-YbaR.js +0 -13
- package/dist/src-CjYM9---.js +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -69,6 +69,14 @@ export interface VisualReviewEnvironment {
|
|
|
69
69
|
devicePixelRatio: number;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
export interface VisualReviewFeedbackLabel {
|
|
73
|
+
id: string;
|
|
74
|
+
name: string;
|
|
75
|
+
color: 'gray' | 'violet' | 'sky' | 'emerald' | 'orange' | 'pink'
|
|
76
|
+
| 'indigo' | 'teal' | 'red' | 'amber' | 'blue';
|
|
77
|
+
archivedAt?: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
/** Advanced resolver seam. Most integrations should use the automatic resolver. */
|
|
73
81
|
export interface VisualReviewSourceContextResolver {
|
|
74
82
|
resolve(element: Element, options?: { signal?: AbortSignal }): Promise<{
|
|
@@ -119,6 +127,33 @@ export interface VisualReviewCursorChatSubscriptionOptions {
|
|
|
119
127
|
roomId: string;
|
|
120
128
|
}
|
|
121
129
|
|
|
130
|
+
export interface VisualReviewFeedbackActor {
|
|
131
|
+
type: 'human' | 'agent';
|
|
132
|
+
id: string;
|
|
133
|
+
displayName: string;
|
|
134
|
+
actingForId?: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface VisualReviewFeedbackActivity {
|
|
138
|
+
id: string;
|
|
139
|
+
feedbackId: string;
|
|
140
|
+
sequence: number;
|
|
141
|
+
type: 'created' | 'replied' | 'started' | 'resolved' | 'reopened';
|
|
142
|
+
actor: VisualReviewFeedbackActor;
|
|
143
|
+
replyId?: string;
|
|
144
|
+
body?: string;
|
|
145
|
+
fromStatus?: VisualReviewComment['status'];
|
|
146
|
+
toStatus?: VisualReviewComment['status'];
|
|
147
|
+
createdAt: number;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface VisualReviewFeedbackReadCursor {
|
|
151
|
+
feedbackId: string;
|
|
152
|
+
viewerId: string;
|
|
153
|
+
lastReadSequence: number;
|
|
154
|
+
updatedAt: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
122
157
|
export interface VisualReviewComment {
|
|
123
158
|
id: string;
|
|
124
159
|
pageId: string;
|
|
@@ -126,6 +161,9 @@ export interface VisualReviewComment {
|
|
|
126
161
|
pageNumber?: number;
|
|
127
162
|
authorId: string;
|
|
128
163
|
authorName: string;
|
|
164
|
+
actor?: VisualReviewFeedbackActor;
|
|
165
|
+
/** How the initial feedback was created. Omitted legacy rows are human-authored. */
|
|
166
|
+
authorKind?: 'human' | 'agent';
|
|
129
167
|
body: string;
|
|
130
168
|
anchor: VisualReviewAnchor;
|
|
131
169
|
/** Latest reviewer-authored position override for a movable pin. */
|
|
@@ -134,12 +172,23 @@ export interface VisualReviewComment {
|
|
|
134
172
|
pinRevision?: number;
|
|
135
173
|
target: VisualReviewAnnotationTarget;
|
|
136
174
|
scope?: Record<string, string | number | boolean | null>;
|
|
137
|
-
|
|
175
|
+
/** Stable project-scoped label ids. Names and colors are owner-configurable. */
|
|
176
|
+
labels?: string[];
|
|
177
|
+
status: 'open' | 'in_progress' | 'resolved';
|
|
138
178
|
workflowRevision?: number;
|
|
179
|
+
/** Monotonic CAS token for replies and workflow changes; pin moves do not advance it. */
|
|
180
|
+
threadRevision?: number;
|
|
139
181
|
createdAt: number;
|
|
140
182
|
updatedAt: number;
|
|
141
183
|
resolvedAt?: number;
|
|
142
184
|
resolvedById?: string;
|
|
185
|
+
resolvedByName?: string;
|
|
186
|
+
resolvedByKind?: 'human' | 'agent';
|
|
187
|
+
resolvedByRole?: 'agency' | 'reviewer';
|
|
188
|
+
resolution?: VisualReviewFeedbackActivity;
|
|
189
|
+
lastActivitySequence?: number;
|
|
190
|
+
lastActivityAt?: number;
|
|
191
|
+
lastReadSequence?: number;
|
|
143
192
|
}
|
|
144
193
|
|
|
145
194
|
export interface VisualReviewReply {
|
|
@@ -147,23 +196,32 @@ export interface VisualReviewReply {
|
|
|
147
196
|
commentId: string;
|
|
148
197
|
authorId: string;
|
|
149
198
|
authorName: string;
|
|
199
|
+
actor?: VisualReviewFeedbackActor;
|
|
200
|
+
authorKind?: 'human' | 'agent';
|
|
201
|
+
authorRole?: 'agency' | 'reviewer';
|
|
150
202
|
body: string;
|
|
151
203
|
createdAt: number;
|
|
152
204
|
updatedAt: number;
|
|
205
|
+
activityId?: string;
|
|
206
|
+
sequence?: number;
|
|
153
207
|
}
|
|
154
208
|
|
|
155
209
|
export interface VisualReviewSnapshot {
|
|
156
210
|
pageId: string;
|
|
211
|
+
feedbackLabels?: VisualReviewFeedbackLabel[];
|
|
157
212
|
comments: VisualReviewComment[];
|
|
158
213
|
replies: VisualReviewReply[];
|
|
214
|
+
activities?: VisualReviewFeedbackActivity[];
|
|
159
215
|
window?: VisualReviewSnapshotWindow;
|
|
160
216
|
}
|
|
161
217
|
|
|
162
218
|
export interface VisualReviewProjectSnapshot {
|
|
163
219
|
projectId: string;
|
|
220
|
+
feedbackLabels?: VisualReviewFeedbackLabel[];
|
|
164
221
|
pages?: VisualReviewProjectPageSummary[];
|
|
165
222
|
comments: VisualReviewComment[];
|
|
166
223
|
replies: VisualReviewReply[];
|
|
224
|
+
activities?: VisualReviewFeedbackActivity[];
|
|
167
225
|
window?: VisualReviewSnapshotWindow;
|
|
168
226
|
}
|
|
169
227
|
|
|
@@ -184,9 +242,44 @@ export interface VisualReviewSnapshotWindow {
|
|
|
184
242
|
export type VisualReviewMutation =
|
|
185
243
|
| { type: 'comment.upsert'; comment: VisualReviewComment }
|
|
186
244
|
| { type: 'comment.delete'; commentId: string }
|
|
187
|
-
| {
|
|
245
|
+
| {
|
|
246
|
+
type: 'reply.upsert';
|
|
247
|
+
reply: VisualReviewReply;
|
|
248
|
+
requestReopen?: boolean;
|
|
249
|
+
}
|
|
188
250
|
| { type: 'reply.delete'; commentId: string; replyId: string };
|
|
189
251
|
|
|
252
|
+
export interface VisualReviewCommentStatusUpdate {
|
|
253
|
+
commentId: string;
|
|
254
|
+
status: 'open' | 'resolved';
|
|
255
|
+
expectedWorkflowRevision: number;
|
|
256
|
+
expectedThreadRevision: number;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface VisualReviewCommentStatusResult {
|
|
260
|
+
commentId: string;
|
|
261
|
+
status: VisualReviewComment['status'];
|
|
262
|
+
workflowRevision: number;
|
|
263
|
+
threadRevision: number;
|
|
264
|
+
updatedAt: number;
|
|
265
|
+
resolvedAt?: number;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface VisualReviewCommentLabelsUpdate {
|
|
269
|
+
commentId: string;
|
|
270
|
+
labels: string[];
|
|
271
|
+
expectedWorkflowRevision: number;
|
|
272
|
+
expectedThreadRevision: number;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface VisualReviewCommentLabelsResult {
|
|
276
|
+
commentId: string;
|
|
277
|
+
labels: string[];
|
|
278
|
+
workflowRevision: number;
|
|
279
|
+
threadRevision: number;
|
|
280
|
+
updatedAt: number;
|
|
281
|
+
}
|
|
282
|
+
|
|
190
283
|
export type VisualReviewSubscriptionFailure =
|
|
191
284
|
| {
|
|
192
285
|
type: 'access-lost';
|
|
@@ -215,6 +308,15 @@ export interface VisualReviewRepository {
|
|
|
215
308
|
onFailure?: (failure: VisualReviewSubscriptionFailure) => void,
|
|
216
309
|
): () => void;
|
|
217
310
|
mutate(pageId: string, mutation: VisualReviewMutation): Promise<void>;
|
|
311
|
+
markFeedbackRead?(commentId: string): Promise<VisualReviewFeedbackReadCursor>;
|
|
312
|
+
updateCommentStatus?(
|
|
313
|
+
pageId: string,
|
|
314
|
+
update: VisualReviewCommentStatusUpdate,
|
|
315
|
+
): Promise<VisualReviewCommentStatusResult>;
|
|
316
|
+
updateCommentLabels?(
|
|
317
|
+
pageId: string,
|
|
318
|
+
update: VisualReviewCommentLabelsUpdate,
|
|
319
|
+
): Promise<VisualReviewCommentLabelsResult>;
|
|
218
320
|
moveCommentPin?(
|
|
219
321
|
pageId: string,
|
|
220
322
|
commentId: string,
|
|
@@ -344,6 +446,87 @@ export interface VisualReviewInactiveState {
|
|
|
344
446
|
origin: string;
|
|
345
447
|
}
|
|
346
448
|
|
|
449
|
+
export interface VisualReviewAgentPoint {
|
|
450
|
+
clientX: number;
|
|
451
|
+
clientY: number;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export interface VisualReviewCommentableTarget {
|
|
455
|
+
index: number;
|
|
456
|
+
tagName: string;
|
|
457
|
+
role: string | null;
|
|
458
|
+
/** Sanitized but still untrusted text from the reviewed page. */
|
|
459
|
+
label: string | null;
|
|
460
|
+
/** Diagnostic evidence only; no mutation accepts this selector. */
|
|
461
|
+
selector: string;
|
|
462
|
+
selectorTruncated: boolean;
|
|
463
|
+
rect: VisualReviewAgentPoint & { width: number; height: number };
|
|
464
|
+
/** Pass this point to createFeedbackAtPoint() after checking the live page. */
|
|
465
|
+
point: VisualReviewAgentPoint;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export interface VisualReviewCommentableTargetInventory {
|
|
469
|
+
schemaVersion: 1;
|
|
470
|
+
trustBoundary: string;
|
|
471
|
+
/** Origin and pathname only; query and fragment credentials are omitted. */
|
|
472
|
+
pageUrl: string;
|
|
473
|
+
viewport: { width: number; height: number };
|
|
474
|
+
/** Fixed at 100 in this protocol version. */
|
|
475
|
+
maxTargets: 100;
|
|
476
|
+
truncated: boolean;
|
|
477
|
+
targets: VisualReviewCommentableTarget[];
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
export interface VisualReviewCreateFeedbackRequest extends VisualReviewAgentPoint {
|
|
481
|
+
body: string;
|
|
482
|
+
endClientX?: number;
|
|
483
|
+
endClientY?: number;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
export interface VisualReviewCreateFeedbackResult {
|
|
487
|
+
commentId: string;
|
|
488
|
+
target: VisualReviewAnnotationTarget;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export interface VisualReviewPagePortableArchive {
|
|
492
|
+
schemaVersion: 1;
|
|
493
|
+
archiveId: string;
|
|
494
|
+
pageUrl: string;
|
|
495
|
+
exportedAt: string;
|
|
496
|
+
feedback: Array<{
|
|
497
|
+
id: string;
|
|
498
|
+
body: string;
|
|
499
|
+
target: VisualReviewAnnotationTarget;
|
|
500
|
+
scope?: Record<string, string | number | boolean | null>;
|
|
501
|
+
replies: Array<{ id: string; body: string }>;
|
|
502
|
+
}>;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
export interface VisualReviewPageImportResult {
|
|
506
|
+
importedComments: number;
|
|
507
|
+
importedReplies: number;
|
|
508
|
+
commentIds: string[];
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/** Authenticated, staging-only browser automation surface. */
|
|
512
|
+
export interface VisualReviewAgentBridge extends HTMLElement {
|
|
513
|
+
readonly mode: 'view' | 'comment' | 'review';
|
|
514
|
+
setMode(mode: 'view' | 'comment' | 'review'): void;
|
|
515
|
+
listCommentableTargets(): VisualReviewCommentableTargetInventory;
|
|
516
|
+
createFeedbackAtPoint(
|
|
517
|
+
request: VisualReviewCreateFeedbackRequest,
|
|
518
|
+
): Promise<VisualReviewCreateFeedbackResult>;
|
|
519
|
+
exportPageFeedback(format: 'json'): VisualReviewPagePortableArchive;
|
|
520
|
+
exportPageFeedback(format: 'markdown'): string;
|
|
521
|
+
importPageFeedback(value: unknown): Promise<VisualReviewPageImportResult>;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
declare global {
|
|
525
|
+
interface HTMLElementTagNameMap {
|
|
526
|
+
'agency-review-widget': VisualReviewAgentBridge;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
347
530
|
export interface InstallVisualReviewOptions {
|
|
348
531
|
/** Override only for local development or self-hosted integration tests. */
|
|
349
532
|
serviceUrl?: string;
|
|
@@ -352,11 +535,11 @@ export interface InstallVisualReviewOptions {
|
|
|
352
535
|
runtime?: VisualReviewRuntime;
|
|
353
536
|
/** Emergency kill switch. Omit for invitation-driven activation. */
|
|
354
537
|
enabled?: boolean;
|
|
355
|
-
/**
|
|
538
|
+
/** Development-only integrations that never persist or transmit copied content. */
|
|
356
539
|
developerTools?: {
|
|
357
|
-
/**
|
|
540
|
+
/** Show a dedicated React Grab action that copies immediately after element selection. */
|
|
358
541
|
codeContextCopy?: boolean;
|
|
359
|
-
/** @deprecated
|
|
542
|
+
/** @deprecated Use `codeContextCopy`. Retained for 0.11 consumers. */
|
|
360
543
|
reactGrab?: boolean;
|
|
361
544
|
};
|
|
362
545
|
/** Opt in to ephemeral Convex-backed reviewer cursors and cursor chat. */
|
|
@@ -374,19 +557,19 @@ export interface InstallVisualReviewOptions {
|
|
|
374
557
|
/** Called when the launcher can safely identify why it stayed inactive. */
|
|
375
558
|
onInactive?: (state: VisualReviewInactiveState) => void;
|
|
376
559
|
/** Called once for each successful mount owned by this installation. */
|
|
377
|
-
onReady?: (widget:
|
|
560
|
+
onReady?: (widget: VisualReviewAgentBridge) => void;
|
|
378
561
|
/** Optional host-router adapter for opening feedback on another page. */
|
|
379
562
|
navigateToFeedback?: (url: string) => void | Promise<void>;
|
|
380
563
|
}
|
|
381
564
|
|
|
382
565
|
export interface VisualReviewInstallation {
|
|
383
|
-
ready: Promise<
|
|
566
|
+
ready: Promise<VisualReviewAgentBridge | null>;
|
|
384
567
|
/**
|
|
385
568
|
* Re-resolve the current route after a framework router changes it in place,
|
|
386
569
|
* and re-anchor the widget to it even when the route did not change. A widget
|
|
387
570
|
* the host detached is remounted; a healthy one is never torn down.
|
|
388
571
|
*/
|
|
389
|
-
refresh(): Promise<
|
|
572
|
+
refresh(): Promise<VisualReviewAgentBridge | null>;
|
|
390
573
|
dispose(): void;
|
|
391
574
|
}
|
|
392
575
|
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./install-
|
|
1
|
+
import{t as e}from"./install-CY72L_bY.js";export{e as installVisualReview};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=`https://review.01.works`;function t(e){let t=new URL(e),n=t.hostname===`localhost`||t.hostname===`127.0.0.1`||t.hostname.endsWith(`.test`)||t.hostname.endsWith(`.local`);if(t.protocol!==`https:`&&!(n&&t.protocol===`http:`))throw Error(`Visual Review serviceUrl must use HTTPS outside local development`);if(t.username||t.password||t.search||t.hash)throw Error(`Visual Review serviceUrl must be a plain origin or base path`);return t.toString().replace(/\/+$/,``)}const n=()=>{let e=Promise.resolve(null);return{ready:e,refresh:()=>e,dispose(){}}},r=new Map,i=6e4,a=1e4,o=new WeakMap;function s(e={}){if(e.enabled===!1||typeof window>`u`||typeof document>`u`)return n();let r=!1,i=0,a=null,o=null,s=null,g=null,_=!1,v=!1,y=null,b=null,w=null,D=t(e.serviceUrl??`https://review.01.works`),k=e.activationParam??`visual-review`,j=le(window),N=ue(window),P=C(window.location);if(!(ae(D,k,P,N,j,e.runtime!==void 0)??re(T(D,P.origin)))){let t={reason:`missing-activation`,origin:P.origin};return M(e.build).mode===`development`&&c(document,t.origin),l(e.onInactive,t),n()}let F=new WeakMap,I=new Map,L=fe(e.styleNonce,document),R=x(window.location,k,e.pageIdentity),z=te(window,t=>{let n=x(t,k,e.pageIdentity);if(n===R)return;let r=O(k,t.href)?.invitationId;r&&(v=!1,I.set(t.origin,r)),R=n,V(t)}),B=t=>{if(!(r||!g)){if(t===`membership-revoked`){let e=C(window.location),t=I.get(e.origin);t&&(E(D,e.origin,t),I.delete(e.origin),K(D,e.origin,N,j,t));return}R=x(window.location,k,e.pageIdentity),W()}};return{ready:W(),refresh(){return r?Promise.resolve(null):(R=x(window.location,k,e.pageIdentity),V(C(window.location),!0))},dispose(){r||(r=!0,i+=1,U(),g?.remove(),g=null,w=null,b?.remove(),b=null,I.clear(),y?.dispose(),y=null,z.unsubscribe())}};function V(e,t=!1){return!g||!w||w.origin!==e.origin||O(k,e.href)?.invitationId?W():H(g,w,e,t)}function H(t,n,r,c){let l=++i;a!==o&&a?.abort();let u=new AbortController;a=u,t.beginPageTransition();let d=(async()=>{try{let i=await A(n.resolvePage({location:r,...e.pageIdentity===`url`?{routeKey:S(r)}:{},signal:u.signal,cursorChat:e.cursorChat===!0}),u.signal);return Q(l,u)?(i.commit?.(),t.setPage({pageId:i.pageId,...e.cursorChat===!0?{cursorChat:{roomId:i.cursorChatRoomId}}:{}},{reload:c}),t.isConnected||document.body?.append(t),t):$(l)}catch{return Q(l,u)?W():$(l)}})();return s=d,d}function U(){a?.abort(),o?.abort(),a=null,o=null}function W(){if(v&&!O(k,C(window.location).href))return Promise.resolve(null);let t=++i;U(),y?.suspendSession(),g?.remove(),g=null,w=null,b?.remove();let n=new AbortController,r=document.createElement(`div`);r.dataset.agencyReviewRoot=``,a=n,o=n,b=r;let c=q(t,n,r);return s=c,c.then(r=>{r&&Q(t,n)&&g===r&&e.onReady?.(r)}),c}async function q(t,n,i){try{let e=document.body??await se(document,n.signal);if(!Q(t,n))return $(t);e.append(i);let r=await J(t,n,i);return Q(t,n)?r:(i.remove(),$(t))}catch(a){if(!Q(t,n))return i.remove(),$(t);if(f(a,`AUTH_CANCELLED`)||f(a,`ACCOUNT_BRIDGE_REDIRECT`))return i.remove(),b===i&&(b=null),null;let o=F.get(i),s=o?.[3];if(Z(a,i),p(s)&&f(a,`INVITATION_EMAIL_REQUIRED`)&&!_){let e=o?.[1]??C(window.location).origin,t=o?.[2];return t&&(I.delete(e),K(D,e,N,j,t)),i.remove(),b===i&&(b=null),null}let c=de(a,o?.[2]),u=o?.[1]??C(window.location).origin,d=f(a,`ORIGIN_NOT_ALLOWED`);if(d&&l(e.onInactive,{reason:`origin-not-allowed`,origin:u}),!p(s)||_||!m(a)){let{originNotAllowedMessage:o,renderBootstrapError:s}=await import(`./bootstrap-error-B30Je5Pg.js`);if(!Q(t,n))return i.remove(),$(t);let l=h(a)?void 0:()=>{r||b!==i||(R=x(window.location,k,e.pageIdentity),W())};s(i,d?o(u):c.message,L,l)}else i.remove(),b===i&&(b=null);return e.onError?.(c),window.dispatchEvent(new CustomEvent(`visual-review:error`,{detail:c})),null}}async function J(t,n,r){let i=C(window.location),a=ae(D,k,i,N,j,e.runtime!==void 0),o=ne(I.get(i.origin)),s=re(T(D,i.origin)),c=a?.source===`url`?a:s??o??a;if(!c)return F.delete(r),r.remove(),b===r&&(b=null),null;let l=c.invitationId;F.set(r,[D,i.origin,l,c.source,c.emailToken]),c.source===`url`?(K(D,i.origin,N,j),I.set(i.origin,l),ie(D,i.origin,l,c.emailToken,c.accountToken),z.suppress(()=>oe(k))):c.source===`handoff`&&I.set(i.origin,l),R=x(window.location,k,e.pageIdentity);let f=C(window.location),p=await A((e.runtime??await u(D)).resolve({invitationId:l,emailToken:c.emailToken,accountToken:c.accountToken??void 0,accountBridgeAttempted:c.accountToken!==void 0,location:f,...e.pageIdentity===`url`?{routeKey:S(f)}:{},signal:n.signal,authHost:r,styleNonce:L,cursorChat:e.cursorChat===!0}),n.signal);if(!Q(t,n))return null;E(D,i.origin,l),ce(D,l,i,N,j,p.sessionScope??`browser`,p.sessionExpiresAt),c.source===`url`&&G(j,X(D,i.origin)),I.set(i.origin,l);let m=e.sourceContextResolver??await ee(
|
|
2
|
-
`)))}function l(e,t){if(e)try{e(t)}catch(e){console.error(`[VisualReview] onInactive callback failed.`,e)}}async function u(e){let{createHostedReviewRuntime:t}=await import(`./hosted-runtime-
|
|
1
|
+
const e=`https://review.01.works`;function t(e){let t=new URL(e),n=t.hostname===`localhost`||t.hostname===`127.0.0.1`||t.hostname.endsWith(`.test`)||t.hostname.endsWith(`.local`);if(t.protocol!==`https:`&&!(n&&t.protocol===`http:`))throw Error(`Visual Review serviceUrl must use HTTPS outside local development`);if(t.username||t.password||t.search||t.hash)throw Error(`Visual Review serviceUrl must be a plain origin or base path`);return t.toString().replace(/\/+$/,``)}const n=()=>{let e=Promise.resolve(null);return{ready:e,refresh:()=>e,dispose(){}}},r=new Map,i=6e4,a=1e4,o=new WeakMap;function s(e={}){if(e.enabled===!1||typeof window>`u`||typeof document>`u`)return n();let r=!1,i=0,a=null,o=null,s=null,g=null,_=!1,v=!1,y=null,b=null,w=null,D=t(e.serviceUrl??`https://review.01.works`),k=e.activationParam??`visual-review`,j=le(window),N=ue(window),P=C(window.location);if(!(ae(D,k,P,N,j,e.runtime!==void 0)??re(T(D,P.origin)))){let t={reason:`missing-activation`,origin:P.origin};return M(e.build).mode===`development`&&c(document,t.origin),l(e.onInactive,t),n()}let F=new WeakMap,I=new Map,L=fe(e.styleNonce,document),R=x(window.location,k,e.pageIdentity),z=te(window,t=>{let n=x(t,k,e.pageIdentity);if(n===R)return;let r=O(k,t.href)?.invitationId;r&&(v=!1,I.set(t.origin,r)),R=n,V(t)}),B=t=>{if(!(r||!g)){if(t===`membership-revoked`){let e=C(window.location),t=I.get(e.origin);t&&(E(D,e.origin,t),I.delete(e.origin),K(D,e.origin,N,j,t));return}R=x(window.location,k,e.pageIdentity),W()}};return{ready:W(),refresh(){return r?Promise.resolve(null):(R=x(window.location,k,e.pageIdentity),V(C(window.location),!0))},dispose(){r||(r=!0,i+=1,U(),g?.remove(),g=null,w=null,b?.remove(),b=null,I.clear(),y?.dispose(),y=null,z.unsubscribe())}};function V(e,t=!1){return!g||!w||w.origin!==e.origin||O(k,e.href)?.invitationId?W():H(g,w,e,t)}function H(t,n,r,c){let l=++i;a!==o&&a?.abort();let u=new AbortController;a=u,t.beginPageTransition();let d=(async()=>{try{let i=await A(n.resolvePage({location:r,...e.pageIdentity===`url`?{routeKey:S(r)}:{},signal:u.signal,cursorChat:e.cursorChat===!0}),u.signal);return Q(l,u)?(i.commit?.(),t.setPage({pageId:i.pageId,...e.cursorChat===!0?{cursorChat:{roomId:i.cursorChatRoomId}}:{}},{reload:c}),t.isConnected||document.body?.append(t),t):$(l)}catch{return Q(l,u)?W():$(l)}})();return s=d,d}function U(){a?.abort(),o?.abort(),a=null,o=null}function W(){if(v&&!O(k,C(window.location).href))return Promise.resolve(null);let t=++i;U(),y?.suspendSession(),g?.remove(),g=null,w=null,b?.remove();let n=new AbortController,r=document.createElement(`div`);r.dataset.agencyReviewRoot=``,a=n,o=n,b=r;let c=q(t,n,r);return s=c,c.then(r=>{r&&Q(t,n)&&g===r&&e.onReady?.(r)}),c}async function q(t,n,i){try{let e=document.body??await se(document,n.signal);if(!Q(t,n))return $(t);e.append(i);let r=await J(t,n,i);return Q(t,n)?r:(i.remove(),$(t))}catch(a){if(!Q(t,n))return i.remove(),$(t);if(f(a,`AUTH_CANCELLED`)||f(a,`ACCOUNT_BRIDGE_REDIRECT`))return i.remove(),b===i&&(b=null),null;let o=F.get(i),s=o?.[3];if(Z(a,i),p(s)&&f(a,`INVITATION_EMAIL_REQUIRED`)&&!_){let e=o?.[1]??C(window.location).origin,t=o?.[2];return t&&(I.delete(e),K(D,e,N,j,t)),i.remove(),b===i&&(b=null),null}let c=de(a,o?.[2]),u=o?.[1]??C(window.location).origin,d=f(a,`ORIGIN_NOT_ALLOWED`);if(d&&l(e.onInactive,{reason:`origin-not-allowed`,origin:u}),!p(s)||_||!m(a)){let{originNotAllowedMessage:o,renderBootstrapError:s}=await import(`./bootstrap-error-B30Je5Pg.js`);if(!Q(t,n))return i.remove(),$(t);let l=h(a)?void 0:()=>{r||b!==i||(R=x(window.location,k,e.pageIdentity),W())};s(i,d?o(u):c.message,L,l)}else i.remove(),b===i&&(b=null);return e.onError?.(c),window.dispatchEvent(new CustomEvent(`visual-review:error`,{detail:c})),null}}async function J(t,n,r){let i=C(window.location),a=ae(D,k,i,N,j,e.runtime!==void 0),o=ne(I.get(i.origin)),s=re(T(D,i.origin)),c=a?.source===`url`?a:s??o??a;if(!c)return F.delete(r),r.remove(),b===r&&(b=null),null;let l=c.invitationId;F.set(r,[D,i.origin,l,c.source,c.emailToken]),c.source===`url`?(K(D,i.origin,N,j),I.set(i.origin,l),ie(D,i.origin,l,c.emailToken,c.accountToken),z.suppress(()=>oe(k))):c.source===`handoff`&&I.set(i.origin,l),R=x(window.location,k,e.pageIdentity);let f=C(window.location),p=await A((e.runtime??await u(D)).resolve({invitationId:l,emailToken:c.emailToken,accountToken:c.accountToken??void 0,accountBridgeAttempted:c.accountToken!==void 0,location:f,...e.pageIdentity===`url`?{routeKey:S(f)}:{},signal:n.signal,authHost:r,styleNonce:L,cursorChat:e.cursorChat===!0}),n.signal);if(!Q(t,n))return null;E(D,i.origin,l),ce(D,l,i,N,j,p.sessionScope??`browser`,p.sessionExpiresAt),c.source===`url`&&G(j,X(D,i.origin)),I.set(i.origin,l);let m=M(e.build),h=e.sourceContextResolver??await ee(m,n.signal);if(!Q(t,n))return null;let{createActiveReviewSessionLifecycle:te,createReviewNavigationHandler:v,mountReviewWidget:O}=await d(n.signal);return!Q(t,n)||(y??=te({window,document,storage:j,onExit:Y,onReauthenticationRequired:B}),y.bindSession(l,X(D,i.origin),p.clearLocalSession),!Q(t,n))?null:(g=O({...p,...e.cursorChat===!0&&p.cursorChatRepository?{cursorChat:{repository:p.cursorChatRepository,roomId:p.cursorChatRoomId}}:{},offset:e.offset,onNavigateToFeedback:v(window,e.navigateToFeedback),sourceContextResolver:h,styleNonce:L,position:e.position,...m.mode===`development`&&(e.developerTools?.codeContextCopy===!0||e.developerTools?.reactGrab===!0)?{codeContextCopy:{}}:{}}),y.attachWidget(g),w=p.resolvePage?{origin:i.origin,resolvePage:e=>p.resolvePage(e)}:null,r.remove(),b===r&&(b=null),_=!0,window.dispatchEvent(new CustomEvent(`visual-review:ready`,{detail:g})),g)}function Y(e){let t=C(window.location).origin;v=!0,E(D,t,e),I.delete(t),K(D,t,N,j,e),i+=1,U(),g?.remove(),g=null,w=null,b?.remove(),b=null}function Z(e,t){if(!m(e))return;let n=F.get(t);if(!n)return;let[r,i,a]=n;E(r,i,a),I.get(i)===a&&I.delete(i),K(r,i,N,j,a)}function Q(e,t){return!r&&i===e&&a===t&&!t.signal.aborted}function $(e){return!r&&i!==e?s:null}}function c(e,t){let n=o.get(e);n||(n=new Set,o.set(e,n)),!n.has(t)&&(n.add(t),console.info([`[VisualReview] Inactive: no invitation or resume marker was found.`,`Open this page using a Visual Review invitation URL.`,`Current origin: ${t}`].join(`
|
|
2
|
+
`)))}function l(e,t){if(e)try{e(t)}catch(e){console.error(`[VisualReview] onInactive callback failed.`,e)}}async function u(e){let{createHostedReviewRuntime:t}=await import(`./hosted-runtime-B7YTLu3G.js`);return t({serviceUrl:e})}async function d(e){return j(import(`./active-review-mount-BpeCsPqV.js`),e,a,`리뷰 위젯을 불러오는 시간이 초과되었습니다. 다시 시도해 주세요.`)}async function ee(e,t){let n=M(e),{createEmbeddedSourceContextResolver:r}=await j(import(`./embedded-source-context-BTB3pFqv.js`),t,a,`리뷰 소스 정보를 불러오는 시간이 초과되었습니다. 다시 시도해 주세요.`);return r({build:n})}function f(e,t){return e instanceof Error&&`code`in e&&e.code===t}function p(e){return e===`tab-storage`||e===`browser-storage`||e===`legacy-storage`}function m(e){let t=g(e);return typeof t==`string`&&/^INVITATION_(?:EXPIRED|NOT_FOUND|REVOKED)$/.test(t)}function h(e){return m(e)||g(e)===`UNSUPPORTED_SERVICE_VERSION`}function g(e){return e instanceof Error&&`code`in e?e.code:void 0}const _=new WeakMap;function te(e,t){let n=_.get(e);if(!n){let t=e.history,r=t.pushState,i=t.replaceState,a=new Set;n={history:t,originalPushStateDescriptor:Object.getOwnPropertyDescriptor(t,`pushState`),originalReplaceStateDescriptor:Object.getOwnPropertyDescriptor(t,`replaceState`),patchedPushState:function(t,n,i){r.call(this,t,n,i),v(e)},patchedReplaceState:function(t,n,r){i.call(this,t,n,r),v(e)},popstateListener:()=>v(e),subscribers:a,suppressionDepth:0},_.set(e,n),y(t,`pushState`,n.patchedPushState),y(t,`replaceState`,n.patchedReplaceState),e.addEventListener(`popstate`,n.popstateListener)}n.subscribers.add(t);let r=!0;return{suppress(e){n.suppressionDepth+=1;try{return e()}finally{--n.suppressionDepth}},unsubscribe(){r&&(r=!1,n.subscribers.delete(t),!(n.subscribers.size>0)&&(e.removeEventListener(`popstate`,n.popstateListener),b(n.history,`pushState`,n.patchedPushState,n.originalPushStateDescriptor),b(n.history,`replaceState`,n.patchedReplaceState,n.originalReplaceStateDescriptor),_.delete(e)))}}}function v(e){let t=_.get(e);if(!t||t.suppressionDepth>0)return;let n=C(e.location);[...t.subscribers].forEach(e=>e(n))}function y(e,t,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}function b(e,t,n,r){if(Object.getOwnPropertyDescriptor(e,t)?.value===n){if(r){Object.defineProperty(e,t,r);return}delete e[t]}}function x(e,t,n){return`${e.origin}\n${n===`url`?S(e):e.pathname}\n${O(t,e.href)?.invitationId??``}`}function S(e){let t=new URL(e.href);return`${t.pathname}${t.search}${t.hash}`}function C(e){return new URL(e.href)}function ne(e){return e?{invitationId:e,source:`memory`}:null}function re(e){return e?{invitationId:e.invitationId,emailToken:e.emailToken,accountToken:e.accountToken,source:`handoff`}:null}function w(e,t){return JSON.stringify([e,t])}function T(e,t,n=Date.now()){let i=w(e,t),a=r.get(i);if(a){if(a.expiresAt>n)return a;clearTimeout(a.timeout),r.delete(i)}}function ie(e,t,n,a,o,s=Date.now()){D(s);let c=w(e,t),l=r.get(c);for(l&&(clearTimeout(l.timeout),r.delete(c));r.size>=32;){let e=r.keys().next().value;if(!e)break;let t=r.get(e);t&&clearTimeout(t.timeout),r.delete(e)}let u=s+i,d=setTimeout(()=>{r.get(c)?.expiresAt===u&&r.delete(c)},i);r.set(c,{invitationId:n,emailToken:a,accountToken:o,expiresAt:u,timeout:d})}function E(e,t,n){let i=w(e,t),a=r.get(i);a?.invitationId===n&&(clearTimeout(a.timeout),r.delete(i))}function D(e){for(let[t,n]of r)n.expiresAt>e||(clearTimeout(n.timeout),r.delete(t))}function ae(e,t,n,r,i,a){let o=O(t,n.href);if(o)return o;let s=U(i,X(e,n.origin)),c=U(r,J(e,n.origin));if(c&&c!==s)return{invitationId:c,source:`tab-storage`};let l=H(i,Y(e,n.origin));if(l&&l.invitationId!==s)return{invitationId:l.invitationId,source:`browser-storage`};let u=U(i,q(e,n.origin));return u&&u!==s?{invitationId:u,source:`legacy-storage`}:a&&Z(n.hostname)?{invitationId:`local-preview`,source:`local-preview`}:null}function O(e,t){let n=new URL(t),r=k(n.hash),i=(r?.get(e)??r?.get(`visual-review`)??r?.get(`agency-review`)??r?.get(`agency-review-invite`)??n.searchParams.get(e)??n.searchParams.get(`agency-review`)??n.searchParams.get(`agency-review-invite`))?.trim();if(!i)return null;let a=r?.get(`visual-review-token`)?.trim(),o=r?.get(`visual-review-account-token`)?.trim();return{invitationId:i,emailToken:a&&/^[\w-]{43}$/.test(a)?a:void 0,accountToken:(o&&o.length<=4096&&/^[\w.-]+$/.test(o)?o:void 0)??(r?.get(`visual-review-account`)===`none`?null:void 0),source:`url`}}function k(e){let t=e.replace(/^#?\??/,``);return t.includes(`=`)?new URLSearchParams(t):null}function oe(e){let t=new URL(window.location.href),n=[e,`visual-review`,`agency-review`,`agency-review-invite`,`visual-review-token`,`visual-review-account-token`,`visual-review-account`,`visual-review-return-hash`];for(let e of n)t.searchParams.delete(e);let r=k(t.hash);if(r){let e=r.get(`visual-review-return-hash`);for(let e of n)r.delete(e);let i=r.toString();t.hash=e!==null&&e.length<=2e3&&(e===``||e[0]===`#`)?e:i?`#${i}`:``}window.history.replaceState(window.history.state,``,`${t.pathname}${t.search}${t.hash}`)}function A(e,t){return new Promise((n,r)=>{let i=()=>r(new DOMException(`Aborted`,`AbortError`));if(t.aborted){i();return}t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}function j(e,t,n,r){return new Promise((i,a)=>{let o=!1,s=e=>{o||(o=!0,clearTimeout(l),t.removeEventListener(`abort`,c),e())},c=()=>{s(()=>a(new DOMException(`Aborted`,`AbortError`)))},l=setTimeout(()=>{s(()=>a(Error(r)))},n);if(t.aborted){c();return}t.addEventListener(`abort`,c,{once:!0}),e.then(e=>s(()=>i(e)),e=>s(()=>a(e)))})}function se(e,t){return e.body?Promise.resolve(e.body):t.aborted?Promise.reject(new DOMException(`Aborted`,`AbortError`)):new Promise((n,r)=>{let i=!1,a=new MutationObserver(()=>c()),o=()=>{e.removeEventListener(`DOMContentLoaded`,c),t.removeEventListener(`abort`,l),a.disconnect()},s=e=>{i||(i=!0,o(),e())},c=()=>{let t=e.body;t&&s(()=>n(t))},l=()=>{s(()=>r(new DOMException(`Aborted`,`AbortError`)))};e.addEventListener(`DOMContentLoaded`,c),t.addEventListener(`abort`,l,{once:!0}),a.observe(e,{childList:!0,subtree:!0}),c()})}function M(e){let t=document.querySelector(`meta[name="visual-review-build"]`),n=document.querySelector(`meta[name="visual-review-commit"]`),r=V(F()),i=V(I());return{buildId:B(e?.buildId)??z(t)??r??`unversioned`,gitCommit:L(e,n,i),generatedAt:e?.generatedAt,mode:e?.mode??P(N())??(Z(window.location.hostname)?`development`:`production`)}}function N(){try{return process.env.VISUAL_REVIEW_PUBLIC_BUILD_MODE}catch{return}}function P(e){return e===`development`||e===`preview`||e===`production`?e:void 0}function F(){try{return process.env.VISUAL_REVIEW_PUBLIC_BUILD_ID}catch{return}}function I(){try{return process.env.VISUAL_REVIEW_PUBLIC_GIT_COMMIT}catch{return}}function L(e,t,n){return e?.gitCommit===null?null:typeof e?.gitCommit==`string`?R(e.gitCommit):R(t?.content)??R(n)}function R(e){if(typeof e!=`string`)return null;let t=e.trim().toLowerCase();return/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(t)?t:null}function z(e){return V(e?.content)}function B(e){let t=typeof e==`string`?e.trim():``;return t.length>0?t:null}function V(e){return typeof e==`string`&&e.length>0?e:null}function ce(e,t,n,r,i,a,o){if(a===`tab`){try{r?.setItem(J(e,n.origin),t)}catch{}G(i,Y(e,n.origin))}else{let a=Number.isSafeInteger(o)&&o>Date.now()?o:Date.now()+1440*6e4;try{i?.setItem(Y(e,n.origin),JSON.stringify({version:2,invitationId:t,expiresAt:a}))}catch{}G(r,J(e,n.origin))}W(e,n.origin,i,t)}function H(e,t){let n=U(e,t);if(!n)return null;let r=()=>{try{e?.removeItem?.(t)}catch{}};try{let e=JSON.parse(n),t=e.expiresAt;return e.version!==2||typeof e.invitationId!=`string`||!e.invitationId.trim()||!Number.isSafeInteger(t)||t<=Date.now()?(r(),null):{version:2,invitationId:e.invitationId,expiresAt:t}}catch{return r(),null}}function U(e,t){try{return e?.getItem(t)??null}catch{return null}}function le(e){try{return e.localStorage}catch{return null}}function ue(e){try{return e.sessionStorage}catch{return null}}function W(e,t,n,r){try{if(!n)return;let i=q(e,t),a=n.getItem(i);if(a===null||r!==void 0&&a!==r)return;n.removeItem(i)}catch{}}function G(e,t){try{e?.removeItem(t)}catch{}}function K(e,t,n,r,i){W(e,t,r,i);let a=J(e,t),o=Y(e,t);if(i===void 0){G(n,a),G(r,o);return}U(n,a)===i&&G(n,a),H(r,o)?.invitationId===i&&G(r,o)}function q(e,t){return`visual-review:${e}:${t}:invitation`}function J(e,t){return`visual-review:${e}:${t}:invitation:tab:v2`}function Y(e,t){return`visual-review:${e}:${t}:invitation:browser:v2`}function X(e,t){return`visual-review:${e}:${t}:exit:v1`}function Z(e){return e===`localhost`||e===`127.0.0.1`||e.endsWith(`.test`)||e.endsWith(`.local`)}function de(e,t){let n=e instanceof Error?e.message:String(e),r=Error(Q(n,t));if(e&&typeof e==`object`){let n=`code`in e?e.code:void 0,i=`status`in e?e.status:void 0;typeof n==`string`&&Object.defineProperty(r,"code",{configurable:!0,enumerable:!0,value:Q(n,t)}),typeof i==`number`&&Number.isFinite(i)&&Object.defineProperty(r,"status",{configurable:!0,enumerable:!0,value:i})}return r}function Q(e,t){if(!t)return e;let n=new Set([t,encodeURIComponent(t)]),r=e;for(let e of n)e&&(r=r.split(e).join(`[redacted]`));return r}function fe(e,t){if(e!==void 0)return pe(e);let n=t.currentScript,r=n?$(n):void 0;if(r)return r;try{for(let e of t.querySelectorAll(`script[nonce],style[nonce]`)){let t=$(e);if(t)return t}}catch{}}function $(e){let t=`nonce`in e?e.nonce:void 0;return typeof t==`string`?pe(t):void 0}function pe(e){return e.trim()||void 0}export{e as n,t as r,s as t};
|