Repository navigation
Releases: straygizmo/winuse
Release list
winuse 0.2.7
winuse 0.2.7 makes select_item and set_checked answer for themselves: both read the result back and say what reached the app, and a single_action switch stops them from acting twice for callers that must not resend an unconfirmed action. The winuse-gate plugin gains the winuse-operator subagent, which drives the app for Claude Code's main conversation so UI trees and screenshots stay out of its context.
Changes
select_itemreads the selection back. The result reportsitem(the label that was matched and acted on),selected(what the container reports afterwards),method(mouse,selection,dom),actions(how many inputs reached the app) andoutcome.donemeans the read-back named the item. A read-back that names another item is an error quoting what is selected, so a success result always means the item is selected.outcome: "unknown"withnotemeans the container exposes no way to read its selection (no UIA Selection / Value pattern or SelectionItem state, no Java AccessibleSelection). The read-back is retried for about half a second for apps that update asynchronously.- UIA combo boxes are committed with a click. Selecting a popup item through the SelectionItem pattern and collapsing the popup leaves Win32 and Qt combo boxes on their old value, which earlier versions reported as success.
select_itemnow clicks the item in the open popup, the way a user commits it, with the pattern path as the fallback; lists, tabs and trees keep the pattern first and the click as the fallback. select_itemsingle_action. Withsingle_action: truethe tool stops after the first path that delivered an input instead of trying the other one when the read-back disagrees; the mismatch error then says that no other method was tried. A mismatch error always names the paths delivered (2 actions delivered: mouse, selection).set_checkedreads the state back. The result reportsmethod(toggle,selection_item,action,dom),toggles(0 when the control already had the state),checked(the state read back) andoutcome. A toggle now gets about half a second to take before the next one is sent, so an asynchronously updating control is no longer toggled three times in a row; the default still sends up to 3 and then fails naming the toggles delivered and the state seen.single_action: truesends at most one toggle and reportsoutcome: "unknown"withnotewhen the state still differs, instead of toggling again or failing.- winuse-gate plugin 0.2.0: the
winuse-operatorsubagent. The main Claude Code conversation hands it the window and the goal; it reads trees and screenshots, drives the app and runs the assertions in its own context, and returns a short text report. Its passing assertions count for the gate (the hooks fire inside the subagent with the parent session id). Thewinuse-e2eskill now delegates the driving to it. Update the plugin with/plugin update winuse-gate@winuse.
Scenarios recorded with 0.2.6 replay unchanged. Behaviour changes for existing clients: select_item on a UIA combo box clicks the popup item instead of selecting it through the pattern, and a selection the app refused is now an error instead of a success; set_checked returns an object instead of a bare success, and takes up to about half a second longer when a toggle does not take at once.
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.7-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading: unzip over the previous folder; no settings change.
Known issues
- The combo box read-back and
single_actionare verified against Win32 controls and the Swing test fixture, not yet on the Qt app that reported them. - The operator subagent is Claude Code only; other MCP clients keep calling the tools directly.
Full changelog: CHANGELOG.md
winuse 0.2.6
winuse 0.2.6 answers the third round of feedback from driving Java Swing apps: every action tool now says what it did and whether the target confirmed it, Java elements that are scrolled out of view or beyond the window edge are recognised as such, a ref click checks where it would land before clicking, and window_close separates the request from the effect.
Changes
invokereports how it acted.method(action,mouse,selection), the accessibilityactionname when one ran, andoutcome:donewhen the target confirmed it,unknownwhen the request was delivered but never answered. On Swing that is what an action that opened a modal dialog looks like (it returns only when the dialog closes), so the result then carriesnote,foregroundandnew_windowsinstead of a misleadingAction 'click' failed.method: "action"/"mouse"force one path.- Swing push buttons are clicked with the mouse by default. A button's
clickaction runs on the JVM's event thread and answers only when it returns, so a button that opens a modal dialog used to hold the Java Access Bridge for the whole life of the dialog, which then could only be driven blind.invokenow brings the window to the front, checks that the point belongs to the app and clicks the visible button; menu items, check boxes, tabs and anything not on screen keep the accessibility action, andmethod: "action"restores it for buttons. Thetimeoutdiagnosis carriesblocked_by_action_atand says how to proceed when an action did block the bridge. set_textreports the path taken.methodisvalue_pattern(UIA) oraccessible_text(Java) when the accessibility API took the text and the field saw no key events,keyboardwhen the field was focused and the text typed (key listeners such as upper-casing run),fillfor the DOM.method: "keyboard"forces typing,method: "api"fails instead of falling back. The text itself is never in the result.window_closeseparates the request from the effect.close_requested,closed,window_exists_after_request,process_alive(when the window is gone),new_windows(windows the same process opened after the request, with refs: the exit confirmation or save prompt),foregroundand ahintsaying how to answer the prompt and wait for the window.- Explicit completeness flags and server identity. Every
get_ui_treeresult carriesbackend(java_access_bridgeoruia) andserver_version, and a Java tree always statesnode_limit_reached,depth_limit_reachedandunreadable_nodes(false/0when the walk was complete), so a complete tree from this version is distinguishable from an older server that did not report them. - Clipped Java elements. Swing reports
showingfor everything in a displayed hierarchy, including what a scroll pane has scrolled out of view or what lies beyond the window's edge after a resize. Java elements are now clipped to their window andviewportancestors:rectis the part on screen, an element with no on-screen part isoffscreen: true(listed only withinclude_offscreen, with its full rect so you know where to scroll), andclick/invokeresolve the same visibility at call time and refuse such an element with the reason. - Click hit check.
clickon a ref checks, before clicking, that the resolved point lies on a window of the process that owns the ref (popups and dialogs of the same process count). A point on another process's window (the taskbar or Start button after the screen shrank, a window covering the target) or on no window fails with the reason and nothing is clicked; the result names the window under the point aslands_on. Coordinates are clicked as given.
Scenarios recorded with 0.2.5 replay unchanged. Behaviour changes for existing clients: invoke on a visible Swing push button clicks it instead of running its action (pass method: "action" for the old behaviour); Java elements scrolled out of view are no longer listed by default (pass include_offscreen: true); a ref click that would land outside the app's windows now fails instead of clicking.
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.6-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading: unzip over the previous folder; no settings change.
Known issues
- The modal-dialog outcome and the clipping are verified against a fake bridge and the Swing test fixture, not yet on the live app that reported them.
- Clipping follows
viewportancestors and the window only; a container that clips its children some other way is not detected.
Full changelog: CHANGELOG.md
winuse 0.2.5
winuse 0.2.5 answers the second round of feedback from driving Java Swing apps: get_table can skip the column header and tells a read failure from an empty cell, and the Java tree says when it may be incomplete for a reason other than the node limit.
Changes
get_tablewithout the header.include_header: falsenever reads the column header (no bridge call, nothing in the result or the log) androwsholds data rows only. The result always carriescolumn_count, somax_rows: 0, include_header: falsereturns the table size alone.- Read failure vs. empty cell. A cell the Java Access Bridge (or UIA) could not hand out or describe is
nullinstead of"", andunreadable_cellscounts them. An empty cell stays"", so a caller that decides on a cell value no longer mistakes a failed read for a blank. - Depth limit.
get_ui_treeon a Java window reportsdepth_limit_reached: truewhen an element atmax_depthhad children that were not walked. A leaf at the limit does not set it. - Unreadable children. Children the bridge gave no handle or no context info for were already skipped;
get_ui_treenow reportsunreadable_nodes: nand the server logs a warning. Together withnode_limit_reachedthese fields say when an element that exists may be missing from the tree; treat "element absent" as unknown while any of them is set.
Scenarios recorded with 0.2.4 replay unchanged. The one behaviour change for existing clients: a get_table cell that fails to read is null where it used to be "".
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.5-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading: unzip over the previous folder; no settings change.
Known issues
- The new fields are verified against a fake bridge in the test suite, not yet on a live Swing app with a failing bridge call.
Full changelog: CHANGELOG.md
winuse 0.2.4
winuse 0.2.4 answers the feedback from driving Java Swing apps: get_table reads Swing tables, a Java window the bridge cannot read comes with a diagnosis that says where the connection stopped, the internal node limit of the Java tree is reported, and passwords can be typed without landing in the log.
Changes
get_tableon Swing tables. AJTableis read through the bridge's table interface: the header row first, then every cell (boolean cells astrue/false).max_rowscaps the data rows;row_countandomitted_rowsare reported for UIA grids as well, so an empty list isrow_count: 0. AJTableis oneTablenode in the interactive tree (its cells no longer eat the node budget); scopeget_ui_treeto the table ref to list the cells.- Bridge diagnostics. When a Java window cannot be read,
get_ui_treereturnsjava_access_bridge_diagnosticsnext to thejava_access_bridgereason:stage(client_unavailable,no_hello,handshake_failed,timeout,send_failed,no_answer,not_owned),jvm_pid,jvm_connected,bridge_module,wire_format,bitness,client_window,timeout_msandconnected_jvmswith the last failed request of each. The reason names the JVM pid and the failed step instead of a generic "not responding";winuse doctorprints the same reason. No window titles or element data are included. - Node limit flag.
get_ui_treereportsnode_limit_reached: trueandnode_limit: 5000when the Java tree walk stopped at its internal bridge round-trip limit (previously only a log warning). - Secrets.
get_ui_treetakesinclude_values: false(no element value is read, so field contents stay out of the result and the log).set_text,type_text,paste_textandclipboard_settakesecret: true: the text is used but the log, the journal and saved scenarios hold"***"; replaying such a step stops withsecret text was not recordeduntil the scenario names the value as${NAME}.
Scenarios recorded with 0.2.3 replay unchanged. The one behaviour change for existing clients: the cells of a Swing table are no longer listed in the default (interactive_only) tree.
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.4-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading from 0.2.3: unzip over the old folder and restart the AI client.
Known issues
The bridge reports no position for a Swing table cell, so a cell listed in a scoped tree carries the table's rectangle. Unchanged from 0.2.3: a JRE without the Java side of the bridge cannot be read; type_text with Japanese text can be garbled under the Japanese IME (intermittent).
Full changelog: CHANGELOG.md
winuse 0.2.3
winuse 0.2.3 closes the ten usability issues filed against 0.2.2 (#9 to #18): modal dialogs and fresh frames in screenshots, an honest window_close, a title regex that survives SPA re-titling, and new tools for waiting, the clipboard, window-relative input and filtered UI trees.
Changes
- Dialogs and stale frames in screenshots (#10, #11). A window is now copied from the screen whenever it or a dialog it owns is in the foreground, so Office save prompts and WebView2 overlays are in the picture and Chromium windows no longer hand out a PrintWindow frame that predates the last input.
screenshottakesmethod(auto/screen/print) andsettle_ms, and reports whichmethodwas used.get_ui_treereads once more after a short wait when a dialog that just opened has no content yet. window_closetells the truth (#16). It waits for the window to go away (timeout_ms, default 2 s) and returnsclosed: falsewithreason: "still_open"plus the foreground window (the save prompt) when the window is still there.- Title regex after
wait_for(#9). A title that matches nothing is retried for 1.5 s beforeNo window matches; the error and thewait_fordescription point at thewin{n}ref as the reliable handle. - Primary monitor by default (#18).
screenshot {target: "screen"}captures the primary monitor at origin (0,0); the former whole-desktop image istarget: "virtual";monitor: <index>picks one, and screen captures reportmonitorswith rect, work area and primary flag. sleep {ms}andwait_for {condition: "time"}(#12).- Clipboard tools (#13).
clipboard_get,clipboard_set,clipboard_set_image(image file under the allowed roots, put on the clipboard as CF_DIB plus PNG),paste_textandpaste_image(set the clipboard, press ctrl+v, restore the previous text). - Window-relative input (#14, #15).
click,hover,scrollanddragtakewindow: the window is activated first and x/y are relative to its rect, so a pixel of a window screenshot can be passed as is.type_textandpress_keystakewindowtoo: the window is activated before the input and the call fails when it cannot take the foreground; the result reports where the input went. - Filtered, compact UI trees (#17).
get_ui_treetakescontrol_type(comma-separated),name(regex),compactandmax_nodes; matching nodes are hoisted,compactdrops null / default fields and packsrectasx,y,w,h, and a truncated result reportsomitted_nodes.
Scenarios recorded with 0.2.2 replay unchanged. The only behaviour change for existing clients is screenshot {target: "screen"}, which is now the primary monitor instead of the whole virtual screen.
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.3-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading from 0.2.2: unzip over the old folder and restart the AI client.
Known issues
Unchanged from 0.2.2: get_table does not read Swing tables yet; a JRE without the Java side of the bridge cannot be read; type_text with Japanese text can be garbled under the Japanese IME (intermittent).
Full changelog: CHANGELOG.md
winuse 0.2.2
winuse 0.2.2 makes window refs stable across calls and reports the frame the user actually sees, so a client can track one window through a session and crop or record exactly it. It also ships the winuse-gate Claude Code plugin in the repository.
Changes
- Stable
win{n}refs.list_windowsre-numbered its refs on every call, so a client could not look a window up again by the ref it had been given. A window now keeps itswin{n}ref for the whole session: observing the same HWND again (list_windows,get_ui_tree,process_run, ...) returns the ref already handed out, with the stored locator refreshed to the current title. Element refs (u{n},j{n}, ...) still number up per observation. visible_rect.list_windows,get_elementand thewindowobject ofget_ui_treereport the DWM extended frame bounds: the frame the user sees, without the invisible resize borders thatrectincludes.get_ui_tree'swindowobject now also carriespid,rectandstate.winuse-gateplugin (plugins/winuse-gate, listed in.claude-plugin/marketplace.json). Hooks that block Claude's turn end once per change, and denygit commit, while UI files changed in the session have no passing winuse assertion, plus thewinuse-e2eskill that tells Claude how to verify. Configured per project with.claude/winuse-gate.json. Install with/plugin marketplace add straygizmo/winusethen/plugin install winuse-gate@winuse.
Scenarios recorded with 0.2.1 replay unchanged.
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.2-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading from 0.2.1: unzip over the old folder and restart the AI client.
Known issues
Unchanged from 0.2.1: get_table does not read Swing tables yet; a JRE without the Java side of the bridge cannot be read; type_text with Japanese text can be garbled under the Japanese IME (intermittent).
Full changelog: CHANGELOG.md
winuse 0.2.1
winuse 0.2.1 is a small follow-up to 0.2.0: every MCP tool now declares its annotation hints, so MCP hosts can tell at a glance which tools only observe and which can change or destroy something.
Changes
- Tool annotations on all 48 tools. Every tool declares
readOnlyHint,destructiveHint,idempotentHintandopenWorldHintexplicitly. Hosts that confirm before destructive or open-world calls (Claude Code, Codex CLI, Copilot CLI, ...) get a real answer per tool instead of a default.- Tools that act on the live desktop are open-world; where a single call can trigger anything in the target app (
act,click,drag,type_text,press_keys,invoke,window_close,process_run,process_kill,scenario_run) they are destructive. - File tools stay inside the allowed roots and are closed-world;
write_text,copy,move,delete,unzipandscenario_saveare destructive because they can replace existing files. - Observation,
find/check,wait_forand theassert_*tools are read-only.
- Tools that act on the live desktop are open-world; where a single call can trigger anything in the target app (
No behaviour of the tools themselves changed. Scenarios recorded with 0.2.0 replay unchanged.
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.1-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading from 0.2.0: unzip over the old folder and restart the AI client.
Known issues
Unchanged from 0.2.0: get_table does not read Swing tables yet; a JRE without the Java side of the bridge cannot be read; type_text with Japanese text can be garbled under the Japanese IME (intermittent).
Full changelog: CHANGELOG.md
winuse 0.2.0
winuse 0.2.0 adds Java Swing support: Swing windows are read and operated through Java Access Bridge like UI Automation apps, and winuse speaks the bridge's wire protocol itself, so 32-bit Java 7/8 JREs that ship only the legacy bridge work too.
Highlights
- Java Swing through Java Access Bridge. Swing windows (
SunAwt*) are read into the same element model as UIA (j{n}refs), soget_ui_tree,act/find/check,click,invoke,set_text,set_checked,select_item,get_text,get_list_items,assert_*,wait_forand scenario replay work on them. Menu items are listed and invokable while their menu is closed. - Built-in bridge client, no DLL. winuse talks the Java Access Bridge wire protocol directly (hidden client window, hello handshake, one memory-mapped file per JVM). Both wire formats are spoken: the wide one of
JavaAccessBridge-32/64.dlland Java 9+'sjavaaccessbridge.dll, and the legacy one of the suffix-lessJavaAccessBridge.dllthat 32-bit Java 7/8 JREs ship. Several JVMs of mixed formats at once. Tested on Temurin 21 x64, Temurin 8 x86 and Temurin 8 x86 on its legacy bridge, and confirmed on a 32-bit Java 7 application. - Enabling accessibility without touching the JRE. Apps started with
process_rungetJAVA_TOOL_OPTIONS=-Djavax.accessibility.assistive_technologies=com.sun.java.accessibility.AccessBridge(WINUSE_JAVA_ACCESSIBILITY=offdisables it); for apps started any other way,winuse jab enable|disable|statusmanages%USERPROFILE%\.accessibility.properties. - Diagnostics.
winuse doctorreports the client window and the JVMs connected to it, the user-profile enablement, and every Java window with its JVM:jvm.dllpath and version, bitness, whichJavaAccessBridge*.dllit loaded and its wire format, the Java and bridge versions the JVM reports, and whether the bridge answers. When a Java window cannot be read,get_ui_treereturnsjava_access_bridgewith the reason andactreportsno elements (java access bridge: ...); the window then falls back to visual grounding. - Settings:
WINUSE_JAB(auto/off),WINUSE_JAVA_ACCESSIBILITY(on/off).
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.2.0-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Upgrading from 0.1.0: unzip over the old folder. Java apps need accessibility enabled in their JVM when they start (see above); restart them after winuse jab enable.
Known issues
get_tabledoes not read Swing tables yet (get_table is not supported for Java elements yet).- A JRE without the Java side of the bridge (trimmed Java 8 without
JavaAccessBridge-32.dll/access-bridge-32.jar, or ajlinkimage withoutjdk.accessibility) cannot be read, and a JVM on such a JRE fails to start when accessibility is requested (AWTError: Assistive Technology not found): setWINUSE_JAVA_ACCESSIBILITY=offfor apps on such a JRE and do not usewinuse jab enable.doctorreports the missing files. A Java app running elevated or as another user is out of reach. type_textwith Japanese text can be garbled under the Japanese IME (intermittent, under investigation).
Full changelog: CHANGELOG.md
winuse 0.1.0
First release of winuse, an MCP server and CLI that lets an AI observe and operate Windows desktop apps.
Highlights
- MCP server over stdio (
winuse --mcp) with 48 tools: observe (screenshot, UI Automation tree, WebView2 DOM via Playwright over CDP), intent (act,find,check), input, element, window, wait, process, file, assert and scenario tools. - Scenario replay without AI (
winuse run,scenario_run): recorded locators resolve deterministically;--healre-groundsactsteps whose element is gone. - Two decision models: TypeSafe Jev (
JEV_API_KEY) or Cloudflare Clef on Workers AI (CLOUDFLARE_ACCOUNT_ID+CLOUDFLARE_API_TOKEN), chosen automatically or forced withWINUSE_DECISION_PROVIDER. - Visual grounding for windows without UI elements (VM consoles, emulators, VNC):
act/find/checkwork from a screenshot, returnpt{n}refs, and replay from a window-relative point (WINUSE_SCREENSHOTS,WINUSE_VISUAL_LOCATOR). winuse doctorreports the decision model, keys, endpoint, probe, UIA, WebView2 and the Playwright driver;winuse --versionprints the version.
Install
- Install the .NET 10 runtime (or SDK).
- Unzip
winuse-0.1.0-win-x64.zipinto a folder. - Register with Claude Code:
claude mcp add winuse -- <folder>\winuse.exe --mcp - Set
JEV_API_KEY, orCLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKEN, as user environment variables, then runwinuse doctor.
Known issues
type_textwith Japanese text can be garbled under the Japanese IME (intermittent, under investigation).- Clef and visual grounding are covered by unit tests with a fake model; they have not yet been exercised against a live Cloudflare account or a real VM window.
Full changelog: CHANGELOG.md