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
6 changes: 3 additions & 3 deletions apps/daemon/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ Runs via `tsx` in dev (`pnpm -F @linkcode/daemon dev`) and a `tsup` bundle in pr
materializes a self-contained dir at `apps/daemon/standalone` (gitignored; pass an explicit path as
argv for CI) via `pnpm --prod deploy` — the tsup bundle plus its runtime externals flat in the dir's
own `node_modules`, runnable anywhere as `node --import ./dist/instrument.js dist/index.js`. This is
distinct from the desktop bundle: it targets **plain Node** (better-sqlite3 keeps its prebuild-install
binary — a **same-platform** artifact, build per target), and it prunes the host-arch agent CLI
platform packages (the daemon downloads them at runtime via `@linkcode/assets`, as the desktop
distinct from the desktop bundle: it targets **plain Node** (still a **same-platform** artifact — the
napi-rs optional deps and @sentry's profiler resolve host-only — build per target), and it prunes
Comment thread
lucas77778 marked this conversation as resolved.
the host-arch agent CLI platform packages (the daemon downloads them at runtime via `@linkcode/assets`, as the desktop
does). The pi npm closure needs no prune (CODE-219): its SDK is a devDependency of
agent-adapter, so the `--prod` deploy never materializes it — the daemon downloads the managed
closure on first use.
Expand Down
5 changes: 3 additions & 2 deletions apps/daemon/scripts/package-daemon.mts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
* `node --import ./dist/instrument.js dist/index.js` with nothing else on disk.
*
* Unlike the desktop bundle (Electron `utilityProcess`, native modules rebuilt to Electron's ABI),
* this targets plain Node: better-sqlite3 keeps the prebuild-install binary for the build host's
* Node/OS/arch. It is therefore a same-platform artifact — build it on (or for) each target.
* this targets plain Node. better-sqlite3 carries a NAPI prebuild per target, but the host-only
* napi-rs optional deps and @sentry's ABI-pinned profiler do not: a same-platform artifact — build
* it on (or for) each target.
Comment thread
lucas77778 marked this conversation as resolved.
*
* Agent CLI platform binaries are pruned: they are host-arch, ~230 MB each, and the daemon
* provisions them at runtime through its managed-asset store (@linkcode/assets, CODE-111) exactly
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ files:
# verify-artifacts.mts guards against reintroduction.
# Dead weight in the deploy closure (CODE-215). @linkcode/* are raw-TS workspace sources —
# main/preload/daemon all bundle them, and migrations run from out/drizzle, so nothing resolves
# them from node_modules at runtime. better-sqlite3/deps is the sqlite3 C amalgamation:
# @electron/rebuild needs it at BUILD time (which is why the staging prune must not delete it),
# but the compiled build/Release binding is all the app loads.
# them from node_modules at runtime. better-sqlite3/deps is the sqlite3 C amalgamation, only ever
# compiled if a from-source @electron/rebuild happens (which is why the staging prune must not
# delete it); the app loads the shipped NAPI prebuild under better-sqlite3/prebuilds instead.
- '!node_modules/@linkcode/**'
- '!node_modules/better-sqlite3/deps/**'

Expand Down
26 changes: 18 additions & 8 deletions apps/desktop/scripts/verify-artifacts.mts
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,23 @@ const EXPECTED: Partial<Record<string, PlatformExpectation>> = {
};

const SIDECAR_BINARY = argv[2] === 'win' ? 'linkcode-pty.exe' : 'linkcode-pty';
/** Node's platform name per builder platform — the token better-sqlite3 names its prebuilds by. */
const NODE_PLATFORM: Partial<Record<string, string>> = {
mac: 'darwin',
win: 'win32',
linux: 'linux',
};
/**
* better-sqlite3's compiled binding, smartUnpacked beside the asar; the daemon requires it at boot.
* A build where @electron/rebuild silently rebuilt nothing ships the wrong CPU/ABI and every client
* shows "Unable to connect to the daemon" (broke every release through 0.2.1; see package-app.mts).
* better-sqlite3's binding, smartUnpacked beside the asar; the daemon requires it at boot. Since
* v13 it is one NAPI prebuild per platform-arch shipped in the tarball (`build/Release` is only
* written when node-gyp actually compiles, which it now skips), so what breaks is the staging
* prune keeping the wrong target — every client then shows "Unable to connect to the daemon".
Comment thread
lucas77778 marked this conversation as resolved.
*/
const NATIVE_BINDING = 'node_modules/better-sqlite3/build/Release/better_sqlite3.node'.replaceAll(
'/',
sep,
);
function sqliteBinding(platform: string, arch: string): string | null {
const nodePlatform = NODE_PLATFORM[platform];
if (nodePlatform === undefined) return null;
return `node_modules/better-sqlite3/prebuilds/${nodePlatform}-${arch}.node`.replaceAll('/', sep);
}
/**
* napi-rs platform-package triple for the target this artifact was packed for. napi-rs ships one
* optional dependency per triple and installs only the host's, so a cross-packed build carries no
Expand Down Expand Up @@ -183,8 +191,10 @@ function readBinaryArch(file: string): 'x64' | 'arm64' | null {
*/
function verifyNativeBindings(platform: string, resourceDir: string, problems: string[]): void {
const expectedArch = resourceDir.includes('arm64') ? 'arm64' : 'x64';
const sqlite = sqliteBinding(platform, expectedArch);
const keyring = keyringBinding(platform, expectedArch);
const bindings: Array<[label: string, path: string]> = [['better-sqlite3', NATIVE_BINDING]];
const bindings: Array<[label: string, path: string]> = [];
if (sqlite !== null) bindings.push(['better-sqlite3', sqlite]);
if (keyring !== null) bindings.push(['@napi-rs/keyring', keyring]);

for (const [label, relative] of bindings) {
Expand Down
Loading