|
1 | | -import { randomUUID } from "node:crypto" |
2 | 1 | import http from "node:http" |
3 | | -import { homedir, tmpdir } from "node:os" |
4 | 2 | import { getCACertificates, setDefaultCACertificates } from "node:tls" |
5 | 3 | import { app } from "electron" |
6 | | -import contextMenu from "electron-context-menu" |
7 | | -import { Effect, FileSystem, Path } from "effect" |
8 | | -import { CHANNEL } from "../constants" |
| 4 | +import { Effect, Path } from "effect" |
9 | 5 | import { DesktopPaths } from "../paths" |
10 | 6 | import { getUserShell, loadShellEnv } from "../service/shell-env" |
11 | 7 | import { registerRendererProtocol, setDockIcon } from "../windows" |
12 | 8 |
|
13 | | -const appNames: Record<string, string> = { |
14 | | - dev: "OpenCode Dev", |
15 | | - beta: "OpenCode Beta", |
16 | | - prod: "OpenCode", |
17 | | -} |
18 | | -const appIDs: Record<string, string> = { |
19 | | - dev: "ai.opencode.desktop.dev", |
20 | | - beta: "ai.opencode.desktop.beta", |
21 | | - prod: "ai.opencode.desktop", |
22 | | -} |
23 | | -const testOnboarding = process.env.OPENCODE_TEST_ONBOARDING === "1" |
24 | | -const jsCallStackFeature = "DocumentPolicyIncludeJSCallStacksInCrashReports" |
25 | | - |
26 | | -export const configureApplication = Effect.fn("Application.configure")(function* () { |
27 | | - const path = yield* Path.Path |
| 9 | +// electron-context-menu attaches to every existing and future window, so it can load once the first |
| 10 | +// window is up instead of holding up startup with its dependency tree. |
| 11 | +export const installContextMenu = Effect.gen(function* () { |
| 12 | + const { default: contextMenu } = yield* Effect.promise(() => import("electron-context-menu")) |
28 | 13 | contextMenu({ showSaveImageAs: true, showLookUpSelection: false, showSearchWithGoogle: false }) |
29 | | - try { |
30 | | - process.chdir(homedir()) |
31 | | - } catch {} |
32 | | - process.env.OPENCODE_DISABLE_EMBEDDED_WEB_UI = "true" |
33 | | - |
34 | | - const appID = app.isPackaged ? appIDs[CHANNEL] : "ai.opencode.desktop.dev" |
35 | | - app.setName(app.isPackaged ? appNames[CHANNEL] : "OpenCode Dev") |
36 | | - app.setAppUserModelId(appID) |
37 | | - app.commandLine.appendSwitch("proxy-bypass-list", "<-loopback>") |
38 | | - const features = app.commandLine.getSwitchValue("enable-features") |
39 | | - app.commandLine.appendSwitch("enable-features", features ? `${jsCallStackFeature},${features}` : jsCallStackFeature) |
40 | | - if (!app.isPackaged) |
41 | | - app.commandLine.appendSwitch("remote-debugging-port", process.env.OPENCODE_DESKTOP_REMOTE_DEBUGGING_PORT ?? "9222") |
42 | | - |
43 | | - const testRoot = yield* createTestRoot() |
44 | | - app.setPath("userData", testRoot ? path.join(testRoot, "desktop") : path.join(app.getPath("appData"), appID)) |
45 | | - if (testRoot) { |
46 | | - app.setPath("sessionData", path.join(testRoot, "session")) |
47 | | - if (testOnboarding) app.setPath("documents", path.join(testRoot, "documents")) |
48 | | - } |
49 | 14 | }) |
50 | 15 |
|
51 | | -export function acquireApplicationLock() { |
52 | | - if (app.requestSingleInstanceLock()) return true |
53 | | - app.quit() |
54 | | - return false |
55 | | -} |
56 | | - |
57 | 16 | export const prepareApplicationEnvironment = Effect.gen(function* () { |
58 | 17 | yield* loadSystemCertificates |
59 | 18 | yield* loadProxyEnvironment |
@@ -91,29 +50,6 @@ export const loadProxyEnvironment = Effect.gen(function* () { |
91 | 50 | }).pipe(Effect.catch((error) => Effect.logWarning("failed to load proxy environment", { error }))) |
92 | 51 | }) |
93 | 52 |
|
94 | | -const createTestRoot = Effect.fn("Application.createTestRoot")(function* () { |
95 | | - const fs = yield* FileSystem.FileSystem |
96 | | - const path = yield* Path.Path |
97 | | - const root = testOnboarding |
98 | | - ? path.join(tmpdir(), `opencode-onboarding-${randomUUID()}`) |
99 | | - : app.isPackaged |
100 | | - ? undefined |
101 | | - : process.env.OPENCODE_DESKTOP_TEST_ROOT |
102 | | - if (!root) return undefined |
103 | | - if (testOnboarding) yield* fs.remove(root, { recursive: true, force: true }) |
104 | | - yield* Effect.forEach( |
105 | | - ["data", "config", "cache", "state", "desktop", "session", "documents"], |
106 | | - (dir) => fs.makeDirectory(path.join(root, dir), { recursive: true }), |
107 | | - { discard: true }, |
108 | | - ) |
109 | | - if (testOnboarding) process.env.OPENCODE_DB = ":memory:" |
110 | | - process.env.XDG_DATA_HOME = path.join(root, "data") |
111 | | - process.env.XDG_CONFIG_HOME = path.join(root, "config") |
112 | | - process.env.XDG_CACHE_HOME = path.join(root, "cache") |
113 | | - process.env.XDG_STATE_HOME = path.join(root, "state") |
114 | | - return root |
115 | | -}) |
116 | | - |
117 | 53 | const loadSystemCertificates = Effect.try({ |
118 | 54 | try: () => { |
119 | 55 | setDefaultCACertificates([...new Set([...getCACertificates("default"), ...getCACertificates("system")])]) |
|
0 commit comments