Skip to content

v1.5.26

Choose a tag to compare

@github-actions github-actions released this 05 Nov 11:23
· 34 commits to main since this release
edd0752

Security

  • Windows: text could run as PowerShell code (GHSA-9ppf-38v8-h97v, high).
    Clipboard writes (type_text, smart_type, copy_all_text and the restore
    of the user's clipboard), app launches, window-title lookups and
    relaunch_with_cdp quoted values into PowerShell source, and the quoting
    could be broken by other characters PowerShell treats as quotes, so text
    from a document, a page or the clipboard could break out and run commands
    with no confirmation. Values now reach PowerShell only as data: clipboard
    text on stdin, names and titles as environment variables, and a window pid
    only when it is an integer. Large clipboard writes, which failed on the
    command-line length limit, work too. macOS and Linux were not affected.
    Versions through 1.5.25 are affected. Reported by @Sauron-sol (CleanIssue).

Fixed

  • macOS: window focus names secure input as the cause (#267). While a
    password field holds secure input, macOS sends keys and focus only to that
    app, and a focus ended with a vague "focus went to Google Chrome" / UNKNOWN.
    The focus read-back stays the assertion (a successful accessibility call is no
    evidence); when it fails, clawdcursor now checks IsSecureEventInputEnabled()
    and, if on, finds the holder (kCGSSessionSecureInputPID via ioreg) and
    returns a typed SECURE_INPUT result: "secure input is on (held by , pid N)
    ... Close or leave the password field in , then try again", with a
    pause_for_user next step. If the check cannot answer, the old message is
    kept. macOS only; no open -b fallback.
  • A field below the fold is scrolled into view, not refused. On a long web form,
    accessibility find_field returned a field, then set_value / invoke on its
    {element_id, snapshot_id} failed with "element is off the active window", and
    smart_type with the field's label said "Could not find element". The ref check
    took "outside the window's rectangle" to mean "in another window", but a page
    element below the fold reports bounds past the window's edge. The element is
    now scrolled into view with the platform's own call (Windows: UIA
    ScrollItemPattern.ScrollIntoView, else SetFocus; macOS: AXScrollToVisible;
    Linux: AT-SPI Component.scroll_to), its bounds are read again, and the act
    lands where it is now. It is still refused when it belongs to another window of
    the app, when the platform cannot scroll, or when the scroll leaves it out of
    view, and the error says which ("could not be scrolled into view (...)",
    "scrolled but still not visible"). Scrolling sends no input and does not change
    the window the agent is bound to (the active window is read again afterwards and
    the act is refused if its handle, title or bounds differ); a stopped session does
    not scroll. The platform looks only in the active window and picks the element
    nearest the last-seen bounds, refusing when several share the name; the result is
    then checked to be the referenced element (name, role kind, size). A scroll moves
    every other element in the snapshot, so the snapshot is invalidated and the next
    ref must be compiled afresh. Window titles and element names in these errors are
    wrapped as untrusted screen content.
    smart_type with a target now also looks the field up in the compiled UI the
    way find_field does (a field's label need not be its accessibility name) and
    scrolls it in. Verified live on Windows 11 / Edge; the macOS and Linux calls are
    unit-tested but still need a run on a real Mac and a real Linux desktop.

Added

  • The pause prompt is now a card: choices and a text box. Agents asked their
    questions in their own chat while the user was looking at the screen (a yes/no on a
    YC application had to be typed). pause_for_user takes choices (2-6 short options,
    at most 40 characters each, de-duplicated: one button each) and/or input
    ({placeholder?, multiline?}: a text box with "Don't type passwords here"), and
    returns {status:"replied", choice:"<exact option text>"} or {status:"replied", reply}. Bad values are rejected with the limit named; done_when cannot be combined
    with a question. Resume / End task are unchanged, and a pause without choices /
    input looks and behaves as before. The overlays print BANNER_CHOICE <index>
    (the text is looked up by the daemon, never taken from the overlay); the card reaches
    them as JSON in CLAWD_BANNER_CHOICES / CLAWD_BANNER_INPUT. Windows and macOS show
    the text box on the card; on Linux the pill cannot take the keyboard, so the
    button reads "Type an answer" and opens the box. Only the user on screen can choose
    (an agent's resume_task stays unverified), and a choice is never a safety approval:
    Send / Delete / Pay confirmations are decided by the safety layer alone.
  • The MCP instructions, the pause_for_user description, the skill and llms.txt say
    it plainly: while an agent is driving the desktop the user is watching the screen,
    not its chat, so it should ask on the pause card (with choices when there are
    options) rather than in its own chat.

Changed

  • A redesigned pill that says what the agent is doing. The running pill read
    "desktop control in progress - double-click to stop" behind a red dot that looked
    like an error, and a wait looked the same as finished work. It now shows an amber
    dot, the current action and app ("Typing in Edge", "Opening a page"), the time since
    it appeared, and a Stop button (a double-click anywhere still stops). Each guarded
    input names its method once it passed the foreground and stop checks, and the
    daemon sends the label as one ACTIVITY <text> line on the pill's stdin when it
    changes; a refused input names nothing. The app is named only for keys, typing and
    the pointer, which read the window in front first. The pause card has the same
    look with a blue outline, "waiting for you" and the app, and one full-width row per
    choice. Answers, focus handling and the stdout lines are unchanged on all three
    overlays.