Commit graph

174 commits

Author SHA1 Message Date
Lahfir
30e80b90bc test: add E2E fixture app and dual-mode harness
Drives the release binary against a real SwiftUI/AppKit fixture and verifies
every effect by independent before/after observation — never the command's own
ok:true — so a command that reports success without an effect is caught. This is
the layer mock-adapter unit tests cannot cover: it exercises the contract
against the real macOS Accessibility API.

- AgentDeskFixture.swift exposes a fixed, diverse AX surface (native AppKit
  slider/stepper, gesture-only and ambiguous controls, a sheet, a press-toggled
  disclosure, async-appearing elements, a drag canvas). It is never tuned to
  make a command pass; a failure is a finding about the CLI or the harness.
- run.sh drives every ref-action command in BOTH headless and --headed mode with
  mode-specific target values, plus the double-click discriminator (headless
  fails closed with POLICY_DENIED, --headed completes) that proves the two modes
  differ. It also covers strict resolution, wait predicates, skeleton drill-down,
  sessions, trace redaction, surfaces, drag, expand, and force-close.
- The compiled fixture .app is a build artifact (gitignored; built on demand).

Run: cargo build --release && bash tests/e2e/run.sh (needs AX permission).
2026-06-17 13:43:19 -07:00
Lahfir
9ad0e889b2 feat: add Playwright-style headed/headless interaction mode
Ref actions now run in exactly two modes. Headless is the default: semantic
accessibility operations only, no cursor movement, and a fail-closed
POLICY_DENIED when only a physical gesture would work. The global --headed flag
upgrades every ref action to permit focus stealing and cursor movement, so the
chain's physical click/double-click/scroll/keypress fallbacks can complete. The
AX path is always tried first, so --headed never regresses headless-capable
elements; it only adds fallbacks for elements that need a real gesture.

- CommandContext::request(action, base) builds the per-command request: each
  command declares its headless base (pure-AX headless; type uses focus_fallback
  because typing requires focus but never moves the cursor) and --headed upgrades
  any base to the headed policy.
- The internal/FFI "physical" policy is renamed "headed" throughout, including
  the C ABI enum (AD_POLICY_KIND_HEADED keeps discriminant 2) and bindings.
- Raw-input commands (press, hover, drag, mouse-*, key-down/up) are unchanged:
  always physical, mode-independent low-level escape hatch.
- Unit tests assert every ref command is headless by default and headed under
  --headed; docs (CONCEPTS, CLAUDE, skills) describe the two-mode contract.
2026-06-17 13:43:19 -07:00
Lahfir
3ad7b2c245 fix: eliminate vacuous AX successes and harden resolution
Dogfooding the binary against a real fixture app surfaced five cases where a
command reported success without producing the effect, or failed with the wrong
error. Each is verified by independent before/after observation in the E2E
harness.

- is_menu_open no longer treats a latent AXMenuBar as an open menu, so select
  and wait --menu-closed stop seeing a permanently-open menu.
- set-value coerces the written AXValue to the element's existing CFNumber/
  CFBoolean/CFString type and verifies numerically, fixing sliders; steppers
  converge via AXIncrement/AXDecrement when AXValue writes are vacuous.
- double-click only claims success when the element advertises AXOpen; otherwise
  it fails closed instead of reporting a non-existent double-click.
- a completed resolution pass that proves a ref absent downgrades a deadline
  TIMEOUT to STALE_REF so removed elements fail with the correct code.
- expand/collapse verify the disclosure state and fall back to a press-toggle
  for press-driven disclosures; press-toggled containers expose EXPAND/COLLAPSE.

roles.rs adds the disclosure expandable role and normalizes textarea/textbox/
searchfield role queries to textfield.
2026-06-17 13:43:19 -07:00
Lahfir
b2f14fcbf5 fix: make action-bearing elements ref-able so scroll/expand can target them
E2E testing against a diverse fixture app surfaced that disclosure
(Expand/Collapse/Click) and scrollarea (Scroll) advertise actions but
never received refs — they are not in INTERACTIVE_ROLES — so the scroll,
expand, and collapse commands required a <REF> their own target roles
could never have. The commands were uninvokable against their primary
targets.

Ref allocation now gates on addressability, not role alone: an element
is ref-able if its role is interactive OR it advertises a primary action
(any action other than a bare SetFocus, which would ref-allocate inert
focusable containers). scrollarea and disclosure become ref-able;
scroll now works against a real app. Ref-count impact is modest
(fixture 61->72, Finder ~262).

