amai 0.0.8 → 0.0.10
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 +361 -206
- package/dist/cli.js +359 -204
- package/dist/lib/daemon-entry.cjs +169 -90
- package/dist/lib/daemon-entry.js +166 -87
- package/dist/server.cjs +52 -24
- package/dist/server.js +51 -23
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -6,7 +6,7 @@ var WebSocket = require('ws');
|
|
|
6
6
|
var zod = require('zod');
|
|
7
7
|
var fs5 = require('fs/promises');
|
|
8
8
|
var path10 = require('path');
|
|
9
|
-
var
|
|
9
|
+
var fs6 = require('fs');
|
|
10
10
|
var os3 = require('os');
|
|
11
11
|
var child_process = require('child_process');
|
|
12
12
|
var util = require('util');
|
|
@@ -23,7 +23,7 @@ var pc5__default = /*#__PURE__*/_interopDefault(pc5);
|
|
|
23
23
|
var WebSocket__default = /*#__PURE__*/_interopDefault(WebSocket);
|
|
24
24
|
var fs5__default = /*#__PURE__*/_interopDefault(fs5);
|
|
25
25
|
var path10__default = /*#__PURE__*/_interopDefault(path10);
|
|
26
|
-
var
|
|
26
|
+
var fs6__default = /*#__PURE__*/_interopDefault(fs6);
|
|
27
27
|
var os3__default = /*#__PURE__*/_interopDefault(os3);
|
|
28
28
|
var readline__default = /*#__PURE__*/_interopDefault(readline);
|
|
29
29
|
|
|
@@ -42,14 +42,14 @@ var ProjectRegistry = class {
|
|
|
42
42
|
}
|
|
43
43
|
load() {
|
|
44
44
|
try {
|
|
45
|
-
if (
|
|
46
|
-
const data =
|
|
45
|
+
if (fs6__default.default.existsSync(REGISTRY_FILE)) {
|
|
46
|
+
const data = fs6__default.default.readFileSync(REGISTRY_FILE, "utf8");
|
|
47
47
|
const parsed = JSON.parse(data);
|
|
48
48
|
if (!Array.isArray(parsed)) {
|
|
49
49
|
console.error("Invalid project registry format: expected array, got", typeof parsed);
|
|
50
50
|
const backupFile = REGISTRY_FILE + ".backup." + Date.now();
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
fs6__default.default.copyFileSync(REGISTRY_FILE, backupFile);
|
|
52
|
+
fs6__default.default.unlinkSync(REGISTRY_FILE);
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
const projects = parsed;
|
|
@@ -62,11 +62,11 @@ var ProjectRegistry = class {
|
|
|
62
62
|
}
|
|
63
63
|
} catch (error) {
|
|
64
64
|
console.error("Failed to load project registry:", error);
|
|
65
|
-
if (
|
|
65
|
+
if (fs6__default.default.existsSync(REGISTRY_FILE)) {
|
|
66
66
|
try {
|
|
67
67
|
const backupFile = REGISTRY_FILE + ".backup." + Date.now();
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
fs6__default.default.copyFileSync(REGISTRY_FILE, backupFile);
|
|
69
|
+
fs6__default.default.unlinkSync(REGISTRY_FILE);
|
|
70
70
|
console.log("Corrupted registry file backed up and removed. Starting fresh.");
|
|
71
71
|
} catch (backupError) {
|
|
72
72
|
}
|
|
@@ -75,11 +75,11 @@ var ProjectRegistry = class {
|
|
|
75
75
|
}
|
|
76
76
|
save() {
|
|
77
77
|
try {
|
|
78
|
-
if (!
|
|
79
|
-
|
|
78
|
+
if (!fs6__default.default.existsSync(AMA_DIR)) {
|
|
79
|
+
fs6__default.default.mkdirSync(AMA_DIR, { recursive: true });
|
|
80
80
|
}
|
|
81
81
|
const projects = Array.from(this.projects.values());
|
|
82
|
-
|
|
82
|
+
fs6__default.default.writeFileSync(REGISTRY_FILE, JSON.stringify(projects, null, 2), "utf8");
|
|
83
83
|
} catch (error) {
|
|
84
84
|
console.error("Failed to save project registry:", error);
|
|
85
85
|
}
|
|
@@ -747,20 +747,20 @@ var editFiles = async function(input, projectCwd) {
|
|
|
747
747
|
let existingContent = "";
|
|
748
748
|
if (isNewFile === void 0) {
|
|
749
749
|
try {
|
|
750
|
-
existingContent = await
|
|
750
|
+
existingContent = await fs6__default.default.promises.readFile(filePath, "utf-8");
|
|
751
751
|
isNewFile = false;
|
|
752
752
|
} catch (error) {
|
|
753
753
|
isNewFile = true;
|
|
754
754
|
}
|
|
755
755
|
} else if (!isNewFile) {
|
|
756
756
|
try {
|
|
757
|
-
existingContent = await
|
|
757
|
+
existingContent = await fs6__default.default.promises.readFile(filePath, "utf-8");
|
|
758
758
|
} catch (error) {
|
|
759
759
|
isNewFile = true;
|
|
760
760
|
}
|
|
761
761
|
}
|
|
762
762
|
try {
|
|
763
|
-
await
|
|
763
|
+
await fs6__default.default.promises.writeFile(filePath, content);
|
|
764
764
|
} catch (writeError) {
|
|
765
765
|
throw writeError;
|
|
766
766
|
}
|
|
@@ -1139,6 +1139,9 @@ var list = async function(input, projectCwd) {
|
|
|
1139
1139
|
var startHttpServer = () => {
|
|
1140
1140
|
const app = new hono.Hono();
|
|
1141
1141
|
app.use(cors.cors());
|
|
1142
|
+
app.get("/", (c) => {
|
|
1143
|
+
return c.text("Hello World");
|
|
1144
|
+
});
|
|
1142
1145
|
nodeServer.serve({ fetch: app.fetch, port: 3456 });
|
|
1143
1146
|
};
|
|
1144
1147
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -1146,10 +1149,10 @@ var CREDENTIALS_DIR = path10__default.default.join(os3__default.default.homedir(
|
|
|
1146
1149
|
var CREDENTIALS_PATH = path10__default.default.join(CREDENTIALS_DIR, "credentials.json");
|
|
1147
1150
|
function isAuthenticated() {
|
|
1148
1151
|
try {
|
|
1149
|
-
if (!
|
|
1152
|
+
if (!fs6__default.default.existsSync(CREDENTIALS_PATH)) {
|
|
1150
1153
|
return false;
|
|
1151
1154
|
}
|
|
1152
|
-
const raw =
|
|
1155
|
+
const raw = fs6__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1153
1156
|
const data = JSON.parse(raw);
|
|
1154
1157
|
return Boolean(data && data.access_token);
|
|
1155
1158
|
} catch {
|
|
@@ -1158,10 +1161,10 @@ function isAuthenticated() {
|
|
|
1158
1161
|
}
|
|
1159
1162
|
function saveTokens(tokens) {
|
|
1160
1163
|
try {
|
|
1161
|
-
if (!
|
|
1162
|
-
|
|
1164
|
+
if (!fs6__default.default.existsSync(CREDENTIALS_DIR)) {
|
|
1165
|
+
fs6__default.default.mkdirSync(CREDENTIALS_DIR, { recursive: true });
|
|
1163
1166
|
}
|
|
1164
|
-
|
|
1167
|
+
fs6__default.default.writeFileSync(
|
|
1165
1168
|
CREDENTIALS_PATH,
|
|
1166
1169
|
JSON.stringify(tokens, null, 2),
|
|
1167
1170
|
"utf8"
|
|
@@ -1172,18 +1175,18 @@ function saveTokens(tokens) {
|
|
|
1172
1175
|
}
|
|
1173
1176
|
function logout() {
|
|
1174
1177
|
try {
|
|
1175
|
-
if (
|
|
1176
|
-
|
|
1178
|
+
if (fs6__default.default.existsSync(CREDENTIALS_PATH)) {
|
|
1179
|
+
fs6__default.default.unlinkSync(CREDENTIALS_PATH);
|
|
1177
1180
|
}
|
|
1178
1181
|
} catch (error) {
|
|
1179
1182
|
console.error(pc5__default.default.red("Failed to logout"), error);
|
|
1180
1183
|
}
|
|
1181
1184
|
}
|
|
1182
1185
|
function getTokens() {
|
|
1183
|
-
if (!
|
|
1186
|
+
if (!fs6__default.default.existsSync(CREDENTIALS_PATH)) {
|
|
1184
1187
|
return null;
|
|
1185
1188
|
}
|
|
1186
|
-
const raw =
|
|
1189
|
+
const raw = fs6__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1187
1190
|
const data = JSON.parse(raw);
|
|
1188
1191
|
return data;
|
|
1189
1192
|
}
|
|
@@ -1251,30 +1254,19 @@ async function pollForTokens({
|
|
|
1251
1254
|
async function login() {
|
|
1252
1255
|
try {
|
|
1253
1256
|
const device = await authorizeDevice();
|
|
1254
|
-
console.log(
|
|
1257
|
+
console.log("");
|
|
1255
1258
|
if (device.verification_uri_complete) {
|
|
1256
|
-
console.log(
|
|
1257
|
-
` 1. Open this URL in your browser: ${pc5__default.default.cyan(
|
|
1258
|
-
device.verification_uri_complete
|
|
1259
|
-
)}`
|
|
1260
|
-
);
|
|
1259
|
+
console.log(pc5__default.default.cyan(`open: ${device.verification_uri_complete}`));
|
|
1261
1260
|
} else {
|
|
1262
|
-
console.log(
|
|
1263
|
-
|
|
1264
|
-
device.verification_uri
|
|
1265
|
-
)}`
|
|
1266
|
-
);
|
|
1267
|
-
console.log(
|
|
1268
|
-
` 2. Enter this code when prompted: ${pc5__default.default.bold(device.user_code)}`
|
|
1269
|
-
);
|
|
1261
|
+
console.log(pc5__default.default.cyan(`open: ${device.verification_uri}`));
|
|
1262
|
+
console.log(pc5__default.default.gray(`code: ${device.user_code}`));
|
|
1270
1263
|
}
|
|
1271
|
-
console.log("
|
|
1272
|
-
console.log();
|
|
1264
|
+
console.log("");
|
|
1273
1265
|
console.log(
|
|
1274
1266
|
pc5__default.default.gray(
|
|
1275
|
-
`
|
|
1267
|
+
`waiting for authorization (~${Math.round(
|
|
1276
1268
|
device.expires_in / 60
|
|
1277
|
-
)}
|
|
1269
|
+
)} min)...`
|
|
1278
1270
|
)
|
|
1279
1271
|
);
|
|
1280
1272
|
const tokens = await pollForTokens({
|
|
@@ -1283,20 +1275,20 @@ async function login() {
|
|
|
1283
1275
|
expiresIn: device.expires_in,
|
|
1284
1276
|
interval: device.interval
|
|
1285
1277
|
});
|
|
1286
|
-
console.log(pc5__default.default.
|
|
1278
|
+
console.log(pc5__default.default.cyan("authenticated"));
|
|
1287
1279
|
saveTokens(tokens);
|
|
1288
1280
|
return tokens;
|
|
1289
1281
|
} catch (error) {
|
|
1290
|
-
console.error(pc5__default.default.red(error.message || "
|
|
1282
|
+
console.error(pc5__default.default.red(error.message || "login failed"));
|
|
1291
1283
|
throw error;
|
|
1292
1284
|
}
|
|
1293
1285
|
}
|
|
1294
1286
|
var getUserId = () => {
|
|
1295
1287
|
try {
|
|
1296
|
-
if (!
|
|
1288
|
+
if (!fs6__default.default.existsSync(CREDENTIALS_PATH)) {
|
|
1297
1289
|
return;
|
|
1298
1290
|
}
|
|
1299
|
-
const raw =
|
|
1291
|
+
const raw = fs6__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
|
|
1300
1292
|
const data = JSON.parse(raw);
|
|
1301
1293
|
return {
|
|
1302
1294
|
userId: data.user.id
|
|
@@ -1443,7 +1435,7 @@ var runTerminalCommand = async (input, projectCwd) => {
|
|
|
1443
1435
|
};
|
|
1444
1436
|
var ignoreFiles = ["node_modules", ".git", ".next", ".env", ".env.local", ".env.development.local", ".env.test.local", ".env.production.local"];
|
|
1445
1437
|
var getContext = (dir, base = dir, allFiles = []) => {
|
|
1446
|
-
const filePath =
|
|
1438
|
+
const filePath = fs6.readdirSync(dir, { withFileTypes: true });
|
|
1447
1439
|
for (const file of filePath) {
|
|
1448
1440
|
if (ignoreFiles.includes(file.name)) continue;
|
|
1449
1441
|
const fullPath = path10__default.default.join(dir, file.name);
|
|
@@ -1475,16 +1467,16 @@ function getWorkspaceStoragePath(ide) {
|
|
|
1475
1467
|
function scanWorkspaceStorage(ide) {
|
|
1476
1468
|
const projects = [];
|
|
1477
1469
|
const storagePath = getWorkspaceStoragePath();
|
|
1478
|
-
if (!
|
|
1470
|
+
if (!fs6__default.default.existsSync(storagePath)) {
|
|
1479
1471
|
return projects;
|
|
1480
1472
|
}
|
|
1481
1473
|
try {
|
|
1482
|
-
const workspaces =
|
|
1474
|
+
const workspaces = fs6__default.default.readdirSync(storagePath);
|
|
1483
1475
|
for (const workspace of workspaces) {
|
|
1484
1476
|
const workspaceJsonPath = path10__default.default.join(storagePath, workspace, "workspace.json");
|
|
1485
|
-
if (
|
|
1477
|
+
if (fs6__default.default.existsSync(workspaceJsonPath)) {
|
|
1486
1478
|
try {
|
|
1487
|
-
const content =
|
|
1479
|
+
const content = fs6__default.default.readFileSync(workspaceJsonPath, "utf-8");
|
|
1488
1480
|
const data = JSON.parse(content);
|
|
1489
1481
|
if (data.folder && typeof data.folder === "string") {
|
|
1490
1482
|
let projectPath = data.folder;
|
|
@@ -1492,7 +1484,7 @@ function scanWorkspaceStorage(ide) {
|
|
|
1492
1484
|
projectPath = projectPath.replace("file://", "");
|
|
1493
1485
|
projectPath = decodeURIComponent(projectPath);
|
|
1494
1486
|
}
|
|
1495
|
-
if (
|
|
1487
|
+
if (fs6__default.default.existsSync(projectPath) && fs6__default.default.statSync(projectPath).isDirectory()) {
|
|
1496
1488
|
projects.push({
|
|
1497
1489
|
name: path10__default.default.basename(projectPath),
|
|
1498
1490
|
path: projectPath,
|
|
@@ -1516,11 +1508,11 @@ var scanIdeProjects = async () => {
|
|
|
1516
1508
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
1517
1509
|
const addProject = (projectPath, ide) => {
|
|
1518
1510
|
try {
|
|
1519
|
-
const resolvedPath =
|
|
1520
|
-
if (
|
|
1511
|
+
const resolvedPath = fs6__default.default.realpathSync(projectPath);
|
|
1512
|
+
if (fs6__default.default.existsSync(resolvedPath) && fs6__default.default.statSync(resolvedPath).isDirectory() && !seenPaths.has(resolvedPath)) {
|
|
1521
1513
|
const isIdeProjectsDir = Object.values(IDE_PROJECTS_PATHS).some((ideDir) => {
|
|
1522
1514
|
try {
|
|
1523
|
-
return
|
|
1515
|
+
return fs6__default.default.realpathSync(ideDir) === resolvedPath;
|
|
1524
1516
|
} catch {
|
|
1525
1517
|
return false;
|
|
1526
1518
|
}
|
|
@@ -1543,30 +1535,30 @@ var scanIdeProjects = async () => {
|
|
|
1543
1535
|
}
|
|
1544
1536
|
for (const [ide, dirPath] of Object.entries(IDE_PROJECTS_PATHS)) {
|
|
1545
1537
|
if (ide === "cursor") continue;
|
|
1546
|
-
if (
|
|
1547
|
-
const projects =
|
|
1538
|
+
if (fs6__default.default.existsSync(dirPath)) {
|
|
1539
|
+
const projects = fs6__default.default.readdirSync(dirPath);
|
|
1548
1540
|
projects.forEach((project) => {
|
|
1549
1541
|
const projectPath = path10__default.default.join(dirPath, project);
|
|
1550
1542
|
try {
|
|
1551
|
-
const stats =
|
|
1543
|
+
const stats = fs6__default.default.lstatSync(projectPath);
|
|
1552
1544
|
let actualPath = null;
|
|
1553
1545
|
if (stats.isSymbolicLink()) {
|
|
1554
|
-
actualPath =
|
|
1546
|
+
actualPath = fs6__default.default.realpathSync(projectPath);
|
|
1555
1547
|
} else if (stats.isFile()) {
|
|
1556
1548
|
try {
|
|
1557
|
-
let content =
|
|
1549
|
+
let content = fs6__default.default.readFileSync(projectPath, "utf-8").trim();
|
|
1558
1550
|
if (content.startsWith("~/") || content === "~") {
|
|
1559
1551
|
content = content.replace(/^~/, HOME);
|
|
1560
1552
|
}
|
|
1561
1553
|
const resolvedContent = path10__default.default.isAbsolute(content) ? content : path10__default.default.resolve(path10__default.default.dirname(projectPath), content);
|
|
1562
|
-
if (
|
|
1563
|
-
actualPath =
|
|
1554
|
+
if (fs6__default.default.existsSync(resolvedContent) && fs6__default.default.statSync(resolvedContent).isDirectory()) {
|
|
1555
|
+
actualPath = fs6__default.default.realpathSync(resolvedContent);
|
|
1564
1556
|
}
|
|
1565
1557
|
} catch {
|
|
1566
1558
|
return;
|
|
1567
1559
|
}
|
|
1568
1560
|
} else if (stats.isDirectory()) {
|
|
1569
|
-
actualPath =
|
|
1561
|
+
actualPath = fs6__default.default.realpathSync(projectPath);
|
|
1570
1562
|
}
|
|
1571
1563
|
if (actualPath) {
|
|
1572
1564
|
addProject(actualPath, ide);
|
|
@@ -1981,7 +1973,19 @@ var rpcHandlers = {
|
|
|
1981
1973
|
return { success: true, diff };
|
|
1982
1974
|
}
|
|
1983
1975
|
};
|
|
1976
|
+
var INITIAL_RECONNECT_DELAY = 1e3;
|
|
1977
|
+
var MAX_RECONNECT_DELAY = 6e4;
|
|
1978
|
+
var BACKOFF_MULTIPLIER = 2;
|
|
1984
1979
|
var reconnectTimeout = null;
|
|
1980
|
+
var reconnectAttempts = 0;
|
|
1981
|
+
function getReconnectDelay() {
|
|
1982
|
+
const delay = Math.min(
|
|
1983
|
+
INITIAL_RECONNECT_DELAY * Math.pow(BACKOFF_MULTIPLIER, reconnectAttempts),
|
|
1984
|
+
MAX_RECONNECT_DELAY
|
|
1985
|
+
);
|
|
1986
|
+
const jitter = delay * 0.25 * (Math.random() * 2 - 1);
|
|
1987
|
+
return Math.floor(delay + jitter);
|
|
1988
|
+
}
|
|
1985
1989
|
var connectToUserStreams = async (serverUrl) => {
|
|
1986
1990
|
const userId = getUserId();
|
|
1987
1991
|
if (!userId?.userId) {
|
|
@@ -2002,7 +2006,8 @@ var connectToUserStreams = async (serverUrl) => {
|
|
|
2002
2006
|
}
|
|
2003
2007
|
});
|
|
2004
2008
|
ws.on("open", () => {
|
|
2005
|
-
|
|
2009
|
+
reconnectAttempts = 0;
|
|
2010
|
+
console.log(pc5__default.default.cyan("connected to user streams"));
|
|
2006
2011
|
if (reconnectTimeout) {
|
|
2007
2012
|
clearTimeout(reconnectTimeout);
|
|
2008
2013
|
reconnectTimeout = null;
|
|
@@ -2013,7 +2018,7 @@ var connectToUserStreams = async (serverUrl) => {
|
|
|
2013
2018
|
const message = JSON.parse(event.toString());
|
|
2014
2019
|
if (message._tag === "rpc_call") {
|
|
2015
2020
|
const { requestId, method, input } = message;
|
|
2016
|
-
console.log(pc5__default.default.gray(
|
|
2021
|
+
console.log(pc5__default.default.gray(`> ${method}`));
|
|
2017
2022
|
const handler = rpcHandlers[method];
|
|
2018
2023
|
if (!handler) {
|
|
2019
2024
|
ws.send(JSON.stringify({
|
|
@@ -2024,7 +2029,6 @@ var connectToUserStreams = async (serverUrl) => {
|
|
|
2024
2029
|
message: `Unknown RPC method: ${method}`
|
|
2025
2030
|
}
|
|
2026
2031
|
}));
|
|
2027
|
-
console.log(pc5__default.default.yellow(`Unknown RPC method: ${method}`));
|
|
2028
2032
|
return;
|
|
2029
2033
|
}
|
|
2030
2034
|
try {
|
|
@@ -2034,7 +2038,6 @@ var connectToUserStreams = async (serverUrl) => {
|
|
|
2034
2038
|
requestId,
|
|
2035
2039
|
data: result
|
|
2036
2040
|
}));
|
|
2037
|
-
console.log(pc5__default.default.green(`RPC completed: ${method}`));
|
|
2038
2041
|
} catch (error) {
|
|
2039
2042
|
const rpcError = error._tag ? error : {
|
|
2040
2043
|
_tag: "RpcError",
|
|
@@ -2045,7 +2048,7 @@ var connectToUserStreams = async (serverUrl) => {
|
|
|
2045
2048
|
requestId,
|
|
2046
2049
|
data: rpcError
|
|
2047
2050
|
}));
|
|
2048
|
-
console.log(pc5__default.default.red(`
|
|
2051
|
+
console.log(pc5__default.default.red(` ${method} failed`));
|
|
2049
2052
|
}
|
|
2050
2053
|
return;
|
|
2051
2054
|
}
|
|
@@ -2064,25 +2067,38 @@ var connectToUserStreams = async (serverUrl) => {
|
|
|
2064
2067
|
}
|
|
2065
2068
|
}
|
|
2066
2069
|
} catch (parseError) {
|
|
2067
|
-
console.error(pc5__default.default.red(`
|
|
2070
|
+
console.error(pc5__default.default.red(`parse error`));
|
|
2068
2071
|
}
|
|
2069
2072
|
});
|
|
2070
2073
|
ws.on("close", (code, reason) => {
|
|
2071
|
-
|
|
2072
|
-
|
|
2074
|
+
const delay = getReconnectDelay();
|
|
2075
|
+
reconnectAttempts++;
|
|
2076
|
+
console.log(pc5__default.default.gray(`user streams disconnected, reconnecting in ${Math.round(delay / 1e3)}s...`));
|
|
2073
2077
|
reconnectTimeout = setTimeout(() => {
|
|
2074
2078
|
connectToUserStreams(serverUrl).catch((err) => {
|
|
2075
|
-
console.error(pc5__default.default.red(`
|
|
2079
|
+
console.error(pc5__default.default.red(`reconnection failed`));
|
|
2076
2080
|
});
|
|
2077
|
-
},
|
|
2081
|
+
}, delay);
|
|
2078
2082
|
});
|
|
2079
2083
|
ws.on("error", (error) => {
|
|
2080
|
-
console.error(pc5__default.default.red(`
|
|
2084
|
+
console.error(pc5__default.default.red(`stream error: ${error.message}`));
|
|
2081
2085
|
});
|
|
2082
2086
|
return ws;
|
|
2083
2087
|
};
|
|
2084
2088
|
|
|
2085
2089
|
// src/server.ts
|
|
2090
|
+
var INITIAL_RECONNECT_DELAY2 = 1e3;
|
|
2091
|
+
var MAX_RECONNECT_DELAY2 = 6e4;
|
|
2092
|
+
var BACKOFF_MULTIPLIER2 = 2;
|
|
2093
|
+
var reconnectAttempts2 = 0;
|
|
2094
|
+
function getReconnectDelay2() {
|
|
2095
|
+
const delay = Math.min(
|
|
2096
|
+
INITIAL_RECONNECT_DELAY2 * Math.pow(BACKOFF_MULTIPLIER2, reconnectAttempts2),
|
|
2097
|
+
MAX_RECONNECT_DELAY2
|
|
2098
|
+
);
|
|
2099
|
+
const jitter = delay * 0.25 * (Math.random() * 2 - 1);
|
|
2100
|
+
return Math.floor(delay + jitter);
|
|
2101
|
+
}
|
|
2086
2102
|
var toolExecutors = {
|
|
2087
2103
|
editFile: editFiles,
|
|
2088
2104
|
deleteFile,
|
|
@@ -2105,12 +2121,13 @@ function connectToServer(serverUrl = DEFAULT_SERVER_URL) {
|
|
|
2105
2121
|
}
|
|
2106
2122
|
});
|
|
2107
2123
|
ws.on("open", () => {
|
|
2108
|
-
|
|
2124
|
+
reconnectAttempts2 = 0;
|
|
2125
|
+
console.log(pc5__default.default.cyan("connected to server"));
|
|
2109
2126
|
});
|
|
2110
2127
|
ws.on("message", async (data) => {
|
|
2111
2128
|
const message = JSON.parse(data.toString());
|
|
2112
2129
|
if (message.type === "tool_call") {
|
|
2113
|
-
console.log(
|
|
2130
|
+
console.log(pc5__default.default.gray(`> ${message.tool}`));
|
|
2114
2131
|
try {
|
|
2115
2132
|
const executor = toolExecutors[message.tool];
|
|
2116
2133
|
if (!executor) {
|
|
@@ -2122,17 +2139,16 @@ function connectToServer(serverUrl = DEFAULT_SERVER_URL) {
|
|
|
2122
2139
|
id: message.id,
|
|
2123
2140
|
result
|
|
2124
2141
|
}));
|
|
2125
|
-
console.log(pc5__default.default.green(`tool call completed: ${message.tool}`));
|
|
2126
2142
|
} catch (error) {
|
|
2127
2143
|
ws.send(JSON.stringify({
|
|
2128
2144
|
type: "tool_result",
|
|
2129
2145
|
id: message.id,
|
|
2130
2146
|
error: error.message
|
|
2131
2147
|
}));
|
|
2132
|
-
console.error(pc5__default.default.red(`
|
|
2148
|
+
console.error(pc5__default.default.red(` ${message.tool} failed: ${error.message}`));
|
|
2133
2149
|
}
|
|
2134
2150
|
} else if (message.type === "rpc_call") {
|
|
2135
|
-
console.log(
|
|
2151
|
+
console.log(pc5__default.default.gray(`> rpc: ${message.method}`));
|
|
2136
2152
|
try {
|
|
2137
2153
|
const handler = rpcHandlers[message.method];
|
|
2138
2154
|
if (!handler) {
|
|
@@ -2144,29 +2160,30 @@ function connectToServer(serverUrl = DEFAULT_SERVER_URL) {
|
|
|
2144
2160
|
id: message.id,
|
|
2145
2161
|
result
|
|
2146
2162
|
}));
|
|
2147
|
-
console.log(pc5__default.default.green(`rpc call completed: ${message.method}`));
|
|
2148
2163
|
} catch (error) {
|
|
2149
2164
|
ws.send(JSON.stringify({
|
|
2150
2165
|
type: "tool_result",
|
|
2151
2166
|
id: message.id,
|
|
2152
2167
|
error: error.message
|
|
2153
2168
|
}));
|
|
2154
|
-
console.error(pc5__default.default.red(`rpc
|
|
2169
|
+
console.error(pc5__default.default.red(` rpc failed: ${message.method}`));
|
|
2155
2170
|
}
|
|
2156
2171
|
}
|
|
2157
2172
|
});
|
|
2158
2173
|
ws.on("close", () => {
|
|
2159
|
-
|
|
2160
|
-
|
|
2174
|
+
const delay = getReconnectDelay2();
|
|
2175
|
+
reconnectAttempts2++;
|
|
2176
|
+
console.log(pc5__default.default.gray(`disconnected, reconnecting in ${Math.round(delay / 1e3)}s...`));
|
|
2177
|
+
setTimeout(() => connectToServer(serverUrl), delay);
|
|
2161
2178
|
});
|
|
2162
2179
|
ws.on("error", (error) => {
|
|
2163
|
-
console.error(pc5__default.default.red(`
|
|
2180
|
+
console.error(pc5__default.default.red(`connection error: ${error.message}`));
|
|
2164
2181
|
});
|
|
2165
2182
|
return ws;
|
|
2166
2183
|
}
|
|
2167
2184
|
async function main() {
|
|
2168
2185
|
const serverUrl = DEFAULT_SERVER_URL;
|
|
2169
|
-
console.log(pc5__default.default.
|
|
2186
|
+
console.log(pc5__default.default.gray("starting ama..."));
|
|
2170
2187
|
connectToServer(serverUrl);
|
|
2171
2188
|
await connectToUserStreams(serverUrl);
|
|
2172
2189
|
startHttpServer();
|
|
@@ -2205,20 +2222,20 @@ function getCodeServerBin() {
|
|
|
2205
2222
|
}
|
|
2206
2223
|
function isCodeServerInstalled() {
|
|
2207
2224
|
const binPath = getCodeServerBin();
|
|
2208
|
-
return
|
|
2225
|
+
return fs6__default.default.existsSync(binPath);
|
|
2209
2226
|
}
|
|
2210
2227
|
async function installCodeServer() {
|
|
2211
2228
|
const { ext } = getPlatformInfo();
|
|
2212
2229
|
const downloadUrl = getDownloadUrl();
|
|
2213
2230
|
const tarballPath = path10__default.default.join(AMA_DIR, `code-server.${ext}`);
|
|
2214
|
-
if (!
|
|
2215
|
-
|
|
2231
|
+
if (!fs6__default.default.existsSync(AMA_DIR)) {
|
|
2232
|
+
fs6__default.default.mkdirSync(AMA_DIR, { recursive: true });
|
|
2216
2233
|
}
|
|
2217
|
-
if (!
|
|
2218
|
-
|
|
2234
|
+
if (!fs6__default.default.existsSync(CODE_DIR)) {
|
|
2235
|
+
fs6__default.default.mkdirSync(CODE_DIR, { recursive: true });
|
|
2219
2236
|
}
|
|
2220
|
-
if (!
|
|
2221
|
-
|
|
2237
|
+
if (!fs6__default.default.existsSync(STORAGE_DIR)) {
|
|
2238
|
+
fs6__default.default.mkdirSync(STORAGE_DIR, { recursive: true });
|
|
2222
2239
|
}
|
|
2223
2240
|
console.log(pc5__default.default.cyan(`Downloading code-server v${CODE_SERVER_VERSION}...`));
|
|
2224
2241
|
console.log(pc5__default.default.gray(downloadUrl));
|
|
@@ -2227,13 +2244,13 @@ async function installCodeServer() {
|
|
|
2227
2244
|
throw new Error(`Failed to download code-server: ${response.statusText}`);
|
|
2228
2245
|
}
|
|
2229
2246
|
const buffer = await response.arrayBuffer();
|
|
2230
|
-
await
|
|
2247
|
+
await fs6__default.default.promises.writeFile(tarballPath, Buffer.from(buffer));
|
|
2231
2248
|
console.log(pc5__default.default.cyan("Extracting code-server..."));
|
|
2232
2249
|
await execAsync3(`tar -xzf ${tarballPath} -C ${CODE_DIR}`);
|
|
2233
|
-
await
|
|
2250
|
+
await fs6__default.default.promises.unlink(tarballPath);
|
|
2234
2251
|
const binPath = getCodeServerBin();
|
|
2235
|
-
if (
|
|
2236
|
-
await
|
|
2252
|
+
if (fs6__default.default.existsSync(binPath)) {
|
|
2253
|
+
await fs6__default.default.promises.chmod(binPath, 493);
|
|
2237
2254
|
}
|
|
2238
2255
|
console.log(pc5__default.default.green("\u2713 code-server installed successfully"));
|
|
2239
2256
|
}
|
|
@@ -2255,26 +2272,77 @@ async function killExistingCodeServer() {
|
|
|
2255
2272
|
} catch {
|
|
2256
2273
|
}
|
|
2257
2274
|
}
|
|
2275
|
+
async function setupDefaultSettings() {
|
|
2276
|
+
const userDir = path10__default.default.join(STORAGE_DIR, "User");
|
|
2277
|
+
const settingsPath = path10__default.default.join(userDir, "settings.json");
|
|
2278
|
+
if (!fs6__default.default.existsSync(userDir)) {
|
|
2279
|
+
fs6__default.default.mkdirSync(userDir, { recursive: true });
|
|
2280
|
+
}
|
|
2281
|
+
const defaultSettings = {
|
|
2282
|
+
// Disable signature verification for Open VSX extensions
|
|
2283
|
+
"extensions.verifySignature": false,
|
|
2284
|
+
// Theme settings
|
|
2285
|
+
"workbench.colorTheme": "Min Dark",
|
|
2286
|
+
"workbench.startupEditor": "none",
|
|
2287
|
+
// Editor settings
|
|
2288
|
+
"editor.fontSize": 14,
|
|
2289
|
+
"editor.fontFamily": "'JetBrains Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace",
|
|
2290
|
+
"editor.minimap.enabled": false,
|
|
2291
|
+
"editor.wordWrap": "on",
|
|
2292
|
+
// UI settings
|
|
2293
|
+
"window.menuBarVisibility": "compact",
|
|
2294
|
+
"workbench.activityBar.location": "top"
|
|
2295
|
+
};
|
|
2296
|
+
let existingSettings = {};
|
|
2297
|
+
if (fs6__default.default.existsSync(settingsPath)) {
|
|
2298
|
+
try {
|
|
2299
|
+
const content = await fs6__default.default.promises.readFile(settingsPath, "utf-8");
|
|
2300
|
+
existingSettings = JSON.parse(content);
|
|
2301
|
+
} catch {
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
const mergedSettings = { ...defaultSettings, ...existingSettings };
|
|
2305
|
+
mergedSettings["workbench.colorTheme"] = "Min Dark";
|
|
2306
|
+
mergedSettings["extensions.verifySignature"] = false;
|
|
2307
|
+
await fs6__default.default.promises.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2));
|
|
2308
|
+
console.log(pc5__default.default.green("ama code-server settings configured"));
|
|
2309
|
+
}
|
|
2310
|
+
async function installExtensions() {
|
|
2311
|
+
const binPath = getCodeServerBin();
|
|
2312
|
+
const extensions = [
|
|
2313
|
+
"castrogusttavo.min-theme"
|
|
2314
|
+
];
|
|
2315
|
+
for (const ext of extensions) {
|
|
2316
|
+
try {
|
|
2317
|
+
console.log(pc5__default.default.cyan(`ama installing extension: ${ext}...`));
|
|
2318
|
+
await execAsync3(`"${binPath}" --user-data-dir "${STORAGE_DIR}" --install-extension ${ext}`);
|
|
2319
|
+
console.log(pc5__default.default.green(`ama extension ${ext} installed`));
|
|
2320
|
+
} catch (error) {
|
|
2321
|
+
console.log(pc5__default.default.yellow(`ama failed to install extension ${ext}`), error);
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2258
2325
|
async function startCodeServer(cwd) {
|
|
2259
2326
|
const binPath = getCodeServerBin();
|
|
2260
2327
|
const workDir = cwd || process.cwd();
|
|
2261
|
-
if (!
|
|
2262
|
-
throw new Error("code-server is not installed. Run installCodeServer() first.");
|
|
2328
|
+
if (!fs6__default.default.existsSync(binPath)) {
|
|
2329
|
+
throw new Error("ama code-server is not installed. Run installCodeServer() first.");
|
|
2263
2330
|
}
|
|
2264
2331
|
await killExistingCodeServer();
|
|
2332
|
+
await setupDefaultSettings();
|
|
2333
|
+
await installExtensions();
|
|
2265
2334
|
const workspaceStoragePath = path10__default.default.join(STORAGE_DIR, "User", "workspaceStorage");
|
|
2266
|
-
path10__default.default.join(STORAGE_DIR, "User", "globalStorage");
|
|
2267
2335
|
try {
|
|
2268
|
-
if (
|
|
2269
|
-
await
|
|
2336
|
+
if (fs6__default.default.existsSync(workspaceStoragePath)) {
|
|
2337
|
+
await fs6__default.default.promises.rm(workspaceStoragePath, { recursive: true, force: true });
|
|
2270
2338
|
}
|
|
2271
2339
|
const stateDbPath = path10__default.default.join(STORAGE_DIR, "User", "globalStorage", "state.vscdb");
|
|
2272
|
-
if (
|
|
2273
|
-
await
|
|
2340
|
+
if (fs6__default.default.existsSync(stateDbPath)) {
|
|
2341
|
+
await fs6__default.default.promises.unlink(stateDbPath);
|
|
2274
2342
|
}
|
|
2275
2343
|
} catch {
|
|
2276
2344
|
}
|
|
2277
|
-
console.log(pc5__default.default.cyan(`
|
|
2345
|
+
console.log(pc5__default.default.cyan(`ama starting code-server`));
|
|
2278
2346
|
const codeServer = child_process.spawn(
|
|
2279
2347
|
binPath,
|
|
2280
2348
|
[
|
|
@@ -2293,7 +2361,7 @@ async function startCodeServer(cwd) {
|
|
|
2293
2361
|
stdio: ["ignore", "pipe", "pipe"]
|
|
2294
2362
|
}
|
|
2295
2363
|
);
|
|
2296
|
-
console.log(pc5__default.default.green(
|
|
2364
|
+
console.log(pc5__default.default.green(`ama code-server running at http://localhost:8081/?folder=${encodeURIComponent(workDir)}`));
|
|
2297
2365
|
return codeServer;
|
|
2298
2366
|
}
|
|
2299
2367
|
var __filename$1 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)));
|
|
@@ -2301,11 +2369,11 @@ var __dirname$1 = path10.dirname(__filename$1);
|
|
|
2301
2369
|
var DAEMON_PID_FILE = path10__default.default.join(AMA_DIR, "daemon.pid");
|
|
2302
2370
|
var DAEMON_LOG_FILE = path10__default.default.join(AMA_DIR, "daemon.log");
|
|
2303
2371
|
function isDaemonRunning() {
|
|
2304
|
-
if (!
|
|
2372
|
+
if (!fs6__default.default.existsSync(DAEMON_PID_FILE)) {
|
|
2305
2373
|
return false;
|
|
2306
2374
|
}
|
|
2307
2375
|
try {
|
|
2308
|
-
const pid = Number(
|
|
2376
|
+
const pid = Number(fs6__default.default.readFileSync(DAEMON_PID_FILE, "utf8"));
|
|
2309
2377
|
process.kill(pid, 0);
|
|
2310
2378
|
return true;
|
|
2311
2379
|
} catch {
|
|
@@ -2313,30 +2381,30 @@ function isDaemonRunning() {
|
|
|
2313
2381
|
}
|
|
2314
2382
|
}
|
|
2315
2383
|
function stopDaemon() {
|
|
2316
|
-
if (!
|
|
2384
|
+
if (!fs6__default.default.existsSync(DAEMON_PID_FILE)) {
|
|
2317
2385
|
return false;
|
|
2318
2386
|
}
|
|
2319
2387
|
try {
|
|
2320
|
-
const pid = Number(
|
|
2388
|
+
const pid = Number(fs6__default.default.readFileSync(DAEMON_PID_FILE, "utf8"));
|
|
2321
2389
|
process.kill(pid, "SIGTERM");
|
|
2322
|
-
|
|
2390
|
+
fs6__default.default.unlinkSync(DAEMON_PID_FILE);
|
|
2323
2391
|
return true;
|
|
2324
2392
|
} catch (error) {
|
|
2325
2393
|
return false;
|
|
2326
2394
|
}
|
|
2327
2395
|
}
|
|
2328
2396
|
function startDaemon() {
|
|
2329
|
-
if (!
|
|
2330
|
-
|
|
2397
|
+
if (!fs6__default.default.existsSync(AMA_DIR)) {
|
|
2398
|
+
fs6__default.default.mkdirSync(AMA_DIR, { recursive: true });
|
|
2331
2399
|
}
|
|
2332
2400
|
if (isDaemonRunning()) {
|
|
2333
2401
|
stopDaemon();
|
|
2334
2402
|
}
|
|
2335
2403
|
const daemonScript = path10__default.default.join(__dirname$1, "lib", "daemon-entry.js");
|
|
2336
|
-
if (!
|
|
2404
|
+
if (!fs6__default.default.existsSync(daemonScript)) {
|
|
2337
2405
|
throw new Error(`Daemon entry script not found at: ${daemonScript}. Please rebuild the project.`);
|
|
2338
2406
|
}
|
|
2339
|
-
const logFd =
|
|
2407
|
+
const logFd = fs6__default.default.openSync(DAEMON_LOG_FILE, "a");
|
|
2340
2408
|
const daemon = child_process.spawn(process.execPath, [daemonScript], {
|
|
2341
2409
|
detached: true,
|
|
2342
2410
|
stdio: ["ignore", logFd, logFd],
|
|
@@ -2344,21 +2412,27 @@ function startDaemon() {
|
|
|
2344
2412
|
cwd: process.cwd()
|
|
2345
2413
|
});
|
|
2346
2414
|
daemon.unref();
|
|
2347
|
-
|
|
2348
|
-
|
|
2415
|
+
fs6__default.default.writeFileSync(DAEMON_PID_FILE, String(daemon.pid));
|
|
2416
|
+
fs6__default.default.closeSync(logFd);
|
|
2349
2417
|
}
|
|
2350
2418
|
function getDaemonPid() {
|
|
2351
|
-
if (!
|
|
2419
|
+
if (!fs6__default.default.existsSync(DAEMON_PID_FILE)) {
|
|
2352
2420
|
return null;
|
|
2353
2421
|
}
|
|
2354
2422
|
try {
|
|
2355
|
-
return Number(
|
|
2423
|
+
return Number(fs6__default.default.readFileSync(DAEMON_PID_FILE, "utf8"));
|
|
2356
2424
|
} catch {
|
|
2357
2425
|
return null;
|
|
2358
2426
|
}
|
|
2359
2427
|
}
|
|
2360
|
-
var VERSION = "0.0.
|
|
2428
|
+
var VERSION = "0.0.10";
|
|
2361
2429
|
var PROJECT_DIR = process.cwd();
|
|
2430
|
+
var LOGO = `
|
|
2431
|
+
__ _ _ __ ___ __ _
|
|
2432
|
+
/ _\` | '_ \` _ \\ / _\` |
|
|
2433
|
+
| (_| | | | | | | (_| |
|
|
2434
|
+
\\__,_|_| |_| |_|\\__,_|
|
|
2435
|
+
`;
|
|
2362
2436
|
function promptUser(question) {
|
|
2363
2437
|
const rl = readline__default.default.createInterface({
|
|
2364
2438
|
input: process.stdin,
|
|
@@ -2373,168 +2447,249 @@ function promptUser(question) {
|
|
|
2373
2447
|
}
|
|
2374
2448
|
async function startWithCodeServer() {
|
|
2375
2449
|
if (!isCodeServerInstalled()) {
|
|
2376
|
-
console.log(pc5__default.default.
|
|
2450
|
+
console.log(pc5__default.default.gray("setting up code-server..."));
|
|
2377
2451
|
try {
|
|
2378
2452
|
await installCodeServer();
|
|
2379
2453
|
} catch (error) {
|
|
2380
|
-
console.error(pc5__default.default.red(`
|
|
2381
|
-
console.log(pc5__default.default.
|
|
2454
|
+
console.error(pc5__default.default.red(`failed to install code-server: ${error.message}`));
|
|
2455
|
+
console.log(pc5__default.default.gray("continuing without code-server..."));
|
|
2382
2456
|
}
|
|
2383
2457
|
}
|
|
2384
2458
|
if (isCodeServerInstalled()) {
|
|
2385
2459
|
try {
|
|
2386
2460
|
await startCodeServer(PROJECT_DIR);
|
|
2387
2461
|
} catch (error) {
|
|
2388
|
-
console.error(pc5__default.default.red(`
|
|
2462
|
+
console.error(pc5__default.default.red(`failed to start code-server: ${error.message}`));
|
|
2389
2463
|
}
|
|
2390
2464
|
}
|
|
2391
2465
|
main();
|
|
2392
2466
|
}
|
|
2467
|
+
async function checkForUpdates() {
|
|
2468
|
+
try {
|
|
2469
|
+
const response = await fetch("https://registry.npmjs.org/amai/latest");
|
|
2470
|
+
const data = await response.json();
|
|
2471
|
+
const latestVersion = data.version;
|
|
2472
|
+
return {
|
|
2473
|
+
current: VERSION,
|
|
2474
|
+
latest: latestVersion,
|
|
2475
|
+
hasUpdate: latestVersion !== VERSION
|
|
2476
|
+
};
|
|
2477
|
+
} catch {
|
|
2478
|
+
return { current: VERSION, latest: VERSION, hasUpdate: false };
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
function runNpmInstall() {
|
|
2482
|
+
return new Promise((resolve, reject) => {
|
|
2483
|
+
const child = child_process.spawn("npm", ["install", "-g", "amai@latest"], {
|
|
2484
|
+
stdio: "inherit",
|
|
2485
|
+
shell: true
|
|
2486
|
+
});
|
|
2487
|
+
child.on("close", (code) => {
|
|
2488
|
+
if (code === 0) resolve();
|
|
2489
|
+
else reject(new Error(`npm install exited with code ${code}`));
|
|
2490
|
+
});
|
|
2491
|
+
child.on("error", reject);
|
|
2492
|
+
});
|
|
2493
|
+
}
|
|
2393
2494
|
var args = process.argv.slice(2);
|
|
2495
|
+
if (args[0] === "--version" || args[0] === "-v") {
|
|
2496
|
+
console.log(pc5__default.default.gray(`amai ${VERSION}`));
|
|
2497
|
+
process.exit(0);
|
|
2498
|
+
}
|
|
2394
2499
|
if (args[0] === "--help" || args[0] === "-h") {
|
|
2395
|
-
console.log(
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
amai login
|
|
2416
|
-
amai start
|
|
2417
|
-
amai project add /path/to/project
|
|
2418
|
-
amai Start the agent (will prompt for background mode)
|
|
2419
|
-
`);
|
|
2500
|
+
console.log(pc5__default.default.cyan(LOGO));
|
|
2501
|
+
console.log(pc5__default.default.gray(` v${VERSION}`));
|
|
2502
|
+
console.log("");
|
|
2503
|
+
console.log(pc5__default.default.cyan(" usage"));
|
|
2504
|
+
console.log(pc5__default.default.gray(" amai [command]"));
|
|
2505
|
+
console.log("");
|
|
2506
|
+
console.log(pc5__default.default.cyan(" commands"));
|
|
2507
|
+
console.log(pc5__default.default.gray(" login authenticate with amai"));
|
|
2508
|
+
console.log(pc5__default.default.gray(" logout remove credentials"));
|
|
2509
|
+
console.log(pc5__default.default.gray(" start start background daemon"));
|
|
2510
|
+
console.log(pc5__default.default.gray(" stop stop background daemon"));
|
|
2511
|
+
console.log(pc5__default.default.gray(" status check daemon status"));
|
|
2512
|
+
console.log(pc5__default.default.gray(" update update to latest version"));
|
|
2513
|
+
console.log(pc5__default.default.gray(" project add register a project"));
|
|
2514
|
+
console.log(pc5__default.default.gray(" project list list projects"));
|
|
2515
|
+
console.log("");
|
|
2516
|
+
console.log(pc5__default.default.cyan(" options"));
|
|
2517
|
+
console.log(pc5__default.default.gray(" -h, --help show help"));
|
|
2518
|
+
console.log(pc5__default.default.gray(" -v, --version show version"));
|
|
2519
|
+
console.log("");
|
|
2420
2520
|
process.exit(0);
|
|
2421
2521
|
}
|
|
2422
|
-
if (args[0] === "
|
|
2423
|
-
|
|
2424
|
-
console.log(pc5__default.default.
|
|
2522
|
+
if (args[0] === "update") {
|
|
2523
|
+
(async () => {
|
|
2524
|
+
console.log(pc5__default.default.gray("checking for updates..."));
|
|
2525
|
+
const { current, latest, hasUpdate } = await checkForUpdates();
|
|
2526
|
+
if (!hasUpdate) {
|
|
2527
|
+
console.log(pc5__default.default.cyan(`already on latest version (${current})`));
|
|
2528
|
+
process.exit(0);
|
|
2529
|
+
}
|
|
2530
|
+
console.log(pc5__default.default.cyan(`update available: ${current} -> ${latest}`));
|
|
2531
|
+
const answer = await promptUser(pc5__default.default.gray("install update? (Y/n): "));
|
|
2532
|
+
if (answer === "" || answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
|
|
2533
|
+
console.log(pc5__default.default.gray("updating..."));
|
|
2534
|
+
try {
|
|
2535
|
+
await runNpmInstall();
|
|
2536
|
+
console.log(pc5__default.default.cyan(`updated to ${latest}`));
|
|
2537
|
+
} catch (error) {
|
|
2538
|
+
console.error(pc5__default.default.red(`update failed: ${error.message}`));
|
|
2539
|
+
process.exit(1);
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2425
2542
|
process.exit(0);
|
|
2426
|
-
}
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
console.log(pc5__default.default.
|
|
2431
|
-
startDaemon();
|
|
2432
|
-
console.log(pc5__default.default.green("ama started in background mode successfully"));
|
|
2543
|
+
})();
|
|
2544
|
+
} else if (args[0] === "start") {
|
|
2545
|
+
(async () => {
|
|
2546
|
+
if (isDaemonRunning()) {
|
|
2547
|
+
console.log(pc5__default.default.gray("amai is already running"));
|
|
2433
2548
|
process.exit(0);
|
|
2434
|
-
}
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2549
|
+
}
|
|
2550
|
+
if (!isAuthenticated()) {
|
|
2551
|
+
console.log(pc5__default.default.gray("not authenticated"));
|
|
2552
|
+
try {
|
|
2553
|
+
await login();
|
|
2554
|
+
} catch {
|
|
2555
|
+
console.error(pc5__default.default.red("login failed"));
|
|
2556
|
+
process.exit(1);
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2439
2559
|
startDaemon();
|
|
2440
|
-
console.log(pc5__default.default.
|
|
2441
|
-
console.log(pc5__default.default.gray(`
|
|
2560
|
+
console.log(pc5__default.default.cyan("amai started"));
|
|
2561
|
+
console.log(pc5__default.default.gray(`check status: amai status`));
|
|
2442
2562
|
process.exit(0);
|
|
2443
|
-
}
|
|
2444
|
-
}
|
|
2445
|
-
if (args[0] === "stop") {
|
|
2563
|
+
})();
|
|
2564
|
+
} else if (args[0] === "stop") {
|
|
2446
2565
|
if (stopDaemon()) {
|
|
2447
|
-
console.log(pc5__default.default.
|
|
2566
|
+
console.log(pc5__default.default.cyan("daemon stopped"));
|
|
2448
2567
|
} else {
|
|
2449
|
-
console.log(pc5__default.default.
|
|
2568
|
+
console.log(pc5__default.default.gray("daemon was not running"));
|
|
2450
2569
|
}
|
|
2451
2570
|
process.exit(0);
|
|
2452
|
-
}
|
|
2453
|
-
if (args[0] === "status") {
|
|
2571
|
+
} else if (args[0] === "status") {
|
|
2454
2572
|
const running = isDaemonRunning();
|
|
2455
2573
|
const pid = getDaemonPid();
|
|
2574
|
+
console.log("");
|
|
2575
|
+
console.log(pc5__default.default.cyan(" amai status"));
|
|
2576
|
+
console.log("");
|
|
2456
2577
|
if (running && pid) {
|
|
2457
|
-
console.log(pc5__default.default.
|
|
2578
|
+
console.log(pc5__default.default.gray(` status running`));
|
|
2579
|
+
console.log(pc5__default.default.gray(` pid ${pid}`));
|
|
2458
2580
|
} else {
|
|
2459
|
-
console.log(pc5__default.default.
|
|
2581
|
+
console.log(pc5__default.default.gray(` status stopped`));
|
|
2460
2582
|
}
|
|
2583
|
+
console.log(pc5__default.default.gray(` version ${VERSION}`));
|
|
2584
|
+
console.log("");
|
|
2461
2585
|
process.exit(0);
|
|
2462
|
-
}
|
|
2463
|
-
if (args[0] === "project") {
|
|
2586
|
+
} else if (args[0] === "project") {
|
|
2464
2587
|
if (args[1] === "add") {
|
|
2465
2588
|
const projectPath = args[2];
|
|
2466
2589
|
if (!projectPath) {
|
|
2467
|
-
console.error(pc5__default.default.red("
|
|
2468
|
-
console.log("
|
|
2590
|
+
console.error(pc5__default.default.red("please provide a project path"));
|
|
2591
|
+
console.log(pc5__default.default.gray("usage: amai project add <path>"));
|
|
2469
2592
|
process.exit(1);
|
|
2470
2593
|
}
|
|
2471
2594
|
const resolvedPath = path10__default.default.resolve(projectPath);
|
|
2472
|
-
if (!
|
|
2473
|
-
console.error(pc5__default.default.red(`
|
|
2595
|
+
if (!fs6__default.default.existsSync(resolvedPath)) {
|
|
2596
|
+
console.error(pc5__default.default.red(`path does not exist: ${resolvedPath}`));
|
|
2474
2597
|
process.exit(1);
|
|
2475
2598
|
}
|
|
2476
|
-
if (!
|
|
2477
|
-
console.error(pc5__default.default.red(`
|
|
2599
|
+
if (!fs6__default.default.statSync(resolvedPath).isDirectory()) {
|
|
2600
|
+
console.error(pc5__default.default.red(`path is not a directory: ${resolvedPath}`));
|
|
2478
2601
|
process.exit(1);
|
|
2479
2602
|
}
|
|
2480
2603
|
const projectId = path10__default.default.basename(resolvedPath);
|
|
2481
2604
|
projectRegistry.register(projectId, resolvedPath);
|
|
2482
|
-
console.log(pc5__default.default.
|
|
2605
|
+
console.log(pc5__default.default.cyan(`project registered: ${projectId}`));
|
|
2606
|
+
console.log(pc5__default.default.gray(` ${resolvedPath}`));
|
|
2483
2607
|
process.exit(0);
|
|
2484
2608
|
} else if (args[1] === "list") {
|
|
2485
2609
|
const projects = projectRegistry.list();
|
|
2610
|
+
console.log("");
|
|
2611
|
+
console.log(pc5__default.default.cyan(" projects"));
|
|
2612
|
+
console.log("");
|
|
2486
2613
|
if (projects.length === 0) {
|
|
2487
|
-
console.log(pc5__default.default.
|
|
2614
|
+
console.log(pc5__default.default.gray(" no projects registered"));
|
|
2488
2615
|
} else {
|
|
2489
|
-
console.log(pc5__default.default.bold("Registered projects:"));
|
|
2490
2616
|
projects.forEach((project) => {
|
|
2491
|
-
|
|
2617
|
+
const status = project.active ? pc5__default.default.cyan("active") : pc5__default.default.gray("inactive");
|
|
2618
|
+
console.log(pc5__default.default.gray(` ${project.id} [${status}]`));
|
|
2619
|
+
console.log(pc5__default.default.gray(` ${project.cwd}`));
|
|
2492
2620
|
});
|
|
2493
2621
|
}
|
|
2622
|
+
console.log("");
|
|
2494
2623
|
process.exit(0);
|
|
2495
2624
|
} else {
|
|
2496
|
-
console.error(pc5__default.default.red(`
|
|
2497
|
-
console.log(
|
|
2625
|
+
console.error(pc5__default.default.red(`unknown project command: ${args[1]}`));
|
|
2626
|
+
console.log(pc5__default.default.gray("usage: amai project add <path> | amai project list"));
|
|
2498
2627
|
process.exit(1);
|
|
2499
2628
|
}
|
|
2500
|
-
}
|
|
2501
|
-
|
|
2502
|
-
|
|
2629
|
+
} else if (args[0] === "login" || args[0] === "--login") {
|
|
2630
|
+
(async () => {
|
|
2631
|
+
try {
|
|
2632
|
+
await login();
|
|
2633
|
+
console.log("");
|
|
2634
|
+
if (isDaemonRunning()) {
|
|
2635
|
+
console.log(pc5__default.default.gray("amai is already running"));
|
|
2636
|
+
process.exit(0);
|
|
2637
|
+
}
|
|
2638
|
+
const answer = await promptUser(pc5__default.default.gray("start amai now? (Y/n): "));
|
|
2639
|
+
const shouldStart = answer === "" || answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
2640
|
+
if (shouldStart) {
|
|
2641
|
+
const bgAnswer = await promptUser(pc5__default.default.gray("run in background? (Y/n): "));
|
|
2642
|
+
const runInBackground = bgAnswer === "" || bgAnswer.toLowerCase() === "y" || bgAnswer.toLowerCase() === "yes";
|
|
2643
|
+
if (runInBackground) {
|
|
2644
|
+
console.log(pc5__default.default.gray("starting..."));
|
|
2645
|
+
startDaemon();
|
|
2646
|
+
console.log(pc5__default.default.cyan("amai started"));
|
|
2647
|
+
console.log(pc5__default.default.gray('use "amai status" to check status'));
|
|
2648
|
+
} else {
|
|
2649
|
+
console.log(pc5__default.default.gray("starting in foreground..."));
|
|
2650
|
+
startWithCodeServer();
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
process.exit(0);
|
|
2655
|
+
} catch {
|
|
2656
|
+
console.error(pc5__default.default.red("login failed"));
|
|
2657
|
+
process.exit(1);
|
|
2658
|
+
}
|
|
2659
|
+
})();
|
|
2503
2660
|
} else if (args[0] === "logout" || args[0] === "--logout") {
|
|
2504
2661
|
logout();
|
|
2505
|
-
console.log(pc5__default.default.
|
|
2662
|
+
console.log(pc5__default.default.cyan("logged out"));
|
|
2506
2663
|
process.exit(0);
|
|
2507
2664
|
} else {
|
|
2508
2665
|
(async () => {
|
|
2666
|
+
console.log(pc5__default.default.cyan(LOGO));
|
|
2509
2667
|
if (!isAuthenticated()) {
|
|
2510
|
-
console.log(pc5__default.default.
|
|
2668
|
+
console.log(pc5__default.default.gray("not authenticated"));
|
|
2511
2669
|
try {
|
|
2512
2670
|
await login();
|
|
2671
|
+
console.log("");
|
|
2513
2672
|
} catch {
|
|
2514
|
-
console.error(pc5__default.default.red("
|
|
2673
|
+
console.error(pc5__default.default.red("login failed"));
|
|
2515
2674
|
process.exit(1);
|
|
2516
2675
|
}
|
|
2517
2676
|
}
|
|
2518
2677
|
if (isDaemonRunning()) {
|
|
2519
|
-
console.log(pc5__default.default.
|
|
2678
|
+
console.log(pc5__default.default.gray("amai is already running"));
|
|
2679
|
+
console.log(pc5__default.default.gray('use "amai status" to check status'));
|
|
2520
2680
|
process.exit(0);
|
|
2521
2681
|
}
|
|
2522
|
-
|
|
2523
|
-
console.log(pc5__default.default.bold("How would you like to run amai?"));
|
|
2524
|
-
console.log(pc5__default.default.gray("Background mode is highly recommended for better performance and stability."));
|
|
2525
|
-
const answer = await promptUser(
|
|
2526
|
-
pc5__default.default.cyan("Run in background? (Y/n): ")
|
|
2527
|
-
);
|
|
2682
|
+
const answer = await promptUser(pc5__default.default.gray("run in background? (Y/n): "));
|
|
2528
2683
|
const runInBackground = answer === "" || answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
2529
2684
|
if (runInBackground) {
|
|
2530
|
-
console.log(pc5__default.default.
|
|
2685
|
+
console.log(pc5__default.default.gray("starting..."));
|
|
2531
2686
|
startDaemon();
|
|
2532
|
-
console.log(pc5__default.default.
|
|
2533
|
-
console.log(pc5__default.default.gray('
|
|
2534
|
-
console.log(pc5__default.default.gray('
|
|
2687
|
+
console.log(pc5__default.default.cyan("amai started"));
|
|
2688
|
+
console.log(pc5__default.default.gray('use "amai status" to check status'));
|
|
2689
|
+
console.log(pc5__default.default.gray('use "amai stop" to stop'));
|
|
2535
2690
|
process.exit(0);
|
|
2536
2691
|
} else {
|
|
2537
|
-
console.log(pc5__default.default.
|
|
2692
|
+
console.log(pc5__default.default.gray("starting in foreground..."));
|
|
2538
2693
|
startWithCodeServer();
|
|
2539
2694
|
}
|
|
2540
2695
|
})();
|