You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Child of #3785 (Windows Computer Use epic), Phase 5 of the Windows roadmap in #2142. The bounded scope follows the maintainer clarifications in #3785, rather than its original broad implementation checklist.
Context
The maintainer preference for the bounded v1 preview is a C#/.NET helper supervised directly by the existing TypeScript host, subject to a small feasibility spike confirming packaging and lifecycle behavior on Windows. This issue is that spike: it does not define the final public protocol, deliver the production semantic v1 slice, or change macOS maka.cu.
Run against the published artifact in the intended packaged-app layout, initially a self-contained single-file exe, not only dotnet run. Single-file publishing is a hypothesis to test, not a reason to reject an otherwise viable .NET helper automatically.
Spike scope — six checks
Long-lived startup/handshake. Start and retain the helper; complete a bounded line-delimited JSON-RPC 2.0 handshake over stdio, with private protocol id maka.cu.windows/0 or an agreed private id, version, capabilities, and limits. Baseline host deadlines: handshake 10s, request 20s, then cancellation grace 2s where applicable. Record any divergence and its reason.
One MTA UIA observation. Use a dedicated non-UI MTA worker (CoInitializeEx(MTA)) and one explicitly selected, already-running top-level HWND. Bound tree nodes, depth, text/response size, and elapsed work. Bind the observation to pid + processStartTime + hwnd + windowGeneration and a retained UIA root. A traversal time budget alone is not proof that a blocked provider call can be interrupted; check 6 supplies the recovery boundary.
One supported semantic action. Implement set_value through ValuePattern; a click through Invoke/Toggle/SelectionItem is optional only if trivial. Resolve an opaque token only within its originating snapshot, atomically spend the snapshot before mutation dispatch, revalidate the target before and after dispatch, and use readback for typed verified/refused/unknown outcomes. Unknown outcomes never trigger automatic mutation replay.
Target-window WGC capture. Use IGraphicsCaptureItemInterop::CreateForWindow(HWND) for the same target generation. Report capture and action paths independently. Confirm that occluding the target does not substitute the covering window's pixels; return capture_unavailable on capture failure, with no silent screen-rectangle fallback. Tree and frame must identify the same target, without claiming temporal atomicity for dynamic content.
Cancellation with execution settlement. Exercise cancellation before dispatch, after dispatch, and while a provider call is blocked. Keep stdio/control handling responsive independently of the UIA worker. A cancellation ACK alone is not completion: the original request must settle with its actual outcome where known, or unknown if dispatch may have occurred. Before-dispatch cancellation must prove no mutation occurred. Release the execution lane only after the old operation has ended or the old helper has been confirmed terminated; do not report cancellation while abandoned work continues in the background. If the request cannot settle within the 2s grace, the host terminates the helper as in check 6. Killing the helper does not undo an action already delivered to the target.
Recovery after a hung provider. Use a deterministic fixture that blocks an actual UIA provider call; sleeping only inside the helper is insufficient evidence. The supervisor terminates and recreates the helper, not the user's target application/provider process. Confirm old-helper exit before admitting new work, advance helper generation, invalidate all old snapshots/tokens, and complete a fresh observe/action/readback against a responsive fixture target after restart. The target process must remain alive; release its injected hang through the test fixture if needed, and record that step. Specify restart count, backoff, recovery deadline, and whether restart is eager or next-request-driven. A successful handshake alone does not prove recovery.
Target identity and invalidation
Define how windowGeneration is established and invalidated, how it relates to the retained UIA root, and how helper generation scopes snapshots. A field with that name is not evidence of detecting HWND reuse. PID/start-time checks do not distinguish replacement windows within the same process.
Use the fixture to verify window close/recreation, control replacement, and duplicate use of a spent token. Ambiguous or changed identity must fail closed, never rematch by name/index. A replacement or modal HWND requires new explicit selection. No old token may become usable after helper restart.
Parent death and Windows shutdown
Treat stdin EOF as a shutdown trigger, not as sufficient proof of orphan prevention. Verify normal protocol shutdown/EOF and abrupt host termination, including while UIA is blocked. The helper must exit within a declared deadline without waiting indefinitely for its MTA worker; record residual-process evidence.
Evaluate an independent parent-liveness mechanism or a correctly owned Windows kill-on-close Job Object if EOF handling alone cannot establish that guarantee. Record the chosen ownership and handle-lifetime behavior. Do not copy the macOS SIGTERM graceful-shutdown assumption: Node terminates Windows children forcefully for these signals. Use protocol shutdown/EOF for the graceful path and a bounded forced-termination path.
Evidence environment
Run checks 1–6 on the published artifact on an interactive Windows 11 x64 desktop, with a deterministic adversarial fixture and committed reproduction scripts. Do not assume an ordinary GitHub-hosted runner supplies the required interactive desktop; local or self-hosted evidence is sufficient for this spike.
Include a clean-machine run with no installed .NET runtime or development SDK, copying only the declared deliverables. Record Windows build, Node/.NET SDK/CsWinRT versions, publish settings, artifact hashes, exact commands, and per-check pass/fail/blocked results. Do not treat a run blocked by environment setup as a demonstrated technical failure or a pass.
Packaging assumptions — verify or explicitly revise
Initial target: self-contained single-file win-x64, with trimming disabled. Pin the actual Windows target framework/SDK version and all required native dependencies.
Evaluate .NET 10 LTS as the forward-looking baseline. .NET 8 remains an allowed short-term spike choice with a documented reason and upgrade plan; its support ends 2026-11-10. Self-contained runtime patching requires rebuilding and redistributing the helper.
Measure executable and total distribution size, native-library extraction location/permissions/footprint if applicable, cold/warm startup, first-frame latency, and memory. Do not assume a single exe implies no extraction or external prerequisites.
Helper is a directly supervised TypeScript-host child over stdio, subject to the parent-death tests above. No orphan helper guarantee may rest only on graceful shutdown.
Spike artifacts remain unsigned (signature: none / unsigned in spike metadata), with distributionReady: false. Authenticode and production distribution readiness are deferred; macOS adhoc signing terminology does not apply here.
No changes to apps/desktop/bundled-tools.json pins and no new public protocol revision.
Decision points — measured evidence and recommendation
#
Decision
Evidence to collect
D1
Managed UIAutomationClient vs direct COM (UIAutomationCore)
Bounded base64 on stdout vs negotiated temporary files
Frame latency/size, base64/envelope overhead and response limits, stdout backpressure/control responsiveness; file ownership and cleanup if files are used
In-tree experiments/maka-cu-windows/ vs maka-agent/maka-cu
Integration findings; final code home decided after the spike
D6
Go compatibility boundary and any justified retention
Concrete existing CLI/MCP or distribution/integration requirements; no Go-to-.NET forwarding layer by default
Deliverables and completion criteria
A draft prototype PR under the agreed code home, with fixture/reproduction scripts for the six checks and lifecycle/identity cases above.
A measured results table with sizes, timings, memory, lifecycle evidence, and reproducible failure evidence where applicable.
A short D1–D6 decision record: decision, evidence, recommendation, and every verified or revised packaging assumption.
A go/no-go recommendation. A reproducible negative feasibility result can complete this research issue; it must not be presented as a successful preview implementation. Environmental blockers or untested assumptions are not a completed feasibility result.
Proceed to the production child issue only when all six checks and the stated identity/parent-death cases pass against the selected published layout on the declared interactive environment, including clean-machine evidence. Any revised packaging choice must be explicit in the decision record and follow-up proposal.
If single-file publishing fails, first isolate the cause and evaluate self-contained multi-file .NET distribution. Consider a long-lived Go helper only if measured language/distribution/integration constraints justify it, not automatically because one packaging mode failed.
No macOS executor, bundled pin, public protocol, or foreground/global-input fallback changes. The helper speaks only the private protocol needed for the spike.
Non-goals
No keyboard, scroll, coordinates, PostMessage, SendInput, or user-facing window manipulation. Fixture-driven window replacement is test setup only.
No new consent/approval UI: reuse the existing product approval flow.
No locked/session-0/secure-desktop/elevation support beyond typed capture_unavailable/refusal.
No multi-monitor, mixed-DPI, or broad toolkit parity guarantees.
No CI lane or production signing/distribution integration; these remain follow-up work.
Relationship
Child of #3785 (Windows Computer Use epic), Phase 5 of the Windows roadmap in #2142. The bounded scope follows the maintainer clarifications in #3785, rather than its original broad implementation checklist.
Context
The maintainer preference for the bounded v1 preview is a C#/.NET helper supervised directly by the existing TypeScript host, subject to a small feasibility spike confirming packaging and lifecycle behavior on Windows. This issue is that spike: it does not define the final public protocol, deliver the production semantic v1 slice, or change macOS
maka.cu.Run against the published artifact in the intended packaged-app layout, initially a self-contained single-file exe, not only
dotnet run. Single-file publishing is a hypothesis to test, not a reason to reject an otherwise viable .NET helper automatically.Spike scope — six checks
maka.cu.windows/0or an agreed private id, version, capabilities, and limits. Baseline host deadlines: handshake 10s, request 20s, then cancellation grace 2s where applicable. Record any divergence and its reason.CoInitializeEx(MTA)) and one explicitly selected, already-running top-level HWND. Bound tree nodes, depth, text/response size, and elapsed work. Bind the observation topid + processStartTime + hwnd + windowGenerationand a retained UIA root. A traversal time budget alone is not proof that a blocked provider call can be interrupted; check 6 supplies the recovery boundary.set_valuethroughValuePattern; a click throughInvoke/Toggle/SelectionItemis optional only if trivial. Resolve an opaque token only within its originating snapshot, atomically spend the snapshot before mutation dispatch, revalidate the target before and after dispatch, and use readback for typedverified/refused/unknownoutcomes. Unknown outcomes never trigger automatic mutation replay.IGraphicsCaptureItemInterop::CreateForWindow(HWND)for the same target generation. Report capture and action paths independently. Confirm that occluding the target does not substitute the covering window's pixels; returncapture_unavailableon capture failure, with no silent screen-rectangle fallback. Tree and frame must identify the same target, without claiming temporal atomicity for dynamic content.unknownif dispatch may have occurred. Before-dispatch cancellation must prove no mutation occurred. Release the execution lane only after the old operation has ended or the old helper has been confirmed terminated; do not report cancellation while abandoned work continues in the background. If the request cannot settle within the 2s grace, the host terminates the helper as in check 6. Killing the helper does not undo an action already delivered to the target.Target identity and invalidation
Define how
windowGenerationis established and invalidated, how it relates to the retained UIA root, and how helper generation scopes snapshots. A field with that name is not evidence of detecting HWND reuse. PID/start-time checks do not distinguish replacement windows within the same process.Use the fixture to verify window close/recreation, control replacement, and duplicate use of a spent token. Ambiguous or changed identity must fail closed, never rematch by name/index. A replacement or modal HWND requires new explicit selection. No old token may become usable after helper restart.
Parent death and Windows shutdown
Treat stdin EOF as a shutdown trigger, not as sufficient proof of orphan prevention. Verify normal protocol shutdown/EOF and abrupt host termination, including while UIA is blocked. The helper must exit within a declared deadline without waiting indefinitely for its MTA worker; record residual-process evidence.
Evaluate an independent parent-liveness mechanism or a correctly owned Windows kill-on-close Job Object if EOF handling alone cannot establish that guarantee. Record the chosen ownership and handle-lifetime behavior. Do not copy the macOS
SIGTERMgraceful-shutdown assumption: Node terminates Windows children forcefully for these signals. Use protocol shutdown/EOF for the graceful path and a bounded forced-termination path.Evidence environment
Run checks 1–6 on the published artifact on an interactive Windows 11 x64 desktop, with a deterministic adversarial fixture and committed reproduction scripts. Do not assume an ordinary GitHub-hosted runner supplies the required interactive desktop; local or self-hosted evidence is sufficient for this spike.
Include a clean-machine run with no installed .NET runtime or development SDK, copying only the declared deliverables. Record Windows build, Node/.NET SDK/CsWinRT versions, publish settings, artifact hashes, exact commands, and per-check pass/fail/blocked results. Do not treat a run blocked by environment setup as a demonstrated technical failure or a pass.
Packaging assumptions — verify or explicitly revise
signature: none/unsignedin spike metadata), withdistributionReady: false. Authenticode and production distribution readiness are deferred; macOSadhocsigning terminology does not apply here.apps/desktop/bundled-tools.jsonpins and no new public protocol revision.Decision points — measured evidence and recommendation
UIAutomationClientvs direct COM (UIAutomationCore)MakaCuServiceexperiments/maka-cu-windows/vsmaka-agent/maka-cuDeliverables and completion criteria
Non-goals
PostMessage,SendInput, or user-facing window manipulation. Fixture-driven window replacement is test setup only.capture_unavailable/refusal.References
packages/computer-use/src/maka-cu-service.ts,stdio-json-rpc.ts,maka-cu-backend.ts,select-backend.ts;apps/desktop/bundled-tools.json,scripts/computer-use/prepare.mjs.中文说明
关系与背景
本 issue 是 #3785(Windows Computer Use epic)的子项,属于 #2142 的 Phase 5。范围以 #3785 后续维护者澄清为准,不沿用正文原有的宽泛实现清单。
维持 C#/.NET helper 由现有 TypeScript host 直接监管的方向,通过小型 spike 验证 Windows 打包与生命周期可行性。本项不定义最终公开协议、不交付生产语义 v1 切片、不修改 macOS
maka.cu。必须使用目标应用打包布局中的发布产物,初始尝试 self-contained 单文件 exe,不能仅运行
dotnet run。单文件是待验证假设,失败不自动否定 .NET helper。六项检查
maka.cu.windows/0或约定值,声明版本、能力和限制。基准为握手 10 秒、请求 20 秒、适用时追加取消宽限 2 秒;偏离需说明理由。CoInitializeEx(MTA)),仅操作显式选择且已运行的顶层 HWND。限制节点数、深度、文本/响应大小与耗时,绑定pid + processStartTime + hwnd + windowGeneration及 retained UIA root。遍历计时不能证明阻塞中的 provider 调用可中断,第 6 项负责恢复边界。ValuePattern的set_value;仅在简单可用时选做Invoke/Toggle/SelectionItem点击。opaque token 只能在原快照内解析;变更派发前原子消费快照,动作前后校验目标,通过 readback 返回verified/refused/unknown。结果未知时禁止自动重放变更。CreateForWindow(HWND),与观察绑定同一目标代次;capture/action 路径独立上报。验证窗口被遮挡时不会返回遮挡窗口的像素;失败返回capture_unavailable,不静默回退屏幕矩形。树与帧必须属于同一目标,不承诺动态内容的时间原子性。unknown;派发前取消须证明没有变更。只有旧操作结束或旧 helper 确认退出后才能释放执行 lane,不能后台工作仍在运行就宣布取消完成。无法在 2 秒宽限内结束则进入第 6 项。终止 helper 不会撤销已经交给目标应用的动作。目标身份与失效
定义
windowGeneration如何建立/失效、与 retained UIA root 的关系,以及 helper 代次如何约束快照。增加同名字段不能证明识别了 HWND 复用;PID/创建时间也不能区分同一进程内的替换窗口。fixture 应验证窗口关闭重建、控件替换、重复使用已消费 token。身份变化或无法确认时必须拒绝,不按名称/索引重新匹配。替换窗口或 modal HWND 必须重新显式选择;helper 重启后旧 token 不得重新有效。
父进程死亡与 Windows 关闭
stdin EOF 是关闭触发条件,不能单独证明没有孤儿进程。测试正常协议 shutdown/EOF,以及强制终止 host,包含 UIA 阻塞期间。helper 必须在声明时限内退出,不能无限等待 MTA worker,并提供残留进程检查证据。
若仅靠 EOF 无法保证,评估独立父进程存活监测或正确归属的 Windows kill-on-close Job Object,记录所有权与句柄生命周期。不要照搬 macOS 的
SIGTERM优雅退出假设:Node 在 Windows 下通过这些信号强制终止子进程。正常路径使用协议 shutdown/EOF,异常路径有界强制终止。证据环境
六项检查必须针对发布产物在交互式 Windows 11 x64 桌面运行,并提交确定性对抗 fixture 和复现脚本。不要假定普通 GitHub 托管 runner 提供所需交互桌面;本地或 self-hosted 证据足够。
补充一次未安装 .NET 运行时或开发 SDK的干净机器运行,只复制声明的交付物。记录 Windows build、Node/.NET SDK/CsWinRT 版本、发布参数、产物哈希、完整命令及每项 pass/fail/blocked。环境未就绪不能算技术不可行,也不能算通过。
打包假设——验证或明确修订
signature: none/unsigned,distributionReady: false;Authenticode 与生产分发留给后续。不使用 macOSadhoc签名术语。apps/desktop/bundled-tools.jsonpin,不引入公开协议版本。决策记录 D1–D6
交付与完成条件
非目标
参考链接与代码位置见上方英文 References;范围和选型分别对应 #3785 中 M4n5ter、sunheyi6、liugddx 的讨论。