Tests assert action-bearing containers get refs, SetFocus-only and inert
elements do not, and interactive roles stay ref-able without actions.
Contract docs (CLAUDE.md, SKILL.md) updated.
2026-06-17 13:43:19 -07:00
Lahfir
9c31e19345 feat: add drag --drop-delay for reliable macOS drop registration
macOS drop targets need the dragged item to dwell over them before they
register as the destination; too short and the gesture lands as a drag
with no drop. The dwell was a hardcoded 500ms dead sleep. Expose it as
--drop-delay <ms> (CLI), drop_delay_ms (DragParams/AdDragParams, 0 =
adapter default sentinel matching duration_ms), and replace the dead
sleep with an event-driven dwell that posts LeftMouseDragged over the
destination every 16ms so the target stays highlighted instead of
dropping the drag mid-pause.

DRY: the C-to-core drag conversion (duration/drop-delay zero-sentinel)
was copied across three FFI sites; collapse them into AdDragParams::
to_core(). FFI ABI: AdDragParams gains drop_delay_ms (header + repr +
header-compile test). Tests: core threads the value into params and
response and omits the field when unset; FFI maps both optionals.
2026-06-17 13:43:19 -07:00
Lahfir
66275f78a3 fix: stop close-app claiming a graceful quit it cannot confirm
close-app returned closed:true the instant a graceful quit was *sent*,
while the app was still running behind an unsaved-changes dialog —
a false completion claim. Empirically (NSWorkspace.runningApplications):
a clean quit completes in ~0.2s, a dialog-blocked quit never completes
on its own, and macOS confirms only that the quit request was sent, not
that the app terminated. Verifying by polling would add seconds of
latency on the exact (blocked) case it is meant to catch, so we do not
poll.

Graceful close now reports { method: graceful, requested: true } —
truthful and instant, no closed claim. --force is a synchronous SIGKILL,
so it reports { method: force, requested: true, closed: true }. Callers
needing graceful confirmation observe via list-apps / wait --window and
can drive a save dialog with snapshot + find, which is the agent-native
path.
2026-06-17 13:43:19 -07:00
Lahfir
71267f942b refactor: move protected-process knowledge out of core into the adapter
close-app hardcoded macOS/Unix process names (loginwindow, windowserver,
dock, launchd, finder) inside core, baking platform-specific knowledge
into the platform-agnostic crate. Windows would need csrss.exe/
winlogon.exe, Linux gnome-shell/Xorg. Add PlatformAdapter::
is_protected_process (default denies nothing); the macOS adapter owns its
list with substring matching over display and bundle identifiers. core's
close-app just asks the adapter. Also genericize a macOS-flavored test
fixture string so core carries zero native vocabulary even in tests.

Verified: core has no platform-native references in non-test source, no
cfg(target_os) gates; the only remaining cfg(unix)/libc use is securing
core's own refmap/trace/lock files with non-unix fallbacks.
2026-06-17 13:43:19 -07:00
Lahfir
9f000552a4 refactor: derive find role hints from the live tree, drop hardcoded vocabulary
Replace the canonical-role allow-list (and its hard INVALID_ARGS
rejection) with a tree-derived approach. A role filter that matches
nothing now returns ok with roles_present — the distinct roles actually
in the searched tree — so the caller distinguishes 'none on screen' from
a wrong role name and self-corrects. This needs no central role list: a
role any adapter newly emits surfaces in roles_present automatically,
with nothing to keep in sync across core and the platform crates.

A tiny role-query normalizer keeps the ergonomic win (textarea, textbox,
searchfield fold to textfield, case-insensitive) but never gates or
rejects — it is a synonym shim, not a vocabulary. The macOS role table
returns to its plain match form; the cross-crate canonical-vocabulary
list and its conformance test are gone.
2026-06-17 13:43:19 -07:00
Lahfir
a95d34b947 fix: validate find roles against the canonical vocabulary
find --role with a role no adapter can emit (textarea, typos) silently
returned ok with zero matches, reading as 'element absent' when the
query could never match. Role queries now resolve through a canonical
vocabulary in core: common text-input aliases (textarea, textbox,
searchfield) normalize to textfield case-insensitively, and unknown
roles fail with INVALID_ARGS carrying details.valid_roles so agents can
self-correct.

The macOS role mapping becomes a sorted single-source table with
binary-search lookup, and a conformance test pins every emitted role
(plus the unknown fallback and the synthesized cell role) to core's
CANONICAL_ROLES — the cross-platform contract Windows/Linux adapters
must map their native vocabularies into, enforced by the same
table + test pattern rather than convention.
2026-06-17 13:43:19 -07:00
Lahfir
606b974178 docs: document notification retry, error-code contract, and diagnostics sensitivity
Note transient-error retry and last_error timeout detail on wait
--notification; make explicit that agents branch on error.code (message
and suggestion text is informational); warn FFI consumers that
ad_last_error_details may carry on-screen element names, values, and
window titles and should stay out of shared log surfaces.
2026-06-17 13:43:19 -07:00
Lahfir
c29b9dcf3a fix(review): eliminate per-element AX round trips and close remaining review findings
Fold AXPosition/AXSize and the scrollbar probe into the existing
AXUIElementCopyMultipleAttributeValues batch so tree traversal and the
actionability preflight pay one IPC per element instead of up to four;
A/B benchmark shows strictly-faster snapshots with identical ref counts
and scroll capabilities (Finder 4.5s -> 2.4s same-session, Docker
Desktop parity at 440 refs / 933 scroll-capable nodes).

Consolidate the CLI and FFI ref-action pipelines into one core
execute_resolved path (actionability, tracing, and dispatch semantics
live once; FFI passes a default context). Remove the no-context
execute() shims from is/right-click/snapshot/wait and the test-only
helper shims; every command now takes an explicit CommandContext.

Split the macOS resolver into resolve (orchestration), resolve_search
(candidate collection), and resolve_classify (strict classification),
clearing the 400-LOC ceiling with room to grow.

Notification waits now retry transient baseline failures inside the
timeout budget with the same retryable gate as window/text waits and
report last_error in timeout details instead of aborting on the first
flake; a baseline is never fabricated.

Refmap writes clean up their temp file on failure, stale *.tmp orphans
are swept under the store lock, and save_existing_snapshot re-verifies
snapshot ownership inside the owning store's write lock with bounded
re-discovery before deterministically recreating in the caller's store.

