Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/cockpit-tray-dev/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ You are working on `cockpit-tray/**`, the Tauri v2 macOS menu-bar app that super

`cockpit-tray` involves two distinct build artifacts. "Why don't I see my change?" almost always means you've confused them:

1. **The cockpit WEB app** (`src/cockpit/web/**`, `src/cockpit/server.ts`) — served by the daemon. A running tray app **auto-rebuilds the web bundle** (mt#2297) and **auto-restarts the daemon on backend changes** (mt#2299) when source changes (e.g. after `git pull`). So a cockpit-web change needs **no manual rebuild** — refresh the window, or let the watcher fire; the "Last build" / "Daemon uptime" menu lines confirm currency.
1. **The cockpit WEB app** (`src/cockpit/web/**`, `src/cockpit/server.ts`) — served by the daemon. A running tray app **auto-rebuilds the web bundle** (mt#2297) and **auto-restarts the daemon on backend changes** (mt#2299) when source changes (e.g. after `git pull`) — any non-test module under `src/**` or `packages/*/src`, not just `src/cockpit` (mt#4230, mt#5060). So a cockpit-web change needs **no manual rebuild** — refresh the window, or let the watcher fire; the "Last build" / "Daemon uptime" menu lines confirm currency.
2. **The tray app's own Rust binary** (`cockpit-tray/src-tauri/**`) — the `.app` itself: menu items, the window, supervision logic. This is **NOT** auto-rebuilt. The installed `/Applications/Minsky Cockpit.app` is a static compiled bundle; merging a Rust change to `main` does nothing to it until you rebuild. This is the layer that bites: mt#2219 (the "Open Cockpit" menu item) was a tray-binary change, so it stayed invisible in the running menu bar until a rebuild.

Decision: **cockpit-web change → no tray rebuild, just refresh. Tray-binary change → `bun run dev` (iterate) or build+reinstall (release).**
Expand Down
2 changes: 1 addition & 1 deletion .minsky/skills/cockpit-tray-dev/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ You are working on `cockpit-tray/**`, the Tauri v2 macOS menu-bar app that super

`cockpit-tray` involves two distinct build artifacts. "Why don't I see my change?" almost always means you've confused them:

1. **The cockpit WEB app** (`src/cockpit/web/**`, `src/cockpit/server.ts`) — served by the daemon. A running tray app **auto-rebuilds the web bundle** (mt#2297) and **auto-restarts the daemon on backend changes** (mt#2299) when source changes (e.g. after `git pull`). So a cockpit-web change needs **no manual rebuild** — refresh the window, or let the watcher fire; the "Last build" / "Daemon uptime" menu lines confirm currency.
1. **The cockpit WEB app** (`src/cockpit/web/**`, `src/cockpit/server.ts`) — served by the daemon. A running tray app **auto-rebuilds the web bundle** (mt#2297) and **auto-restarts the daemon on backend changes** (mt#2299) when source changes (e.g. after `git pull`) — any non-test module under `src/**` or `packages/*/src`, not just `src/cockpit` (mt#4230, mt#5060). So a cockpit-web change needs **no manual rebuild** — refresh the window, or let the watcher fire; the "Last build" / "Daemon uptime" menu lines confirm currency.
2. **The tray app's own Rust binary** (`cockpit-tray/src-tauri/**`) — the `.app` itself: menu items, the window, supervision logic. This is **NOT** auto-rebuilt. The installed `/Applications/Minsky Cockpit.app` is a static compiled bundle; merging a Rust change to `main` does nothing to it until you rebuild. This is the layer that bites: mt#2219 (the "Open Cockpit" menu item) was a tray-binary change, so it stayed invisible in the running menu bar until a rebuild.

Decision: **cockpit-web change → no tray rebuild, just refresh. Tray-binary change → `bun run dev` (iterate) or build+reinstall (release).**
Expand Down
2 changes: 1 addition & 1 deletion cockpit-tray/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ For depth on this app — daemon lifecycle, status labels, auto-rebuild, testing

"Why don't I see my change?" almost always means these two were confused:

- **cockpit-web** (`src/cockpit/web/**`, `src/cockpit/server.ts`) — the running tray **auto-rebuilds the bundle (mt#2297) and auto-restarts the daemon (mt#2299)** on source change. No manual tray rebuild; just refresh the window.
- **cockpit-web** (`src/cockpit/web/**`, `src/cockpit/server.ts`) — the running tray **auto-rebuilds the bundle (mt#2297) and auto-restarts the daemon (mt#2299)** on source change. The restart fires on any non-test module under `src/**` or `packages/*/src` (mt#4230, mt#5060), not just `src/cockpit`. No manual tray rebuild; just refresh the window.
- **tray binary** (`cockpit-tray/src-tauri/**`) — the `.app` itself (menu, window, supervision). **NOT** auto-rebuilt; the installed app is a static bundle. A merged Rust change is invisible until rebuilt. mt#2219 was this layer.

## Dev loop (tray-binary changes)
Expand Down
34 changes: 23 additions & 11 deletions cockpit-tray/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,18 +184,30 @@ keeps the daemon current:

- **Startup staleness (adopted daemon).** When the tray adopts an already-running
daemon, it reads that daemon's start time (`ps -o etime=`) and compares it against
the newest backend-source mtime under `src/cockpit/**` (excluding `web/**`,
`node_modules`, `.git`, `dist`, and `*.test.ts`). If source is newer — the daemon
predates the current code — the tray restarts it before reporting ready. This is
the originating 2026-06-04 case: an 8-day-old daemon that missed two merged
feature PRs. A daemon the tray spawns fresh is trivially current, so no check is
needed there.
the newest backend-source mtime across every watched root — `src/**` plus each
discovered `packages/*/src` (mt#4230, mt#5060) — excluding `web/**`,
`node_modules`, `.git`, `dist`, the fixture/mock/test directory family, and
`*.test.*` / `*.spec.*` files. If source is newer — the daemon predates the current
code — the tray restarts it before reporting ready. This is the originating
2026-06-04 case: an 8-day-old daemon that missed two merged feature PRs. A daemon
the tray spawns fresh is trivially current, so no check is needed there.
- **Runtime watcher.** While the daemon runs, a debounced (~2s — larger than the
web rebuild's 500ms, since a restart is more disruptive) filesystem watcher on
`src/cockpit/**` restarts the daemon on any relevant backend `.ts` change. `web/**`
is excluded (the mt#2297 rebuild path owns it), so a frontend edit rebuilds the
bundle without bouncing the daemon, and a backend edit restarts the daemon without
a build.
web rebuild's 500ms, since a restart is more disruptive) filesystem watcher on the
same roots restarts the daemon on any relevant backend module change
(`.ts`/`.mts`/`.cts`/`.json`). `web/**` is excluded (the mt#2297 rebuild path owns
it), so a frontend edit rebuilds the bundle without bouncing the daemon, and a
backend edit restarts the daemon without a build.
- **Why the roots are trees, not a list (mt#4230, mt#5060).** The daemon is
`bun run src/cli.ts`, so its import closure is `src/**` plus `packages/**`. The
watcher started as `src/cockpit` only; mt#4230 added `packages/*/src` by
discovery, and mt#5060 widened the `src/` side to the whole tree after measuring
that 322 of the daemon's 465 `src/` closure files — `src/adapters`, `src/mcp`,
`src/generated`, … — were unwatched, and that the `.ts`-only module class dropped
the two generated `.json` imports even where they were watched. A tree root is a
superset of the closure by construction and cannot drift as new subdirectories
appear; the cost is a spurious restart on an edit to a `src/` module the daemon
never loads, which the debounce absorbs and which is far cheaper than serving
stale code with nothing to notice.
- **Source-presence gate.** Like the rebuild path, all of the above is gated on a
source checkout; a packaged / no-source install skips it.
- **"Daemon uptime" line.** The tray menu shows how long the daemon has run plus the
Expand Down
7 changes: 4 additions & 3 deletions cockpit-tray/src-tauri/src/supervisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1559,9 +1559,10 @@ fn run_supervisor(
let _web_watcher = cockpit_source_root(&path)
.and_then(|root| start_web_watcher(&app, &cockpit_web_src(&root)));
// mt#2299: runtime backend-source watcher. Sibling of `_web_watcher`;
// dispatches `Restart` (not `Rebuild`) on a backend `.ts`/`.mts`/`.cts`
// change. `web/**` is excluded so a frontend edit never restarts the
// daemon. Gated on `cockpit_backend_root` (BACKEND source presence), NOT
// dispatches `Restart` (not `Rebuild`) on a backend module change
// (`.ts`/`.mts`/`.cts`/`.json`) anywhere under `src/` or `packages/*/src`
// (mt#4230, mt#5060). `web/**` is excluded so a frontend edit never
// restarts the daemon. Gated on `cockpit_backend_root` (BACKEND source presence), NOT
// `cockpit_source_root` (web presence) — reviewer R1 B1: the web gate
// made the whole feature silently no-op when `web/` was absent.
//
Expand Down
Loading
Loading