Skip to content

chore(computer-use): remove cua-driver - #1959

Merged
hqhq1025 merged 1 commit into
mainfrom
pr/drop-cua-driver
Aug 3, 2026
Merged

chore(computer-use): remove cua-driver#1959
hqhq1025 merged 1 commit into
mainfrom
pr/drop-cua-driver

Conversation

@hqhq1025

@hqhq1025 hqhq1025 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

This pull request is the third and last link in a three-part chain. Its base is
the second link, feat(computer-use): make maka-cu the executor that actually
runs, which is itself based on pull request 1953, feat(computer-use): add
maka-cu as a selectable executor backend. The chain has to merge in order:
after this change main has exactly one Computer Use executor, so the two
changes before it must already be in or Computer Use has none at all.

This is the point of no return for cua-driver. It is a deletion. The backend,
its service, release, result, snapshot, page-target and target-resolution
modules and their tests are gone; so are the acquisition script, the bundle
integrity checker, the provenance test, the vendored MIT notice, the
bundled-tools.json entry, and the artifact integrity document. Recovering
cua-driver after this means reverting it, not flipping a flag.

Nothing is renamed. CuaSessionState, CuaFrameState and their neighbours name
sessions and frames rather than the executor, so renaming them would produce
diff noise and no clarity. The comments that explain a current decision by
reference to how cua-driver behaved are kept for the same reason: they are why
the code has the shape it has, and deleting them would leave the shape
unexplained.

What moved rather than disappeared

The two real-machine e2e scripts and the fixture-discovery launcher construct
the maka-cu backend instead, and prepare it with prepare:maka-cu rather than
prepare:cua-driver and check:cua-driver-artifact. Their hardcoded expected
digest is replaced by a read of the digest bundled-tools.json already pins,
because a copy of a digest goes stale the first time the executor is rebuilt
and then fails as though the binary had been tampered with.

The DMG verifier stops forbidding a path that can no longer be produced. It
still forbids the maka-cu path, which is the check that matters.

The provenance record becomes a single-executor record. Pull request 1953 wrote
section 1 to account for both executors and its test asserted that both were
accounted for. Nothing third-party ships for Computer Use now, so section 1 has
one row again, and the test asserts that the manifest pins no second executor
rather than asserting cua-driver is still in it. The path floor in the same test
moves from ten to eight because two real paths left the document with the
component.

What a reviewer should check to be confident nothing still depends on it

Run grep -ri "cua-driver" over packages, apps, scripts and docs, excluding dist
and docs/archive. Every remaining hit is prose: a comment explaining why a
supervision policy or a stdout policy is what it is, or the provenance record
saying the component was removed. No module imports a deleted file.

Check that no export of @maka/computer-use that this change removes was consumed
anywhere else. createCuaDriverBackend, normalizeCuaDriverOutcome,
CuaDriverService, resolveCuaPageTextTarget, elementAtScreenPoint and the rest of
the cua-driver export surface had no consumer outside the package; the only
importers were index.ts and select-backend.ts, both of which are updated here.

Check that the selector no longer has a way to reach a second executor:
CU_BACKEND_IDS has one member, there is one overload rather than two, and the
returned backendId is the constant.

Check the manifest: bundled-tools.json now has a single key.

Verification

npm --workspace @maka/computer-use run build and run test pass. npm run
test:scripts, npm run format:check, npm run lint and node
scripts/check-console.mjs pass. The extended script tests that touch changed
files, cu-real-model-launcher, macos-arm64-release and cu-provider-matrix, pass.
npm --workspace @maka/desktop run build:main reports the same two pre-existing
errors on this machine as the base branch does, both from @maka/ui failing to
build for an unrelated local reason; the delta is zero.

@hqhq1025
hqhq1025 force-pushed the pr/maka-cu-default branch from d83c516 to 11ffd6d Compare August 3, 2026 09:30
@hqhq1025
hqhq1025 force-pushed the pr/drop-cua-driver branch from 578f06a to bf442a0 Compare August 3, 2026 09:46
@hqhq1025

hqhq1025 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

The one real break is fixed, and the branch is rebased so it sits on the current #1958, which sits on the rebased #1953.

scripts/cu-process-restart-e2e.mjs called backend.serviceState(). It does not exist. I checked it against a real constructed backend rather than by reading the diff:

serviceState is a function: false
executorState is a function: true
snapshot keys: generation,restartAttempts,state
has action role: false has capture role: false

So the two-role loop would have found undefined.restartAttempts even if the method had existed. It reads one snapshot and one generation now, and the report field is named executorGeneration for what it holds.

The reason this mattered more than a typo: the throw was inside the try, after the round's real work had already succeeded, so the harness caught it and wrote an ok:false report. A passing real-machine run was reported as a failure, and the only way to find out was to have the machine.

Nothing in the suite can run this harness, so I added scripts/cu-process-restart-harness.test.mjs, which reads the harness's own source for the methods it calls on the backend and asks a real backend whether it has them. It is wired into test:scripts:extended and into ci-test-plan's extended file set.

Negative control, run: putting backend.serviceState() back.

✖ every backend method the process-restart soak calls exists on the backend
AssertionError [ERR_ASSERTION]: the soak harness calls backend.serviceState(), which the backend does not have

Restored: 2 pass, 0 fail.

On the forbidPath asymmetry, agreed and restored. apps/desktop/resources/bin is gitignored, so removing a helper from the repository does not remove it from the tree of anyone who prepared it once, and a leftover ad-hoc binary fails notarization for the whole app. The two cua-driver forbids are back beside the officecli ones they match, and macos-arm64-release.test.mjs now asserts every unsigned helper is among the paths the packaged app is checked against.

