Skip to content

Commit 33b7e6b

Browse files
committed
feat: Improved edit to install the codify desktop app instead
1 parent 56621d7 commit 33b7e6b

1 file changed

Lines changed: 141 additions & 12 deletions

File tree

src/orchestrators/edit.ts

Lines changed: 141 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,156 @@
1-
import { Config } from '@oclif/core';
21
import open from 'open';
2+
import * as fs from 'node:fs/promises';
3+
import { tmpdir } from 'node:os';
4+
import os from 'node:os';
5+
import path from 'node:path';
36

47
import { DashboardApiClient } from '../api/dashboard/index.js';
58
import { config } from '../config.js';
69
import { LoginHelper } from '../connect/login-helper.js';
710
import { Reporter } from '../ui/reporters/reporter.js';
11+
import { OsUtils } from '../utils/os-utils.js';
12+
import { spawn } from '../utils/spawn.js';
813
import { ConnectOrchestrator } from './connect.js';
9-
import { LoginOrchestrator } from './login.js';
14+
15+
const DESKTOP_APP_PATHS = {
16+
darwin: '/Applications/Codify.app',
17+
linux: '/usr/bin/codify',
18+
};
19+
20+
const DOWNLOAD_URLS: Record<string, Record<string, string>> = {
21+
darwin: {
22+
arm64: 'https://releases-desktop.codifycli.com/channels/stable/Codify_aarch64.dmg',
23+
x64: 'https://releases-desktop.codifycli.com/channels/stable/Codify_x64.dmg',
24+
},
25+
linux_deb: {
26+
arm64: 'https://releases-desktop.codifycli.com/channels/stable/Codify_arm64.deb',
27+
x64: 'https://releases-desktop.codifycli.com/channels/stable/Codify_amd64.deb',
28+
},
29+
linux_rpm: {
30+
aarch64: 'https://releases-desktop.codifycli.com/channels/stable/Codify_aarch64.rpm',
31+
x64: 'https://releases-desktop.codifycli.com/channels/stable/Codify_x86_64.rpm',
32+
},
33+
};
34+
35+
async function getDesktopAppPath(): Promise<string | null> {
36+
const appPath = OsUtils.isMacOS()
37+
? DESKTOP_APP_PATHS.darwin
38+
: OsUtils.isLinux()
39+
? DESKTOP_APP_PATHS.linux
40+
: null;
41+
42+
if (!appPath) return null;
43+
44+
try {
45+
await fs.access(appPath);
46+
return appPath;
47+
} catch {
48+
return null;
49+
}
50+
}
51+
52+
function getDownloadUrl(): { url: string; platform: 'darwin' | 'linux_deb' | 'linux_rpm' } | null {
53+
const arch = os.arch();
54+
55+
if (OsUtils.isMacOS()) {
56+
return {
57+
url: DOWNLOAD_URLS.darwin[arch] ?? DOWNLOAD_URLS.darwin['x64'],
58+
platform: 'darwin',
59+
};
60+
}
61+
62+
if (OsUtils.isLinux()) {
63+
const platform = OsUtils.isDebianBased() ? 'linux_deb' : 'linux_rpm';
64+
return {
65+
url: DOWNLOAD_URLS[platform][arch] ?? DOWNLOAD_URLS[platform]['x64'],
66+
platform,
67+
};
68+
}
69+
70+
return null;
71+
}
72+
73+
async function installDesktopApp(reporter: Reporter, url: string, platform: 'darwin' | 'linux_deb' | 'linux_rpm'): Promise<void> {
74+
const ext = url.split('.').pop()!;
75+
const tmpFile = path.join(tmpdir(), `codify-desktop.${ext}`);
76+
77+
console.log('Downloading Codify desktop app...');
78+
await spawn(`curl -L -o ${tmpFile} ${url}`);
79+
80+
if (platform === 'darwin') {
81+
const mountPoint = path.join(tmpdir(), 'codify-dmg-mount');
82+
try {
83+
console.log('Installing Codify desktop app...');
84+
await spawn(`hdiutil attach ${tmpFile} -mountpoint ${mountPoint} -nobrowse -quiet`);
85+
await spawn(`cp -R ${mountPoint}/Codify.app /Applications/Codify.app`);
86+
} finally {
87+
await spawn(`hdiutil detach ${mountPoint} -quiet`).catch(() => {});
88+
await fs.unlink(tmpFile).catch(() => {});
89+
}
90+
} else {
91+
const password = await reporter.promptSudo('codify-installer', {
92+
command: platform === 'linux_deb' ? `dpkg -i ${tmpFile}` : `rpm -i ${tmpFile}`,
93+
options: { requiresRoot: true },
94+
});
95+
96+
if (password == null) {
97+
console.log('Installation cancelled.');
98+
return;
99+
}
100+
101+
try {
102+
console.log('Installing Codify desktop app...');
103+
const cmd = platform === 'linux_deb' ? `dpkg -i ${tmpFile}` : `rpm -i ${tmpFile}`;
104+
await spawn(cmd, { requiresRoot: true }, undefined, password);
105+
} finally {
106+
await fs.unlink(tmpFile).catch(() => {});
107+
}
108+
}
109+
110+
console.log('Codify desktop app installed successfully.');
111+
}
10112

11113
export class EditOrchestrator {
12114

13115
static async run(rootCommand: string, reporter: Reporter) {
14-
const login = LoginHelper.get()?.isLoggedIn;
15-
if (!login) {
16-
console.log('User is not logged in. Attempting to log in...')
17-
await LoginOrchestrator.run();
116+
const desktopPath = await getDesktopAppPath();
117+
118+
if (desktopPath) {
119+
await open(desktopPath);
120+
return;
121+
}
122+
123+
const download = getDownloadUrl();
124+
if (download) {
125+
const shouldInstall = await reporter.promptConfirmation(
126+
'Codify desktop app is not installed. Would you like to download and install it?'
127+
);
128+
129+
await reporter.hide();
130+
131+
if (shouldInstall) {
132+
await installDesktopApp(reporter, download.url, download.platform);
133+
const installedPath = await getDesktopAppPath();
134+
if (installedPath) {
135+
await open(installedPath);
136+
}
137+
return;
138+
}
18139
}
19140

141+
await EditOrchestrator.openDashboard(rootCommand, reporter);
142+
}
143+
144+
private static async openDashboard(rootCommand: string, reporter: Reporter) {
145+
const isLoggedIn = LoginHelper.get()?.isLoggedIn;
146+
20147
let defaultDocumentId: null | string = null;
21-
try {
22-
defaultDocumentId = await DashboardApiClient.getDefaultDocumentId();
23-
} catch {
24-
console.warn('Mismatch accounts between local and dashboard. Cannot open default document')
148+
if (isLoggedIn) {
149+
try {
150+
defaultDocumentId = await DashboardApiClient.getDefaultDocumentId();
151+
} catch {
152+
// ignore — just open homepage
153+
}
25154
}
26155

27156
const url = defaultDocumentId
@@ -31,11 +160,11 @@ export class EditOrchestrator {
31160
await ConnectOrchestrator.run(rootCommand, reporter, false, (code) => {
32161
open(`${url}?connection_code=${code}`);
33162
console.log(
34-
`Opening default Codify file:
163+
`Opening Codify dashboard:
35164
${url}?connection_code=${code}
36165
37166
Starting connection. If unsuccessful, manually enter the code:
38-
${code}`)
167+
${code}`);
39168
});
40169
}
41170
}

0 commit comments

Comments
 (0)