@runalabs/rill-cli 0.1.16 → 0.1.18
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 +2 -0
- package/dist/cli.js +196 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -370,6 +370,8 @@ Progress runs through `uploading` → `queued` → `encoding` → `processing`
|
|
|
370
370
|
|
|
371
371
|
Run `rill connect --email you@example.com` to authorize account access or keep your anonymous recordings. Open the displayed link, sign in, and enter the code yourself. Approval allows creation and reading of your existing and new recordings for 90 days, with automatic renewal of one-hour access tokens. Revoke the connection in Settings → Agent access to stop access and renewal. Deletion and changes to existing sharing settings are not included.
|
|
372
372
|
|
|
373
|
+
Browser approval does not finish the handshake: the CLI must collect and save credentials. With `--no-wait`, keep polling the returned `connect status <authorizationId>` command until `authenticated`. Starting with 0.1.17, the CLI checks the server even after its local approval deadline. Approval codes expire after ten minutes; successful approval starts a separate 30-minute collection window, with a 60-second lost-response retry window after first collection. If collection expires, run `connect --email` again with the same account to request fresh human approval while preserving the registration and recordings. Do not delete saved credentials to recover. Auth requests include the CLI version for consent-aware diagnostics.
|
|
374
|
+
|
|
373
375
|
Use `rill record list` to list accessible recordings and `rill inspect <recording-id>` for private recording details. `rill inspect <share-url>` continues to work without account access. The existing `rill login` and `RILL_TOKEN` flows remain supported. Local credential storage requires macOS Keychain, Linux Secret Service, or Windows current-user DPAPI.
|
|
374
376
|
|
|
375
377
|
### Check the connected account
|
package/dist/cli.js
CHANGED
|
@@ -127,6 +127,11 @@ function browserAttachment(cdpUrl, tabId) {
|
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
// src/version.ts
|
|
131
|
+
import { createRequire } from "module";
|
|
132
|
+
var packageJson = createRequire(import.meta.url)("../package.json");
|
|
133
|
+
var CLI_VERSION = packageJson.version;
|
|
134
|
+
|
|
130
135
|
// src/agent-session.ts
|
|
131
136
|
var JWT_GRANT = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
132
137
|
var CLAIM_GRANT = "urn:workos:agent-auth:grant-type:claim";
|
|
@@ -150,7 +155,7 @@ async function request(apiUrl, path, body, form = false) {
|
|
|
150
155
|
method: "POST",
|
|
151
156
|
redirect: "error",
|
|
152
157
|
signal: AbortSignal.timeout(15e3),
|
|
153
|
-
headers: { "Content-Type": form ? "application/x-www-form-urlencoded" : "application/json" },
|
|
158
|
+
headers: { "Content-Type": form ? "application/x-www-form-urlencoded" : "application/json", "X-Rill-CLI-Version": CLI_VERSION },
|
|
154
159
|
body: form ? new URLSearchParams(Object.entries(body).map(([key2, value2]) => [key2, String(value2)])) : JSON.stringify(body)
|
|
155
160
|
});
|
|
156
161
|
const value = await response.json();
|
|
@@ -246,6 +251,12 @@ async function connectAgent(apiUrl, email3, options = {}) {
|
|
|
246
251
|
async function beginConnection(apiUrl, email3) {
|
|
247
252
|
if (process.env.RILL_TOKEN) throw new Error("Unset RILL_TOKEN before connecting a local identity.");
|
|
248
253
|
let saved = parseAuthorization(await loadStoredCredential(apiUrl));
|
|
254
|
+
if (saved?.connection?.status === "pending" && saved.connection.expiresAt <= Date.now()) {
|
|
255
|
+
if (saved.connection.email !== email3) throw new Error("Use the original account to finish or recover this connection.");
|
|
256
|
+
const result = await pollSavedConnection(apiUrl, saved.connection.id);
|
|
257
|
+
if (result.status !== "expired") return result;
|
|
258
|
+
saved = parseAuthorization(await loadStoredCredential(apiUrl));
|
|
259
|
+
}
|
|
249
260
|
if (saved?.connection?.status === "pending" && saved.connection.expiresAt > Date.now()) {
|
|
250
261
|
if (saved.connection.email !== email3) throw new Error("A connection for another email is pending. Let it expire before starting a different connection.");
|
|
251
262
|
process.stderr.write(`Open ${saved.connection.verificationUri}
|
|
@@ -259,6 +270,22 @@ Sign in as ${email3} and enter ${saved.connection.userCode}. Approve only the re
|
|
|
259
270
|
const result = await request(apiUrl, "/agent/identity/claim", { claim_token: saved.claimToken, email: email3 });
|
|
260
271
|
claim = result.claim_attempt;
|
|
261
272
|
} catch (error51) {
|
|
273
|
+
if (error51 instanceof AgentAuthError && error51.code === "claim_already_approved") {
|
|
274
|
+
saved.connection ??= {
|
|
275
|
+
id: randomBytes(16).toString("hex"),
|
|
276
|
+
email: email3,
|
|
277
|
+
verificationUri: "",
|
|
278
|
+
userCode: "",
|
|
279
|
+
expiresAt: Date.now(),
|
|
280
|
+
interval: 5,
|
|
281
|
+
nextPollAt: 0,
|
|
282
|
+
status: "pending"
|
|
283
|
+
};
|
|
284
|
+
saved.connection.status = "pending";
|
|
285
|
+
saved.connection.nextPollAt = 0;
|
|
286
|
+
await save(apiUrl, saved);
|
|
287
|
+
return pollSavedConnection(apiUrl, saved.connection.id);
|
|
288
|
+
}
|
|
262
289
|
if (!(error51 instanceof AgentAuthError) || error51.code !== "claim_expired") throw error51;
|
|
263
290
|
}
|
|
264
291
|
}
|
|
@@ -309,11 +336,6 @@ async function pollSavedConnection(apiUrl, authorizationId) {
|
|
|
309
336
|
if (!saved?.connection || saved.connection.id !== authorizationId) throw new AgentAuthError("authorization_not_found", "No matching saved connection for this API URL. Use the latest connect response.");
|
|
310
337
|
const connection = saved.connection;
|
|
311
338
|
if (connection.status !== "pending") return connectionView(apiUrl, saved);
|
|
312
|
-
if (Date.now() >= connection.expiresAt) {
|
|
313
|
-
connection.status = "expired";
|
|
314
|
-
await save(apiUrl, saved);
|
|
315
|
-
return connectionView(apiUrl, saved);
|
|
316
|
-
}
|
|
317
339
|
if (Date.now() < connection.nextPollAt) return connectionView(apiUrl, saved);
|
|
318
340
|
connection.nextPollAt = Date.now() + connection.interval * 1e3;
|
|
319
341
|
await save(apiUrl, saved);
|
|
@@ -322,7 +344,7 @@ async function pollSavedConnection(apiUrl, authorizationId) {
|
|
|
322
344
|
saved = withTokens({ version: 1, anonymous: false, connection: { ...connection, status: "authenticated", userCode: "" } }, tokens);
|
|
323
345
|
} catch (error51) {
|
|
324
346
|
if (!(error51 instanceof AgentAuthError)) throw error51;
|
|
325
|
-
if (error51.code === "expired_token" || error51.code === "claim_expired") connection.status = "expired";
|
|
347
|
+
if (error51.code === "expired_token" || error51.code === "claim_expired" || error51.code === "claim_delivery_expired" || error51.code === "claimed_or_in_flight" && Date.now() >= connection.expiresAt) connection.status = "expired";
|
|
326
348
|
else if (error51.code === "access_denied" || error51.code === "claim_revoked") connection.status = "denied";
|
|
327
349
|
else if (error51.code === "slow_down") {
|
|
328
350
|
connection.interval += 5;
|
|
@@ -15777,7 +15799,8 @@ var interactionReportFields = {
|
|
|
15777
15799
|
sideEffects: external_exports.array(sideEffectSchema).max(30).optional(),
|
|
15778
15800
|
cleanup: external_exports.literal("not_attempted").optional()
|
|
15779
15801
|
};
|
|
15780
|
-
var
|
|
15802
|
+
var cloudRunPrompt = external_exports.string().min(1).max(2e3).refine((value) => Boolean(value.trim()), "Describe what you want Rill to do.");
|
|
15803
|
+
var cloudSubmission = external_exports.object({ ...interactionFields, id: external_exports.string().uuid(), url: cloudRunTarget, prompt: cloudRunPrompt, expectation: external_exports.string().trim().min(1).max(1e3).optional(), account: external_exports.string().regex(/^[a-z0-9-]{1,60}$/).optional() }).strict();
|
|
15781
15804
|
var siteAccountSchema = external_exports.object({
|
|
15782
15805
|
name: external_exports.string().regex(/^[a-z0-9-]{1,60}$/),
|
|
15783
15806
|
origin: publicTarget.refine((v) => new URL(v).protocol === "https:" && new URL(v).origin === v, "Use an exact HTTPS origin."),
|
|
@@ -15831,15 +15854,70 @@ var agentOutcomeSchema = external_exports.object({
|
|
|
15831
15854
|
evidence: external_exports.string().max(1e3)
|
|
15832
15855
|
}).strict();
|
|
15833
15856
|
|
|
15857
|
+
// ../recorder/src/collaborator-pointer.ts
|
|
15858
|
+
var collaboratorPointerSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="17.3" height="17.3" viewBox="-0.75 -0.75 17.3 17.3">
|
|
15859
|
+
<!-- Hotspot is (0, 0) in user units: 0.75px right and 0.75px down from the SVG's top-left corner. -->
|
|
15860
|
+
<defs>
|
|
15861
|
+
<linearGradient id="rill-pointer-fill" x1="0" y1="0" x2=".6" y2="1">
|
|
15862
|
+
<stop offset="0" style="stop-color: var(--rill-cursor-accent-light, #8f91f5)"/>
|
|
15863
|
+
<stop offset=".55" style="stop-color: var(--rill-cursor-accent, #6366f1)"/>
|
|
15864
|
+
</linearGradient>
|
|
15865
|
+
</defs>
|
|
15866
|
+
<path d="M0 0L4.1 14.9Q4.5 16.5 5.5 15.2L8.8 8.8L15.2 5.5Q16.5 4.5 14.9 4.1Z" fill="url(#rill-pointer-fill)" stroke="#fff" stroke-width="1.5" stroke-linejoin="round"/>
|
|
15867
|
+
</svg>`;
|
|
15868
|
+
var collaboratorPointerMarkup = `<span class="rill-cursor-shape">${collaboratorPointerSvg}</span><span class="rill-cursor-label">Rill</span>`;
|
|
15869
|
+
var collaboratorPointerStyles = `
|
|
15870
|
+
.rill-cursor-visual { position:absolute; left:0; top:0; width:0; height:0; --rill-cursor-accent-light:color-mix(in srgb,var(--rill-cursor-accent) 72%,#fff); }
|
|
15871
|
+
.rill-cursor-shape { position:absolute; left:-.75px; top:-.75px; width:17.3px; height:17.3px; }
|
|
15872
|
+
.rill-cursor-shape svg { display:block; width:17.3px; height:17.3px; transform-origin:.75px .75px; transition:transform 110ms ease-out; filter:drop-shadow(0 .5px 1px rgba(12,12,18,.25)) drop-shadow(0 1.5px 3px rgba(12,12,18,.14)); }
|
|
15873
|
+
.rill-cursor-visual.is-pressed .rill-cursor-shape svg { transform:scale(.86); transition-duration:50ms; }
|
|
15874
|
+
.rill-cursor-label { position:absolute; left:10px; top:15px; height:15px; padding:0 6px; display:flex; align-items:center; border-radius:8px; font:600 9px/1 system-ui,sans-serif; letter-spacing:.02em; color:#fff; white-space:nowrap; opacity:.92; background:linear-gradient(180deg,color-mix(in srgb,var(--rill-cursor-accent) 78%,#fff),var(--rill-cursor-accent)); box-shadow:0 0 0 1.25px #fff,0 1px 3px rgba(12,12,18,.18),0 0 1px 1.25px rgba(12,12,18,.1); }
|
|
15875
|
+
.rill-cursor-visual.label-left .rill-cursor-label { left:auto; right:4px; }
|
|
15876
|
+
.rill-cursor-visual.label-above .rill-cursor-label { top:auto; bottom:6px; }
|
|
15877
|
+
@media (prefers-reduced-motion:reduce) { .rill-cursor-shape svg { transition:none; } }
|
|
15878
|
+
`;
|
|
15879
|
+
|
|
15880
|
+
// ../recorder/src/scroll-capsule.ts
|
|
15881
|
+
var scrollCapsuleSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="20.5" height="42.5" viewBox="0 0 20.5 42.5">
|
|
15882
|
+
<!-- Capsule body is 18 x 40 at (1.25, 1.25); the white edge sits 1.25px outside it. Shown pointing down. -->
|
|
15883
|
+
<defs>
|
|
15884
|
+
<linearGradient id="rill-capsule-fill" x1="0" y1="0" x2="0" y2="1">
|
|
15885
|
+
<stop offset="0" style="stop-color: var(--rill-cursor-accent-light, #8588f4)"/>
|
|
15886
|
+
<stop offset="1" style="stop-color: var(--rill-cursor-accent, #6366f1)"/>
|
|
15887
|
+
</linearGradient>
|
|
15888
|
+
</defs>
|
|
15889
|
+
<rect x="1.25" y="1.25" width="18" height="40" rx="9" fill="url(#rill-capsule-fill)" stroke="#fff" stroke-width="2.5" paint-order="stroke"/>
|
|
15890
|
+
<!-- For scrolling up, rotate this group 180deg around the capsule center (10.25, 21.25). -->
|
|
15891
|
+
<g id="chevrons" fill="none" stroke="#fff" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">
|
|
15892
|
+
<path d="M5.85 11.05Q8.85 13.85 10.25 15.25Q11.65 13.85 14.65 11.05" opacity=".32"/>
|
|
15893
|
+
<path d="M5.85 19.05Q8.85 21.85 10.25 23.25Q11.65 21.85 14.65 19.05" opacity=".6"/>
|
|
15894
|
+
<path d="M5.85 27.05Q8.85 29.85 10.25 31.25Q11.65 29.85 14.65 27.05" opacity=".95"/>
|
|
15895
|
+
</g>
|
|
15896
|
+
</svg>`;
|
|
15897
|
+
var scrollCapsuleStyles = `
|
|
15898
|
+
.scroll-indicator { position:absolute; right:12.75px; bottom:10.75px; width:20.5px; height:42.5px; opacity:0; transform:translateY(4px) scale(.92); transform-origin:center; transition:opacity 180ms ease-out,transform 180ms ease-out; filter:drop-shadow(0 1px 1.5px rgba(12,12,18,.18)) drop-shadow(0 4px 5px rgba(12,12,18,.12)); --rill-cursor-accent-light:color-mix(in srgb,var(--rill-cursor-accent) 78%,#fff); }
|
|
15899
|
+
.scroll-indicator.is-visible { opacity:1; transform:none; transition:opacity 160ms ease-out,transform 260ms cubic-bezier(.2,.9,.3,1.25); }
|
|
15900
|
+
.scroll-indicator svg { position:absolute; left:50%; top:50%; width:20.5px; height:42.5px; translate:-50% -50%; transform-origin:center; }
|
|
15901
|
+
.scroll-indicator[data-direction="right"],.scroll-indicator[data-direction="left"] { width:42.5px; height:20.5px; }
|
|
15902
|
+
.scroll-indicator[data-direction="right"] svg { rotate:-90deg; }
|
|
15903
|
+
.scroll-indicator[data-direction="left"] svg { rotate:90deg; }
|
|
15904
|
+
.scroll-indicator[data-direction="unknown"] #chevrons { visibility:hidden; }
|
|
15905
|
+
@media (prefers-reduced-motion:reduce) { .scroll-indicator,.scroll-indicator.is-visible { transform:none; transition:none; } }
|
|
15906
|
+
`;
|
|
15907
|
+
|
|
15834
15908
|
// ../recorder/src/cursor-overlay.ts
|
|
15835
15909
|
function installCursorOverlay(options) {
|
|
15836
15910
|
const scope = window;
|
|
15837
15911
|
if (scope[options.key]) return;
|
|
15838
15912
|
let host;
|
|
15913
|
+
let scrollTimer;
|
|
15914
|
+
let scrollExitTimer;
|
|
15839
15915
|
const controller = new AbortController();
|
|
15840
15916
|
const animations = /* @__PURE__ */ new Set();
|
|
15841
15917
|
const cleanup = () => {
|
|
15842
15918
|
controller.abort();
|
|
15919
|
+
window.clearTimeout(scrollTimer);
|
|
15920
|
+
window.clearTimeout(scrollExitTimer);
|
|
15843
15921
|
for (const animation of animations) animation.cancel();
|
|
15844
15922
|
host?.remove();
|
|
15845
15923
|
delete scope[options.key];
|
|
@@ -15855,48 +15933,135 @@ function installCursorOverlay(options) {
|
|
|
15855
15933
|
const style = document.createElement("style");
|
|
15856
15934
|
style.textContent = `
|
|
15857
15935
|
:host, * { pointer-events: none !important; }
|
|
15858
|
-
.
|
|
15859
|
-
.
|
|
15860
|
-
|
|
15861
|
-
.
|
|
15936
|
+
${options.pointerStyles}
|
|
15937
|
+
.pointer { display:none; --rill-cursor-accent:${options.color}; }
|
|
15938
|
+
${options.scrollStyles}
|
|
15939
|
+
.scroll-indicator { --rill-cursor-accent:${options.color}; }
|
|
15940
|
+
.click-dot, .click-ring { position:absolute; border-radius:50%; transform:translate(-50%,-50%); }
|
|
15941
|
+
.click-dot { width:5px; height:5px; background:${options.color}; box-shadow:0 0 0 1px #fff,0 0 2px rgba(0,0,0,.3); }
|
|
15942
|
+
.click-ring { box-sizing:border-box; border:1px solid ${options.color}; box-shadow:0 0 0 .5px #fffc,inset 0 0 0 .5px #fffc,0 0 2px rgba(0,0,0,.25); }
|
|
15862
15943
|
`;
|
|
15863
15944
|
const pointer = document.createElement("div");
|
|
15864
|
-
pointer.className = "pointer";
|
|
15865
|
-
pointer.innerHTML =
|
|
15866
|
-
|
|
15945
|
+
pointer.className = "pointer rill-cursor-visual";
|
|
15946
|
+
pointer.innerHTML = options.pointerMarkup;
|
|
15947
|
+
const scrollIndicator = document.createElement("div");
|
|
15948
|
+
scrollIndicator.className = "scroll-indicator";
|
|
15949
|
+
scrollIndicator.innerHTML = options.scrollMarkup;
|
|
15950
|
+
const chevrons = scrollIndicator.querySelector("#chevrons");
|
|
15951
|
+
root.append(style, pointer, scrollIndicator);
|
|
15867
15952
|
document.documentElement.appendChild(host);
|
|
15868
15953
|
const listenerOptions = { capture: true, passive: true, signal: controller.signal };
|
|
15954
|
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
15955
|
+
let scrollDirection;
|
|
15956
|
+
let drift;
|
|
15957
|
+
const stopDrift = () => {
|
|
15958
|
+
if (!drift) return;
|
|
15959
|
+
animations.delete(drift);
|
|
15960
|
+
drift.cancel();
|
|
15961
|
+
drift = void 0;
|
|
15962
|
+
};
|
|
15963
|
+
const showScroll = (direction) => {
|
|
15964
|
+
window.clearTimeout(scrollTimer);
|
|
15965
|
+
window.clearTimeout(scrollExitTimer);
|
|
15966
|
+
scrollIndicator.dataset.direction = direction;
|
|
15967
|
+
chevrons.setAttribute("transform", direction === "up" ? "rotate(180 10.25 21.25)" : "");
|
|
15968
|
+
scrollIndicator.classList.add("is-visible");
|
|
15969
|
+
if (reducedMotion.matches || direction === "unknown") stopDrift();
|
|
15970
|
+
else if (direction !== scrollDirection || !drift) {
|
|
15971
|
+
stopDrift();
|
|
15972
|
+
const distance = direction === "up" || direction === "left" ? -3 : 3;
|
|
15973
|
+
const translate = direction === "left" || direction === "right" ? `${distance}px 0` : `0 ${distance}px`;
|
|
15974
|
+
drift = scrollIndicator.animate([
|
|
15975
|
+
{ translate: "0 0", easing: "cubic-bezier(.4,0,.6,1)" },
|
|
15976
|
+
{ translate, offset: 0.65, easing: "cubic-bezier(.4,0,.2,1)" },
|
|
15977
|
+
{ translate: "0 0" }
|
|
15978
|
+
], { duration: 820, iterations: Infinity });
|
|
15979
|
+
animations.add(drift);
|
|
15980
|
+
void drift.finished.catch(() => void 0);
|
|
15981
|
+
}
|
|
15982
|
+
scrollDirection = direction;
|
|
15983
|
+
scrollTimer = window.setTimeout(() => {
|
|
15984
|
+
scrollIndicator.classList.remove("is-visible");
|
|
15985
|
+
if (reducedMotion.matches) stopDrift();
|
|
15986
|
+
else scrollExitTimer = window.setTimeout(stopDrift, 180);
|
|
15987
|
+
}, 550);
|
|
15988
|
+
};
|
|
15989
|
+
reducedMotion.addEventListener("change", () => {
|
|
15990
|
+
if (reducedMotion.matches) stopDrift();
|
|
15991
|
+
}, { signal: controller.signal });
|
|
15992
|
+
const positions = /* @__PURE__ */ new WeakMap();
|
|
15993
|
+
positions.set(document, { x: window.scrollX, y: window.scrollY });
|
|
15994
|
+
document.addEventListener("scroll", (event) => {
|
|
15995
|
+
if (!event.isTrusted || document.hidden) return;
|
|
15996
|
+
const target = event.target;
|
|
15997
|
+
if (target !== document && !(target instanceof Element)) return;
|
|
15998
|
+
const position = target === document ? { x: window.scrollX, y: window.scrollY } : { x: target.scrollLeft, y: target.scrollTop };
|
|
15999
|
+
const previous = positions.get(target);
|
|
16000
|
+
positions.set(target, position);
|
|
16001
|
+
const dx = previous ? position.x - previous.x : 0;
|
|
16002
|
+
const dy = previous ? position.y - previous.y : 0;
|
|
16003
|
+
if (previous && !dx && !dy) return;
|
|
16004
|
+
const direction = !previous ? "unknown" : Math.abs(dy) >= Math.abs(dx) ? dy > 0 ? "down" : "up" : dx > 0 ? "right" : "left";
|
|
16005
|
+
showScroll(direction);
|
|
16006
|
+
}, listenerOptions);
|
|
15869
16007
|
const hide = () => {
|
|
15870
16008
|
pointer.style.display = "none";
|
|
16009
|
+
pointer.classList.remove("is-pressed");
|
|
15871
16010
|
};
|
|
15872
16011
|
const move = (event) => {
|
|
15873
|
-
if (event.pointerType === "touch") return;
|
|
16012
|
+
if (event.pointerType === "touch") return false;
|
|
15874
16013
|
if (event.target instanceof HTMLIFrameElement || event.target instanceof HTMLFrameElement) {
|
|
15875
16014
|
hide();
|
|
15876
|
-
return;
|
|
16015
|
+
return false;
|
|
15877
16016
|
}
|
|
15878
16017
|
pointer.style.display = "block";
|
|
15879
16018
|
pointer.style.transform = `translate(${event.clientX}px, ${event.clientY}px)`;
|
|
16019
|
+
pointer.classList.toggle("label-left", event.clientX > window.innerWidth - 90);
|
|
16020
|
+
pointer.classList.toggle("label-above", event.clientY > window.innerHeight - 34);
|
|
16021
|
+
pointer.classList.toggle("is-pressed", event.buttons !== 0);
|
|
16022
|
+
return true;
|
|
16023
|
+
};
|
|
16024
|
+
const release = (event) => {
|
|
16025
|
+
if (event.pointerType !== "touch") pointer.classList.toggle("is-pressed", event.type !== "pointercancel" && event.buttons !== 0);
|
|
15880
16026
|
};
|
|
15881
16027
|
document.addEventListener("pointermove", move, listenerOptions);
|
|
15882
16028
|
document.addEventListener("pointerover", move, listenerOptions);
|
|
15883
|
-
document.addEventListener("
|
|
15884
|
-
|
|
15885
|
-
|
|
15886
|
-
|
|
15887
|
-
|
|
15888
|
-
pulse.style.left = `${event.clientX - 16}px`;
|
|
15889
|
-
pulse.style.top = `${event.clientY - 16}px`;
|
|
15890
|
-
root.insertBefore(pulse, pointer);
|
|
15891
|
-
const animation = pulse.animate([
|
|
15892
|
-
{ transform: "scale(.4)", opacity: 0.9 },
|
|
15893
|
-
{ transform: "scale(1.8)", opacity: 0 }
|
|
15894
|
-
], { duration: 400, easing: "ease-out" });
|
|
16029
|
+
document.addEventListener("pointerup", release, listenerOptions);
|
|
16030
|
+
document.addEventListener("pointercancel", release, listenerOptions);
|
|
16031
|
+
const animateFeedback = (element, frames, duration3, easing) => {
|
|
16032
|
+
root.insertBefore(element, pointer);
|
|
16033
|
+
const animation = element.animate(frames, { duration: duration3, easing });
|
|
15895
16034
|
animations.add(animation);
|
|
15896
16035
|
void animation.finished.catch(() => void 0).finally(() => {
|
|
15897
16036
|
animations.delete(animation);
|
|
15898
|
-
|
|
16037
|
+
element.remove();
|
|
15899
16038
|
});
|
|
16039
|
+
};
|
|
16040
|
+
document.addEventListener("pointerdown", (event) => {
|
|
16041
|
+
if (!move(event)) return;
|
|
16042
|
+
const dot = document.createElement("div");
|
|
16043
|
+
dot.className = "click-dot";
|
|
16044
|
+
dot.style.left = `${event.clientX}px`;
|
|
16045
|
+
dot.style.top = `${event.clientY}px`;
|
|
16046
|
+
animateFeedback(dot, reducedMotion.matches ? [{ opacity: 1 }, { opacity: 0 }] : [
|
|
16047
|
+
{ transform: "translate(-50%,-50%) scale(1)", opacity: 1, offset: 0 },
|
|
16048
|
+
{ transform: "translate(-50%,-50%) scale(1)", opacity: 1, offset: 0.5 },
|
|
16049
|
+
{ transform: "translate(-50%,-50%) scale(.3)", opacity: 0, offset: 1 }
|
|
16050
|
+
], reducedMotion.matches ? 120 : 300, "ease-in");
|
|
16051
|
+
const ring = document.createElement("div");
|
|
16052
|
+
ring.className = "click-ring";
|
|
16053
|
+
ring.style.left = `${event.clientX}px`;
|
|
16054
|
+
ring.style.top = `${event.clientY}px`;
|
|
16055
|
+
if (event.button === 2) ring.style.borderStyle = "dashed";
|
|
16056
|
+
if (reducedMotion.matches) {
|
|
16057
|
+
ring.style.width = "26px";
|
|
16058
|
+
ring.style.height = "26px";
|
|
16059
|
+
}
|
|
16060
|
+
animateFeedback(ring, reducedMotion.matches ? [{ opacity: 1 }, { opacity: 0 }] : [
|
|
16061
|
+
{ width: "4px", height: "4px", opacity: 1, offset: 0 },
|
|
16062
|
+
{ opacity: 1, offset: 0.4 },
|
|
16063
|
+
{ width: "26px", height: "26px", opacity: 0, offset: 1 }
|
|
16064
|
+
], reducedMotion.matches ? 120 : 320, "cubic-bezier(.2,.7,.2,1)");
|
|
15900
16065
|
}, listenerOptions);
|
|
15901
16066
|
document.addEventListener("pointerout", (event) => {
|
|
15902
16067
|
if (!event.relatedTarget) hide();
|
|
@@ -15914,7 +16079,7 @@ async function attachCursorOverlay(page, cdp, input) {
|
|
|
15914
16079
|
if (!appearance.enabled) return async () => {
|
|
15915
16080
|
};
|
|
15916
16081
|
const key2 = `__rillCursor_${crypto.randomUUID().replaceAll("-", "")}`;
|
|
15917
|
-
const source = `(${installCursorOverlay.toString()})(${JSON.stringify({ ...appearance, key: key2 })})`;
|
|
16082
|
+
const source = `(${installCursorOverlay.toString()})(${JSON.stringify({ ...appearance, key: key2, pointerMarkup: collaboratorPointerMarkup, pointerStyles: collaboratorPointerStyles, scrollMarkup: scrollCapsuleSvg, scrollStyles: scrollCapsuleStyles })})`;
|
|
15918
16083
|
await cdp.send("Page.enable");
|
|
15919
16084
|
const { identifier } = await cdp.send("Page.addScriptToEvaluateOnNewDocument", { source });
|
|
15920
16085
|
let stopped = false;
|
|
@@ -16771,13 +16936,6 @@ async function withRunFeedback(session, start) {
|
|
|
16771
16936
|
|
|
16772
16937
|
// src/doctor.ts
|
|
16773
16938
|
import { spawn as spawn7 } from "child_process";
|
|
16774
|
-
|
|
16775
|
-
// src/version.ts
|
|
16776
|
-
import { createRequire } from "module";
|
|
16777
|
-
var packageJson = createRequire(import.meta.url)("../package.json");
|
|
16778
|
-
var CLI_VERSION = packageJson.version;
|
|
16779
|
-
|
|
16780
|
-
// src/doctor.ts
|
|
16781
16939
|
var defaultDependencies = {
|
|
16782
16940
|
platform: process.platform,
|
|
16783
16941
|
encoding: "remote",
|