Coverage hardening: zero-budget wait timeout shape, wait --text
--count 0 absence detection, ref-action pipeline call-count guard
(1 resolve / 1 live read / 1 dispatch), duplicate snapshot-id collision
on load, pruned-everywhere recreation, tmp sweep and rename-failure
cleanup, FFI AMBIGUOUS_TARGET last-error code assertion.
2026-06-17 13:43:19 -07:00
Lahfir
f5f97dceeb fix(review): preserve action results, delegate timeout resolution, tighten core boundaries
Apply verified code-review fixes: ref-action release failures no longer
mask successful action results (prevents double-dispatch on retry);
resolve_element_strict_with_timeout defaults to delegating so strict-only
adapters support wait --element; wait --text reports count only when
--count is requested; latest-refmap refresh logs load failures instead of
silently serving stale refs; InteractionPolicy moved to its own module and
actionability/trace modules scoped pub(crate) per file rules; duplicate
wait test helper extracted to shared support module; timeout error
constructors deduplicated; redaction test covers description; policy
focus-denial path covered; skills document steps array, actionability
details, trace redaction, and batch trace inheritance.
2026-06-17 13:43:19 -07:00
Lahfir
d2478c941e chore: strip inline comments and enforce docstrings
Replace inline // comments with /// docstrings where they carry non-obvious
contract, and add a pre-commit guard so inline comments cannot regress.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 13:43:19 -07:00
Lahfir
13947d5da3 fix: fail closed on uncertain ref fallback 2026-06-17 13:43:19 -07:00
Lahfir
a06d16ef28 fix: harden ref fallback resolution 2026-06-17 13:43:19 -07:00
Lahfir
6f50b41865 fix: make explicit snapshots session-independent 2026-06-17 13:43:19 -07:00
Lahfir
cd3b0ed29d fix: preserve safe window title fallback 2026-06-17 13:43:18 -07:00
Lahfir
d281d5dac5 fix: harden source-window ref resolution 2026-06-17 13:43:18 -07:00
Lahfir
02137b1f7c fix: harden ref reliability edge cases 2026-06-17 13:43:18 -07:00
Lahfir
ba80312a11 docs: compound reliability patterns 2026-06-17 13:43:18 -07:00
Lahfir
0bc04b9b82 fix: harden ref action reliability 2026-06-17 13:43:18 -07:00
Lahfir
f92b6cc92e fix: harden ref action reliability 2026-06-17 13:43:18 -07:00
Lahfir
8792f8a704 refactor: organize binary crate modules 2026-06-17 13:43:18 -07:00
Lahfir
d11ff33583 fix: stabilize macos ref resolution 2026-06-17 13:43:18 -07:00
Lahfir
e2bc493e54 refactor: centralize reliability helpers 2026-06-17 13:43:18 -07:00
Lahfir
e232540a1f fix: harden wait and ref action reliability 2026-06-17 13:43:18 -07:00
Lahfir
052ced9de3 docs: update reliability docs and skills 2026-06-17 13:43:18 -07:00
Lahfir
db25b4a030 fix: address reliability follow-ups 2026-06-17 13:43:18 -07:00
Lahfir
7abaa4e6f1 fix: close final reliability edge cases 2026-06-17 13:43:18 -07:00
Lahfir
eeff52f62a fix: harden reliability edge cases 2026-06-17 13:43:18 -07:00
Lahfir
6134c1afa6 fix: close reliability review findings 2026-06-17 13:43:18 -07:00
Lahfir
26c6b92691 fix: harden ref action reliability 2026-06-17 13:43:18 -07:00
Lahfir
e102328f05 fix: report wait and trace failure context 2026-06-17 13:43:18 -07:00
Lahfir
18441baa33 fix: skip finder pseudo windows for snapshots 2026-06-17 13:43:18 -07:00
Lahfir
51f537d749 feat: add session-scoped reliability diagnostics 2026-06-17 13:43:18 -07:00
Lahfir
8059d769a5 feat: add strict ref reliability core 2026-06-17 13:43:18 -07:00
dependabot[bot]
1aa4f5f10f
chore(deps): bump smallvec to 1.15.2
Some checks failed
CI / Format (push) Has been cancelled
CI / Test (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
Release / Release Please (push) Has been cancelled
Supply Chain / Audit (push) Has been cancelled
Release / Build (aarch64-apple-darwin) (push) Has been cancelled
Release / Build (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (aarch64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (aarch64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (x86_64-pc-windows-msvc) (push) Has been cancelled
Release / Publish to GitHub Release (push) Has been cancelled
Release / Publish to npm (push) Has been cancelled
Release / Publish Skills to ClawHub (push) Has been cancelled
2026-06-17 13:42:35 -07:00
dependabot[bot]
2521eb4ef0
chore(deps): bump github/codeql-action to 4.36.2 2026-06-17 13:40:09 -07:00
github-actions[bot]
239ebf0230
chore(main): release 0.2.3 (#57)
Some checks failed
CI / Format (push) Has been cancelled
CI / Test (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
Release / Release Please (push) Has been cancelled
Supply Chain / Audit (push) Has been cancelled
Release / Build (aarch64-apple-darwin) (push) Has been cancelled
Release / Build (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (aarch64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (aarch64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (x86_64-pc-windows-msvc) (push) Has been cancelled
Release / Publish to GitHub Release (push) Has been cancelled
Release / Publish to npm (push) Has been cancelled
Release / Publish Skills to ClawHub (push) Has been cancelled
* chore(main): release 0.2.3

* chore: sync cargo lock for release 1.85

* docs: deduplicate release changelog entry

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Lahfir <nmhlahfir2@gmail.com>
Co-authored-by: Lahfir <70215676+lahfir@users.noreply.github.com>
2026-06-05 21:33:11 -04:00
Lahfir
44b6c71d03
Merge pull request #55 from lahfir/dependabot/github_actions/github-actions-25747c8ec3
chore(deps): bump the github-actions group with 3 updates
2026-06-05 18:27:40 -07:00
Lahfir
cd5a4aac4b
Merge branch 'main' into dependabot/github_actions/github-actions-25747c8ec3 2026-06-05 18:24:12 -07:00
Lahfir
11d01e1c9f
Merge pull request #56 from noy4/fix/fullscreen-ax-tree
fix: resolve fullscreen AX tree retrieval returning ref_count: 0
2026-06-05 18:07:29 -07:00
Lahfir
3b266fdf04 fix: harden macos ax window fallback 2026-06-05 17:57:39 -07:00
noy4
a52b7c704a fix: resolve fullscreen AX tree retrieval returning ref_count: 0
- Add !t.is_empty() check to prevent false positives in partial title matching
- Add fallback to select the first window with children > 0 using count_children API
- Ensures reliable active window selection in macOS native fullscreen mode
2026-06-06 01:18:13 +09:00
dependabot[bot]
c5bc21ab8c
chore(deps): bump the github-actions group with 3 updates
Bumps the github-actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [github/codeql-action](https://github.com/github/codeql-action) and [EmbarkStudios/cargo-deny-action](https://github.com/embarkstudios/cargo-deny-action).


Updates `actions/checkout` from 6.0.2 to 6.0.3
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](de0fac2e45...df4cb1c069)

Updates `github/codeql-action` from 4.36.0 to 4.36.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](7211b7c807...87557b9c84)

Updates `EmbarkStudios/cargo-deny-action` from 2.0.19 to 2.0.20
- [Release notes](https://github.com/embarkstudios/cargo-deny-action/releases)
- [Commits](a531616d8c...bb137d7af7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-version: 4.36.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: EmbarkStudios/cargo-deny-action
  dependency-version: 2.0.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-04 00:48:22 +00:00
github-actions[bot]
594e93f4db
chore(main): release 0.2.2 (#52)
Some checks failed
CI / Format (push) Has been cancelled
CI / Test (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
Release / Release Please (push) Has been cancelled
Supply Chain / Audit (push) Has been cancelled
Release / Build (aarch64-apple-darwin) (push) Has been cancelled
Release / Build (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (aarch64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (aarch64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (x86_64-pc-windows-msvc) (push) Has been cancelled
Release / Publish to GitHub Release (push) Has been cancelled
Release / Publish to npm (push) Has been cancelled
Release / Publish Skills to ClawHub (push) Has been cancelled
* chore(main): release 0.2.2

* chore: sync cargo lock for release 1.85

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-02 00:54:22 -04:00
Agent-Mouses
c02cb5ecb7
fix(macos): guard CFArray casts with type-ID check (fixes Mail.app crash) (#50)
* fix(macos): guard CFArray casts with type-ID check

AXUIElementCopyAttributeValue and CopyMultipleAttributeValues can
return non-array CF types for attributes that are normally arrays
(observed with Mail.app on macOS 26.3 beta). Casting the raw
CFTypeRef to CFArray<CFType> without verifying the type ID is
undefined behaviour and can cause a panic with 'entered unreachable
code' when the resulting fake array is iterated.

Add CFGetTypeID / CFArrayGetTypeID guards in copy_ax_array and
fetch_node_attrs before the unsafe casts. On mismatch, release the
value and fall back gracefully (None / per-attribute fallback path).

Fixes #49

* refactor: extract fetch_node_attrs_slow, remove inline comments

* fix: harden macos accessibility inventory

* fix: guard null ax element refs

* fix: harden macos app inventory fallbacks

* test: cover macos inventory edge cases

* fix: keep macos launch in background

* fix: tighten macos app fallback matching

* fix: harden macos app inventory fallbacks

* refactor: simplify macos inventory cleanup

---------

Co-authored-by: Agent-Mouses <agent-mouses@users.noreply.github.com>
Co-authored-by: Lahfir <nmhlahfir2@gmail.com>
Co-authored-by: Lahfir <70215676+lahfir@users.noreply.github.com>
2026-06-02 00:51:49 -04:00
meichuanyi
5987b35859
docs: Add FAQ section for common questions (#51)
* docs: Add FAQ section for common questions

* docs: tighten faq for agent discovery

---------

Co-authored-by: Lahfir <nmhlahfir2@gmail.com>
2026-06-01 23:27:34 -04:00
dependabot[bot]
4840344bf7
chore(deps): bump serde_json to 1.0.150
Some checks failed
CI / Format (push) Has been cancelled
CI / Test (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
Release / Release Please (push) Has been cancelled
Supply Chain / Audit (push) Has been cancelled
Release / Build (aarch64-apple-darwin) (push) Has been cancelled
Release / Build (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (aarch64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-apple-darwin) (push) Has been cancelled
Release / Build FFI (x86_64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (aarch64-unknown-linux-gnu) (push) Has been cancelled
Release / Build FFI (x86_64-pc-windows-msvc) (push) Has been cancelled
Release / Publish to GitHub Release (push) Has been cancelled
Release / Publish to npm (push) Has been cancelled
Release / Publish Skills to ClawHub (push) Has been cancelled
Update serde_json from 1.0.149 to 1.0.150.
2026-05-28 20:49:36 -07:00
dependabot[bot]
8a34173eb3
chore(deps): bump cargo-deny-action to 2.0.19
Update the SHA-pinned EmbarkStudios/cargo-deny-action workflow dependency to v2.0.19.
2026-05-28 20:45:52 -07:00