Skip to content

fix(trigger-watcher): discrete-Enter submit + chain triggers; prune stale sidebar cache - #33

Merged
JeanBaptisteRenard merged 2 commits into
mainfrom
fix/trigger-watcher-discrete-submit
Jun 2, 2026
Merged

fix(trigger-watcher): discrete-Enter submit + chain triggers; prune stale sidebar cache#33
JeanBaptisteRenard merged 2 commits into
mainfrom
fix/trigger-watcher-discrete-submit

Conversation

@JeanBaptisteRenard

Copy link
Copy Markdown
Collaborator

What

Two fixes to the trigger-watcher input-injection path and the sidebar session cache, bundled because they were built and live-verified together in one AppImage.

1. Discrete-Enter submit + chain triggers (trigger-watcher.js)

Bug: the watcher wrote command + '\r' in a single PTY write. Under Claude Code's kitty keyboard protocol, a CR concatenated onto text is absorbed as a literal newline in the composer — it does not submit. Only a discrete Enter keypress (a separate write) submits. So harness-injected prompts appeared in the input box but were never sent; the user had to press Enter manually.

Fix: submitToPty(pty, command) writes the command, waits a short configurable delay, then writes \r as its own discrete write. Delay defaults to 50 ms, overridable via SWITCHBOARD_SUBMIT_ENTER_DELAY_MS.

Also lands the chain trigger feature: a trigger file may carry chain: [{command, timeout_ms?}, ...]; steps run sequentially, waiting for the terminal to go busy→idle between steps (waitForTurnComplete). Enables multi-step harness sequences (e.g. /compact then a resume prompt) from one trigger.

2. Prune stale cache rows on startup (main.js)

Sidebar listed workflow-spawned sessions whose transcripts no longer exist ("uuid introuvable" ghosts). Added a startup cache rebuild so deleted-file rows are pruned on launch, not only during full folder refreshes.

Testing

  • test/trigger-watcher.test.js extended (+612): discrete-Enter assertions (writes split into command then \r), chain sequencing, busy→idle gating. SWITCHBOARD_SUBMIT_ENTER_DELAY_MS=1 in tests to keep them fast.
  • Built via npm run build:linux, deployed, and live-verified 2026-06-02: auto-submit of both /compact and a free-text resume prompt confirmed end-to-end (ACK-FIX-OK).

Notes

  • submitToPty is async; both the single-command and chain-step write sites now await it.
  • Delay is intentionally configurable — 50 ms is conservative for the PTY to register two distinct writes; tune down if needed.

Two coupled changes:

1. chain field — a trigger may carry `chain: [{command, timeout_ms?}, ...]`
   instead of a single `command`. Steps are injected sequentially, each
   waiting for the prior turn to complete (busy then idle) before the next,
   under a shared global deadline. Lets one trigger drive a /compact then a
   resume prompt without racing on a shared idle tick.

2. discrete-Enter submit — write the command text and the Enter keypress as
   SEPARATE PTY writes (SUBMIT_ENTER_DELAY_MS apart). A CR concatenated onto
   the text in a single write is absorbed by Claude Code (kitty keyboard
   protocol) as a literal newline and the command never submits; only a
   discrete CR submits, mirroring how xterm sends each keypress. Fixes
   free-text trigger commands landing in the composer unsubmitted while the
   short menu-driven /compact path appeared to work.

Tests: 101 passing (node:test). Write-shape assertions updated for the
two-write submit; makeChainCtx starts a turn only on the discrete Enter.
Call populateCacheViaWorker() unconditionally in app.whenReady so
deleted transcripts (sub-agent / workflow runs cleaned up between
sessions) are evicted from session_cache on the next launch. The
worker does a deleteCachedFolder + upsert per folder — a full prune —
and runs in a Worker thread so startup is non-blocking. Concurrent
callers (FTS-recreated path, first get-projects call) share the
in-flight Promise via the existing guard, so no double scan occurs.

Previously the prune only ran when isCachePopulated() was false (cold
DB after migration) or when searchFtsRecreated was set, leaving ~457
stale rows visible in the sidebar across normal restarts.
@JeanBaptisteRenard
JeanBaptisteRenard force-pushed the fix/trigger-watcher-discrete-submit branch from 13185c8 to 528513e Compare June 2, 2026 00:16
@JeanBaptisteRenard
JeanBaptisteRenard merged commit 6890a10 into main Jun 2, 2026
7 checks passed
@JeanBaptisteRenard
JeanBaptisteRenard deleted the fix/trigger-watcher-discrete-submit branch June 2, 2026 00:25
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