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 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 fs4 = require('fs');
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 fs4__default = /*#__PURE__*/_interopDefault(fs4);
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 (fs4__default.default.existsSync(REGISTRY_FILE)) {
46
- const data = fs4__default.default.readFileSync(REGISTRY_FILE, "utf8");
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
- fs4__default.default.copyFileSync(REGISTRY_FILE, backupFile);
52
- fs4__default.default.unlinkSync(REGISTRY_FILE);
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 (fs4__default.default.existsSync(REGISTRY_FILE)) {
65
+ if (fs6__default.default.existsSync(REGISTRY_FILE)) {
66
66
  try {
67
67
  const backupFile = REGISTRY_FILE + ".backup." + Date.now();
68
- fs4__default.default.copyFileSync(REGISTRY_FILE, backupFile);
69
- fs4__default.default.unlinkSync(REGISTRY_FILE);
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 (!fs4__default.default.existsSync(AMA_DIR)) {
79
- fs4__default.default.mkdirSync(AMA_DIR, { recursive: true });
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
- fs4__default.default.writeFileSync(REGISTRY_FILE, JSON.stringify(projects, null, 2), "utf8");
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 fs4__default.default.promises.readFile(filePath, "utf-8");
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 fs4__default.default.promises.readFile(filePath, "utf-8");
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 fs4__default.default.promises.writeFile(filePath, content);
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 (!fs4__default.default.existsSync(CREDENTIALS_PATH)) {
1152
+ if (!fs6__default.default.existsSync(CREDENTIALS_PATH)) {
1150
1153
  return false;
1151
1154
  }
1152
- const raw = fs4__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
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 (!fs4__default.default.existsSync(CREDENTIALS_DIR)) {
1162
- fs4__default.default.mkdirSync(CREDENTIALS_DIR, { recursive: true });
1164
+ if (!fs6__default.default.existsSync(CREDENTIALS_DIR)) {
1165
+ fs6__default.default.mkdirSync(CREDENTIALS_DIR, { recursive: true });
1163
1166
  }
1164
- fs4__default.default.writeFileSync(
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 (fs4__default.default.existsSync(CREDENTIALS_PATH)) {
1176
- fs4__default.default.unlinkSync(CREDENTIALS_PATH);
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 (!fs4__default.default.existsSync(CREDENTIALS_PATH)) {
1186
+ if (!fs6__default.default.existsSync(CREDENTIALS_PATH)) {
1184
1187
  return null;
1185
1188
  }
1186
- const raw = fs4__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
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(pc5__default.default.bold("To sign in, follow these steps:"));
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
- ` 1. Open this URL in your browser: ${pc5__default.default.cyan(
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(" 3. Come back here; we will detect when you finish logging in.");
1272
- console.log();
1264
+ console.log("");
1273
1265
  console.log(
1274
1266
  pc5__default.default.gray(
1275
- `Waiting for authorization (expires in ~${Math.round(
1267
+ `waiting for authorization (~${Math.round(
1276
1268
  device.expires_in / 60
1277
- )} minutes)...`
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.green("Successfully authenticated!"));
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 || "Login failed"));
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 (!fs4__default.default.existsSync(CREDENTIALS_PATH)) {
1288
+ if (!fs6__default.default.existsSync(CREDENTIALS_PATH)) {
1297
1289
  return;
1298
1290
  }
1299
- const raw = fs4__default.default.readFileSync(CREDENTIALS_PATH, "utf8");
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 = fs4.readdirSync(dir, { withFileTypes: true });
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 (!fs4__default.default.existsSync(storagePath)) {
1470
+ if (!fs6__default.default.existsSync(storagePath)) {
1479
1471
  return projects;
1480
1472
  }
1481
1473
  try {
1482
- const workspaces = fs4__default.default.readdirSync(storagePath);
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 (fs4__default.default.existsSync(workspaceJsonPath)) {
1477
+ if (fs6__default.default.existsSync(workspaceJsonPath)) {
1486
1478
  try {
1487
- const content = fs4__default.default.readFileSync(workspaceJsonPath, "utf-8");
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 (fs4__default.default.existsSync(projectPath) && fs4__default.default.statSync(projectPath).isDirectory()) {
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 = fs4__default.default.realpathSync(projectPath);
1520
- if (fs4__default.default.existsSync(resolvedPath) && fs4__default.default.statSync(resolvedPath).isDirectory() && !seenPaths.has(resolvedPath)) {
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 fs4__default.default.realpathSync(ideDir) === resolvedPath;
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 (fs4__default.default.existsSync(dirPath)) {
1547
- const projects = fs4__default.default.readdirSync(dirPath);
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 = fs4__default.default.lstatSync(projectPath);
1543
+ const stats = fs6__default.default.lstatSync(projectPath);
1552
1544
  let actualPath = null;
1553
1545
  if (stats.isSymbolicLink()) {
1554
- actualPath = fs4__default.default.realpathSync(projectPath);
1546
+ actualPath = fs6__default.default.realpathSync(projectPath);
1555
1547
  } else if (stats.isFile()) {
1556
1548
  try {
1557
- let content = fs4__default.default.readFileSync(projectPath, "utf-8").trim();
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 (fs4__default.default.existsSync(resolvedContent) && fs4__default.default.statSync(resolvedContent).isDirectory()) {
1563
- actualPath = fs4__default.default.realpathSync(resolvedContent);
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 = fs4__default.default.realpathSync(projectPath);
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
- console.log(pc5__default.default.green("CLI connected to user-streams"));
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(`RPC call: ${method}`));
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(`RPC failed: ${method} - ${rpcError.message}`));
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(`Failed to parse message: ${parseError}`));
2070
+ console.error(pc5__default.default.red(`parse error`));
2068
2071
  }
2069
2072
  });
2070
2073
  ws.on("close", (code, reason) => {
2071
- console.log(pc5__default.default.yellow(`CLI disconnected from user-streams (code: ${code})`));
2072
- console.log(pc5__default.default.gray("Reconnecting in 5 seconds..."));
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(`Reconnection failed: ${err.message}`));
2079
+ console.error(pc5__default.default.red(`reconnection failed`));
2076
2080
  });
2077
- }, 5e3);
2081
+ }, delay);
2078
2082
  });
2079
2083
  ws.on("error", (error) => {
2080
- console.error(pc5__default.default.red(`User streams WebSocket error: ${error.message}`));
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
- console.log(pc5__default.default.green("Connected to server agent streams"));
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(`tool call: ${message.tool}${message.projectCwd ? ` (project: ${message.projectCwd})` : ""}`);
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(`tool call failed: ${message.tool} ${error.message}`));
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(`rpc call: ${message.method}`);
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 call failed: ${message.method} ${error.message}`));
2169
+ console.error(pc5__default.default.red(` rpc failed: ${message.method}`));
2155
2170
  }
2156
2171
  }
2157
2172
  });
2158
2173
  ws.on("close", () => {
2159
- console.log(pc5__default.default.red("disconnected from server. reconnecting in 5s..."));
2160
- setTimeout(() => connectToServer(serverUrl), 5e3);
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(`web socket error: ${error.message}`));
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.green("starting local amai..."));
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 fs4__default.default.existsSync(binPath);
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 (!fs4__default.default.existsSync(AMA_DIR)) {
2215
- fs4__default.default.mkdirSync(AMA_DIR, { recursive: true });
2231
+ if (!fs6__default.default.existsSync(AMA_DIR)) {
2232
+ fs6__default.default.mkdirSync(AMA_DIR, { recursive: true });
2216
2233
  }
2217
- if (!fs4__default.default.existsSync(CODE_DIR)) {
2218
- fs4__default.default.mkdirSync(CODE_DIR, { recursive: true });
2234
+ if (!fs6__default.default.existsSync(CODE_DIR)) {
2235
+ fs6__default.default.mkdirSync(CODE_DIR, { recursive: true });
2219
2236
  }
2220
- if (!fs4__default.default.existsSync(STORAGE_DIR)) {
2221
- fs4__default.default.mkdirSync(STORAGE_DIR, { recursive: true });
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 fs4__default.default.promises.writeFile(tarballPath, Buffer.from(buffer));
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 fs4__default.default.promises.unlink(tarballPath);
2250
+ await fs6__default.default.promises.unlink(tarballPath);
2234
2251
  const binPath = getCodeServerBin();
2235
- if (fs4__default.default.existsSync(binPath)) {
2236
- await fs4__default.default.promises.chmod(binPath, 493);
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 (!fs4__default.default.existsSync(binPath)) {
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 (fs4__default.default.existsSync(workspaceStoragePath)) {
2269
- await fs4__default.default.promises.rm(workspaceStoragePath, { recursive: true, force: true });
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 (fs4__default.default.existsSync(stateDbPath)) {
2273
- await fs4__default.default.promises.unlink(stateDbPath);
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(`Starting code-server in ${workDir}...`));
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(`\u2713 code-server running at http://localhost:8081/?folder=${encodeURIComponent(workDir)}`));
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 (!fs4__default.default.existsSync(DAEMON_PID_FILE)) {
2372
+ if (!fs6__default.default.existsSync(DAEMON_PID_FILE)) {
2305
2373
  return false;
2306
2374
  }
2307
2375
  try {
2308
- const pid = Number(fs4__default.default.readFileSync(DAEMON_PID_FILE, "utf8"));
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 (!fs4__default.default.existsSync(DAEMON_PID_FILE)) {
2384
+ if (!fs6__default.default.existsSync(DAEMON_PID_FILE)) {
2317
2385
  return false;
2318
2386
  }
2319
2387
  try {
2320
- const pid = Number(fs4__default.default.readFileSync(DAEMON_PID_FILE, "utf8"));
2388
+ const pid = Number(fs6__default.default.readFileSync(DAEMON_PID_FILE, "utf8"));
2321
2389
  process.kill(pid, "SIGTERM");
2322
- fs4__default.default.unlinkSync(DAEMON_PID_FILE);
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 (!fs4__default.default.existsSync(AMA_DIR)) {
2330
- fs4__default.default.mkdirSync(AMA_DIR, { recursive: true });
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 (!fs4__default.default.existsSync(daemonScript)) {
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 = fs4__default.default.openSync(DAEMON_LOG_FILE, "a");
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
- fs4__default.default.writeFileSync(DAEMON_PID_FILE, String(daemon.pid));
2348
- fs4__default.default.closeSync(logFd);
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 (!fs4__default.default.existsSync(DAEMON_PID_FILE)) {
2419
+ if (!fs6__default.default.existsSync(DAEMON_PID_FILE)) {
2352
2420
  return null;
2353
2421
  }
2354
2422
  try {
2355
- return Number(fs4__default.default.readFileSync(DAEMON_PID_FILE, "utf8"));
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.8";
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.cyan("First run detected. Setting up code-server..."));
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(`Failed to install code-server: ${error.message}`));
2381
- console.log(pc5__default.default.yellow("Continuing without code-server..."));
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(`Failed to start code-server: ${error.message}`));
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
- ${pc5__default.default.bold("amai cli")} ${pc5__default.default.gray(VERSION)}
2397
-
2398
- Usage: amai [command] [options]
2399
-
2400
- Commands:
2401
- login Authorize device
2402
- logout Log out and remove credentials
2403
- start Start background daemon (background mode is highly recommended for better performance and stability)
2404
- stop Stop background daemon
2405
- status Check daemon status
2406
- project add <path> Register a project directory
2407
- project list List registered projects
2408
- Options:
2409
- --help, -h Show this help message
2410
- --logout, -l Log out and remove credentials
2411
- Environment Variables:
2412
- SERVER_URL Server URL to connect to
2413
-
2414
- Example:
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] === "start") {
2423
- if (isDaemonRunning()) {
2424
- console.log(pc5__default.default.yellow("ama is already running"));
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
- if (!isAuthenticated()) {
2428
- console.log(pc5__default.default.yellow("Not authenticated. Please log in first."));
2429
- login().then(() => {
2430
- console.log(pc5__default.default.green("starting ama in background mode..."));
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
- }).catch(() => {
2435
- console.error(pc5__default.default.red("Login failed. Cannot start ama in background mode."));
2436
- process.exit(1);
2437
- });
2438
- } else {
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.green(pc5__default.default.bold("amai started in background mode")));
2441
- console.log(pc5__default.default.gray(`Tip: You can check status any time with ${pc5__default.default.bold("amai status")}`));
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.green("Daemon stopped successfully"));
2566
+ console.log(pc5__default.default.cyan("daemon stopped"));
2448
2567
  } else {
2449
- console.log(pc5__default.default.yellow("Daemon was not running"));
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.green(`Daemon is running (PID: ${pid})`));
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.yellow("Daemon is not running"));
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("Please provide a project path"));
2468
- console.log("Usage: amai project add <path>");
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 (!fs4__default.default.existsSync(resolvedPath)) {
2473
- console.error(pc5__default.default.red(`Path does not exist: ${resolvedPath}`));
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 (!fs4__default.default.statSync(resolvedPath).isDirectory()) {
2477
- console.error(pc5__default.default.red(`Path is not a directory: ${resolvedPath}`));
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.green(`Project registered: ${projectId} -> ${resolvedPath}`));
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.yellow("No projects registered"));
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
- console.log(` ${pc5__default.default.cyan(project.id)}: ${project.cwd} ${project.active ? pc5__default.default.green("(active)") : ""}`);
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(`Unknown project command: ${args[1]}`));
2497
- console.log('Use "amai project add <path>" or "amai project list"');
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
- if (args[0] === "login" || args[0] === "--login") {
2502
- login().then(() => process.exit(0)).catch(() => process.exit(1));
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.green("Logged out successfully"));
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.yellow("Not authenticated. Please log in first."));
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("Login failed. Cannot start server."));
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.yellow('Daemon is already running. Use "amai status" to check its status.'));
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
- console.log("");
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.green("Starting daemon in background..."));
2685
+ console.log(pc5__default.default.gray("starting..."));
2531
2686
  startDaemon();
2532
- console.log(pc5__default.default.green("Daemon started successfully!"));
2533
- console.log(pc5__default.default.gray('Use "amai status" to check daemon status.'));
2534
- console.log(pc5__default.default.gray('Use "amai stop" to stop the daemon.'));
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.yellow("Starting in foreground mode..."));
2692
+ console.log(pc5__default.default.gray("starting in foreground..."));
2538
2693
  startWithCodeServer();
2539
2694
  }
2540
2695
  })();