Skip to content

fix: agent command and history items from #34 - #56

Open
Jozkah wants to merge 7 commits into
CNCKitchen:mainfrom
Jozkah:review/app-commands-history
Open

Jozkah wants to merge 7 commits into
CNCKitchen:mainfrom
Jozkah:review/app-commands-history

Conversation

@Jozkah

@Jozkah Jozkah commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

The agent command and history items from #34, rebased on 0.9.3, one commit per item, each with a regression test that fails without it:

  • fix: keep a stopped agent link off after the permission check
  • fix: keep async history steps out of an open edit group
  • fix: undo the scan swap when a history participant fails
  • fix: report a failed session reset to the agent
  • fix: check plugin ids after the enabled filter and skip failed installs
  • fix: let the next change wait for a timed-out command to finish
  • fix: refuse plugin history and project keys that collide

Notes:

  • A timed-out command now holds the change queue until it settles, capped at one more timeout so one that never ends can't block it. Commands still don't honour ctx.signal.
  • A plugin whose install() throws is logged and left out. What it registered before throwing is not rolled back, since install() returns no cleanup.
  • Key collisions: history section keys may not match a core snapshot key or another plugin's, and project section keys may not match the manifest keys the app writes itself. Workspace and worker-plugin ids aren't checked yet.

Build: npm run build passes. npm test (3103), npm --prefix mcp test (127), the plugin boundary and units checks, and npm run e2e:ci all pass.

The bridge awaited the browser's local-network permission query and then set the link to refused and armed another retry without checking whether it had been switched off meanwhile. It now returns when stopped after that await.
An async step such as an agent command was recorded with whatever edit group a focused field or held pointer had open, so it merged into the user's own step and one undo reverted both. Async steps now record with no group.
The app swaps or moves the scan before the participants prepare a step, so a participant that threw left the scan on the other side of the step from the stores. A failing participant now has the app's part, and the participants before it, put back to the current side before the error is reported.
runImport shows a failure on screen instead of throwing it, so session.reset returned the state as if the session had been started over. The command now checks the error the import left and fails with it.
The duplicate-id check ran over every plugin in the build, so ?plugins=none could not open a build with a clash, and the installed list was set before any install ran, so a plugin whose install threw still counted as in use. Only enabled plugins are checked now, and a plugin that fails to install is logged and left out. Registrations it made before throwing are not undone, since install() returns no cleanup.
A change given up on at its timeout kept running after its history step closed, so what it changed late could land inside the next change's step. The queue now waits for the timed-out run to settle, or for one more of its timeout if it never does, before starting the next change.
A plugin's history section could take a key of the app's own snapshot or another participant's, and a project section a manifest key the app writes itself, silently overwriting one of them. Both now throw at registration. Command names were already checked; workspace and worker-plugin ids are left as they are.

This branch has not been deployed

No deployments
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