replicas-computer 0.3.4 → 0.3.5

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
@@ -10,6 +10,7 @@ The versioned computer-use runtime for Replicas workspace images.
10
10
  - `src/pacer.ts` owns the per-viewer send budget: fresh media, NACK repairs and protective copies share one token bucket.
11
11
  - `src/rtp.ts` owns RTP continuity, keyframe detection, and frame reassembly for the socket fallback.
12
12
  - `src/stream-viewer.ts` owns the browser side: WebRTC playback, input routing, the WebSocket fallback, diagnostics and reconnects.
13
+ - `src/input-bridge.ts` converts takeover input into desktop events, accumulating small trackpad movements while preserving full mouse-wheel steps.
13
14
  - `src/viewer.ts` owns the optional noVNC fallback.
14
15
  - `assets/desktop/start-services.sh` owns the X11 and stream process lifecycle.
15
16
  - `xsettingsd` broadcasts theme changes to running GTK apps and Chrome. Chrome follows the dashboard theme without reopening tabs; launch it without a `GTK_THEME` override.
package/dist/index.js CHANGED
@@ -2937,7 +2937,7 @@ async function computerStatusCommand() {
2937
2937
  }
2938
2938
 
2939
2939
  // src/version.ts
2940
- var COMPUTER_USE_VERSION = "0.3.4";
2940
+ var COMPUTER_USE_VERSION = "0.3.5";
2941
2941
  var COMPUTER_USE_PROTOCOL_VERSION = 1;
2942
2942
 
2943
2943
  // src/program.ts
