feat: add app-owned Copilot and Grok subscription connections
This commit is contained in:
+30
-1
@@ -27,6 +27,8 @@
|
||||
const { app, BrowserWindow, Menu, ipcMain, session, shell, dialog } = require("electron");
|
||||
const { createChatGPT, fileStore } = require("./chatgpt.cjs");
|
||||
const { attachChatGPTChild, trustedSender, chatGPTControl } = require("./chatgpt-ipc.cjs");
|
||||
const { createSubscriptions, loadSubscriptionSDK } = require("./subscriptions.cjs");
|
||||
const { attachSubscriptionChild, subscriptionControl } = require("./subscription-ipc.cjs");
|
||||
const { desktopAPIHeaders } = require("./desktop-api.cjs");
|
||||
const { randomBytes } = require("node:crypto");
|
||||
const { spawn } = require("node:child_process");
|
||||
@@ -134,6 +136,8 @@ if (process.argv.includes("--browser-service")) {
|
||||
let serverProcess = null;
|
||||
let chatgpt = null;
|
||||
let chatgptChild = null;
|
||||
let subscriptions = null;
|
||||
let subscriptionChild = null;
|
||||
// Per-launch request capability, never OAuth tokens and never renderer state.
|
||||
let desktopAPISecret = null;
|
||||
const trustedAppWindows = new Set();
|
||||
@@ -222,6 +226,7 @@ function startServer(port) {
|
||||
);
|
||||
serverProcess = child;
|
||||
chatgptChild = attachChatGPTChild(child, chatgpt);
|
||||
subscriptionChild = attachSubscriptionChild(child, subscriptions);
|
||||
const fwd = (buf) => buf.toString().trimEnd().split("\n").forEach((l) => l && log(`server: ${l}`));
|
||||
child.stdout.on("data", fwd);
|
||||
child.stderr.on("data", fwd);
|
||||
@@ -230,7 +235,10 @@ function startServer(port) {
|
||||
serverProcess = null;
|
||||
chatgptChild?.dispose();
|
||||
chatgptChild = null;
|
||||
subscriptionChild?.dispose();
|
||||
subscriptionChild = null;
|
||||
chatgpt?.close();
|
||||
subscriptions?.close();
|
||||
});
|
||||
resolve(child);
|
||||
});
|
||||
@@ -255,6 +263,7 @@ function waitUntilUp(url, tries = 150) {
|
||||
|
||||
function killServer() {
|
||||
chatgpt?.close();
|
||||
subscriptions?.close();
|
||||
if (!serverProcess) return;
|
||||
const child = serverProcess;
|
||||
serverProcess = null;
|
||||
@@ -569,6 +578,7 @@ function installMenu() {
|
||||
async function main() {
|
||||
app.on("window-all-closed", () => {
|
||||
chatgpt?.pause();
|
||||
subscriptions?.pause();
|
||||
// macOS convention: the app stays resident, reactivated from the Dock.
|
||||
if (process.platform !== "darwin") app.quit();
|
||||
});
|
||||
@@ -600,6 +610,16 @@ async function main() {
|
||||
for (const win of BrowserWindow.getAllWindows()) win.webContents.send("lh:chatgpt:changed");
|
||||
},
|
||||
});
|
||||
subscriptions = createSubscriptions({
|
||||
directory: app.getPath("userData"),
|
||||
loadSDK: () => loadSubscriptionSDK(path.dirname(serverEntry())),
|
||||
openExternal: (target) => shell.openExternal(target),
|
||||
onChange: (snapshot) => {
|
||||
subscriptionChild?.send(snapshot);
|
||||
for (const win of BrowserWindow.getAllWindows()) win.webContents.send("lh:subscriptions:changed");
|
||||
},
|
||||
});
|
||||
await subscriptions.ready;
|
||||
log(`starting server: ${serverEntry()}`);
|
||||
log(`data dir: ${DATA_DIR()}${fs.existsSync(AUTH_FILE()) ? " · auth.json: present" : " · auth.json: ABSENT (no BYOK keys yet)"}`);
|
||||
await startServer(new URL(url).port);
|
||||
@@ -617,6 +637,15 @@ async function main() {
|
||||
return chatGPTControl(command, chatgpt);
|
||||
});
|
||||
|
||||
ipcMain.handle("lh:subscriptions:control", async (event, command) => {
|
||||
if (!trustedAppWindows.has(BrowserWindow.fromWebContents(event.sender)) || !trustedSender(event, new URL(url).origin, BrowserWindow)) throw new Error("Untrusted desktop request.");
|
||||
if (!subscriptions || !serverProcess?.connected) {
|
||||
if (command?.op === "status") return [];
|
||||
throw new Error("Subscription sign-in requires the desktop app's private server connection.");
|
||||
}
|
||||
return subscriptionControl(command, subscriptions);
|
||||
});
|
||||
|
||||
installMenu();
|
||||
|
||||
// Auto-update (Wave C): wire the updater before the window so the
|
||||
@@ -642,7 +671,7 @@ async function main() {
|
||||
if (width < target) win.setBounds({ x, y, width: target, height });
|
||||
});
|
||||
app.on("activate", () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) { chatgpt?.resume(); createWindow(url); }
|
||||
if (BrowserWindow.getAllWindows().length === 0) { chatgpt?.resume(); subscriptions?.resume(); createWindow(url); }
|
||||
});
|
||||
createWindow(url);
|
||||
log(`window open: ${url}`);
|
||||
|
||||
Reference in New Issue
Block a user