[1/5] feat(desktop): bootstrap @kanban/desktop workspace + bundle CLI runtime deps#355
Conversation
20d4948 to
9500c48
Compare
5af6c49 to
d5ce87d
Compare
d5ce87d to
5d6a0d8
Compare
Greptile SummaryThis PR bootstraps the Confidence Score: 5/5Safe to merge — only finding is a P2 nit about vitest globals types that will need addressing before real tests land in PR4+. All changes are well-reasoned and verified by the author. The single remaining finding (missing vitest/globals types in tsconfig) is a P2 style issue that causes no runtime or build failure at this stage since there are no test files yet. packages/desktop/tsconfig.json — should add "vitest/globals" to types before first test file is added. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[npm run build] --> B[esbuild: src/cli.ts]
A --> C[esbuild: src/index.ts]
B --> D[dist/cli.js\n16 MB self-contained ESM]
C --> E[dist/index.js\n552 KB]
D --> F{Runtime context}
F -->|npm i -g kanban| G[node_modules resolves node-pty]
F -->|Monorepo dev| G
F -->|Electron app.asar.unpacked| H[app.asar.unpacked/node_modules\nresolves node-pty via ESM walk]
subgraph Externalized
I[node-pty\nnative addon + spawn-helper]
end
D -.->|import| I
Reviews (1): Last reviewed commit: "chore: extend install:all to cover packa..." | Re-trigger Greptile |
6341bc7 to
02b2196
Compare
Part 2 of the desktop split. Stacked on #355. Introduces `RuntimeChildManager` — spawns the Kanban CLI as a subprocess and manages its lifecycle: - Spawns the CLI out-of-process (no in-process runtime imports) - HTTP readiness polling against `/` (default 200ms, 30s total timeout) - Typed lifecycle events: `ready`, `error`, `crashed` - Clean contract: failures before `ready` reject `start()`; failures after `ready` flow through events. One failure never produces both - Graceful shutdown via SIGTERM, force-kill fallback after 5s (`taskkill /T /F` on Windows) - Rolling 8KB stderr tail surfaced to the `crashed` listener for diagnostics Env/PATH policy lives in its own file (`runtime-child-env.ts`): - Strict allowlist: exact keys (PATH, HOME, LANG, SHELL, XDG_*, Windows %APPDATA% family, etc.) + prefix allowlist (KANBAN_, ANTHROPIC_, OPENAI_, etc.) - GUI-launch PATH enrichment: Homebrew on macOS, `/snap/bin` on Linux, npm-global/Node/Git on Windows Tests: 38 unit tests covering spawn, ready-path, crash scenarios, shutdown races, env filtering, and PATH assembly.
…ipts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
… runtime deps ## Summary First of a 5-PR stack that adds Electron desktop support. Pure bootstrap — no Electron code yet, just the workspace scaffolding and a build-infrastructure prerequisite. **Follow-up PRs** (branches pushed, will open one at a time): - `pr/desktop-4-runtime-child` — runtime child process manager - `pr/desktop-5-preflight` — desktop preflight checks - `pr/desktop-6-electron-main` — Electron main process - `pr/desktop-7-packaging` — electron-builder packaging + CLI shims ## Two commits, reviewable independently ### 1. [`7e719213`](7e719213) — `build: bundle all non-native runtime deps into dist/cli.js` The previous `scripts/build.mjs` externalized 11 packages at bundle time (`zod`, `commander`, `@trpc/client`, `@trpc/server`, `@sentry/node`, `@modelcontextprotocol/sdk`, `ws`, `open`, `proper-lockfile`, `tree-kill`, `node-pty`), so `dist/cli.js` contained literal `import "zod"` / `require("ws")` that Node resolved via an ancestor `node_modules/` at runtime. That worked for the two existing contexts: 1. **`npm i -g kanban`** — npm installs prod deps at `lib/node_modules/kanban/node_modules/`; resolver walks up from `dist/cli.js` and finds them. 2. **Monorepo dev** — root `node_modules/` satisfies resolution. But it fails for the packaged Electron app: `Resources/cli/cli.js` has no enclosing `node_modules/` → `ERR_MODULE_NOT_FOUND`. **Fix**: drop the externals list down to just `node-pty` (the one genuinely non-bundlable package — native addon with a compiled binding + spawn-helper binary on disk). esbuild inlines the other 10 directly into the bundle. **Result**: `dist/cli.js` is a single self-contained 16 MB ESM bundle with one runtime-resolved external. In the packaging PR later in this stack, `node-pty` gets rebuilt for Electron's ABI by `electron-builder install-app-deps` and the CLI's ESM resolution walks up from its location in `app.asar.unpacked/cli/` to find it in `app.asar.unpacked/node_modules/`. Single source of truth: no `dist/node_modules/` staging, no build-time `npm install`, no duplicate node-pty, no version drift between what esbuild saw and what the runtime resolves. `scripts/build.mjs` goes from ~190 lines (with an earlier `--stage` approach) to ~60 lines of pure esbuild config. ### 2. [`5d6a0d8e`](5d6a0d8e) — `feat(desktop): bootstrap @kanban/desktop workspace` `packages/desktop/`: - **`package.json`** — intentionally minimal: `typecheck` + `test` scripts, devDeps `@types/node` + `typescript` + `vitest`. No `electron`, no `electron-builder`, no runtime deps. Each downstream PR adds the specific deps its code actually uses (`node-pty` in PR5; `electron` / `esbuild` / `shx` in PR6; `electron-builder` / `@electron/notarize` / `@electron/rebuild` in PR7). Keeps each PR self-contained and the bootstrap diff tiny. - **`tsconfig.json`** / **`tsconfig.build.json`** — strict TS with NodeNext, extends root `tsconfig.base.json`. - **`vitest.config.ts`** — node env, `test/**/*.test.ts` pattern. - **`src/index.ts`** — placeholder `export {}`. Required: tsc errors `TS18003: No inputs were found` without it. Replaced with real `main.ts` in the Electron main-process PR. Root changes: - **`vitest.config.ts`** — add `packages/**` to exclude. Root vitest's resolver aliases (`@clinebot/agents` → `/node`) shouldn't apply to desktop tests; that workspace has its own vitest invocation. - **`.gitignore`** — ignore `packages/desktop/out` (electron-builder output) and `*.tgz`. - **`.github/workflows/test.yml`** — add `npm ci --prefix packages/desktop`, then run the desktop workspace's typecheck and tests alongside the root + web-ui suites so the new workspace is actually covered by CI. ## Verification ``` node scripts/build.mjs # → esbuild: bundled dist/cli.js (16 MB) and dist/index.js (552 KB) cd packages/desktop && npm test # exits 0 (passWithNoTests on this PR; real tests land in PR4+) cd packages/desktop && npm run typecheck # silent, exits 0 ``` Root test suite unchanged: 536/536 passing.
02b2196 to
c53635f
Compare
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
…se scripts Part 5 of the desktop split. Stacked on the PR for `pr/desktop-6-electron-main`. The packaging layer — turns the code in #370–#372 into a signed, notarized macOS DMG. - `electron-builder.yml`: macOS DMG config (arm64 + x64, hardened runtime, entitlements, Apple notarization). **Only macOS is configured in this stack — no `win:` / `linux:` target yet.** The Windows CMD shim (`build/bin/kanban.cmd`) and the cross-platform runtime code (win32/linux/darwin branches in the CLI subprocess spawner) are already in earlier PRs, but wiring them into electron-builder for a `.exe`/`.AppImage` output is deliberately out of scope here. - `build/bin/{kanban, kanban-dev, kanban.cmd}`: CLI shim scripts shipped inside the bundle so users can invoke the packaged CLI directly. - `scripts/stage-cli.mjs`: copies the root `dist/cli.js` + its runtime deps into `packages/desktop/cli/` as the electron-builder input. Fails loudly if the root `dist/` is incomplete (avoids silently shipping a broken CLI). - `scripts/patch-node-pty.mjs`: monkey-patches node-pty's spawn-helper resolution so asar-unpacked paths aren't double-suffixed. - `scripts/notarize.cjs`: afterSign hook wrapping Apple `notarytool` (no-op on non-macOS or when env vars missing). - `scripts/launch-electron.mjs`: dev-launch wrapper. - `build/entitlements.mac.plist` + `build/icon.icns`. Tests: 18 tests covering the CLI shim behavior and the notarize afterSign hook's env-var handling. After this, the full stack (#355 + #370–#373) produces a working macOS DMG (arm64 + x64). Windows/Linux packaging is a follow-up.
Summary
First of a 5-PR stack that adds Electron desktop support. Pure bootstrap — no Electron code yet, just the workspace scaffolding and a build-infrastructure prerequisite.
Follow-up PRs (branches pushed, will open one at a time):
pr/desktop-4-runtime-child— runtime child process managerpr/desktop-5-preflight— desktop preflight checkspr/desktop-6-electron-main— Electron main processpr/desktop-7-packaging— electron-builder packaging + CLI shimsTwo commits, reviewable independently
1.
7e719213—build: bundle all non-native runtime deps into dist/cli.jsThe previous
scripts/build.mjsexternalized 11 packages at bundle time (zod,commander,@trpc/client,@trpc/server,@sentry/node,@modelcontextprotocol/sdk,ws,open,proper-lockfile,tree-kill,node-pty), sodist/cli.jscontained literalimport "zod"/require("ws")that Node resolved via an ancestornode_modules/at runtime.That worked for the two existing contexts:
npm i -g kanban— npm installs prod deps atlib/node_modules/kanban/node_modules/; resolver walks up fromdist/cli.jsand finds them.node_modules/satisfies resolution.But it fails for the packaged Electron app:
Resources/cli/cli.jshas no enclosingnode_modules/→ERR_MODULE_NOT_FOUND.Fix: drop the externals list down to just
node-pty(the one genuinely non-bundlable package — native addon with a compiled binding + spawn-helper binary on disk). esbuild inlines the other 10 directly into the bundle.Result:
dist/cli.jsis a single self-contained 16 MB ESM bundle with one runtime-resolved external. In the packaging PR later in this stack,node-ptygets rebuilt for Electron's ABI byelectron-builder install-app-depsand the CLI's ESM resolution walks up from its location inapp.asar.unpacked/cli/to find it inapp.asar.unpacked/node_modules/.Single source of truth: no
dist/node_modules/staging, no build-timenpm install, no duplicate node-pty, no version drift between what esbuild saw and what the runtime resolves.scripts/build.mjsgoes from ~190 lines (with an earlier--stageapproach) to ~60 lines of pure esbuild config.2.
5d6a0d8e—feat(desktop): bootstrap @kanban/desktop workspacepackages/desktop/:package.json— intentionally minimal:typecheck+testscripts, devDeps@types/node+typescript+vitest. Noelectron, noelectron-builder, no runtime deps. Each downstream PR adds the specific deps its code actually uses (node-ptyin PR5;electron/esbuild/shxin PR6;electron-builder/@electron/notarize/@electron/rebuildin PR7). Keeps each PR self-contained and the bootstrap diff tiny.tsconfig.json/tsconfig.build.json— strict TS with NodeNext, extends roottsconfig.base.json.vitest.config.ts— node env,test/**/*.test.tspattern.src/index.ts— placeholderexport {}. Required: tsc errorsTS18003: No inputs were foundwithout it. Replaced with realmain.tsin the Electron main-process PR.Root changes:
vitest.config.ts— addpackages/**to exclude. Root vitest's resolver aliases (@clinebot/agents→/node) shouldn't apply to desktop tests; that workspace has its own vitest invocation..gitignore— ignorepackages/desktop/out(electron-builder output) and*.tgz..github/workflows/test.yml— addnpm ci --prefix packages/desktop, then run the desktop workspace's typecheck and tests alongside the root + web-ui suites so the new workspace is actually covered by CI.Verification
Root test suite unchanged: 536/536 passing.