Skip to content

Commit ffd64a3

Browse files
committed
refactor: initial decoupling of electron
1 parent 6a13d32 commit ffd64a3

15 files changed

Lines changed: 134 additions & 3 deletions

File tree

.github/workflows/build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ jobs:
3333
- name: Build electron-trpc
3434
run: pnpm --filter @posthog/electron-trpc build
3535

36+
- name: Build platform
37+
run: pnpm --filter @posthog/platform build
38+
3639
- name: Build shared
3740
run: pnpm --filter @posthog/shared build
3841

.github/workflows/code-release.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ jobs:
8585
- name: Build electron-trpc package
8686
run: pnpm --filter @posthog/electron-trpc run build
8787

88+
- name: Build platform package
89+
run: pnpm --filter @posthog/platform run build
90+
8891
- name: Build shared package
8992
run: pnpm --filter @posthog/shared run build
9093

@@ -182,6 +185,9 @@ jobs:
182185
- name: Build electron-trpc package
183186
run: pnpm --filter @posthog/electron-trpc run build
184187

188+
- name: Build platform package
189+
run: pnpm --filter @posthog/platform run build
190+
185191
- name: Build shared package
186192
run: pnpm --filter @posthog/shared run build
187193

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ jobs:
7878
- name: Build packages
7979
run: |
8080
pnpm --filter @posthog/electron-trpc build &
81+
pnpm --filter @posthog/platform build &
8182
pnpm --filter @posthog/shared build
8283
pnpm --filter @posthog/git build
8384
pnpm --filter agent build &

apps/code/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
"@posthog/quill-components": "link:/Users/adamleithp/Dev/posthog/packages/quill/packages/components",
135135
"@posthog/quill-primitives": "link:/Users/adamleithp/Dev/posthog/packages/quill/packages/primitives",
136136
"@posthog/quill-tokens": "link:/Users/adamleithp/Dev/posthog/packages/quill/packages/tokens",
137+
"@posthog/platform": "workspace:*",
137138
"@posthog/shared": "workspace:*",
138139
"@radix-ui/react-collapsible": "^1.1.12",
139140
"@radix-ui/react-icons": "^1.3.2",

apps/code/src/main/di/container.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { SuspensionRepositoryImpl } from "../db/repositories/suspension-reposito
99
import { WorkspaceRepository } from "../db/repositories/workspace-repository";
1010
import { WorktreeRepository } from "../db/repositories/worktree-repository";
1111
import { DatabaseService } from "../db/service";
12+
import { ElectronUrlLauncher } from "../platform-adapters/electron-url-launcher";
1213
import { AgentAuthAdapter } from "../services/agent/auth-adapter";
1314
import { AgentService } from "../services/agent/service";
1415
import { AppLifecycleService } from "../services/app-lifecycle/service";
@@ -52,6 +53,8 @@ export const container = new Container({
5253
defaultScope: "Singleton",
5354
});
5455

56+
container.bind(MAIN_TOKENS.UrlLauncher).to(ElectronUrlLauncher);
57+
5558
container.bind(MAIN_TOKENS.DatabaseService).to(DatabaseService);
5659
container
5760
.bind(MAIN_TOKENS.AuthPreferenceRepository)

apps/code/src/main/di/tokens.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* Never import this file from renderer code.
66
*/
77
export const MAIN_TOKENS = Object.freeze({
8+
// Platform ports (host-agnostic interfaces from @posthog/platform)
9+
UrlLauncher: Symbol.for("Platform.UrlLauncher"),
10+
811
// Stores
912
SettingsStore: Symbol.for("Main.SettingsStore"),
1013

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { IUrlLauncher } from "@posthog/platform/url-launcher";
2+
import { shell } from "electron";
3+
import { injectable } from "inversify";
4+
5+
@injectable()
6+
export class ElectronUrlLauncher implements IUrlLauncher {
7+
public async launch(url: string): Promise<void> {
8+
await shell.openExternal(url);
9+
}
10+
}

apps/code/src/main/services/github-integration/service.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
import type { IUrlLauncher } from "@posthog/platform/url-launcher";
12
import { getCloudUrlFromRegion } from "@shared/constants/oauth";
2-
import { shell } from "electron";
3-
import { injectable } from "inversify";
3+
import { inject, injectable } from "inversify";
4+
import { MAIN_TOKENS } from "../../di/tokens";
45
import { logger } from "../../utils/logger";
56
import type { CloudRegion, StartGitHubFlowOutput } from "./schemas";
67

78
const log = logger.scope("github-integration-service");
89

910
@injectable()
1011
export class GitHubIntegrationService {
12+
constructor(
13+
@inject(MAIN_TOKENS.UrlLauncher) private readonly urlLauncher: IUrlLauncher,
14+
) {}
15+
1116
public async startFlow(
1217
region: CloudRegion,
1318
projectId: number,
@@ -18,7 +23,7 @@ export class GitHubIntegrationService {
1823
const authorizeUrl = `${cloudUrl}/api/environments/${projectId}/integrations/authorize/?kind=github&next=${encodeURIComponent(next)}`;
1924

2025
log.info("Opening GitHub authorization URL in browser");
21-
await shell.openExternal(authorizeUrl);
26+
await this.urlLauncher.launch(authorizeUrl);
2227

2328
return { success: true };
2429
} catch (error) {

biome.jsonc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,31 @@
128128
}
129129
}
130130
},
131+
{
132+
// Main-process code must not import from "electron" directly.
133+
// Electron APIs go through platform ports (@posthog/platform) implemented
134+
// by adapters in apps/code/src/main/platform-adapters/. This keeps the
135+
// service layer host-agnostic so it can later run as a standalone Node server.
136+
//
137+
// The ban is opt-in per migrated area. As each service is refactored to
138+
// depend on platform ports, add its folder to this includes list. When the
139+
// entire main process is migrated, simplify to "apps/code/src/main/**/*.ts".
140+
"includes": ["apps/code/src/main/services/github-integration/**/*.ts"],
141+
"linter": {
142+
"rules": {
143+
"style": {
144+
"noRestrictedImports": {
145+
"level": "error",
146+
"options": {
147+
"paths": {
148+
"electron": "Do not import from 'electron' in main-process services. Define a port interface in @posthog/platform and implement it as an adapter in apps/code/src/main/platform-adapters/. The service should depend on the port via DI."
149+
}
150+
}
151+
}
152+
}
153+
}
154+
}
155+
},
131156
{
132157
// Renderer code should use path aliases
133158
"includes": [

mprocs.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ procs:
66
depends_on:
77
- agent
88
- git
9+
- platform
910

1011
agent:
1112
shell: 'node scripts/pnpm-run.mjs --filter agent run dev'
1213

1314
git:
1415
shell: 'node scripts/pnpm-run.mjs --filter @posthog/git run dev'
1516

17+
platform:
18+
shell: 'node scripts/pnpm-run.mjs --filter @posthog/platform run dev'
19+
1620
enricher:
1721
shell: 'node scripts/pnpm-run.mjs --filter @posthog/enricher run dev'
1822

0 commit comments

Comments
 (0)