Skip to content

Commit a289096

Browse files
authored
chore: speed up slow dev boot times (#3027)
1 parent ddbce59 commit a289096

18 files changed

Lines changed: 1162 additions & 1309 deletions

File tree

apps/code/electron.vite.config.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { readFileSync } from "node:fs";
1+
import { existsSync, readFileSync } from "node:fs";
22
import { builtinModules, createRequire } from "node:module";
33
import path from "node:path";
44
import { fileURLToPath } from "node:url";
@@ -45,6 +45,43 @@ const nodeExternals = [
4545
// the staged node_modules at runtime (see scripts/before-pack.ts).
4646
const nativeModules = buildExternals;
4747

48+
const nearestPackageType = (fromFile: string): string | undefined => {
49+
let dir = path.dirname(fromFile);
50+
while (true) {
51+
const manifest = path.join(dir, "package.json");
52+
if (existsSync(manifest)) {
53+
try {
54+
return JSON.parse(readFileSync(manifest, "utf-8")).type;
55+
} catch {
56+
return undefined;
57+
}
58+
}
59+
const parent = path.dirname(dir);
60+
if (parent === dir) return undefined;
61+
dir = parent;
62+
}
63+
};
64+
65+
const resolvesToCommonJs = (name: string): boolean => {
66+
let resolved: string;
67+
try {
68+
resolved = require.resolve(name);
69+
} catch {
70+
return false;
71+
}
72+
if (resolved.endsWith(".cjs")) return true;
73+
if (resolved.endsWith(".mjs")) return false;
74+
return nearestPackageType(resolved) !== "module";
75+
};
76+
77+
const computeDevThirdPartyExternals = (): RegExp[] =>
78+
Object.keys(pkg.dependencies ?? {})
79+
.filter((name) => !name.startsWith("@posthog/") && resolvesToCommonJs(name))
80+
.map(
81+
(name) =>
82+
new RegExp(`^${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(/.+)?$`),
83+
);
84+
4885
export default defineConfig(({ mode }) => {
4986
const env = loadEnv(mode, path.resolve(__dirname, "../.."), "");
5087
const isDev = mode === "development";
@@ -115,6 +152,7 @@ export default defineConfig(({ mode }) => {
115152
"electron/main",
116153
...nodeExternals,
117154
...nativeModules,
155+
...(isDev ? computeDevThirdPartyExternals() : []),
118156
],
119157
onwarn(warning, warn) {
120158
if (warning.code === "UNUSED_EXTERNAL_IMPORT") return;

apps/code/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"@types/react": "^19.2.15",
5858
"@types/react-dom": "^19.2.3",
5959
"@types/semver": "^7.7.1",
60-
"@vitejs/plugin-react": "^4.7.0",
60+
"@vitejs/plugin-react": "^5.2.0",
6161
"@vitest/ui": "^4.1.8",
6262
"adm-zip": "^0.5.17",
6363
"electron": "^42.3.0",

apps/code/vite-main-plugins.mts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ function detectBinaryArch(
119119
return null;
120120
}
121121

122+
function isStagedCopyCurrent(source: string, dest: string): boolean {
123+
if (!existsSync(dest)) return false;
124+
return statSync(dest).mtimeMs >= statSync(source).mtimeMs;
125+
}
126+
122127
function signClaudeBinary(destPath: string): void {
123128
if (targetPlatform() !== "darwin") return;
124129
if (process.platform !== "darwin") {
@@ -196,6 +201,11 @@ export function copyClaudeExecutable(): Plugin {
196201
return;
197202
}
198203

204+
if (isStagedCopyCurrent(source, destBinary)) {
205+
claudeCliCopied = true;
206+
return;
207+
}
208+
199209
copyFileSync(source, destBinary);
200210
if (targetPlatform() !== "win32") {
201211
execSync(`chmod +x "${destBinary}"`);
@@ -569,6 +579,11 @@ export function copyCodexAcpBinaries(): Plugin {
569579

570580
if (existsSync(sourcePath)) {
571581
const destPath = join(destDir, binaryName);
582+
583+
if (isStagedCopyCurrent(sourcePath, destPath)) {
584+
continue;
585+
}
586+
572587
copyFileSync(sourcePath, destPath);
573588
console.log(`Copied ${binary.name} binary to ${destDir}`);
574589

apps/code/vite.shared.mts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ export const workspaceAliases: Alias[] = [
102102
"../../packages/workspace-server/src/$1",
103103
),
104104
},
105+
{
106+
find: /^@posthog\/platform\/(.+)$/,
107+
replacement: path.resolve(__dirname, "../../packages/platform/src/$1"),
108+
},
105109
];
106110

107111
export const mainAliases: Alias[] = [
@@ -113,6 +117,10 @@ export const mainAliases: Alias[] = [
113117
"../../packages/electron-trpc/src/main/index.ts",
114118
),
115119
},
120+
{
121+
find: /^@posthog\/git\/(.+)$/,
122+
replacement: path.resolve(__dirname, "../../packages/git/src/$1"),
123+
},
116124
...workspaceAliases,
117125
];
118126

apps/mobile/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"phosphor-react-native": "^3.0.2",
6565
"posthog-react-native": "^4.18.0",
6666
"posthog-react-native-session-replay": "^1.6.0",
67-
"react": "19.1.0",
67+
"react": "19.2.6",
6868
"react-native": "0.81.5",
6969
"react-native-keyboard-controller": "1.18.5",
7070
"react-native-reanimated": "~4.1.1",
@@ -77,11 +77,11 @@
7777
},
7878
"devDependencies": {
7979
"@testing-library/react-native": "^13.3.3",
80-
"@types/react": "^19.1.0",
80+
"@types/react": "^19.2.0",
8181
"@types/react-test-renderer": "^19.1.0",
8282
"@vitejs/plugin-react": "^4.7.0",
8383
"react-native-svg-transformer": "^1.5.3",
84-
"react-test-renderer": "^19.1.0",
84+
"react-test-renderer": "^19.2.6",
8585
"tailwindcss": "^3.4.18",
8686
"typescript": "~5.9.2",
8787
"vite": "^6.4.1",

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,10 @@
6161
"biome check --write --unsafe --files-ignore-unknown=true --no-errors-on-unmatched",
6262
"bash -c 'pnpm typecheck'"
6363
]
64+
},
65+
"pnpm": {
66+
"overrides": {
67+
"vite": "npm:rolldown-vite@7.3.1"
68+
}
6469
}
6570
}

packages/agent/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
"tsup": "^8.5.1",
126126
"tsx": "^4.20.6",
127127
"typescript": "^5.5.0",
128-
"vitest": "^2.1.8"
128+
"vitest": "^4.1.8"
129129
},
130130
"dependencies": {
131131
"@agentclientprotocol/sdk": "0.25.0",

packages/agent/src/adapters/codex/codex-agent.refresh.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ const hoisted = vi.hoisted(() => {
4444
cancel: vi.fn().mockResolvedValue(undefined),
4545
});
4646

47-
const clientSideConnectionCtor = vi.fn(() => {
48-
const conn = makeConnection();
49-
createdConnections.push(conn);
50-
return conn;
51-
});
47+
const clientSideConnectionCtor = class {
48+
constructor() {
49+
Object.assign(this, makeConnection());
50+
createdConnections.push(this as unknown as MockCodexConnection);
51+
}
52+
};
5253

5354
const spawnCodexProcessMock = vi.fn(() => {
5455
const handle: SpawnHandle = {
@@ -75,7 +76,6 @@ const hoisted = vi.hoisted(() => {
7576

7677
const createdConnections = hoisted.createdConnections;
7778
const spawnedProcesses = hoisted.spawnedProcesses;
78-
const clientSideConnectionCtor = hoisted.clientSideConnectionCtor;
7979

8080
vi.mock("@agentclientprotocol/sdk", async () => {
8181
const actual = await vi.importActual("@agentclientprotocol/sdk");
@@ -91,13 +91,14 @@ vi.mock("./spawn", () => ({
9191
}));
9292

9393
vi.mock("./settings", () => ({
94-
CodexSettingsManager: vi.fn().mockImplementation((cwd: string) => ({
95-
initialize: vi.fn().mockResolvedValue(undefined),
96-
dispose: vi.fn(),
97-
getCwd: () => cwd,
98-
setCwd: vi.fn(),
99-
getSettings: () => ({ mcpServerNames: [] }),
100-
})),
94+
CodexSettingsManager: class {
95+
constructor(private readonly cwd: string) {}
96+
initialize = vi.fn().mockResolvedValue(undefined);
97+
dispose = vi.fn();
98+
getCwd = () => this.cwd;
99+
setCwd = vi.fn();
100+
getSettings = () => ({ mcpServerNames: [] });
101+
},
101102
}));
102103

103104
import { CodexAcpAgent } from "./codex-agent";
@@ -171,7 +172,6 @@ describe("CodexAcpAgent.extMethod refresh_session", () => {
171172
beforeEach(() => {
172173
spawnedProcesses.length = 0;
173174
createdConnections.length = 0;
174-
clientSideConnectionCtor.mockClear();
175175
});
176176

177177
it("returns methodNotFound for unknown extension methods", async () => {

packages/agent/src/adapters/codex/codex-agent.test.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ vi.mock("@agentclientprotocol/sdk", async () => {
2323

2424
return {
2525
...actual,
26-
ClientSideConnection: vi.fn(() => mockCodexConnection),
26+
ClientSideConnection: class {
27+
constructor() {
28+
Object.assign(this, mockCodexConnection);
29+
}
30+
},
2731
ndJsonStream: vi.fn(() => ({}) as object),
2832
};
2933
});
@@ -44,13 +48,14 @@ vi.mock("./spawn", () => ({
4448
}));
4549

4650
vi.mock("./settings", () => ({
47-
CodexSettingsManager: vi.fn().mockImplementation((cwd: string) => ({
48-
initialize: vi.fn(),
49-
dispose: vi.fn(),
50-
getCwd: () => cwd,
51-
setCwd: vi.fn(),
52-
getSettings: () => ({}),
53-
})),
51+
CodexSettingsManager: class {
52+
constructor(private readonly cwd: string) {}
53+
initialize = vi.fn();
54+
dispose = vi.fn();
55+
getCwd = () => this.cwd;
56+
setCwd = vi.fn();
57+
getSettings = () => ({});
58+
},
5459
}));
5560

5661
vi.mock("node:fs", async (importActual) => {

packages/agent/src/otel-log-writer.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ const mockExport = vi.fn((_logs, callback) => {
88
});
99

1010
vi.mock("@opentelemetry/exporter-logs-otlp-http", () => ({
11-
OTLPLogExporter: vi.fn().mockImplementation(() => ({
12-
export: mockExport,
13-
shutdown: vi.fn().mockResolvedValue(undefined),
14-
})),
11+
OTLPLogExporter: class {
12+
export = mockExport;
13+
shutdown = vi.fn().mockResolvedValue(undefined);
14+
},
1515
}));
1616

1717
describe("OtelLogWriter", () => {

0 commit comments

Comments
 (0)