Skip to content

Releases: Agent-Pattern-Labs/geometra

v1.62.1

01 Jun 21:32

Choose a tag to compare

Release notes — 1.62.1 (Playwright browser cache recovery)

Summary

1.62.1 hardens the MCP browser proxy against Playwright browser-cache skew:

  • @geometra/proxy now retries stock Chromium launch once after installing the browser revision required by the resolved local Playwright package. This covers shared-cache states where another Playwright version pruned the expected chromium_headless_shell revision.
  • @geometra/mcp now treats managed child-process proxy startup as ready only after the structured ready signal, which is emitted after browser launch and initial page readiness.
  • Added npm run browsers:install as a local-version-safe repair command for the Playwright Chromium cache.

Migration notes

No API or protocol changes. GEOM v1 stays compatible.

Operators can disable automatic browser repair with:

GEOMETRA_PROXY_AUTO_INSTALL_BROWSERS=0

If browser downloads are disabled via PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1, Geometra will not auto-install Chromium and will surface the explicit local install command instead.

Performance notes

  • Normal proxy startup is unchanged when the expected browser revision already exists.
  • The retry path only runs after Playwright reports a missing Chromium executable.
  • No hit-test, text metrics, layout, or geometry-diff behavior changed.

Verification

  • npm run check -w @geometra/proxy
  • npm run mcp:check
  • npx vitest run mcp/src/__tests__/connect-utils.test.ts mcp/src/__tests__/proxy-session-recovery.test.ts
  • npm run build -w @geometra/proxy
  • npm run mcp:build
  • Stock proxy smoke through launchProxyRuntime({ stealth: false })

v1.61.3

14 May 00:44

Choose a tag to compare

Release v1.61.3 adds opt-in CloakBrowser stealth Chromium support for Geometra proxy and MCP pageUrl flows.\n\nHighlights:\n- Add --stealth / GEOMETRA_STEALTH=1 / GEOMETRA_BROWSER=stealth to geometra-proxy.\n- Add stealth: true to proxy-backed MCP connect, prepare, schema, fill, submit, and run-actions flows.\n- Partition the warm proxy pool by browser flavor so stock and stealth Chromium sessions cannot reuse each other.\n- Document CloakBrowser setup and add focused MCP coverage.\n\nVerification run locally:\n- bun run build\n- bun run release:gate\n- bun run lint\n- npm run check -w @geometra/proxy\n- npm run check in mcp\n- npx vitest run mcp/src/tests/proxy-session-recovery.test.ts mcp/src/tests/server-batch-results.test.ts

v1.61.2

12 May 20:47

Choose a tag to compare

Fix Geometra MCP host-timeout behavior by adding host-safe soft deadlines, resumable run_actions progress, submit_form timeout capping, and bounded semantic reveal loops.

v1.61.1 — Publish gateway package

25 Apr 20:40

Choose a tag to compare

Summary

  • Adds @geometra/gateway to the publish manifest so deploy apps can install it from npm.
  • Adds public hosted sandbox deployment guidance.
  • Bumps publishable packages to 1.61.1.

Verification

  • Quality checks passed on main for 95caeee.
  • Release source check includes @geometra/gateway at 1.61.1.

v1.61.0 — Agent-native claims hardening

25 Apr 18:33

Choose a tag to compare

Summary

  • Adds a public audit replay viewer for the agent-native claims workflow.
  • Adds core gateway approval/result hooks for webhook-style integrations.
  • Deepens the claims/compliance starter with queue filters, evidence panels, risk policy, and audit packet export.
  • Expands the live browser comparison into a fuller approval flow with DOM/screenshot trace comparison.

Verification

  • Quality checks passed on main for d93292d.
  • Local focused gateway tests, demo build, examples check, lint, and live benchmark passed.

v1.60.0 — Agent-native UI protocol runtime

25 Apr 10:20

Choose a tag to compare

Summary

  • Add agent-native semantic geometry snapshots and stable UI ids in @geometra/core.
  • Add createAgentRuntime() for inspect/click/focus/type/key/replay workflows.
  • Add gateway /inspect, MCP-style inspect tooling, replay artifacts, external-agent demo script, and benchmark methodology.

Validation

  • GitHub quality check passed on b9915acd.
  • Local focused tests, core/gateway builds, demo build, and benchmark:agent-native:assert passed before release.

