wrangle 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c71a3ad462a532ec7f6ddea4621ff5620bfde1085cbdbcb5ec0f04995b2707e3
4
- data.tar.gz: de242cf8fa5fb7b3c21c03af57d8f8287db282c487fabc20b61f52459756d113
3
+ metadata.gz: b938bca1479790bd7cd763b621d7075e12f7b0021f4552b8a5c78a3567fbb55a
4
+ data.tar.gz: 34f213f2393cec5fc75443e65ff1e2eb7bef998998a193cce2fbeb809b7e5ea1
5
5
  SHA512:
6
- metadata.gz: f295f56bb4e7553dcac794b08ef3d63295f57a2f18922a6fc1d7142dfde7ece183f0971340db080d7a87ce55fb671ef8c431a8e57cd0fd930d0c710a0c051c5f
7
- data.tar.gz: e4d1eaffa60d2360f513aaf20f2a4a97255bc387e24ff3e1e563a1d2c189912c37eba1fb022e25dd4931540a37b8f6f9a74c5fdd6d96361f1d8ce9700b5b145c
6
+ metadata.gz: 6963739192d1de1c1efc3b7399ceaab2b5072a7c24f08d045c6c8c0e9c0a17219aede195d266f787cd4e1202075b21a78b123cd7bfeab4ca9795c48a0a3f6c6d
7
+ data.tar.gz: a9f666405cd6db619f8f0c3126b441c70de381e71356ddf8a21b97aace0bb58115f57b70027daf4716aa3ea6b3a0196940320701e98a2db902d1ee9c558ab15d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0] - 2026-09-30
4
+
5
+ - Native macOS desktop engine: `wrangle task --app APP --goal GOAL` runs a bounded
6
+ observe → decide → preview → execute → verify loop in one exact application window (Jev by
7
+ default, at most 8 actions), and `attach`/`observe`/`drill`/`preview`/`execute`/`continue`
8
+ drive the same loop interactively through a persistent session server.
9
+ - One exact window, never more: the CoreGraphics window and process birth-time identity are
10
+ re-verified before every snapshot and dispatch. A replaced process, moved window, or ambiguous
11
+ target fails closed instead of acting. Policy denies credential handoffs and window-control
12
+ actions outright; consequential actions need a separate `--approve` approval.
13
+ - At-most-once dispatch: a durable marker crosses the dispatch gap, so an interrupted action is
14
+ reported `delivery_unknown` and never retried. Target-specific effect verification reports
15
+ `verified`, `unchanged`, or `unverified` instead of trusting that the screen changed.
16
+ - `wrangle qualify --provider NAME` runs the recorded conformance suite and emits an owner-only
17
+ receipt; only a qualified provider may dispatch, and replay providers are bound to their trace
18
+ digest. Qualification expires after 7 days.
19
+ - Read-only Tart guest driver: `windows --vm VM --app APP` and `tart-observe` inspect one guest
20
+ application window, bound to the VM's boot generation, with no mutation path.
21
+ - Project-local Pi tool (`.pi/extensions/computer.ts`): a single-call `computer` tool that owns
22
+ the whole loop and releases the window automatically.
23
+ - Fixed a dispatch-marker leak where a pre-delivery driver refusal bricked the scope with a
24
+ phantom unresolved dispatch; it now finishes the marker and reports `not_delivered` without
25
+ poisoning the session.
26
+
3
27
  ## [0.1.0] - 2026-09-18
4
28
 
5
29
  - `wrangle run --goal "..." --execute`: a decision loop driven by Jev, a typed-choice model that
