amai 0.0.14 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +27 -5
- package/dist/cli.js +27 -5
- package/dist/lib/code-server.cjs +204 -0
- package/dist/lib/code-server.d.cts +8 -0
- package/dist/lib/code-server.d.ts +8 -0
- package/dist/lib/code-server.js +191 -0
- package/dist/lib/daemon-entry.cjs +27 -5
- package/dist/lib/daemon-entry.js +27 -5
- package/dist/server.cjs +25 -2
- package/dist/server.js +25 -2
- package/package.json +10 -5
package/dist/cli.cjs
CHANGED
|
@@ -1382,7 +1382,14 @@ var startHttpServer = () => {
|
|
|
1382
1382
|
app.get("/", (c) => {
|
|
1383
1383
|
return c.text("Hello World");
|
|
1384
1384
|
});
|
|
1385
|
-
nodeServer.serve({ fetch: app.fetch, port: 3456 });
|
|
1385
|
+
const server = nodeServer.serve({ fetch: app.fetch, port: 3456 });
|
|
1386
|
+
server.on("error", (err) => {
|
|
1387
|
+
if (err.code === "EADDRINUSE") {
|
|
1388
|
+
console.error(`[http] Port 3456 is already in use, skipping HTTP server`);
|
|
1389
|
+
} else {
|
|
1390
|
+
throw err;
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1386
1393
|
};
|
|
1387
1394
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1388
1395
|
var CREDENTIALS_DIR = path10__default.default.join(os3__default.default.homedir(), ".amai");
|
|
@@ -1530,8 +1537,24 @@ var getUserId = () => {
|
|
|
1530
1537
|
}
|
|
1531
1538
|
const raw = fs8__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1532
1539
|
const data = JSON.parse(raw);
|
|
1540
|
+
const fromUserObject = data.user?.id;
|
|
1541
|
+
const fromTopLevel = data.sub ?? data.user_id;
|
|
1542
|
+
let fromToken;
|
|
1543
|
+
if (data.access_token) {
|
|
1544
|
+
try {
|
|
1545
|
+
const payload = JSON.parse(
|
|
1546
|
+
Buffer.from(data.access_token.split(".")[1], "base64").toString("utf8")
|
|
1547
|
+
);
|
|
1548
|
+
fromToken = payload.sub ?? payload.user_id;
|
|
1549
|
+
} catch {
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
const userId = fromUserObject ?? fromTopLevel ?? fromToken;
|
|
1553
|
+
if (!userId) {
|
|
1554
|
+
throw new Error("User ID not found in credentials");
|
|
1555
|
+
}
|
|
1533
1556
|
return {
|
|
1534
|
-
userId
|
|
1557
|
+
userId
|
|
1535
1558
|
};
|
|
1536
1559
|
} catch {
|
|
1537
1560
|
throw new Error("Error while getting userId");
|
|
@@ -2641,8 +2664,7 @@ async function setupDefaultSettings() {
|
|
|
2641
2664
|
async function installExtensions() {
|
|
2642
2665
|
const binPath = getCodeServerBin();
|
|
2643
2666
|
const extensions = [
|
|
2644
|
-
"castrogusttavo.min-theme"
|
|
2645
|
-
"sourcegraph.amp"
|
|
2667
|
+
"castrogusttavo.min-theme"
|
|
2646
2668
|
];
|
|
2647
2669
|
for (const ext of extensions) {
|
|
2648
2670
|
try {
|
|
@@ -2757,7 +2779,7 @@ function getDaemonPid() {
|
|
|
2757
2779
|
return null;
|
|
2758
2780
|
}
|
|
2759
2781
|
}
|
|
2760
|
-
var VERSION = "0.0.
|
|
2782
|
+
var VERSION = "0.0.16";
|
|
2761
2783
|
var PROJECT_DIR = process.cwd();
|
|
2762
2784
|
var LOGO = `
|
|
2763
2785
|
__ _ _ __ ___ __ _
|
package/dist/cli.js
CHANGED
|
@@ -1369,7 +1369,14 @@ var startHttpServer = () => {
|
|
|
1369
1369
|
app.get("/", (c) => {
|
|
1370
1370
|
return c.text("Hello World");
|
|
1371
1371
|
});
|
|
1372
|
-
serve({ fetch: app.fetch, port: 3456 });
|
|
1372
|
+
const server = serve({ fetch: app.fetch, port: 3456 });
|
|
1373
|
+
server.on("error", (err) => {
|
|
1374
|
+
if (err.code === "EADDRINUSE") {
|
|
1375
|
+
console.error(`[http] Port 3456 is already in use, skipping HTTP server`);
|
|
1376
|
+
} else {
|
|
1377
|
+
throw err;
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1373
1380
|
};
|
|
1374
1381
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1375
1382
|
var CREDENTIALS_DIR = path10.join(os3.homedir(), ".amai");
|
|
@@ -1517,8 +1524,24 @@ var getUserId = () => {
|
|
|
1517
1524
|
}
|
|
1518
1525
|
const raw = fs8.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1519
1526
|
const data = JSON.parse(raw);
|
|
1527
|
+
const fromUserObject = data.user?.id;
|
|
1528
|
+
const fromTopLevel = data.sub ?? data.user_id;
|
|
1529
|
+
let fromToken;
|
|
1530
|
+
if (data.access_token) {
|
|
1531
|
+
try {
|
|
1532
|
+
const payload = JSON.parse(
|
|
1533
|
+
Buffer.from(data.access_token.split(".")[1], "base64").toString("utf8")
|
|
1534
|
+
);
|
|
1535
|
+
fromToken = payload.sub ?? payload.user_id;
|
|
1536
|
+
} catch {
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
const userId = fromUserObject ?? fromTopLevel ?? fromToken;
|
|
1540
|
+
if (!userId) {
|
|
1541
|
+
throw new Error("User ID not found in credentials");
|
|
1542
|
+
}
|
|
1520
1543
|
return {
|
|
1521
|
-
userId
|
|
1544
|
+
userId
|
|
1522
1545
|
};
|
|
1523
1546
|
} catch {
|
|
1524
1547
|
throw new Error("Error while getting userId");
|
|
@@ -2628,8 +2651,7 @@ async function setupDefaultSettings() {
|
|
|
2628
2651
|
async function installExtensions() {
|
|
2629
2652
|
const binPath = getCodeServerBin();
|
|
2630
2653
|
const extensions = [
|
|
2631
|
-
"castrogusttavo.min-theme"
|
|
2632
|
-
"sourcegraph.amp"
|
|
2654
|
+
"castrogusttavo.min-theme"
|
|
2633
2655
|
];
|
|
2634
2656
|
for (const ext of extensions) {
|
|
2635
2657
|
try {
|
|
@@ -2744,7 +2766,7 @@ function getDaemonPid() {
|
|
|
2744
2766
|
return null;
|
|
2745
2767
|
}
|
|
2746
2768
|
}
|
|
2747
|
-
var VERSION = "0.0.
|
|
2769
|
+
var VERSION = "0.0.16";
|
|
2748
2770
|
var PROJECT_DIR = process.cwd();
|
|
2749
2771
|
var LOGO = `
|
|
2750
2772
|
__ _ _ __ ___ __ _
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var child_process = require('child_process');
|
|
5
|
+
var util = require('util');
|
|
6
|
+
var fs = require('fs');
|
|
7
|
+
var path2 = require('path');
|
|
8
|
+
var pc = require('picocolors');
|
|
9
|
+
var os = require('os');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
14
|
+
var path2__default = /*#__PURE__*/_interopDefault(path2);
|
|
15
|
+
var pc__default = /*#__PURE__*/_interopDefault(pc);
|
|
16
|
+
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
17
|
+
|
|
18
|
+
var AMA_DIR = path2__default.default.join(os__default.default.homedir(), ".amai");
|
|
19
|
+
var CODE_DIR = path2__default.default.join(AMA_DIR, "code");
|
|
20
|
+
var STORAGE_DIR = path2__default.default.join(AMA_DIR, "storage");
|
|
21
|
+
|
|
22
|
+
// src/lib/code-server.ts
|
|
23
|
+
var execAsync = util.promisify(child_process.exec);
|
|
24
|
+
var CODE_SERVER_VERSION = "4.96.4";
|
|
25
|
+
function getPlatformInfo() {
|
|
26
|
+
const platform = process.platform;
|
|
27
|
+
const arch = process.arch;
|
|
28
|
+
if (platform === "darwin") {
|
|
29
|
+
return {
|
|
30
|
+
platform: "macos",
|
|
31
|
+
arch: arch === "arm64" ? "arm64" : "amd64",
|
|
32
|
+
ext: "tar.gz"
|
|
33
|
+
};
|
|
34
|
+
} else if (platform === "linux") {
|
|
35
|
+
return {
|
|
36
|
+
platform: "linux",
|
|
37
|
+
arch: arch === "arm64" ? "arm64" : "amd64",
|
|
38
|
+
ext: "tar.gz"
|
|
39
|
+
};
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function getDownloadUrl() {
|
|
45
|
+
const { platform, arch, ext } = getPlatformInfo();
|
|
46
|
+
return `https://github.com/coder/code-server/releases/download/v${CODE_SERVER_VERSION}/code-server-${CODE_SERVER_VERSION}-${platform}-${arch}.${ext}`;
|
|
47
|
+
}
|
|
48
|
+
function getCodeServerDir() {
|
|
49
|
+
const { platform, arch } = getPlatformInfo();
|
|
50
|
+
return path2__default.default.join(CODE_DIR, `code-server-${CODE_SERVER_VERSION}-${platform}-${arch}`);
|
|
51
|
+
}
|
|
52
|
+
function getCodeServerBin() {
|
|
53
|
+
return path2__default.default.join(getCodeServerDir(), "bin", "code-server");
|
|
54
|
+
}
|
|
55
|
+
function isCodeServerInstalled() {
|
|
56
|
+
const binPath = getCodeServerBin();
|
|
57
|
+
return fs__default.default.existsSync(binPath);
|
|
58
|
+
}
|
|
59
|
+
async function installCodeServer() {
|
|
60
|
+
const { ext } = getPlatformInfo();
|
|
61
|
+
const downloadUrl = getDownloadUrl();
|
|
62
|
+
const tarballPath = path2__default.default.join(AMA_DIR, `code-server.${ext}`);
|
|
63
|
+
if (!fs__default.default.existsSync(AMA_DIR)) {
|
|
64
|
+
fs__default.default.mkdirSync(AMA_DIR, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
if (!fs__default.default.existsSync(CODE_DIR)) {
|
|
67
|
+
fs__default.default.mkdirSync(CODE_DIR, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
if (!fs__default.default.existsSync(STORAGE_DIR)) {
|
|
70
|
+
fs__default.default.mkdirSync(STORAGE_DIR, { recursive: true });
|
|
71
|
+
}
|
|
72
|
+
console.log(pc__default.default.cyan(`downloading code-server v${CODE_SERVER_VERSION}...`));
|
|
73
|
+
console.log(pc__default.default.gray(downloadUrl));
|
|
74
|
+
const response = await fetch(downloadUrl);
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new Error(`Failed to download code-server: ${response.statusText}`);
|
|
77
|
+
}
|
|
78
|
+
const buffer = await response.arrayBuffer();
|
|
79
|
+
await fs__default.default.promises.writeFile(tarballPath, Buffer.from(buffer));
|
|
80
|
+
console.log(pc__default.default.cyan("Extracting code-server..."));
|
|
81
|
+
await execAsync(`tar -xzf ${tarballPath} -C ${CODE_DIR}`);
|
|
82
|
+
await fs__default.default.promises.unlink(tarballPath);
|
|
83
|
+
const binPath = getCodeServerBin();
|
|
84
|
+
if (fs__default.default.existsSync(binPath)) {
|
|
85
|
+
await fs__default.default.promises.chmod(binPath, 493);
|
|
86
|
+
}
|
|
87
|
+
console.log(pc__default.default.green("code-server installed successfully"));
|
|
88
|
+
}
|
|
89
|
+
async function killExistingCodeServer() {
|
|
90
|
+
try {
|
|
91
|
+
if (process.platform === "win32") {
|
|
92
|
+
await execAsync("netstat -ano | findstr :8081 | findstr LISTENING").then(async ({ stdout }) => {
|
|
93
|
+
const pid = stdout.trim().split(/\s+/).pop();
|
|
94
|
+
if (pid) await execAsync(`taskkill /PID ${pid} /F`);
|
|
95
|
+
}).catch(() => {
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
await execAsync("lsof -ti:8081").then(async ({ stdout }) => {
|
|
99
|
+
const pid = stdout.trim();
|
|
100
|
+
if (pid) await execAsync(`kill -9 ${pid}`);
|
|
101
|
+
}).catch(() => {
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function setupDefaultSettings() {
|
|
108
|
+
const userDir = path2__default.default.join(STORAGE_DIR, "User");
|
|
109
|
+
const settingsPath = path2__default.default.join(userDir, "settings.json");
|
|
110
|
+
if (!fs__default.default.existsSync(userDir)) {
|
|
111
|
+
fs__default.default.mkdirSync(userDir, { recursive: true });
|
|
112
|
+
}
|
|
113
|
+
const defaultSettings = {
|
|
114
|
+
// Disable signature verification for Open VSX extensions
|
|
115
|
+
"extensions.verifySignature": false,
|
|
116
|
+
// Theme settings
|
|
117
|
+
"workbench.colorTheme": "Min Dark",
|
|
118
|
+
"workbench.startupEditor": "none",
|
|
119
|
+
// Editor settings
|
|
120
|
+
"editor.fontSize": 14,
|
|
121
|
+
"editor.fontFamily": "'JetBrains Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace",
|
|
122
|
+
"editor.minimap.enabled": false,
|
|
123
|
+
"editor.wordWrap": "on",
|
|
124
|
+
// UI settings
|
|
125
|
+
"window.menuBarVisibility": "compact",
|
|
126
|
+
"workbench.activityBar.location": "top"
|
|
127
|
+
};
|
|
128
|
+
let existingSettings = {};
|
|
129
|
+
if (fs__default.default.existsSync(settingsPath)) {
|
|
130
|
+
try {
|
|
131
|
+
const content = await fs__default.default.promises.readFile(settingsPath, "utf-8");
|
|
132
|
+
existingSettings = JSON.parse(content);
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const mergedSettings = { ...defaultSettings, ...existingSettings };
|
|
137
|
+
mergedSettings["workbench.colorTheme"] = "Min Dark";
|
|
138
|
+
mergedSettings["extensions.verifySignature"] = false;
|
|
139
|
+
await fs__default.default.promises.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2));
|
|
140
|
+
console.log(pc__default.default.green("ama code-server settings configured"));
|
|
141
|
+
}
|
|
142
|
+
async function installExtensions() {
|
|
143
|
+
const binPath = getCodeServerBin();
|
|
144
|
+
const extensions = [
|
|
145
|
+
"castrogusttavo.min-theme"
|
|
146
|
+
];
|
|
147
|
+
for (const ext of extensions) {
|
|
148
|
+
try {
|
|
149
|
+
console.log(pc__default.default.cyan(`ama installing extension: ${ext}...`));
|
|
150
|
+
await execAsync(`"${binPath}" --user-data-dir "${STORAGE_DIR}" --install-extension ${ext}`);
|
|
151
|
+
console.log(pc__default.default.green(`ama extension ${ext} installed`));
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.log(pc__default.default.yellow(`ama failed to install extension ${ext}`), error);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function startCodeServer(cwd) {
|
|
158
|
+
const binPath = getCodeServerBin();
|
|
159
|
+
const workDir = cwd || process.cwd();
|
|
160
|
+
if (!fs__default.default.existsSync(binPath)) {
|
|
161
|
+
throw new Error("ama code-server is not installed. Run installCodeServer() first.");
|
|
162
|
+
}
|
|
163
|
+
await killExistingCodeServer();
|
|
164
|
+
await setupDefaultSettings();
|
|
165
|
+
await installExtensions();
|
|
166
|
+
const workspaceStoragePath = path2__default.default.join(STORAGE_DIR, "User", "workspaceStorage");
|
|
167
|
+
try {
|
|
168
|
+
if (fs__default.default.existsSync(workspaceStoragePath)) {
|
|
169
|
+
await fs__default.default.promises.rm(workspaceStoragePath, { recursive: true, force: true });
|
|
170
|
+
}
|
|
171
|
+
const stateDbPath = path2__default.default.join(STORAGE_DIR, "User", "globalStorage", "state.vscdb");
|
|
172
|
+
if (fs__default.default.existsSync(stateDbPath)) {
|
|
173
|
+
await fs__default.default.promises.unlink(stateDbPath);
|
|
174
|
+
}
|
|
175
|
+
} catch {
|
|
176
|
+
}
|
|
177
|
+
console.log(pc__default.default.cyan(`ama starting code-server`));
|
|
178
|
+
const codeServer = child_process.spawn(
|
|
179
|
+
binPath,
|
|
180
|
+
[
|
|
181
|
+
"--port",
|
|
182
|
+
"8081",
|
|
183
|
+
"--host",
|
|
184
|
+
"0.0.0.0",
|
|
185
|
+
"--auth",
|
|
186
|
+
"none",
|
|
187
|
+
"--user-data-dir",
|
|
188
|
+
STORAGE_DIR,
|
|
189
|
+
"--disable-workspace-trust",
|
|
190
|
+
workDir
|
|
191
|
+
],
|
|
192
|
+
{
|
|
193
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
console.log(pc__default.default.green(`ama code-server running at http://localhost:8081/?folder=${encodeURIComponent(workDir)}`));
|
|
197
|
+
return codeServer;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
exports.CODE_SERVER_VERSION = CODE_SERVER_VERSION;
|
|
201
|
+
exports.installCodeServer = installCodeServer;
|
|
202
|
+
exports.isCodeServerInstalled = isCodeServerInstalled;
|
|
203
|
+
exports.isInstalled = isCodeServerInstalled;
|
|
204
|
+
exports.startCodeServer = startCodeServer;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
|
|
3
|
+
declare const CODE_SERVER_VERSION = "4.96.4";
|
|
4
|
+
declare function isCodeServerInstalled(): boolean;
|
|
5
|
+
declare function installCodeServer(): Promise<void>;
|
|
6
|
+
declare function startCodeServer(cwd?: string): Promise<ReturnType<typeof spawn>>;
|
|
7
|
+
|
|
8
|
+
export { CODE_SERVER_VERSION, installCodeServer, isCodeServerInstalled, isCodeServerInstalled as isInstalled, startCodeServer };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
|
|
3
|
+
declare const CODE_SERVER_VERSION = "4.96.4";
|
|
4
|
+
declare function isCodeServerInstalled(): boolean;
|
|
5
|
+
declare function installCodeServer(): Promise<void>;
|
|
6
|
+
declare function startCodeServer(cwd?: string): Promise<ReturnType<typeof spawn>>;
|
|
7
|
+
|
|
8
|
+
export { CODE_SERVER_VERSION, installCodeServer, isCodeServerInstalled, isCodeServerInstalled as isInstalled, startCodeServer };
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { exec, spawn } from 'child_process';
|
|
3
|
+
import { promisify } from 'util';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path2 from 'path';
|
|
6
|
+
import pc from 'picocolors';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
|
|
9
|
+
var AMA_DIR = path2.join(os.homedir(), ".amai");
|
|
10
|
+
var CODE_DIR = path2.join(AMA_DIR, "code");
|
|
11
|
+
var STORAGE_DIR = path2.join(AMA_DIR, "storage");
|
|
12
|
+
|
|
13
|
+
// src/lib/code-server.ts
|
|
14
|
+
var execAsync = promisify(exec);
|
|
15
|
+
var CODE_SERVER_VERSION = "4.96.4";
|
|
16
|
+
function getPlatformInfo() {
|
|
17
|
+
const platform = process.platform;
|
|
18
|
+
const arch = process.arch;
|
|
19
|
+
if (platform === "darwin") {
|
|
20
|
+
return {
|
|
21
|
+
platform: "macos",
|
|
22
|
+
arch: arch === "arm64" ? "arm64" : "amd64",
|
|
23
|
+
ext: "tar.gz"
|
|
24
|
+
};
|
|
25
|
+
} else if (platform === "linux") {
|
|
26
|
+
return {
|
|
27
|
+
platform: "linux",
|
|
28
|
+
arch: arch === "arm64" ? "arm64" : "amd64",
|
|
29
|
+
ext: "tar.gz"
|
|
30
|
+
};
|
|
31
|
+
} else {
|
|
32
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function getDownloadUrl() {
|
|
36
|
+
const { platform, arch, ext } = getPlatformInfo();
|
|
37
|
+
return `https://github.com/coder/code-server/releases/download/v${CODE_SERVER_VERSION}/code-server-${CODE_SERVER_VERSION}-${platform}-${arch}.${ext}`;
|
|
38
|
+
}
|
|
39
|
+
function getCodeServerDir() {
|
|
40
|
+
const { platform, arch } = getPlatformInfo();
|
|
41
|
+
return path2.join(CODE_DIR, `code-server-${CODE_SERVER_VERSION}-${platform}-${arch}`);
|
|
42
|
+
}
|
|
43
|
+
function getCodeServerBin() {
|
|
44
|
+
return path2.join(getCodeServerDir(), "bin", "code-server");
|
|
45
|
+
}
|
|
46
|
+
function isCodeServerInstalled() {
|
|
47
|
+
const binPath = getCodeServerBin();
|
|
48
|
+
return fs.existsSync(binPath);
|
|
49
|
+
}
|
|
50
|
+
async function installCodeServer() {
|
|
51
|
+
const { ext } = getPlatformInfo();
|
|
52
|
+
const downloadUrl = getDownloadUrl();
|
|
53
|
+
const tarballPath = path2.join(AMA_DIR, `code-server.${ext}`);
|
|
54
|
+
if (!fs.existsSync(AMA_DIR)) {
|
|
55
|
+
fs.mkdirSync(AMA_DIR, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
if (!fs.existsSync(CODE_DIR)) {
|
|
58
|
+
fs.mkdirSync(CODE_DIR, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
if (!fs.existsSync(STORAGE_DIR)) {
|
|
61
|
+
fs.mkdirSync(STORAGE_DIR, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
console.log(pc.cyan(`downloading code-server v${CODE_SERVER_VERSION}...`));
|
|
64
|
+
console.log(pc.gray(downloadUrl));
|
|
65
|
+
const response = await fetch(downloadUrl);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new Error(`Failed to download code-server: ${response.statusText}`);
|
|
68
|
+
}
|
|
69
|
+
const buffer = await response.arrayBuffer();
|
|
70
|
+
await fs.promises.writeFile(tarballPath, Buffer.from(buffer));
|
|
71
|
+
console.log(pc.cyan("Extracting code-server..."));
|
|
72
|
+
await execAsync(`tar -xzf ${tarballPath} -C ${CODE_DIR}`);
|
|
73
|
+
await fs.promises.unlink(tarballPath);
|
|
74
|
+
const binPath = getCodeServerBin();
|
|
75
|
+
if (fs.existsSync(binPath)) {
|
|
76
|
+
await fs.promises.chmod(binPath, 493);
|
|
77
|
+
}
|
|
78
|
+
console.log(pc.green("code-server installed successfully"));
|
|
79
|
+
}
|
|
80
|
+
async function killExistingCodeServer() {
|
|
81
|
+
try {
|
|
82
|
+
if (process.platform === "win32") {
|
|
83
|
+
await execAsync("netstat -ano | findstr :8081 | findstr LISTENING").then(async ({ stdout }) => {
|
|
84
|
+
const pid = stdout.trim().split(/\s+/).pop();
|
|
85
|
+
if (pid) await execAsync(`taskkill /PID ${pid} /F`);
|
|
86
|
+
}).catch(() => {
|
|
87
|
+
});
|
|
88
|
+
} else {
|
|
89
|
+
await execAsync("lsof -ti:8081").then(async ({ stdout }) => {
|
|
90
|
+
const pid = stdout.trim();
|
|
91
|
+
if (pid) await execAsync(`kill -9 ${pid}`);
|
|
92
|
+
}).catch(() => {
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
} catch {
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function setupDefaultSettings() {
|
|
99
|
+
const userDir = path2.join(STORAGE_DIR, "User");
|
|
100
|
+
const settingsPath = path2.join(userDir, "settings.json");
|
|
101
|
+
if (!fs.existsSync(userDir)) {
|
|
102
|
+
fs.mkdirSync(userDir, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
const defaultSettings = {
|
|
105
|
+
// Disable signature verification for Open VSX extensions
|
|
106
|
+
"extensions.verifySignature": false,
|
|
107
|
+
// Theme settings
|
|
108
|
+
"workbench.colorTheme": "Min Dark",
|
|
109
|
+
"workbench.startupEditor": "none",
|
|
110
|
+
// Editor settings
|
|
111
|
+
"editor.fontSize": 14,
|
|
112
|
+
"editor.fontFamily": "'JetBrains Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace",
|
|
113
|
+
"editor.minimap.enabled": false,
|
|
114
|
+
"editor.wordWrap": "on",
|
|
115
|
+
// UI settings
|
|
116
|
+
"window.menuBarVisibility": "compact",
|
|
117
|
+
"workbench.activityBar.location": "top"
|
|
118
|
+
};
|
|
119
|
+
let existingSettings = {};
|
|
120
|
+
if (fs.existsSync(settingsPath)) {
|
|
121
|
+
try {
|
|
122
|
+
const content = await fs.promises.readFile(settingsPath, "utf-8");
|
|
123
|
+
existingSettings = JSON.parse(content);
|
|
124
|
+
} catch {
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const mergedSettings = { ...defaultSettings, ...existingSettings };
|
|
128
|
+
mergedSettings["workbench.colorTheme"] = "Min Dark";
|
|
129
|
+
mergedSettings["extensions.verifySignature"] = false;
|
|
130
|
+
await fs.promises.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2));
|
|
131
|
+
console.log(pc.green("ama code-server settings configured"));
|
|
132
|
+
}
|
|
133
|
+
async function installExtensions() {
|
|
134
|
+
const binPath = getCodeServerBin();
|
|
135
|
+
const extensions = [
|
|
136
|
+
"castrogusttavo.min-theme"
|
|
137
|
+
];
|
|
138
|
+
for (const ext of extensions) {
|
|
139
|
+
try {
|
|
140
|
+
console.log(pc.cyan(`ama installing extension: ${ext}...`));
|
|
141
|
+
await execAsync(`"${binPath}" --user-data-dir "${STORAGE_DIR}" --install-extension ${ext}`);
|
|
142
|
+
console.log(pc.green(`ama extension ${ext} installed`));
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.log(pc.yellow(`ama failed to install extension ${ext}`), error);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function startCodeServer(cwd) {
|
|
149
|
+
const binPath = getCodeServerBin();
|
|
150
|
+
const workDir = cwd || process.cwd();
|
|
151
|
+
if (!fs.existsSync(binPath)) {
|
|
152
|
+
throw new Error("ama code-server is not installed. Run installCodeServer() first.");
|
|
153
|
+
}
|
|
154
|
+
await killExistingCodeServer();
|
|
155
|
+
await setupDefaultSettings();
|
|
156
|
+
await installExtensions();
|
|
157
|
+
const workspaceStoragePath = path2.join(STORAGE_DIR, "User", "workspaceStorage");
|
|
158
|
+
try {
|
|
159
|
+
if (fs.existsSync(workspaceStoragePath)) {
|
|
160
|
+
await fs.promises.rm(workspaceStoragePath, { recursive: true, force: true });
|
|
161
|
+
}
|
|
162
|
+
const stateDbPath = path2.join(STORAGE_DIR, "User", "globalStorage", "state.vscdb");
|
|
163
|
+
if (fs.existsSync(stateDbPath)) {
|
|
164
|
+
await fs.promises.unlink(stateDbPath);
|
|
165
|
+
}
|
|
166
|
+
} catch {
|
|
167
|
+
}
|
|
168
|
+
console.log(pc.cyan(`ama starting code-server`));
|
|
169
|
+
const codeServer = spawn(
|
|
170
|
+
binPath,
|
|
171
|
+
[
|
|
172
|
+
"--port",
|
|
173
|
+
"8081",
|
|
174
|
+
"--host",
|
|
175
|
+
"0.0.0.0",
|
|
176
|
+
"--auth",
|
|
177
|
+
"none",
|
|
178
|
+
"--user-data-dir",
|
|
179
|
+
STORAGE_DIR,
|
|
180
|
+
"--disable-workspace-trust",
|
|
181
|
+
workDir
|
|
182
|
+
],
|
|
183
|
+
{
|
|
184
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
console.log(pc.green(`ama code-server running at http://localhost:8081/?folder=${encodeURIComponent(workDir)}`));
|
|
188
|
+
return codeServer;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export { CODE_SERVER_VERSION, installCodeServer, isCodeServerInstalled, isCodeServerInstalled as isInstalled, startCodeServer };
|
|
@@ -1377,7 +1377,14 @@ var startHttpServer = () => {
|
|
|
1377
1377
|
app.get("/", (c) => {
|
|
1378
1378
|
return c.text("Hello World");
|
|
1379
1379
|
});
|
|
1380
|
-
nodeServer.serve({ fetch: app.fetch, port: 3456 });
|
|
1380
|
+
const server = nodeServer.serve({ fetch: app.fetch, port: 3456 });
|
|
1381
|
+
server.on("error", (err) => {
|
|
1382
|
+
if (err.code === "EADDRINUSE") {
|
|
1383
|
+
console.error(`[http] Port 3456 is already in use, skipping HTTP server`);
|
|
1384
|
+
} else {
|
|
1385
|
+
throw err;
|
|
1386
|
+
}
|
|
1387
|
+
});
|
|
1381
1388
|
};
|
|
1382
1389
|
var CREDENTIALS_DIR = path10__default.default.join(os3__default.default.homedir(), ".amai");
|
|
1383
1390
|
var CREDENTIALS_PATH = path10__default.default.join(CREDENTIALS_DIR, "credentials.json");
|
|
@@ -1396,8 +1403,24 @@ var getUserId = () => {
|
|
|
1396
1403
|
}
|
|
1397
1404
|
const raw = fs8__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1398
1405
|
const data = JSON.parse(raw);
|
|
1406
|
+
const fromUserObject = data.user?.id;
|
|
1407
|
+
const fromTopLevel = data.sub ?? data.user_id;
|
|
1408
|
+
let fromToken;
|
|
1409
|
+
if (data.access_token) {
|
|
1410
|
+
try {
|
|
1411
|
+
const payload = JSON.parse(
|
|
1412
|
+
Buffer.from(data.access_token.split(".")[1], "base64").toString("utf8")
|
|
1413
|
+
);
|
|
1414
|
+
fromToken = payload.sub ?? payload.user_id;
|
|
1415
|
+
} catch {
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
const userId = fromUserObject ?? fromTopLevel ?? fromToken;
|
|
1419
|
+
if (!userId) {
|
|
1420
|
+
throw new Error("User ID not found in credentials");
|
|
1421
|
+
}
|
|
1399
1422
|
return {
|
|
1400
|
-
userId
|
|
1423
|
+
userId
|
|
1401
1424
|
};
|
|
1402
1425
|
} catch {
|
|
1403
1426
|
throw new Error("Error while getting userId");
|
|
@@ -2507,8 +2530,7 @@ async function setupDefaultSettings() {
|
|
|
2507
2530
|
async function installExtensions() {
|
|
2508
2531
|
const binPath = getCodeServerBin();
|
|
2509
2532
|
const extensions = [
|
|
2510
|
-
"castrogusttavo.min-theme"
|
|
2511
|
-
"sourcegraph.amp"
|
|
2533
|
+
"castrogusttavo.min-theme"
|
|
2512
2534
|
];
|
|
2513
2535
|
for (const ext of extensions) {
|
|
2514
2536
|
try {
|
|
@@ -2584,7 +2606,7 @@ if (process.env.AMA_DAEMON === "1") {
|
|
|
2584
2606
|
}
|
|
2585
2607
|
await main();
|
|
2586
2608
|
} catch (error) {
|
|
2587
|
-
console.error(pc4__default.default.red(
|
|
2609
|
+
console.error(pc4__default.default.red(`daemon error: ${error?.message ?? error}`));
|
|
2588
2610
|
process.exit(1);
|
|
2589
2611
|
}
|
|
2590
2612
|
})();
|
package/dist/lib/daemon-entry.js
CHANGED
|
@@ -1366,7 +1366,14 @@ var startHttpServer = () => {
|
|
|
1366
1366
|
app.get("/", (c) => {
|
|
1367
1367
|
return c.text("Hello World");
|
|
1368
1368
|
});
|
|
1369
|
-
serve({ fetch: app.fetch, port: 3456 });
|
|
1369
|
+
const server = serve({ fetch: app.fetch, port: 3456 });
|
|
1370
|
+
server.on("error", (err) => {
|
|
1371
|
+
if (err.code === "EADDRINUSE") {
|
|
1372
|
+
console.error(`[http] Port 3456 is already in use, skipping HTTP server`);
|
|
1373
|
+
} else {
|
|
1374
|
+
throw err;
|
|
1375
|
+
}
|
|
1376
|
+
});
|
|
1370
1377
|
};
|
|
1371
1378
|
var CREDENTIALS_DIR = path10.join(os3.homedir(), ".amai");
|
|
1372
1379
|
var CREDENTIALS_PATH = path10.join(CREDENTIALS_DIR, "credentials.json");
|
|
@@ -1385,8 +1392,24 @@ var getUserId = () => {
|
|
|
1385
1392
|
}
|
|
1386
1393
|
const raw = fs8.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1387
1394
|
const data = JSON.parse(raw);
|
|
1395
|
+
const fromUserObject = data.user?.id;
|
|
1396
|
+
const fromTopLevel = data.sub ?? data.user_id;
|
|
1397
|
+
let fromToken;
|
|
1398
|
+
if (data.access_token) {
|
|
1399
|
+
try {
|
|
1400
|
+
const payload = JSON.parse(
|
|
1401
|
+
Buffer.from(data.access_token.split(".")[1], "base64").toString("utf8")
|
|
1402
|
+
);
|
|
1403
|
+
fromToken = payload.sub ?? payload.user_id;
|
|
1404
|
+
} catch {
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
const userId = fromUserObject ?? fromTopLevel ?? fromToken;
|
|
1408
|
+
if (!userId) {
|
|
1409
|
+
throw new Error("User ID not found in credentials");
|
|
1410
|
+
}
|
|
1388
1411
|
return {
|
|
1389
|
-
userId
|
|
1412
|
+
userId
|
|
1390
1413
|
};
|
|
1391
1414
|
} catch {
|
|
1392
1415
|
throw new Error("Error while getting userId");
|
|
@@ -2496,8 +2519,7 @@ async function setupDefaultSettings() {
|
|
|
2496
2519
|
async function installExtensions() {
|
|
2497
2520
|
const binPath = getCodeServerBin();
|
|
2498
2521
|
const extensions = [
|
|
2499
|
-
"castrogusttavo.min-theme"
|
|
2500
|
-
"sourcegraph.amp"
|
|
2522
|
+
"castrogusttavo.min-theme"
|
|
2501
2523
|
];
|
|
2502
2524
|
for (const ext of extensions) {
|
|
2503
2525
|
try {
|
|
@@ -2573,7 +2595,7 @@ if (process.env.AMA_DAEMON === "1") {
|
|
|
2573
2595
|
}
|
|
2574
2596
|
await main();
|
|
2575
2597
|
} catch (error) {
|
|
2576
|
-
console.error(pc4.red(
|
|
2598
|
+
console.error(pc4.red(`daemon error: ${error?.message ?? error}`));
|
|
2577
2599
|
process.exit(1);
|
|
2578
2600
|
}
|
|
2579
2601
|
})();
|
package/dist/server.cjs
CHANGED
|
@@ -1377,7 +1377,14 @@ var startHttpServer = () => {
|
|
|
1377
1377
|
app.get("/", (c) => {
|
|
1378
1378
|
return c.text("Hello World");
|
|
1379
1379
|
});
|
|
1380
|
-
nodeServer.serve({ fetch: app.fetch, port: 3456 });
|
|
1380
|
+
const server = nodeServer.serve({ fetch: app.fetch, port: 3456 });
|
|
1381
|
+
server.on("error", (err) => {
|
|
1382
|
+
if (err.code === "EADDRINUSE") {
|
|
1383
|
+
console.error(`[http] Port 3456 is already in use, skipping HTTP server`);
|
|
1384
|
+
} else {
|
|
1385
|
+
throw err;
|
|
1386
|
+
}
|
|
1387
|
+
});
|
|
1381
1388
|
};
|
|
1382
1389
|
var CREDENTIALS_DIR = path10__default.default.join(os3__default.default.homedir(), ".amai");
|
|
1383
1390
|
var CREDENTIALS_PATH = path10__default.default.join(CREDENTIALS_DIR, "credentials.json");
|
|
@@ -1396,8 +1403,24 @@ var getUserId = () => {
|
|
|
1396
1403
|
}
|
|
1397
1404
|
const raw = fs6__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1398
1405
|
const data = JSON.parse(raw);
|
|
1406
|
+
const fromUserObject = data.user?.id;
|
|
1407
|
+
const fromTopLevel = data.sub ?? data.user_id;
|
|
1408
|
+
let fromToken;
|
|
1409
|
+
if (data.access_token) {
|
|
1410
|
+
try {
|
|
1411
|
+
const payload = JSON.parse(
|
|
1412
|
+
Buffer.from(data.access_token.split(".")[1], "base64").toString("utf8")
|
|
1413
|
+
);
|
|
1414
|
+
fromToken = payload.sub ?? payload.user_id;
|
|
1415
|
+
} catch {
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
const userId = fromUserObject ?? fromTopLevel ?? fromToken;
|
|
1419
|
+
if (!userId) {
|
|
1420
|
+
throw new Error("User ID not found in credentials");
|
|
1421
|
+
}
|
|
1399
1422
|
return {
|
|
1400
|
-
userId
|
|
1423
|
+
userId
|
|
1401
1424
|
};
|
|
1402
1425
|
} catch {
|
|
1403
1426
|
throw new Error("Error while getting userId");
|
package/dist/server.js
CHANGED
|
@@ -1366,7 +1366,14 @@ var startHttpServer = () => {
|
|
|
1366
1366
|
app.get("/", (c) => {
|
|
1367
1367
|
return c.text("Hello World");
|
|
1368
1368
|
});
|
|
1369
|
-
serve({ fetch: app.fetch, port: 3456 });
|
|
1369
|
+
const server = serve({ fetch: app.fetch, port: 3456 });
|
|
1370
|
+
server.on("error", (err) => {
|
|
1371
|
+
if (err.code === "EADDRINUSE") {
|
|
1372
|
+
console.error(`[http] Port 3456 is already in use, skipping HTTP server`);
|
|
1373
|
+
} else {
|
|
1374
|
+
throw err;
|
|
1375
|
+
}
|
|
1376
|
+
});
|
|
1370
1377
|
};
|
|
1371
1378
|
var CREDENTIALS_DIR = path10.join(os3.homedir(), ".amai");
|
|
1372
1379
|
var CREDENTIALS_PATH = path10.join(CREDENTIALS_DIR, "credentials.json");
|
|
@@ -1385,8 +1392,24 @@ var getUserId = () => {
|
|
|
1385
1392
|
}
|
|
1386
1393
|
const raw = fs6.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1387
1394
|
const data = JSON.parse(raw);
|
|
1395
|
+
const fromUserObject = data.user?.id;
|
|
1396
|
+
const fromTopLevel = data.sub ?? data.user_id;
|
|
1397
|
+
let fromToken;
|
|
1398
|
+
if (data.access_token) {
|
|
1399
|
+
try {
|
|
1400
|
+
const payload = JSON.parse(
|
|
1401
|
+
Buffer.from(data.access_token.split(".")[1], "base64").toString("utf8")
|
|
1402
|
+
);
|
|
1403
|
+
fromToken = payload.sub ?? payload.user_id;
|
|
1404
|
+
} catch {
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
const userId = fromUserObject ?? fromTopLevel ?? fromToken;
|
|
1408
|
+
if (!userId) {
|
|
1409
|
+
throw new Error("User ID not found in credentials");
|
|
1410
|
+
}
|
|
1388
1411
|
return {
|
|
1389
|
-
userId
|
|
1412
|
+
userId
|
|
1390
1413
|
};
|
|
1391
1414
|
} catch {
|
|
1392
1415
|
throw new Error("Error while getting userId");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amai",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.16",
|
|
5
5
|
"description": "ama cli",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ama",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"local",
|
|
11
11
|
"tools"
|
|
12
12
|
],
|
|
13
|
-
"author": "",
|
|
14
|
-
"license": "
|
|
13
|
+
"author": "Shujan Shaikh",
|
|
14
|
+
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git"
|
|
17
17
|
},
|
|
@@ -28,7 +28,12 @@
|
|
|
28
28
|
"require": "./dist/server.cjs"
|
|
29
29
|
},
|
|
30
30
|
"./dist/*": "./dist/*.js",
|
|
31
|
-
"./dist/*.js": "./dist/*.js"
|
|
31
|
+
"./dist/*.js": "./dist/*.js",
|
|
32
|
+
"./lib/code-server": {
|
|
33
|
+
"types": "./dist/lib/code-server.d.ts",
|
|
34
|
+
"import": "./dist/lib/code-server.js",
|
|
35
|
+
"require": "./dist/lib/code-server.cjs"
|
|
36
|
+
}
|
|
32
37
|
},
|
|
33
38
|
"browser": "dist/client.global.js",
|
|
34
39
|
"files": [
|
|
@@ -59,4 +64,4 @@
|
|
|
59
64
|
"publishConfig": {
|
|
60
65
|
"access": "public"
|
|
61
66
|
}
|
|
62
|
-
}
|
|
67
|
+
}
|