v1.59.1 — menu-trigger dropdowns with container labels

23 Apr 22:03

Choose a tag to compare

Fix

pickListboxOption / setFieldChoice / fillFields kind:choice now match GitHub Primer–style dropdown triggers where the button's accessible name is the current selected value (e.g. Branch) rather than the field label (Ref type).

  • Adds [aria-haspopup="menu"] / [aria-haspopup="true"] to labeled-control discovery
  • Adds [role="menuitemradio"] / [role="menuitemcheckbox"] to the option picker
  • New findMenuTriggerByContainerLabel fallback walks up to 4 parent levels to match on the container's visible text minus the button's own text, with trailing-colon tolerance (Ref type:)
  • 2 new fixture tests in packages/proxy/src/__tests__/dom-actions.test.ts

Motivating case

GitHub's Add deployment branch or tag rule dialog (and other Primer admin UIs) render dropdowns as <span>Ref type</span><button aria-haspopup="menu">Branch</button> — this pattern was previously invisible to fill_fields/pick_listbox_option. Tested live against GitHub settings while fixing it.

Verified

  • 2473 / 2473 fast tests across 88 files
  • packages/proxy + mcp builds clean

🤖 Generated with Claude Code

v1.59.0 — BYO proxy passthrough in geometra_connect / prepare_browser

20 Apr 14:59

Choose a tag to compare

Summary

Adds optional BYO proxy passthrough so consumers can route the spawned Chromium through a residential / mobile / SOCKS proxy.

  • New proxy parameter on geometra_connect and geometra_prepare_browser MCP tools: { server, username?, password?, bypass? }
  • Forwarded to Playwright's chromium.launch({ proxy }) — supports http://, https://, socks5:// servers with optional basic auth and comma-separated bypass patterns
  • Reusable proxy pool partitioned by proxy identity (server + username + bypass) so direct and proxied sessions never share a Chromium, and sessions with different proxy configs don't pool either
  • CLI flags on geometra-proxy: --proxy-server, --proxy-username, --proxy-password, --proxy-bypass
  • Env fallbacks: GEOMETRA_PROXY_SERVER, GEOMETRA_PROXY_USERNAME, GEOMETRA_PROXY_PASSWORD, GEOMETRA_PROXY_BYPASS
  • Back-compat: no proxy argument → identical existing behavior

Why

Apply portals on Ashby, Lever, and Cloudflare-fronted ATSes fingerprint datacenter IPs and silently reject headless submits as bots ("flagged as possible spam"). Giving consumers a BYO proxy hook lets them pay for residential IP coverage without Geometra needing to bundle or resell bandwidth.

Usage

await geometra_connect({
  pageUrl: "https://jobs.ashbyhq.com/acme",
  isolated: true,
  proxy: {
    server: "http://residential-proxy.example.com:8080",
    username: "me",
    password: "secret",
    bypass: "*.internal,localhost",
  },
})

v1.58.0 — durable MCP sessions via @razroo/parallel-mcp

18 Apr 18:03

Choose a tag to compare

@geometra/mcp — durable sessions

Wired @razroo/parallel-mcp into Geometra MCP so session state survives WebSocket crashes.

  • Sessions get UUID-backed ids backed by a SqliteParallelMcpStore.
  • Snapshots on proxy attach, transport close, reconnect, and navigate.
  • A WebSocket crash no longer erases the logical session — it stays addressable, records a session.transport_closed snapshot, and Geometra reconnects on the next tool call.
  • Explicit disconnect now finalizes durable state instead of just dropping in-memory state.
  • SQLite file is process-scoped by default (override with GEOMETRA_MCP_STATE_FILE) to avoid lock contention across parallel workers.

CI

