Skip to content

Add a disabled state to shortcut pins - #937

Merged
selfcontained merged 2 commits into
mainfrom
agt_48e047401271/build-disabled-state-for-shortcut-pins
Aug 11, 2026
Merged

Add a disabled state to shortcut pins#937
selfcontained merged 2 commits into
mainfrom
agt_48e047401271/build-disabled-state-for-shortcut-pins

Conversation

@selfcontained

Copy link
Copy Markdown
Owner

Summary

Retiring a shortcut pin's action currently means deleting the pin — losing the context of what was offered. This adds a disabled: boolean field (shortcut pins only, alongside icon/variant/confirm) so an agent can grey out a shortcut instead of deleting it.

The existing caption field does double duty as the reason shown in place of its normal subtitle (e.g. "already building — agt_...") — no new reason field needed.

Motivated by [an idea from the shortcut-pins dogfooding thread](brain: shortcut-pin-disabled-state): an idea's launch pin currently has to be deleted the moment its builder starts, per the Idea Inbox's Housekeeping convention.

Behavior

  • Button renders non-interactive: aria-disabled, dimmed, cursor-not-allowed, no click delivery.
  • dispatch_pin sets disabled: true/false (shortcut pins only); omitting it keeps the current value, matching confirm's convention. Set false to re-enable.
  • Server-side guard: POST .../inject-pin/:id refuses a disabled pin with 400, even if a client bypasses the greyed-out button.
  • Tooltip on a disabled shortcut reads "This action is currently unavailable." — distinct from the existing "agent not running" / "no stable ID" unavailable states.

Changes

  • pin-merge.ts: disabled joins the shortcut-only fields stripped when a pin is re-typed away from shortcut.
  • pin-run.ts / mcp-handlers.ts: the trust-boundary guard for running a shortcut.
  • pin-listing.ts: disabled flows through dispatch_list_pins/dispatch_pin echoes.
  • pins-panel.tsx: disabled state folded into ShortcutPinItem's existing unavailable/tooltip logic.
  • shared/mcp/server.ts: dispatch_pin schema + description document the new field.

Testing

  • pnpm run check — clean.
  • pnpm run finalize:web — clean build.
  • Server unit tests: 155 files / 2648 tests pass (incl. new cases in pin-run.test.ts, pin-merge.test.ts, pin-run-route.test.ts).
  • Web unit tests: 58 files / 777 tests pass (incl. new case in pins-panel.test.tsx).
  • pnpm run test:e2e: 179 passed / 12 skipped (pre-existing live-terminal skips) — no regressions, including the existing shortcut-pin e2e spec.
  • Manually validated in a live dev stack via Playwright: a disabled pin renders dimmed with its caption as the reason, direct JS .click() does not deliver the prompt (no inject-pin request fires), while a normal enabled pin still fires correctly.

🤖 Generated with Claude Code

Retiring a shortcut pin's action currently means deleting the pin — losing
the context of what was offered. Add disabled: boolean (shortcut pins only,
alongside icon/variant/confirm) so an agent can grey out a shortcut instead:
the button renders non-interactive (aria-disabled, dimmed, cursor-not-allowed,
no click delivery), and the existing caption field doubles as the reason
shown under it (e.g. "already building — agt_...").
- pin-merge.ts: disabled joins the shortcut-only fields stripped on re-type
- pin-run.ts / mcp-handlers.ts: server-side guard refuses to run a disabled
pin even if the client bypasses the greyed-out button
- pins-panel.tsx: disabled pins get their own tooltip reason, independent of
the existing "agent not running" / "no stable ID" unavailable states
- dispatch_pin tool description + schema document the new field
Motivated by an idea from the shortcut-pins dogfooding thread: an idea's
launch pin has to be deleted once its builder is already running.
- Fall back to a generic reason ("This action is currently unavailable.")
in the caption slot when a disabled shortcut has no caption of its own —
the tooltip alone isn't reachable on touch devices, so a caption-less
disabled pin previously went inert with zero visible explanation.
- Swap in a Ban icon for a disabled shortcut, ahead of the destructive
AlertTriangle swap, so it reads distinctly from the other blocked states
(agent-not-running, no-stable-id) that share the same dimmed styling.
- Rename ShortcutPinItem's local `disabled` prop to `agentUnavailable` to
stop it colliding, in reading, with the new `pin.disabled` field.
Addresses review #660 items #1415, #1416, #1417.
@selfcontained
selfcontained merged commit 7dfb025 into mainAug 11, 2026
1 check passed
@selfcontained
selfcontained deleted the agt_48e047401271/build-disabled-state-for-shortcut-pins branch August 11, 2026 16:20
selfcontained added a commit that referenced this pull request Aug 12, 2026
Worktrees deep-dive against workspace-prep.ts, shared/git/worktree.ts,
tmux/setup-script.ts, and archive.ts:
- "When creation fails" claimed the card shows an Attention badge. That
badge renders only for status `error`; a worktree failure goes through
markSetupFailed, which sets `stopped` — and the reconciler never
revisits it, since its query only selects running/stopping/creating/
archiving. What users actually see is the status line flipping to
Blocked with the git error, so say that.
- Both launch paths fetch the starting branch from origin and fork the
new branch from `origin/<branch>`; checking out the starting branch
directly uses the local copy. Neither was documented.
- Removing a worktree also deletes the branch Dispatch created for it,
and "Archive and remove worktree" force-deletes it (`branch -D`)
including unpushed commits. The section only described the directory.
- The tmux setup script skips the dependency install for terminal-type
agents.
Also from the diff since the last audit: the shortcut-pin `disabled`
state (#937) in the Pins paragraph, the two terminal injection routes
inject-text (#935) and inject-pin (#930) in the api-spec Terminal table,
and a new ambient tip for shortcut pins deep-linked to a new
media#media-sidebar anchor.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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

@selfcontained