Skip to content

Commit 6bad7e2

Browse files
committed
cleanup, correctly resolve path
1 parent 1c0da4f commit 6bad7e2

File tree

7 files changed

+96
-24
lines changed

7 files changed

+96
-24
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Thumbs.db
2525
# Temporary files
2626
*.tmp
2727
*.temp
28+
*.tgz
2829

2930
AGENTS.md
3031
.claude/

forge.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ const config: ForgeConfig = {
1616
{
1717
entry: "src/main/index.ts",
1818
config: "vite.main.config.mts",
19+
target: "main",
1920
},
2021
{
2122
entry: "src/main/preload.ts",
2223
config: "vite.preload.config.mts",
24+
target: "preload",
2325
},
2426
],
2527
renderer: [

forge.env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="@electron-forge/plugin-vite/forge-vite-env" />

src/main/services/agent.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
import { execSync } from "node:child_process";
12
import { randomUUID } from "node:crypto";
3+
import { existsSync } from "node:fs";
4+
import { homedir } from "node:os";
5+
import { join } from "node:path";
26
import { Agent, PermissionMode } from "@posthog/agent";
37
import { type BrowserWindow, type IpcMainInvokeEvent, ipcMain } from "electron";
48

@@ -36,6 +40,50 @@ function resolvePermissionMode(
3640
return (match as PermissionMode | undefined) ?? PermissionMode.ACCEPT_EDITS;
3741
}
3842

43+
function findClaudeExecutable(): string | undefined {
44+
// Common installation locations based on Claude Code docs
45+
const commonPaths = [
46+
join(homedir(), ".local", "bin", "claude"), // Native installer location
47+
join(homedir(), ".claude", "local", "claude"), // Migrated local installation
48+
join(homedir(), ".volta", "bin", "claude"), // Volta (Node version manager)
49+
join(homedir(), ".nvm", "current", "bin", "claude"), // nvm
50+
"/opt/homebrew/bin/claude", // Homebrew on Apple Silicon
51+
"/usr/local/bin/claude", // Homebrew on Intel Mac / apt on Linux
52+
"/usr/bin/claude", // System installation
53+
];
54+
55+
// Add npm global installation paths
56+
try {
57+
const npmPrefix = execSync("npm config get prefix", {
58+
encoding: "utf-8",
59+
}).trim();
60+
if (npmPrefix) {
61+
commonPaths.push(join(npmPrefix, "bin", "claude"));
62+
}
63+
} catch {
64+
// npm not available or failed, continue
65+
}
66+
67+
// Check common paths first
68+
for (const path of commonPaths) {
69+
if (existsSync(path)) {
70+
return path;
71+
}
72+
}
73+
74+
// Fall back to using 'which' if available
75+
try {
76+
const path = execSync("which claude", { encoding: "utf-8" }).trim();
77+
if (path && existsSync(path)) {
78+
return path;
79+
}
80+
} catch {
81+
// which command failed, continue
82+
}
83+
84+
return undefined;
85+
}
86+
3987
export function registerAgentIpc(
4088
taskControllers: Map<string, TaskController>,
4189
getMainWindow: () => BrowserWindow | null,
@@ -171,13 +219,21 @@ export function registerAgentIpc(
171219

172220
const mcpOverrides = {};
173221

222+
const claudePath = findClaudeExecutable();
223+
if (!claudePath) {
224+
throw new Error(
225+
"Claude Code executable not found in PATH. Please install Claude Code CLI.",
226+
);
227+
}
228+
174229
await agent.runWorkflow(posthogTaskId, workflowId, {
175230
repositoryPath: repoPath,
176231
permissionMode: resolvedPermission,
177232
autoProgress: autoProgress ?? true,
178233
queryOverrides: {
179234
abortController,
180235
...(model ? { model } : {}),
236+
pathToClaudeCodeExecutable: claudePath,
181237
stderr: forwardClaudeStderr,
182238
env: envOverrides,
183239
mcpServers: mcpOverrides,

vite.main.config.mts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
1-
import { defineConfig } from "vite";
1+
import { defineConfig, type Plugin } from "vite";
2+
3+
/**
4+
* Custom Vite plugin to fix circular __filename references in bundled ESM packages.
5+
*
6+
* When Vite bundles ESM packages like @posthog/agent that use import.meta.url,
7+
* it transforms them into a complex polyfill that creates circular references:
8+
* `const __filename2 = fileURLToPath(... pathToFileURL(__filename2) ...)`
9+
*
10+
* This plugin post-processes the bundle to replace the circular reference with
11+
* a simple assignment to Node.js's global __filename variable.
12+
*/
13+
function fixFilenameCircularRef(): Plugin {
14+
return {
15+
name: "fix-filename-circular-ref",
16+
enforce: "post",
17+
generateBundle(_options, bundle) {
18+
for (const fileName in bundle) {
19+
const chunk = bundle[fileName];
20+
if (chunk.type === "chunk") {
21+
// Replace circular __filename references with direct __filename usage
22+
chunk.code = chunk.code.replace(
23+
/const __filename(\d+) = url\.fileURLToPath\(typeof document === "undefined" \? require\("url"\)\.pathToFileURL\(__filename\1\)\.href : [^;]+\);/g,
24+
"const __filename$1 = __filename;",
25+
);
26+
}
27+
}
28+
},
29+
};
30+
}
231

332
export default defineConfig({
33+
plugins: [fixFilenameCircularRef()],
434
build: {
5-
rollupOptions: {
6-
onwarn(warning, warn) {
7-
// Ignore unused import warnings from node_modules
8-
if (warning.code === "UNUSED_EXTERNAL_IMPORT") return;
9-
warn(warning);
10-
},
35+
target: "node18",
36+
minify: false, // Disable minification to prevent variable name conflicts
37+
commonjsOptions: {
38+
transformMixedEsModules: true,
1139
},
1240
},
13-
resolve: {
14-
mainFields: ["module", "jsnext:main", "jsnext"],
15-
},
1641
});

vite.preload.config.mts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
import { defineConfig } from "vite";
22

3-
export default defineConfig({
4-
resolve: {
5-
mainFields: ["module", "jsnext:main", "jsnext"],
6-
},
7-
});
3+
export default defineConfig({});

vite.renderer.config.mts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
77

88
export default defineConfig({
99
plugins: [react()],
10-
base: "./",
11-
build: {
12-
outDir: "dist/renderer",
13-
emptyOutDir: true,
14-
},
15-
server: {
16-
port: 5173,
17-
strictPort: true,
18-
},
1910
resolve: {
2011
alias: {
2112
"@": path.resolve(__dirname, "./src"),

0 commit comments

Comments
 (0)