@@ -3556,6 +3556,7 @@ function superviseEncoder(options) {
3556
3556
 
3557
3557
  // src/input-bridge.ts
3558
3558
  import { spawn as spawn4 } from "child_process";
3559
+ var scrollPixelsPerStep = 80;
3559
3560
  var namedKeys = {
3560
3561
  AltLeft: "Alt_L",
3561
3562
  AltRight: "Alt_R",
@@ -3615,6 +3616,8 @@ var InputBridge = class {
3615
3616
  pointerFlush;
3616
3617
  positionSequence = -1;
3617
3618
  actionId = 0;
3619
+ scrollRemainder = 0;
3620
+ scrollButton = 0;
3618
3621
  latestPosition;
3619
3622
  pressedButtons = /* @__PURE__ */ new Set();
3620
3623
  pressedKeys = /* @__PURE__ */ new Set();
@@ -3673,13 +3676,23 @@ var InputBridge = class {
3673
3676
  if (message.type === "wheel") {
3674
3677
  this.pointer = this.coordinates(message.x, message.y);
3675
3678
  this.flushPointer(true);
3676
- const vertical = Math.min(4, Math.max(1, Math.round(Math.abs(message.deltaY) / 80)));
3677
- const horizontal = Math.min(4, Math.max(1, Math.round(Math.abs(message.deltaX) / 80)));
3678
- if (Math.abs(message.deltaY) >= Math.abs(message.deltaX) && message.deltaY) {
3679
- for (let index = 0; index < vertical; index += 1) this.write(`mouseclick ${message.deltaY < 0 ? 4 : 5}`);
3680
- } else if (message.deltaX) {
3681
- for (let index = 0; index < horizontal; index += 1) this.write(`mouseclick ${message.deltaX < 0 ? 6 : 7}`);
3679
+ const vertical = Math.abs(message.deltaY) >= Math.abs(message.deltaX);
3680
+ const delta = vertical ? message.deltaY : message.deltaX;
3681
+ if (!delta) return;
3682
+ const button = vertical ? delta < 0 ? 4 : 5 : delta < 0 ? 6 : 7;
3683
+ if (button !== this.scrollButton) this.scrollRemainder = 0;
3684
+ this.scrollButton = button;
3685
+ const distance = Math.abs(delta);
3686
+ let steps;
3687
+ if (distance >= scrollPixelsPerStep) {
3688
+ steps = Math.min(4, Math.round(distance / scrollPixelsPerStep));
3689
+ this.scrollRemainder = 0;
3690
+ } else {
3691
+ this.scrollRemainder += distance;
3692
+ steps = Math.floor(this.scrollRemainder / scrollPixelsPerStep);
3693
+ this.scrollRemainder %= scrollPixelsPerStep;
3682
3694
  }
3695
+ for (let index = 0; index < steps; index += 1) this.write(`mouseclick ${button}`);
3683
3696
  return;
3684
3697
  }
3685
3698
  if (message.type === "key") {
@@ -3701,6 +3714,8 @@ var InputBridge = class {
3701
3714
  if (this.pointerFlush) clearImmediate(this.pointerFlush);
3702
3715
  this.pointerFlush = void 0;
3703
3716
  this.pointer = void 0;
3717
+ this.scrollRemainder = 0;
3718
+ this.scrollButton = 0;
3704
3719
  for (const button of this.pressedButtons) this.write(`mouseup ${button}`);
3705
3720
  for (const key of this.pressedKeys) this.write(`keyup ${key}`);
3706
3721
  this.pressedButtons.clear();
@@ -30,6 +30,12 @@ function validServerMessage(value) {
30
30
  }
31
31
  }
32
32
 
33
+ // src/wheel.ts
34
+ function wheelDeltaPixels(event, pageHeight) {
35
+ const scale = event.deltaMode === WheelEvent.DOM_DELTA_LINE ? 32 : event.deltaMode === WheelEvent.DOM_DELTA_PAGE ? pageHeight : 1;
36
+ return { deltaX: event.deltaX * scale, deltaY: event.deltaY * scale };
37
+ }
38
+
33
39
  // ../shared/src/desktop-stream.ts
34
40
  var DEFAULT_STREAM_REQUEST = {
35
41
  transport: "webrtc",
@@ -611,7 +617,7 @@ screen.addEventListener("pointerup", (event) => {
611
617
  screen.addEventListener("pointercancel", () => send({ type: "release" }));
612
618
  screen.addEventListener("wheel", (event) => {
613
619
  event.preventDefault();
614
- send({ type: "wheel", ...normalizedPointer(event), deltaX: event.deltaX, deltaY: event.deltaY });
620
+ send({ type: "wheel", ...normalizedPointer(event), ...wheelDeltaPixels(event, screen.clientHeight) });
615
621
  }, { passive: false });
616
622
  screen.addEventListener("contextmenu", (event) => event.preventDefault());
617
623
  window.addEventListener("keydown", (event) => {
package/dist/viewer.js CHANGED
@@ -1,6 +1,14 @@
1
1
  // src/viewer.ts
2
2
  import RFB from "./core/rfb.js";
3
3
  import { encodings } from "./core/encodings.js";
4
+
5
+ // src/wheel.ts
6
+ function wheelDeltaPixels(event, pageHeight) {
7
+ const scale = event.deltaMode === WheelEvent.DOM_DELTA_LINE ? 32 : event.deltaMode === WheelEvent.DOM_DELTA_PAGE ? pageHeight : 1;
8
+ return { deltaX: event.deltaX * scale, deltaY: event.deltaY * scale };
9
+ }
10
+
11
+ // src/viewer.ts
4
12
  var screen = document.querySelector("#screen");
5
13
  var status = document.querySelector("#status");
6
14
  var statusText = document.querySelector("#status-text");
@@ -145,9 +153,9 @@ var shiftCanvasForWheel = (event) => {
145
153
  const canvas = screen.querySelector("canvas");
146
154
  const context = canvas?.getContext("2d");
147
155
  if (!canvas || !context || !canvas.width || !canvas.height) return;
148
- const scale = event.deltaMode === WheelEvent.DOM_DELTA_LINE ? 32 : event.deltaMode === WheelEvent.DOM_DELTA_PAGE ? canvas.height : 1;
156
+ const { deltaY } = wheelDeltaPixels(event, canvas.height);
149
157
  const limit = Math.max(0, Math.min(optimisticScrollMax, canvas.height - 1));
150
- const offset = Math.trunc(Math.max(-limit, Math.min(limit, event.deltaY * scale)));
158
+ const offset = Math.trunc(Math.max(-limit, Math.min(limit, deltaY)));
151
159
  if (offset > 0) {
152
160
  context.drawImage(canvas, 0, offset, canvas.width, canvas.height - offset, 0, 0, canvas.width, canvas.height - offset);
153
161
  context.drawImage(canvas, 0, canvas.height - offset - 1, canvas.width, 1, 0, canvas.height - offset, canvas.width, offset);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-computer",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Replicas workspace computer-use runtime",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",