Includes a CI fix hoisting @razroo/parallel-mcp into the root lockfile so root vitest can resolve imports from mcp/src (mcp/ isn't a bun workspace).

Scope

Improves the failure mode for parallel MCP state: durable, reconnectable, less likely to smear across workers. Does not magically fix every upstream proxy/browser crash — live DOM/layout and some workflow state remain in-memory for now.

v1.57.0 — draggableSort + vitest cleanup + cookbook fix

18 Apr 11:10

Choose a tag to compare

Release notes — 1.57.0 (draggableSort + vitest cleanup + cookbook fix)

Summary

1.57.0 adds the second big gesture-driven UI primitive, fixes a long-standing cookbook error, and cleans up the default vitest run invocation on a fresh checkout:

  • @geometra/ui — new draggableSort primitive. Vertical list that reorders via pan gesture (canvas) or keyboard (ArrowUp/Down, Home/End). Complements swipeableList to round out the gesture-driven list family.
  • INTEGRATION_COOKBOOK.md — the modal focus policy recipe no longer uses the non-existent Signal.subscribe(callback) API; it now uses effect(() => signal.value) which is the real Signal observation surface shipped from @geometra/core.
  • vitest.config.ts — excludes tests/e2e/** so Playwright specs (which import @playwright/test) no longer crash a bare vitest run on a fresh checkout. Spec runs still happen through the Playwright runner.

@geometra/ui — draggableSort

Vertical reorderable list. Rows carry their own click + key handlers, so drag and keyboard flows share the same hit pipeline:

import { draggableSort } from '@geometra/ui'
import { attachGestureRecognizers } from '@geometra/renderer-canvas'

const list = draggableSort({
  items: tasks,
  itemHeight: 48,
  renderItem: (task, { index, isDragging }) =>
    taskRow(task, index, isDragging),
  onReorder: (from, to, next) => saveOrder(next),
})

attachGestureRecognizers(canvas, list.recognizers)

// Imperative rail:
list.moveUp(0)          // bump first task up (no-op at edge)
list.move(3, 0)         // move index 3 to index 0
list.order.value        // current snapshot
list.draggingIndex.value // index held by the user, or null

Keyboard rail (bound to each row automatically):

  • ArrowDown / ArrowUp — move the focused row down / up one slot
  • Home / End — jump the focused row to the top / bottom

Reorder semantics:

  • itemHeight is fixed across all rows (variable row height is out of scope).
  • Drag uses the pan recognizer's deltaY divided by itemHeight to compute the target slot; live reorder updates while the pointer is held, committed on release.
  • Pointer-cancel keeps the interim reorder (undo is a caller concern).

Scope note: attach list.recognizers when there's no other canvas-wide pan consumer. Scoping recognizers to a region is an app-level concern — the local-canvas demo intentionally runs draggableSort with keyboard-only input because swipeableList.recognizers are already attached canvas-wide.

Cookbook fix — modal focus policy

The 1.55.0 recipe for composing focusFirstInside + trapFocusStep + animatedDialog used a dlg.isOpen.subscribe((open) => …) call. Signal<T> in @geometra/core exposes value / set / peek — there is no .subscribe() method. The correct pattern uses effect:

import { effect } from '@geometra/core'

effect(() => {
  const open = dlg.isOpen.value
  if (!open) return
  queueMicrotask(() => {
    focusFirstInside(app.tree, app.layout, DIALOG_PATH)
  })
})

Anyone who followed the 1.55.0 recipe literally would have hit a runtime TypeError on the .subscribe call. The updated recipe in INTEGRATION_COOKBOOK.md uses effect and matches the real API.

vitest cleanup

Before this release, npx vitest run (no config parameter) picked up tests/e2e/full-stack-dashboard.spec.ts via vitest's default **/*.spec.ts glob and crashed on the @playwright/test import. vitest.config.ts now explicitly excludes tests/e2e/** while keeping vitest's default excludes (node_modules, dist, various build configs).

Consequence: a fresh checkout can run vitest run from the repo root and get a clean unit-test pass (2,701 / 2,701 across 92 files). Playwright specs continue to run through npx playwright test.

Migration notes

All additions are additive. No protocol changes. GEOM v1 stays fully compatible.

New exports from @geometra/ui:

  • draggableSort<T>
  • Types: DraggableSort<T>, DraggableSortOptions<T>, DraggableSortItemState

No existing export signatures changed.

Performance notes

  • draggableSort's pan path fires only when a row has latched pendingIndex at pointerdown — dragging empty space in the list bounds does nothing, matching swipeableList's cost profile.
  • draggableSort.view() re-renders on order / draggingIndex changes via signals — no extra reconciler work when idle.
  • vitest exclude is a bare glob check; no measurable test-suite time change.

Verification

  • Full fast suite: 2,471 / 2,471 passing across 88 test files.
  • Default vitest run (no config parameter): 2,701 / 2,701 passing across 92 files.
  • New tests: 7 for draggableSort.