You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: ship cork CLI inside the app bundle and link it onto PATH
Add a skeleton cork CLI as a separate lean crate in a new Cargo
workspace, embed it into Cork.app via Tauri's externalBin sidecar, and
expose it on PATH through a Homebrew Cask binary stanza — so installing
the app also installs the cork command. The CLI version is injected from
package.json at build time so it never drifts from the app.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: AGENTS.md
+13-11Lines changed: 13 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,7 @@
2
2
3
3
Frontend = React + atomic design (see `src/AGENTS.md`).
4
4
Backend = Tauri v2 + Rust (see `src-tauri/AGENTS.md`).
5
+
CLI = the `cork` command, a separate lean Rust crate shipped **inside** the app bundle (see `src-tauri/AGENTS.md` → "CLI distribution").
5
6
Multi-window: a single process can host any number of windows, each with its own workspace. The `File > New Window` menu / `Cmd+Shift+N` opens an empty welcome window, and the macOS Dock-reopen path restores the last-used workspace into a fresh window. Per-window state lives in `AppState` keyed by `WebviewWindow::label()`; see `src-tauri/AGENTS.md` for the state model.
6
7
7
8
## Stack
@@ -14,17 +15,18 @@ Multi-window: a single process can host any number of windows, each with its own
|`bun run dev`| Vite dev server on port 1420 (frontend only — Tauri APIs error in browser) |
21
+
|`bun run build`|`tsc && vite build` (full typecheck + bundle) |
22
+
|`bun run build:sidecar`| Build the `cork` CLI and stage it as a Tauri sidecar (`src-tauri/binaries/cork-cli-<triple>`). Run automatically by `tauri dev` / `tauri build` via the before-commands. |
23
+
|`bun run tauri`| Tauri CLI passthrough (e.g. `bun run tauri dev`, `bun run tauri build`) |
-`cork-cli` (`cli/`) — the `cork` command-line tool. A deliberately lean crate (depends only on `clap`) so it never drags Tauri / axum / rmcp / objc2 into its compile-and-link. Shared logic, if it ever appears, should be factored into a third `core` member rather than pulling `cork_lib` (which is Tauri-bound) into the CLI.
9
+
10
+
Build them separately: `tauri build` builds only the `cork` package; the CLI is built with `cargo build -p cork-cli` (wrapped by `bun run build:sidecar`). Both share `src-tauri/target/`. The app executable inside the bundle is `Contents/MacOS/cork` (named after the Cargo package, lowercase), which is why the CLI binary is named `cork-cli` — `cork` would collide on the case-insensitive APFS.
11
+
12
+
## CLI distribution
13
+
14
+
The `cork` CLI ships **inside**`Cork.app` and is exposed on `PATH` by Homebrew — installing the app gives you the command, with nothing extra to download.
15
+
16
+
1.**Build + stage** — `scripts/build-sidecar.ts` (`bun run build:sidecar`) runs `cargo build --release -p cork-cli`, then copies the binary to `src-tauri/binaries/cork-cli-<host-target-triple>` (the suffix Tauri's `externalBin` requires; the dir is gitignored). It's wired into `tauri.conf.json` → `build.beforeDevCommand` / `beforeBuildCommand`, so `tauri dev` and `tauri build` stage it with no extra step (and dev won't fail on a missing sidecar).
17
+
2.**Embed** — `tauri.conf.json` → `bundle.externalBin: ["binaries/cork-cli"]` tells Tauri to strip the triple suffix and embed the binary as `Cork.app/Contents/MacOS/cork-cli`.
18
+
3.**Expose on PATH** — `scripts/build-cask.ts` emits a Homebrew `binary "#{appdir}/Cork.app/Contents/MacOS/cork-cli", target: "cork"` stanza, symlinking the embedded binary to `$(brew --prefix)/bin/cork`. Invoked as `cork`, argv[0] makes `clap` print `cork` in usage; `--version` reads from the `name = "cork"` attribute. The cask's existing ad-hoc `codesign --deep` preflight re-signs the embedded CLI too, so it runs from the terminal without Gatekeeper complaints.
19
+
20
+
The CLI version is **not** maintained separately: `cli/build.rs` reads the repo-root `package.json``version` (the single source release-please bumps) and injects it as `CORK_VERSION` at compile time. DMG-only installs (drag-to-Applications, no Homebrew) don't get the `cork` symlink — a future `cork`-self-install subcommand can cover that.
21
+
3
22
## Layout
4
23
5
24
`main.rs` is the entry point and calls `cork_lib::run()`. `lib.rs` only declares modules and wires plugins, state, `#[tauri::command]`s, the `on_window_event` cleanup hook, and the macOS `RunEvent::Reopen` handler in `run()` — domain logic lives in the per-module files below.
0 commit comments