Negative control, run: dropping the two forbids again.

✖ the packaged app is checked for every unsigned helper that could still be in a tree
AssertionError [ERR_ASSERTION]: cua-driver is not among the paths the packaged app is checked against

Restored: 2 pass, 0 fail.

I did not re-litigate the deletion. All script tests pass, 27 and 15 in the two groups. Full suite: core, mcp, ui and computer-use pass; runtime, storage, cli, runtime-host and desktop fail on the usual environmental set — PTY spawn and shell streaming under load, macOS /private/var realpath, node:sqlite — across twenty-eight files, none of which this branch touches.

@hqhq1025
hqhq1025 force-pushed the pr/maka-cu-default branch 4 times, most recently from d048398 to d4195e9 Compare August 3, 2026 14:09
@hqhq1025
hqhq1025 changed the base branch from pr/maka-cu-default to main August 3, 2026 14:21
@hqhq1025
hqhq1025 force-pushed the pr/drop-cua-driver branch from bf442a0 to a1833bc Compare August 3, 2026 14:37
@hqhq1025

hqhq1025 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Rebuilt on current main rather than rebased.

This branch was the third link of a stack. #1953 added maka-cu as a selectable backend and #1958 made it the default; both have since squash-merged into main, so the two commits this branch was written on top of now exist there under different hashes. Replaying the branch conflicts in eight files and resolving those conflicts by hand is exactly the operation that loses things quietly, so the change was reconstructed from its final state onto main at 3793cc0 instead. The deletion set is byte-for-byte the one the previous version carried, and the third-round review verdict of "surgical deletion" still describes it: nineteen files removed, all of them cua-driver, and git diff --diff-filter=D over the branch lists nothing else.

Three files had genuinely moved under the branch and were merged by hand rather than replayed. select-backend.ts keeps the screenLocked hook main gained. package.json keeps the dependency-patch postinstall. The settings story keeps its new content and only loses the executor name in three fixture strings.

One thing the previous version did not have to do, because its base did not have it. main's merged #1958 kept computer-use-host.ts able to read either executor's shape, since cua-driver still existed at that point: computerUseServiceHealth took a union of an action/capture role pair and maka-cu's single-child snapshot, reconciled them through a roleStates helper, and boot read backend.serviceState() with a fallback to executorState(). With cua-driver gone the role pair is not a shape anything can produce, so the health function collapses to reading one snapshot and boot reads executorState directly. The desktop main suite loses exactly one test with it, the one whose whole subject was the role pair.

Both fixes the previous version carried are kept. The process-restart soak still called backend.serviceState(), which maka-cu does not expose, and threw a TypeError on round one inside the try after the real work had already succeeded, writing up a passing real-machine run as a failure; it now reads executorState() and compares one generation. scripts/cu-process-restart-harness.test.mjs comes with it, reading the harness's own source for the backend methods it calls and asking a real backend whether they exist, wired into test:scripts:extended and ci-test-plan.mjs. verify-macos-arm64-dmg.mjs keeps forbidding both cua-driver paths, and macos-arm64-release.test.mjs now asserts every unsigned helper is among the forbidden paths, because apps/desktop/resources/bin is gitignored and a binary a developer prepared before this change is still sitting in their tree.

docs/computer-use-provenance.md becomes a single-executor record and its test with it, asserting the manifest pins no executor section 1 does not account for.

Measured against a clean origin/main baseline taken on the same machine: build, typecheck, lint, format:check and check-console pass on both. test:scripts is 27 passing on both. test:scripts:extended is 13 passing and 1 failing on both, the failure being measure-session-bundle against an older prebuilt dependency, and its composition changes as expected. @maka/computer-use goes from 245 passing to 124, the difference being the deleted cua-driver test files, with zero failures. The desktop main suite goes from 1521 to 1520 passing, zero failures. knip is clean on both workspaces.

maka-cu is the executor that runs (#1953, #1958), so the third-party one it
replaced has no caller left. This deletes the cua-driver backend, service,
snapshot, page-target, result and release modules with their tests, the
preparation and bundle-check scripts, its vendored notice, its manifest entry
and its artifact-integrity document.

Shared modules stay: stdio-json-rpc, frame-budget, display-snapshot and
abortable-delay are used by maka-cu. Nothing is renamed — CuaSessionState,
CuaFrameState and CuaBoundAction describe sessions and frames, not the
executor.

The selector, the capability card and the boot wiring collapse to one
executor. The selector loses the union and its two overloads; the health
function reads one snapshot instead of reconciling an action/capture role
pair; boot reads executorState directly rather than falling back from a
serviceState that no longer exists anywhere.

Two fixes travel with it. The process-restart soak still called
backend.serviceState(), which maka-cu does not expose, so it threw a
TypeError on round 1 inside the try — after the real work had succeeded —
and wrote up a passing real-machine run as a failure; it now reads
executorState() and compares one generation. A new
scripts/cu-process-restart-harness.test.mjs reads the harness's own source
for the backend methods it calls and asks a real backend whether they exist,
so the next such drift fails in CI rather than on a real machine.

verify-macos-arm64-dmg keeps forbidding both cua-driver paths, and
macos-arm64-release.test.mjs now asserts every unsigned helper is checked:
apps/desktop/resources/bin is gitignored, so a binary prepared before this
change is still in developers' trees and would otherwise be packaged
unnoticed.

The provenance record becomes a single-executor record, and its test asserts
the manifest pins no executor the record does not account for.
@hqhq1025
hqhq1025 force-pushed the pr/drop-cua-driver branch from a1833bc to a312753 Compare August 3, 2026 14:39
@hqhq1025
hqhq1025 merged commit a7d17e5 into main Aug 3, 2026
7 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant