Skip to content

fix: publish the commands when the skills change - #643

Open
nikita-ashihmin wants to merge 2 commits into
agentclientprotocol:mainfrom
nikita-ashihmin:fix/publish-commands-on-skills-changed
Open

nikita-ashihmin wants to merge 2 commits into
agentclientprotocol:mainfrom
nikita-ashihmin:fix/publish-commands-on-skills-changed

Conversation

@nikita-ashihmin

Copy link
Copy Markdown
Collaborator

Problem

A skill that appears while a session is open — a new SKILL.md, a new symlink into .agents/skills, or a link whose target changed — did not show up in the slash-command completion until the next completed turn.

The app-server sends skills/changed for exactly this, and documents it as "Treat this as an invalidation signal and re-run skills/list". The adapter listed it among the ignored notifications, so nothing re-ran. The only re-list was the post-turn publish, which is why the skill eventually appeared — one turn late.

Change

  • CodexAcpServer handles skills/changed on both the baseline turn tracker and the prompt subscription, and asks the command registry to publish for that session.
  • CodexCommands.publishOnSkillsChanged debounces the publish by 300 ms, so one burst of file changes lists the skills once. The timer is unref'd, and a session that closed in the meantime publishes nothing.
  • CodexEventHandler gives skills/changed its own case instead of leaving it in the ignored block — the change itself is no session update.
  • The stale comment at the post-turn publish ("Codex sends no notification for a new skill file.") is corrected; that publish stays as the catch-all for a notification missed during a turn.

Tests

Two cases in CodexAcpClient.test.ts: a burst of skill changes publishes once after it settles and publishes again when the list actually differs; a session that closed while its change settled never lists.

npx tsc --noEmit is clean. The three failures in a full vitest run (CodexHomeWatcher) reproduce on untouched main on this machine.

A skill that appears while a session is open — a new file, a new symlink,
or a link whose target changed — became a slash command only after the next
completed turn, because the `skills/changed` notification was ignored.

The server now lists the skills again on that notification and publishes the
commands, debounced so one burst of file changes lists once.
A publish now carries a revision, so a slower earlier `skills/list` no longer
overwrites the newer list a later one already sent — the very command the
change is about would stay missing until the next turn.

The pending publish holds the full `sessionPublishIsCurrent` guard, including
the close fence, instead of a bare identity check, and `closeSession` drops
the publish a closing session was still waiting out. The debounce keeps a cap,
so a writer that never pauses — a long checkout, a watcher of a skill root —
no longer holds the publish back forever.

The two publishes a turn triggers now use the same guard.

The tests go through the wire: `skills-changed.test.ts` emits the real
notification and asserts the commands the client receives, which the unit
tests on the private handler could not. Removing either call site now fails
the suite.

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