data/README.md CHANGED
@@ -3,10 +3,11 @@
3
3
  [![CI](https://github.com/ericboehs/wrangle/actions/workflows/ci.yml/badge.svg)](https://github.com/ericboehs/wrangle/actions/workflows/ci.yml)
4
4
  [![Gem Version](https://badge.fury.io/rb/wrangle.svg)](https://rubygems.org/gems/wrangle)
5
5
 
6
- **Hand one Safari window to a program, and no more than that.**
6
+ **Scoped computer use for macOS — hand one Safari window or one app window to a program, and no more than that.**
7
7
 
8
- Wrangle drives an ordinary Safari window through Apple Events. There is no automation session, no
9
- extension, and no native helper — so the window stays a real one you can see, keep, and take back at
8
+ Wrangle drives an ordinary Safari window through Apple Events, or one exact macOS application window
9
+ through a shipped native helper over the accessibility stack. Either way there is no session beyond
10
+ the window you hand over — so the window stays a real one you can see, keep, and take back at
10
11
  any moment. It is pure Ruby with **no runtime dependencies**: everything it needs ships with Ruby and
11
12
  macOS.
12
13
 
@@ -15,6 +16,13 @@ with a banner across the top, none of your cookies, and none of your sessions. T
15
16
  for testing a site. It is the wrong tool for doing something *in* a browser you are already logged
16
17
  into. Wrangle is for the second case.
17
18
 
19
+ > **Release status:** 0.1 is the stable Safari engine described below. `main` now also carries the
20
+ > macOS desktop engine: scoped AX computer use (`wrangle task`, `attach`, `preview`, `execute`),
21
+ > provider qualification (`wrangle qualify`), and a project-local Pi tool
22
+ > (`.pi/extensions/computer.ts`). Its controlled Finder/Settings/Slack gate passes on the alpha host
23
+ > through the exact-window native driver; see
24
+ > [`docs/evaluations/macos-alpha-acceptance-2026-09-19.md`](docs/evaluations/macos-alpha-acceptance-2026-09-19.md).
25
+
18
26
  ```ruby
19
27
  require "wrangle"
20
28
 
@@ -163,6 +171,83 @@ one evaluation) and a mutation costs four. The page scripts are shipped once at
163
171
  ~12 KB per call, unresolved specifiers are addressed rather than resolved, and nothing reads window
164
172
  bounds on the hot path.
165
173
 
174
+ ## Scoped macOS alpha
175
+
176
+ The alpha keeps the same observe → propose → execute boundary for one exact application window. A
177
+ shipped Swift helper owns window/process/display discovery, Electron accessibility setup, bounded AX
178
+ observation, and native dispatch. There is no `agent-desktop` runtime prerequisite. Native refs remain
179
+ bound to one snapshot and scope, actions revalidate the exact process/window/AX target, and delivery
180
+ is still verified independently afterward. A locked login session is reported as unavailable rather
181
+ than treated as an empty or broken AX tree.
182
+
183
+ The primary interface is one natural task. Wrangle selects the only or uniquely focused app window,
184
+ runs at most eight typed decision/action cycles internally, verifies every delivered action, releases
185
+ its lease automatically, and leaves the application window open:
186
+
187
+ ```bash
188
+ wrangle doctor
189
+ wrangle task --app Finder --goal "Open Search in the disposable Finder window"
190
+ ```
191
+
192
+ `windows`, `attach`, `observe`, `drill`, `preview`, `execute`, and `close` remain debug and conformance
193
+ interfaces; an outer agent does not orchestrate them during a normal task.
194
+
195
+ Desktop tasks use Jev when neither `--provider` nor `WRANGLE_DESKTOP_PROVIDER` is set. An explicitly
196
+ configured provider overrides that default, and Wrangle never falls back between providers. No provider is
197
+ mutation-qualified merely because its API is compatible. Qualification receipts are bound to the canonical
198
+ suite and provider/model, to the exact configured endpoint for Jev, and to the exact trace digest for replay;
199
+ they expire after seven days:
200
+
201
+ ```bash
202
+ wrangle qualify --provider replay --provider-trace trace.jsonl --output qualification.json
203
+ wrangle task --app Finder --goal "Open the fixture" --provider replay \
204
+ --provider-trace trace.jsonl --provider-qualification qualification.json
205
+ ```
206
+
207
+ A task invocation authorizes only its necessary reversible actions. Internally each action still uses
208
+ a revision-bound one-shot proposal. Consequential actions stop before delivery, and uncertain delivery
209
+ terminates the task without retry. Text must be an exact quoted goal span or named literal;
210
+ credentials are always a handoff. If multiple AX targets expose the same visible role, label, value,
211
+ states, and operation, Wrangle omits that operation from every match rather than resolving the tie
212
+ with an opaque ref, path, or list position.
213
+
214
+ In a source checkout, the stdlib-only
215
+ [macOS acceptance harness](docs/evaluations/macos-app-compatibility.md) probes exact windows without
216
+ retaining UI content. `script/macos_accept finder --runs 5` checks one profile;
217
+ `script/macos_matrix --tier core --runs 5` checks a compatibility wave. App preparation and bounded
218
+ provider tasks are separate opt-in flags, and the checked-in task profiles permit zero delivered
219
+ actions. `script/tart_vm` creates, preflights, snapshots, starts, stops, and explicitly resets
220
+ disposable Tart acceptance VMs; clone/snapshot refuse replacement and reset requires `--replace`.
221
+ Clone and reset default to the validated `wrangle-provisioned-base-v2`; it, the original
222
+ `wrangle-provisioned-base`, and the Pi-enabled `wrangle-pi-base` are protected from reset replacement.
223
+ The guest preflight rejects a
224
+ running or login-restored Setup Assistant. `start` must pass that check
225
+ before returning a fixture as ready, and `snapshot` preflights and stops its running source before
226
+ preserving it. The experimental read-only guest backend requires both scopes explicitly:
227
+
228
+ ```bash
229
+ wrangle tart-observe --vm wrangle-acceptance --app Finder
230
+ wrangle attach --vm wrangle-acceptance --app Finder --session guest
231
+ ```
232
+
233
+ It verifies the VM boot generation around every guest-helper request and has no mutation or host-pixel
234
+ fallback. Guest sessions expose observe/drill/inspect, identify themselves as read-only, and return a
235
+ `not_delivered/read_only` receipt for every execution attempt. See
236
+ [ADR 0004](docs/adr/0004-tart-guest-driver.md).
237
+
238
+ Pi discovers [`.pi/extensions/computer.ts`](.pi/extensions/computer.ts) in this checkout. Users can
239
+ ask naturally:
240
+
241
+ > Check the #notifications channel in Boehs Slack.
242
+
243
+ The agent calls `computer` once with only the natural goal and application name. Wrangle performs
244
+ window selection, progressive observation, typed decisions, proposals, dispatch, verification, and
245
+ cleanup internally; users and the outer agent never handle window IDs, refs, proposal IDs, revisions,
246
+ or receipt vocabulary. Consequential actions stop before delivery; this first protocol reports the
247
+ pending action but cannot yet resume its bound approval. Every result releases Wrangle's exclusive
248
+ lease and deliberately leaves the user-owned app window open. Policy remains in Wrangle rather than
249
+ the extension.
250
+
166
251
  ## CLI
167
252
 
168
253
  ```
@@ -459,6 +544,12 @@ property of the transport, not of a stub.
459
544
  ```
460
545
  COVERAGE=1 rake test # per-file lines and branches
461
546
  COVERAGE=1 COVERAGE_DETAIL=1 rake test # and which ones are missing
547
+ script/macos_accept --list # macOS compatibility profiles, no app access
548
+ script/macos_accept finder --runs 5 # read-only exact-window probes
549
+ script/tart_vm status # sanitized disposable-VM lifecycle state
550
+ script/tart_vm preflight # reject active/persisted Setup Assistant state
551
+ wrangle tart-observe --vm VM --app APP # exact read-only guest application observation
552
+ wrangle attach --vm VM --app APP # read-only guest observe/drill/inspect session
462
553
  ```
463
554
 
464
555
  Coverage is measured with Ruby's own `Coverage` module rather than a gem: adding a dependency to