@inetafrica/open-claudia 3.5.25 → 3.5.26

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.5.26
4
+
5
+ The Browser app's phone and web view stays sharp after a page load. A canary build for the Browser canary bot first; the fleet waits for Sumeet's OK.
6
+
7
+ - **Sharp after every page.** On the canary's Chrome 150 (Linux) the driver's pictures dropped from the view's density to 1x at the first page load (the view kept its density; the picture did not). After a main-frame navigation or a load, the window is now resized by a pixel and back, which brings the density back: 906x1760 pictures for a 412x800 phone at 2.2x on duckduckgo.com, en.m.wikipedia.org and example.com, 1 to 4 s after each load.
8
+ - **Tests:** `test-browser-drive.js`.
9
+
3
10
  ## 3.5.25
4
11
 
5
12
  The Browser app feels like a browser on the phone and on the web (Sumeet, 10 Oct 08:53 EAT on his phone: "it feels like a browser on my phone… like Google Chrome app", and 09:18: "the web and mobile still need to also feel native… don't forget the website"). A canary build for the Browser canary bot first; the fleet waits for his OK.
@@ -32,6 +32,8 @@ const CALL_TIMEOUT_MS = 4000;
32
32
  const CONNECT_TIMEOUT_MS = 3000;
33
33
  // The text fields are read this long after the page stops changing (and after a tap).
34
34
  const FIELDS_SETTLE_MS = 250;
35
+ // After a page load the window is nudged this long after the load's events settle.
36
+ const NUDGE_DELAY_MS = 120;
35
37
  const MAX_FIELDS = 60;
36
38
  const TEXT_MAX = 500;
37
39
 
@@ -278,6 +280,30 @@ function onFrame(drive, params) {
278
280
  scheduleFields(drive);
279
281
  }
280
282
 
283
+ // After a page load, Chrome 150 on Linux draws the view at 1x again: the view keeps its density,
284
+ // the picture does not (proven 10 Oct on the canary's Chrome 150.0.7871.124: 2x until the load,
285
+ // 1x after; the same view sent again, a new screencast, or the view cleared and set again change
286
+ // nothing; the window resized by a pixel and back brings 2x back). Chrome 149 on a Mac did the
287
+ // opposite, 1x until the first load. So after every main-frame navigation and load, the window
288
+ // is nudged by a pixel and back.
289
+ function nudgeWindow(drive) {
290
+ if (!drive || drive.stopped || !drive.viewport || drive.windowId === null) return;
291
+ clearTimeout(drive.nudgeTimer);
292
+ drive.nudgeTimer = setTimeout(async () => {
293
+ if (drive.stopped || !drive.viewport) return;
294
+ const vp = drive.viewport;
295
+ const width = Math.round(vp.width * vp.dpr) + drive.insets.width;
296
+ const height = Math.round(vp.height * vp.dpr) + drive.insets.height;
297
+ try {
298
+ await call(drive.conn, "Browser.setWindowBounds", { windowId: drive.windowId, bounds: { width: width + 1, height, windowState: "normal" } });
299
+ await call(drive.conn, "Browser.setWindowBounds", { windowId: drive.windowId, bounds: { width, height, windowState: "normal" } });
300
+ } catch (_) {
301
+ // the next load nudges again
302
+ }
303
+ }, NUDGE_DELAY_MS);
304
+ if (drive.nudgeTimer.unref) drive.nudgeTimer.unref();
305
+ }
306
+
281
307
  // ---------------------------------------------------------------------------
282
308
  // start / fit / stop
283
309
 
@@ -351,9 +377,11 @@ async function start({ session, viewport, savedBounds = null } = {}) {
351
377
  fieldsTimer: null,
352
378
  fieldsKey: "",
353
379
  touchBase: null,
380
+ nudgeTimer: null,
354
381
  };
355
382
  conn.handlers.push((msg) => {
356
383
  if (msg.method === "Page.screencastFrame" && msg.sessionId === drive.sid) onFrame(drive, msg.params);
384
+ else if (msg.sessionId === drive.sid && ((msg.method === "Page.frameNavigated" && msg.params && msg.params.frame && !msg.params.frame.parentId) || msg.method === "Page.loadEventFired")) nudgeWindow(drive);
357
385
  else if (msg.method === "_closed" || (msg.method === "Target.detachedFromTarget" && msg.params && msg.params.sessionId === drive.sid)) {
358
386
  if (!drive.stopped) lost(drive);
359
387
  }
@@ -416,6 +444,7 @@ async function fit(viewport) {
416
444
  async function restore(drive) {
417
445
  drive.stopped = true;
418
446
  clearTimeout(drive.fieldsTimer);
447
+ clearTimeout(drive.nudgeTimer);
419
448
  const { conn, sid } = drive;
420
449
  if (conn && !conn.closed) {
421
450
  if (sid && drive.screencasting) await call(conn, "Page.stopScreencast", {}, sid).catch(() => {});
@@ -437,6 +466,7 @@ function lost(drive) {
437
466
  }
438
467
  drive.stopped = true;
439
468
  clearTimeout(drive.fieldsTimer);
469
+ clearTimeout(drive.nudgeTimer);
440
470
  closeConnection(drive.conn);
441
471
  view.driveFeed.emit("stop", { session: drive.session.name, reason: "lost" });
442
472
  console.error("[browser] the driver's view lost its connection to Chrome");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inetafrica/open-claudia",
3
- "version": "3.5.25",
3
+ "version": "3.5.26",
4
4
  "description": "An always-on, provider-agnostic coding-agent harness for Claude Code and OpenAI Codex via chat",
5
5
  "main": "bot.js",
6
6
  "bin": {
@@ -615,7 +615,9 @@ assert.match(pkg.description, /provider-agnostic coding-agent harness/i);
615
615
  // ("it feels like a browser on my phone… like Google Chrome app"): the bot's tab takes
616
616
  // the driver's screen, input straight to Chrome, the page's text fields, hand backs wake
617
617
  // only a waiting bot. A canary build for the Browser canary bot; the fleet waits for his OK.
618
- assert.strictEqual(pkg.version, "3.5.25", "release version must remain unchanged without explicit approval");
618
+ // 3.5.26: the same go-ahead; 3.5.25's pictures fell back to 1x after a page load on the
619
+ // canary's Chrome 150, now nudged back to the view's density. Canary first, fleet on his OK.
620
+ assert.strictEqual(pkg.version, "3.5.26", "release version must remain unchanged without explicit approval");
619
621
  for (const keyword of ["claude", "codex", "coding-agent", "provider-agnostic"]) {
620
622
  assert.ok(pkg.keywords.includes(keyword), `package keyword missing: ${keyword}`);
621
623
  }