@agentrix/cli 0.0.3 → 0.0.5
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/README.md +69 -0
- package/dist/index.cjs +315 -155
- package/dist/index.mjs +162 -2
- package/dist/lib.cjs +4 -4
- package/dist/lib.mjs +1 -1
- package/dist/{logger-B7C5x_8c.cjs → logger-BZmE9yGJ.cjs} +29 -2
- package/dist/{logger-DAsm4mPf.mjs → logger-uuzG-sjn.mjs} +28 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6,7 +6,7 @@ var chalk = require('chalk');
|
|
|
6
6
|
var shared = require('@agentrix/shared');
|
|
7
7
|
var node_crypto = require('node:crypto');
|
|
8
8
|
var axios = require('axios');
|
|
9
|
-
var
|
|
9
|
+
var _package = require('./logger-BZmE9yGJ.cjs');
|
|
10
10
|
var fs$1 = require('node:fs');
|
|
11
11
|
var node_readline = require('node:readline');
|
|
12
12
|
var fs = require('fs');
|
|
@@ -58,10 +58,10 @@ async function delay(ms) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
async function daemonPost(path, body) {
|
|
61
|
-
const state = await
|
|
61
|
+
const state = await _package.machine.readDaemonState();
|
|
62
62
|
if (!state?.port) {
|
|
63
63
|
const errorMessage = "No daemon running, no state file found";
|
|
64
|
-
|
|
64
|
+
_package.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
65
65
|
return {
|
|
66
66
|
error: errorMessage
|
|
67
67
|
};
|
|
@@ -70,7 +70,7 @@ async function daemonPost(path, body) {
|
|
|
70
70
|
process.kill(state.pid, 0);
|
|
71
71
|
} catch (error) {
|
|
72
72
|
const errorMessage = "Daemon is not running, file is stale";
|
|
73
|
-
|
|
73
|
+
_package.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
74
74
|
return {
|
|
75
75
|
error: errorMessage
|
|
76
76
|
};
|
|
@@ -86,7 +86,7 @@ async function daemonPost(path, body) {
|
|
|
86
86
|
});
|
|
87
87
|
if (!response.ok) {
|
|
88
88
|
const errorMessage = `Request failed: ${path}, HTTP ${response.status}`;
|
|
89
|
-
|
|
89
|
+
_package.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
90
90
|
return {
|
|
91
91
|
error: errorMessage
|
|
92
92
|
};
|
|
@@ -94,7 +94,7 @@ async function daemonPost(path, body) {
|
|
|
94
94
|
return await response.json();
|
|
95
95
|
} catch (error) {
|
|
96
96
|
const errorMessage = `Request failed: ${path}, ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
97
|
-
|
|
97
|
+
_package.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
98
98
|
return {
|
|
99
99
|
error: errorMessage
|
|
100
100
|
};
|
|
@@ -118,7 +118,7 @@ async function stopDaemonHttp() {
|
|
|
118
118
|
await daemonPost("/stop");
|
|
119
119
|
}
|
|
120
120
|
async function checkIfDaemonRunningAndCleanupStaleState() {
|
|
121
|
-
const state = await
|
|
121
|
+
const state = await _package.machine.readDaemonState();
|
|
122
122
|
if (!state) {
|
|
123
123
|
return false;
|
|
124
124
|
}
|
|
@@ -126,60 +126,60 @@ async function checkIfDaemonRunningAndCleanupStaleState() {
|
|
|
126
126
|
process.kill(state.pid, 0);
|
|
127
127
|
return true;
|
|
128
128
|
} catch {
|
|
129
|
-
|
|
129
|
+
_package.logger.debug("[DAEMON RUN] Daemon PID not running, cleaning up state");
|
|
130
130
|
await cleanupDaemonState();
|
|
131
131
|
return false;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
async function isLatestDaemonRunning() {
|
|
135
|
-
|
|
135
|
+
_package.logger.debug("[DAEMON CONTROL] Checking if daemon is running same version");
|
|
136
136
|
const runningDaemon = await checkIfDaemonRunningAndCleanupStaleState();
|
|
137
137
|
if (!runningDaemon) {
|
|
138
|
-
|
|
138
|
+
_package.logger.debug("[DAEMON CONTROL] No daemon running, returning false");
|
|
139
139
|
return false;
|
|
140
140
|
}
|
|
141
|
-
const state = await
|
|
141
|
+
const state = await _package.machine.readDaemonState();
|
|
142
142
|
if (!state) {
|
|
143
|
-
|
|
143
|
+
_package.logger.debug("[DAEMON CONTROL] No daemon state found, returning false");
|
|
144
144
|
return false;
|
|
145
145
|
}
|
|
146
146
|
try {
|
|
147
|
-
const packageJsonPath = require$$1.join(
|
|
147
|
+
const packageJsonPath = require$$1.join(_package.projectPath(), "package.json");
|
|
148
148
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
149
149
|
const currentCliVersion = packageJson.version;
|
|
150
|
-
|
|
150
|
+
_package.logger.debug(`[DAEMON CONTROL] Current CLI version: ${currentCliVersion}, Daemon started with version: ${state.cliVersion}`);
|
|
151
151
|
return currentCliVersion === state.cliVersion;
|
|
152
152
|
} catch (error) {
|
|
153
|
-
|
|
153
|
+
_package.logger.debug("[DAEMON CONTROL] Error checking daemon version", error);
|
|
154
154
|
return false;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
async function cleanupDaemonState() {
|
|
158
158
|
try {
|
|
159
|
-
await
|
|
160
|
-
|
|
159
|
+
await _package.machine.clearDaemonState();
|
|
160
|
+
_package.logger.debug("[DAEMON RUN] Daemon state file removed");
|
|
161
161
|
} catch (error) {
|
|
162
|
-
|
|
162
|
+
_package.logger.debug("[DAEMON RUN] Error cleaning up daemon metadata", error);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
async function stopDaemon() {
|
|
166
166
|
try {
|
|
167
|
-
const state = await
|
|
167
|
+
const state = await _package.machine.readDaemonState();
|
|
168
168
|
if (!state) {
|
|
169
|
-
|
|
169
|
+
_package.logger.debug("No daemon state found");
|
|
170
170
|
return;
|
|
171
171
|
}
|
|
172
|
-
|
|
172
|
+
_package.logger.debug(`Stopping daemon with PID ${state.pid}`);
|
|
173
173
|
try {
|
|
174
174
|
await stopDaemonHttp();
|
|
175
175
|
await waitForProcessDeath(state.pid, 2e3);
|
|
176
176
|
return;
|
|
177
177
|
} catch (error) {
|
|
178
|
-
|
|
178
|
+
_package.logger.debug("HTTP stop failed, will force kill", error);
|
|
179
179
|
}
|
|
180
180
|
process.kill(state.pid, "SIGKILL");
|
|
181
181
|
} catch (error) {
|
|
182
|
-
|
|
182
|
+
_package.logger.debug("Error stopping daemon", error);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
async function waitForProcessDeath(pid, timeout) {
|
|
@@ -202,10 +202,10 @@ function generateWebAuthUrl(publicKey, machineId) {
|
|
|
202
202
|
};
|
|
203
203
|
const authDataJson = JSON.stringify(authData);
|
|
204
204
|
const authDataBase64 = shared.encodeBase64(new TextEncoder().encode(authDataJson), "base64url");
|
|
205
|
-
return `${
|
|
205
|
+
return `${_package.machine.webappUrl}/terminal/connect?auth=${authDataBase64}`;
|
|
206
206
|
}
|
|
207
207
|
async function handleAuthLogout() {
|
|
208
|
-
const credentials = await
|
|
208
|
+
const credentials = await _package.machine.readCredentials();
|
|
209
209
|
if (!credentials) {
|
|
210
210
|
console.log(chalk.yellow("Not currently authenticated"));
|
|
211
211
|
return;
|
|
@@ -227,7 +227,7 @@ async function handleAuthLogout() {
|
|
|
227
227
|
console.log(chalk.gray("Stopped daemon"));
|
|
228
228
|
} catch {
|
|
229
229
|
}
|
|
230
|
-
const paths =
|
|
230
|
+
const paths = _package.machine.getStatePaths();
|
|
231
231
|
if (fs$1.existsSync(paths.rootDir)) {
|
|
232
232
|
fs$1.rmSync(paths.rootDir, { recursive: true, force: true });
|
|
233
233
|
console.log(chalk.gray(`Removed agentrix home directory`));
|
|
@@ -241,7 +241,7 @@ async function handleAuthLogout() {
|
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
243
|
async function handleAuthStatus() {
|
|
244
|
-
const credentials = await
|
|
244
|
+
const credentials = await _package.machine.readCredentials();
|
|
245
245
|
console.log(chalk.bold("\nAuthentication Status\n"));
|
|
246
246
|
if (!credentials) {
|
|
247
247
|
console.log(chalk.red("\u2717 Not authenticated"));
|
|
@@ -258,7 +258,7 @@ async function handleAuthStatus() {
|
|
|
258
258
|
console.log(chalk.yellow("\u26A0\uFE0F Machine not registered"));
|
|
259
259
|
}
|
|
260
260
|
console.log(chalk.gray(`
|
|
261
|
-
Data directory: ${
|
|
261
|
+
Data directory: ${_package.machine.agentrixHomeDir}`));
|
|
262
262
|
try {
|
|
263
263
|
const running = await checkIfDaemonRunningAndCleanupStaleState();
|
|
264
264
|
if (running) {
|
|
@@ -274,32 +274,32 @@ async function handleAuthStatus() {
|
|
|
274
274
|
async function openBrowser(url) {
|
|
275
275
|
try {
|
|
276
276
|
if (!process.stdout.isTTY || process.env.CI || process.env.HEADLESS) {
|
|
277
|
-
|
|
277
|
+
_package.logger.debug("[browser] Headless environment detected, skipping browser open");
|
|
278
278
|
return false;
|
|
279
279
|
}
|
|
280
|
-
|
|
280
|
+
_package.logger.debug(`[browser] Attempting to open URL: ${url}`);
|
|
281
281
|
await open(url);
|
|
282
|
-
|
|
282
|
+
_package.logger.debug("[browser] Browser opened successfully");
|
|
283
283
|
return true;
|
|
284
284
|
} catch (error) {
|
|
285
|
-
|
|
285
|
+
_package.logger.debug("[browser] Failed to open browser:", error);
|
|
286
286
|
return false;
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
async function doAuth() {
|
|
291
291
|
console.clear();
|
|
292
|
-
const machineId =
|
|
292
|
+
const machineId = _package.machine.generateMachineId();
|
|
293
293
|
const secret = new Uint8Array(node_crypto.randomBytes(32));
|
|
294
294
|
const keypair = await shared.createKeyPairWithUit8Array(secret);
|
|
295
295
|
try {
|
|
296
|
-
console.log(`[AUTH] Sending auth request to: ${
|
|
296
|
+
console.log(`[AUTH] Sending auth request to: ${_package.machine.serverUrl}/v1/auth/machine`);
|
|
297
297
|
console.log(`[AUTH] Public key: ${shared.encodeBase64(keypair.publicKey).substring(0, 20)}...`);
|
|
298
298
|
const requestBody = {
|
|
299
299
|
machineId
|
|
300
300
|
};
|
|
301
301
|
await axios.post(
|
|
302
|
-
`${
|
|
302
|
+
`${_package.machine.serverUrl}/v1/auth/machine`,
|
|
303
303
|
requestBody
|
|
304
304
|
);
|
|
305
305
|
console.log(`[AUTH] Auth request sent successfully`);
|
|
@@ -344,7 +344,7 @@ async function waitForAuthentication(keypair, machineId) {
|
|
|
344
344
|
while (!cancelled) {
|
|
345
345
|
try {
|
|
346
346
|
const response = await axios.get(
|
|
347
|
-
`${
|
|
347
|
+
`${_package.machine.serverUrl}/v1/auth/machine?machineId=${machineId}`
|
|
348
348
|
);
|
|
349
349
|
if (response.data.state === "authorized") {
|
|
350
350
|
const token = response.data.token;
|
|
@@ -380,7 +380,7 @@ async function syncMachine(credentials, metadata, userPublicKey, keypair) {
|
|
|
380
380
|
requestBody.dataEncryptionKey = shared.encryptMachineEncryptionKey(keypair.publicKey, shared.generateAESKey(), shared.decodeBase64(userPublicKey));
|
|
381
381
|
}
|
|
382
382
|
await axios.post(
|
|
383
|
-
`${
|
|
383
|
+
`${_package.machine.serverUrl}/v1/machines/sync`,
|
|
384
384
|
requestBody,
|
|
385
385
|
{
|
|
386
386
|
headers: {
|
|
@@ -398,9 +398,9 @@ async function syncMachine(credentials, metadata, userPublicKey, keypair) {
|
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
400
|
async function authAndSetupMachineIfNeeded() {
|
|
401
|
-
const localCredentials = await
|
|
401
|
+
const localCredentials = await _package.machine.readCredentials();
|
|
402
402
|
if (localCredentials) {
|
|
403
|
-
|
|
403
|
+
_package.logger.info("[AUTH] Using existing credentials");
|
|
404
404
|
return localCredentials;
|
|
405
405
|
}
|
|
406
406
|
const cloudAuthToken = process.env.CLOUD_AUTH_TOKEN;
|
|
@@ -413,7 +413,7 @@ async function authAndSetupMachineIfNeeded() {
|
|
|
413
413
|
token: cloudAuthToken,
|
|
414
414
|
machineId: cloudDeviceId
|
|
415
415
|
};
|
|
416
|
-
|
|
416
|
+
_package.logger.info("[AUTH] Cloud mode detected, using CLOUD_AUTH_TOKEN");
|
|
417
417
|
} else {
|
|
418
418
|
const authResult = await doAuth();
|
|
419
419
|
if (!authResult.credentials || !authResult.userPublicKey) {
|
|
@@ -423,9 +423,9 @@ async function authAndSetupMachineIfNeeded() {
|
|
|
423
423
|
keypair = authResult.keypair;
|
|
424
424
|
userPublicKey = authResult.userPublicKey;
|
|
425
425
|
}
|
|
426
|
-
await
|
|
427
|
-
await syncMachine(credentials,
|
|
428
|
-
|
|
426
|
+
await _package.machine.writeCredentials(credentials);
|
|
427
|
+
await syncMachine(credentials, _package.machine.metadata(), userPublicKey, keypair);
|
|
428
|
+
_package.logger.info("[AUTH] Machine setup completed");
|
|
429
429
|
return credentials;
|
|
430
430
|
}
|
|
431
431
|
|
|
@@ -11522,32 +11522,32 @@ var mimeTypesExports = requireMimeTypes();
|
|
|
11522
11522
|
|
|
11523
11523
|
async function decryptDataEncryptionKey(encryptedKey) {
|
|
11524
11524
|
try {
|
|
11525
|
-
const secretKey = await
|
|
11525
|
+
const secretKey = await _package.machine.getSecretKey();
|
|
11526
11526
|
if (!secretKey) {
|
|
11527
|
-
|
|
11527
|
+
_package.logger.warn("[WORKSPACE] Machine secret key not available");
|
|
11528
11528
|
return null;
|
|
11529
11529
|
}
|
|
11530
11530
|
const encryptedKeyBytes = shared.decodeBase64(encryptedKey);
|
|
11531
11531
|
const decryptedKey = shared.decryptWithEphemeralKey(encryptedKeyBytes, secretKey);
|
|
11532
11532
|
if (!decryptedKey) {
|
|
11533
|
-
|
|
11533
|
+
_package.logger.warn("[WORKSPACE] Failed to decrypt dataEncryptionKey");
|
|
11534
11534
|
return null;
|
|
11535
11535
|
}
|
|
11536
11536
|
return decryptedKey;
|
|
11537
11537
|
} catch (error) {
|
|
11538
|
-
|
|
11538
|
+
_package.logger.warn("[WORKSPACE] Error decrypting dataEncryptionKey:", error);
|
|
11539
11539
|
return null;
|
|
11540
11540
|
}
|
|
11541
11541
|
}
|
|
11542
11542
|
function resolveFilePath(userId, taskId, relativePath) {
|
|
11543
|
-
const workspaceBase = path__namespace.dirname(
|
|
11543
|
+
const workspaceBase = path__namespace.dirname(_package.machine.resolveProjectDir(void 0, userId, taskId));
|
|
11544
11544
|
return path__namespace.join(workspaceBase, relativePath);
|
|
11545
11545
|
}
|
|
11546
11546
|
function sendResponse(client, response) {
|
|
11547
11547
|
if (client) {
|
|
11548
11548
|
client.send("workspace-file-response", response);
|
|
11549
11549
|
} else {
|
|
11550
|
-
|
|
11550
|
+
_package.logger.error("[WORKSPACE] Cannot send workspace-file-response: client not available");
|
|
11551
11551
|
}
|
|
11552
11552
|
}
|
|
11553
11553
|
function createErrorResponse(requestId, taskId, code, message) {
|
|
@@ -11560,7 +11560,7 @@ function createErrorResponse(requestId, taskId, code, message) {
|
|
|
11560
11560
|
};
|
|
11561
11561
|
}
|
|
11562
11562
|
function handleNotModified(client, requestId, taskId, filePath) {
|
|
11563
|
-
|
|
11563
|
+
_package.logger.debug(`[WORKSPACE] File not modified: ${filePath}`);
|
|
11564
11564
|
sendResponse(client, {
|
|
11565
11565
|
eventId: shared.createEventId(),
|
|
11566
11566
|
requestId,
|
|
@@ -11600,7 +11600,7 @@ async function handleDirectory(client, requestId, taskId, filePath, stats, maxSi
|
|
|
11600
11600
|
});
|
|
11601
11601
|
}
|
|
11602
11602
|
function handleFileTooLarge(client, requestId, taskId, filePath, stats, mimeType, maxSizeBytes) {
|
|
11603
|
-
|
|
11603
|
+
_package.logger.warn(`[WORKSPACE] File too large (${stats.size} bytes > ${maxSizeBytes} bytes): ${filePath}`);
|
|
11604
11604
|
sendResponse(client, {
|
|
11605
11605
|
eventId: shared.createEventId(),
|
|
11606
11606
|
requestId,
|
|
@@ -11649,13 +11649,13 @@ async function handleFile(client, requestId, taskId, filePath, stats, dataEncryp
|
|
|
11649
11649
|
function workspaceFileRequestHandler(context) {
|
|
11650
11650
|
return async (data) => {
|
|
11651
11651
|
const { taskId, userId, relativePath, requestId, maxFileSizeMB, ifModifiedSince, dataEncryptionKey } = data;
|
|
11652
|
-
|
|
11652
|
+
_package.logger.debug(`[WORKSPACE] File request: taskId=${taskId}, userId=${userId}, relativePath=${relativePath}, maxFileSizeMB=${maxFileSizeMB}, ifModifiedSince=${ifModifiedSince}, hasEncryptionKey=${!!dataEncryptionKey}`);
|
|
11653
11653
|
try {
|
|
11654
11654
|
const maxSizeMB = maxFileSizeMB || 10;
|
|
11655
11655
|
const maxSizeBytes = maxSizeMB * 1024 * 1024;
|
|
11656
11656
|
const filePath = resolveFilePath(userId, taskId, relativePath);
|
|
11657
11657
|
if (!fs__namespace.existsSync(filePath)) {
|
|
11658
|
-
|
|
11658
|
+
_package.logger.warn(`[WORKSPACE] File not found: ${filePath}`);
|
|
11659
11659
|
sendResponse(context.client, createErrorResponse(requestId, taskId, "file_not_found", "File or directory not found"));
|
|
11660
11660
|
return;
|
|
11661
11661
|
}
|
|
@@ -11678,7 +11678,7 @@ function workspaceFileRequestHandler(context) {
|
|
|
11678
11678
|
return;
|
|
11679
11679
|
}
|
|
11680
11680
|
} catch (error) {
|
|
11681
|
-
|
|
11681
|
+
_package.logger.error(`[WORKSPACE] Failed to handle workspace-file-request: ${error.message}`, error);
|
|
11682
11682
|
const errorCode = error.code === "ENOENT" ? "file_not_found" : error.code === "EACCES" ? "permission_denied" : "unknown_error";
|
|
11683
11683
|
sendResponse(context.client, createErrorResponse(requestId, taskId, errorCode, error.message));
|
|
11684
11684
|
}
|
|
@@ -11688,28 +11688,28 @@ function workspaceFileRequestHandler(context) {
|
|
|
11688
11688
|
function createTaskHandler(context) {
|
|
11689
11689
|
return async (data, callback) => {
|
|
11690
11690
|
try {
|
|
11691
|
-
|
|
11691
|
+
_package.logger.info(`[EVENT HANDLER] create-task: ${data.taskId}, agentType=${data.agentType}, agentId=${data.agentId}`);
|
|
11692
11692
|
const result = await context.workerManager.startWorker(data);
|
|
11693
11693
|
callback(result);
|
|
11694
11694
|
} catch (error) {
|
|
11695
|
-
|
|
11695
|
+
_package.logger.warn(`[EVENT HANDLER] Failed to handle create-task ${data.taskId}`, error);
|
|
11696
11696
|
}
|
|
11697
11697
|
};
|
|
11698
11698
|
}
|
|
11699
11699
|
function resumeTaskHandler(context) {
|
|
11700
11700
|
return async (data, callback) => {
|
|
11701
|
-
|
|
11701
|
+
_package.logger.debug(`[EVENT HANDLER] resume-task: ${data.taskId}, agentSessionId=${data.agentSessionId}`);
|
|
11702
11702
|
try {
|
|
11703
11703
|
const result = await context.workerManager.startWorker(data);
|
|
11704
11704
|
callback(result);
|
|
11705
11705
|
} catch (error) {
|
|
11706
|
-
|
|
11706
|
+
_package.logger.warn(`[EVENT HANDLER] Failed to handle resume-task ${data.taskId}`, error);
|
|
11707
11707
|
}
|
|
11708
11708
|
};
|
|
11709
11709
|
}
|
|
11710
11710
|
function shutdownMachineHandler(context) {
|
|
11711
11711
|
return async (data) => {
|
|
11712
|
-
|
|
11712
|
+
_package.logger.info("[EVENT HANDLER] shutdown-machine received", data);
|
|
11713
11713
|
context.requestShutdown("agentrix-app", data.reason);
|
|
11714
11714
|
};
|
|
11715
11715
|
}
|
|
@@ -11770,16 +11770,16 @@ class MachineClient {
|
|
|
11770
11770
|
|
|
11771
11771
|
let caffeinateProcess = null;
|
|
11772
11772
|
function startCaffeinate() {
|
|
11773
|
-
if (
|
|
11774
|
-
|
|
11773
|
+
if (_package.machine.disableCaffeinate) {
|
|
11774
|
+
_package.logger.debug("[caffeinate] Caffeinate disabled via AGENTRIX_DISABLE_CAFFEINATE environment variable");
|
|
11775
11775
|
return false;
|
|
11776
11776
|
}
|
|
11777
11777
|
if (process.platform !== "darwin") {
|
|
11778
|
-
|
|
11778
|
+
_package.logger.debug("[caffeinate] Not on macOS, skipping caffeinate");
|
|
11779
11779
|
return false;
|
|
11780
11780
|
}
|
|
11781
11781
|
if (caffeinateProcess && !caffeinateProcess.killed) {
|
|
11782
|
-
|
|
11782
|
+
_package.logger.debug("[caffeinate] Caffeinate already running");
|
|
11783
11783
|
return true;
|
|
11784
11784
|
}
|
|
11785
11785
|
try {
|
|
@@ -11788,30 +11788,30 @@ function startCaffeinate() {
|
|
|
11788
11788
|
detached: false
|
|
11789
11789
|
});
|
|
11790
11790
|
caffeinateProcess.on("error", (error) => {
|
|
11791
|
-
|
|
11791
|
+
_package.logger.debug("[caffeinate] Error starting caffeinate:", error);
|
|
11792
11792
|
caffeinateProcess = null;
|
|
11793
11793
|
});
|
|
11794
11794
|
caffeinateProcess.on("exit", (code, signal) => {
|
|
11795
|
-
|
|
11795
|
+
_package.logger.debug(`[caffeinate] Process exited with code ${code}, signal ${signal}`);
|
|
11796
11796
|
caffeinateProcess = null;
|
|
11797
11797
|
});
|
|
11798
|
-
|
|
11798
|
+
_package.logger.info(`[caffeinate] Started with PID ${caffeinateProcess.pid}`);
|
|
11799
11799
|
setupCleanupHandlers();
|
|
11800
11800
|
return true;
|
|
11801
11801
|
} catch (error) {
|
|
11802
|
-
|
|
11802
|
+
_package.logger.info("[caffeinate] Failed to start caffeinate:", error);
|
|
11803
11803
|
return false;
|
|
11804
11804
|
}
|
|
11805
11805
|
}
|
|
11806
11806
|
let isStopping = false;
|
|
11807
11807
|
async function stopCaffeinate() {
|
|
11808
11808
|
if (isStopping) {
|
|
11809
|
-
|
|
11809
|
+
_package.logger.info("[caffeinate] Already stopping, skipping");
|
|
11810
11810
|
return;
|
|
11811
11811
|
}
|
|
11812
11812
|
if (caffeinateProcess && !caffeinateProcess.killed) {
|
|
11813
11813
|
isStopping = true;
|
|
11814
|
-
|
|
11814
|
+
_package.logger.info(`[caffeinate] Stopping caffeinate process PID ${caffeinateProcess.pid}`);
|
|
11815
11815
|
try {
|
|
11816
11816
|
caffeinateProcess.kill("SIGTERM");
|
|
11817
11817
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
@@ -11821,7 +11821,7 @@ async function stopCaffeinate() {
|
|
|
11821
11821
|
caffeinateProcess = null;
|
|
11822
11822
|
isStopping = false;
|
|
11823
11823
|
} catch (error) {
|
|
11824
|
-
|
|
11824
|
+
_package.logger.info("[caffeinate] Error stopping caffeinate:", error);
|
|
11825
11825
|
isStopping = false;
|
|
11826
11826
|
}
|
|
11827
11827
|
}
|
|
@@ -11841,11 +11841,11 @@ function setupCleanupHandlers() {
|
|
|
11841
11841
|
process.on("SIGUSR1", cleanup);
|
|
11842
11842
|
process.on("SIGUSR2", cleanup);
|
|
11843
11843
|
process.on("uncaughtException", (error) => {
|
|
11844
|
-
|
|
11844
|
+
_package.logger.debug("[caffeinate] Uncaught exception, cleaning up:", error);
|
|
11845
11845
|
cleanup();
|
|
11846
11846
|
});
|
|
11847
11847
|
process.on("unhandledRejection", (reason, promise) => {
|
|
11848
|
-
|
|
11848
|
+
_package.logger.debug("[caffeinate] Unhandled rejection, cleaning up:", reason);
|
|
11849
11849
|
cleanup();
|
|
11850
11850
|
});
|
|
11851
11851
|
}
|
|
@@ -11927,9 +11927,9 @@ function getEnvironmentInfo() {
|
|
|
11927
11927
|
DEBUG: process.env.DEBUG,
|
|
11928
11928
|
workingDirectory: process.cwd(),
|
|
11929
11929
|
processArgv: process.argv,
|
|
11930
|
-
agentrixDir:
|
|
11931
|
-
serverUrl:
|
|
11932
|
-
logsDir:
|
|
11930
|
+
agentrixDir: _package.machine.agentrixHomeDir,
|
|
11931
|
+
serverUrl: _package.machine.serverUrl,
|
|
11932
|
+
logsDir: _package.machine.getStatePaths().logsDir,
|
|
11933
11933
|
processPid: process.pid,
|
|
11934
11934
|
nodeVersion: process.version,
|
|
11935
11935
|
platform: process.platform,
|
|
@@ -11947,12 +11947,12 @@ async function runDoctorCommand(filter) {
|
|
|
11947
11947
|
console.log(chalk.bold.cyan("\n\u{1FA7A} Agentrix CLI Doctor\n"));
|
|
11948
11948
|
if (filter === "all") {
|
|
11949
11949
|
console.log(chalk.bold("\u{1F4CB} Basic Information"));
|
|
11950
|
-
console.log(`Agentrix CLI Version: ${chalk.green(
|
|
11950
|
+
console.log(`Agentrix CLI Version: ${chalk.green(_package.packageJson.version)}`);
|
|
11951
11951
|
console.log(`Platform: ${chalk.green(process.platform)} ${process.arch}`);
|
|
11952
11952
|
console.log(`Node.js Version: ${chalk.green(process.version)}`);
|
|
11953
11953
|
console.log("");
|
|
11954
11954
|
console.log(chalk.bold("\u{1F527} Daemon Spawn Diagnostics"));
|
|
11955
|
-
const projectRoot =
|
|
11955
|
+
const projectRoot = _package.projectPath();
|
|
11956
11956
|
const wrapperPath = path.join(projectRoot, "bin", "agentrix.mjs");
|
|
11957
11957
|
const cliEntrypoint = path.join(projectRoot, "dist", "index.mjs");
|
|
11958
11958
|
console.log(`Project Root: ${chalk.blue(projectRoot)}`);
|
|
@@ -11962,9 +11962,9 @@ async function runDoctorCommand(filter) {
|
|
|
11962
11962
|
console.log(`CLI Exists: ${fs$1.existsSync(cliEntrypoint) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
|
|
11963
11963
|
console.log("");
|
|
11964
11964
|
console.log(chalk.bold("\u2699\uFE0F Configuration"));
|
|
11965
|
-
console.log(`Agentrix Home: ${chalk.blue(
|
|
11966
|
-
console.log(`Server URL: ${chalk.blue(
|
|
11967
|
-
console.log(`Logs Dir: ${chalk.blue(
|
|
11965
|
+
console.log(`Agentrix Home: ${chalk.blue(_package.machine.agentrixHomeDir)}`);
|
|
11966
|
+
console.log(`Server URL: ${chalk.blue(_package.machine.serverUrl)}`);
|
|
11967
|
+
console.log(`Logs Dir: ${chalk.blue(_package.machine.getStatePaths().logsDir)}`);
|
|
11968
11968
|
console.log(chalk.bold("\n\u{1F30D} Environment Variables"));
|
|
11969
11969
|
const env = getEnvironmentInfo();
|
|
11970
11970
|
console.log(`AGENTRIX_HOME_DIR: ${env.AGENTRIX_HOME_DIR ? chalk.green(env.AGENTRIX_HOME_DIR) : chalk.gray("not set")}`);
|
|
@@ -11974,7 +11974,7 @@ async function runDoctorCommand(filter) {
|
|
|
11974
11974
|
console.log(`NODE_ENV: ${env.NODE_ENV ? chalk.green(env.NODE_ENV) : chalk.gray("not set")}`);
|
|
11975
11975
|
console.log(chalk.bold("\n\u{1F510} Authentication"));
|
|
11976
11976
|
try {
|
|
11977
|
-
const credentials = await
|
|
11977
|
+
const credentials = await _package.machine.readCredentials();
|
|
11978
11978
|
if (credentials) {
|
|
11979
11979
|
console.log(chalk.green("\u2713 Authenticated (credentials found)"));
|
|
11980
11980
|
} else {
|
|
@@ -11987,7 +11987,7 @@ async function runDoctorCommand(filter) {
|
|
|
11987
11987
|
console.log(chalk.bold("\n\u{1F916} Daemon Status"));
|
|
11988
11988
|
try {
|
|
11989
11989
|
const isRunning = await checkIfDaemonRunningAndCleanupStaleState();
|
|
11990
|
-
const state = await
|
|
11990
|
+
const state = await _package.machine.readDaemonState();
|
|
11991
11991
|
if (isRunning && state) {
|
|
11992
11992
|
console.log(chalk.green("\u2713 Daemon is running"));
|
|
11993
11993
|
console.log(` PID: ${state.pid}`);
|
|
@@ -12003,7 +12003,7 @@ async function runDoctorCommand(filter) {
|
|
|
12003
12003
|
}
|
|
12004
12004
|
if (state) {
|
|
12005
12005
|
console.log(chalk.bold("\n\u{1F4C4} Daemon State:"));
|
|
12006
|
-
const paths =
|
|
12006
|
+
const paths = _package.machine.getStatePaths();
|
|
12007
12007
|
console.log(chalk.blue(`Location: ${paths.daemonStateFile}`));
|
|
12008
12008
|
console.log(chalk.gray(JSON.stringify(state, null, 2)));
|
|
12009
12009
|
}
|
|
@@ -12070,7 +12070,7 @@ function startDaemonControlServer({
|
|
|
12070
12070
|
}
|
|
12071
12071
|
}, async (request) => {
|
|
12072
12072
|
const { sessionId, metadata } = request.body;
|
|
12073
|
-
|
|
12073
|
+
_package.logger.debug(`[CONTROL SERVER] Session started: ${sessionId}`);
|
|
12074
12074
|
registerSession(sessionId, metadata);
|
|
12075
12075
|
return { status: "ok" };
|
|
12076
12076
|
});
|
|
@@ -12088,7 +12088,7 @@ function startDaemonControlServer({
|
|
|
12088
12088
|
}
|
|
12089
12089
|
}, async () => {
|
|
12090
12090
|
const children = getChildren();
|
|
12091
|
-
|
|
12091
|
+
_package.logger.debug(`[CONTROL SERVER] Listing ${children.length} sessions`);
|
|
12092
12092
|
return {
|
|
12093
12093
|
children: children.filter((child) => child.taskId !== void 0).map((child) => ({
|
|
12094
12094
|
startedBy: child.startedBy,
|
|
@@ -12110,7 +12110,7 @@ function startDaemonControlServer({
|
|
|
12110
12110
|
}
|
|
12111
12111
|
}, async (request) => {
|
|
12112
12112
|
const { sessionId } = request.body;
|
|
12113
|
-
|
|
12113
|
+
_package.logger.debug(`[CONTROL SERVER] Stop session request: ${sessionId}`);
|
|
12114
12114
|
const success = stopSession(sessionId);
|
|
12115
12115
|
return { success };
|
|
12116
12116
|
});
|
|
@@ -12123,25 +12123,25 @@ function startDaemonControlServer({
|
|
|
12123
12123
|
}
|
|
12124
12124
|
}
|
|
12125
12125
|
}, async () => {
|
|
12126
|
-
|
|
12126
|
+
_package.logger.debug("[CONTROL SERVER] Stop daemon request received");
|
|
12127
12127
|
setTimeout(() => {
|
|
12128
|
-
|
|
12128
|
+
_package.logger.debug("[CONTROL SERVER] Triggering daemon shutdown");
|
|
12129
12129
|
requestShutdown();
|
|
12130
12130
|
}, 50);
|
|
12131
12131
|
return { status: "stopping" };
|
|
12132
12132
|
});
|
|
12133
12133
|
app.listen({ port: 0, host: "127.0.0.1" }, (err, address) => {
|
|
12134
12134
|
if (err) {
|
|
12135
|
-
|
|
12135
|
+
_package.logger.info("[CONTROL SERVER] Failed to start:", err);
|
|
12136
12136
|
throw err;
|
|
12137
12137
|
}
|
|
12138
12138
|
const port = parseInt(address.split(":").pop());
|
|
12139
|
-
|
|
12139
|
+
_package.logger.info(`[CONTROL SERVER] Started on port ${port}`);
|
|
12140
12140
|
resolve({
|
|
12141
12141
|
port,
|
|
12142
12142
|
stop: async () => {
|
|
12143
12143
|
await app.close();
|
|
12144
|
-
|
|
12144
|
+
_package.logger.info("[CONTROL SERVER] Server stopped");
|
|
12145
12145
|
}
|
|
12146
12146
|
});
|
|
12147
12147
|
});
|
|
@@ -12149,12 +12149,12 @@ function startDaemonControlServer({
|
|
|
12149
12149
|
}
|
|
12150
12150
|
|
|
12151
12151
|
function spawnAgentrixCLI(args, options = {}) {
|
|
12152
|
-
const projectRoot =
|
|
12152
|
+
const projectRoot = _package.projectPath();
|
|
12153
12153
|
const entrypoint = path.join(projectRoot, "dist", "index.mjs");
|
|
12154
12154
|
const nodeArgs = ["--no-warnings", "--no-deprecation", entrypoint, ...args];
|
|
12155
12155
|
if (!fs$1.existsSync(entrypoint)) {
|
|
12156
12156
|
const errorMessage = `Entrypoint ${entrypoint} does not exist`;
|
|
12157
|
-
|
|
12157
|
+
_package.logger.debug(`[SPAWN Agentrix CLI] ${errorMessage}`);
|
|
12158
12158
|
throw new Error(errorMessage);
|
|
12159
12159
|
}
|
|
12160
12160
|
return child_process.spawn("node", nodeArgs, options);
|
|
@@ -12192,10 +12192,10 @@ class TaskWorkerManager {
|
|
|
12192
12192
|
registerTaskWorker(taskId, sessionMetadata) {
|
|
12193
12193
|
const pid = sessionMetadata.pid;
|
|
12194
12194
|
if (!pid) {
|
|
12195
|
-
|
|
12195
|
+
_package.logger.warn(`[SESSION] Missing PID for task ${taskId}`);
|
|
12196
12196
|
return;
|
|
12197
12197
|
}
|
|
12198
|
-
|
|
12198
|
+
_package.logger.info(`[SESSION] Registered task ${taskId}, PID: ${pid}`);
|
|
12199
12199
|
const existingSession = this.pidToTrackedSession.get(pid);
|
|
12200
12200
|
if (existingSession && existingSession.taskId === taskId) {
|
|
12201
12201
|
const awaiter = this.pidToAwaiter.get(pid);
|
|
@@ -12234,8 +12234,8 @@ class TaskWorkerManager {
|
|
|
12234
12234
|
opCode: options.eventId
|
|
12235
12235
|
};
|
|
12236
12236
|
try {
|
|
12237
|
-
const cwd =
|
|
12238
|
-
|
|
12237
|
+
const cwd = _package.machine.resolveProjectDir(options.cwd, options.userId, options.taskId);
|
|
12238
|
+
_package.machine.writeTaskInput(options);
|
|
12239
12239
|
const args = [
|
|
12240
12240
|
"worker",
|
|
12241
12241
|
"--type",
|
|
@@ -12259,10 +12259,10 @@ class TaskWorkerManager {
|
|
|
12259
12259
|
});
|
|
12260
12260
|
if (process.env.DEBUG) {
|
|
12261
12261
|
workerProcess.stdout?.on("data", (data) => {
|
|
12262
|
-
|
|
12262
|
+
_package.logger.debug(`[Daemon] worker stdout: ${data.toString()}`);
|
|
12263
12263
|
});
|
|
12264
12264
|
workerProcess.stderr?.on("data", (data) => {
|
|
12265
|
-
|
|
12265
|
+
_package.logger.debug(`[Daemon] worker stderr: ${data.toString()}`);
|
|
12266
12266
|
});
|
|
12267
12267
|
}
|
|
12268
12268
|
if (!workerProcess.pid) {
|
|
@@ -12270,7 +12270,7 @@ class TaskWorkerManager {
|
|
|
12270
12270
|
ack.message = "Failed to start worker - no PID";
|
|
12271
12271
|
return ack;
|
|
12272
12272
|
}
|
|
12273
|
-
|
|
12273
|
+
_package.logger.info(`[SESSION] Worker started, PID: ${workerProcess.pid}`);
|
|
12274
12274
|
this.trackWorkerProcess(options, workerProcess);
|
|
12275
12275
|
const [promise, resolver] = createPromiseWithTimeout({
|
|
12276
12276
|
timeoutMs: 15e3,
|
|
@@ -12297,14 +12297,14 @@ class TaskWorkerManager {
|
|
|
12297
12297
|
try {
|
|
12298
12298
|
const target = session.childProcess ? session.childProcess : { kill: (sig) => process.kill(pid, sig) };
|
|
12299
12299
|
target.kill("SIGTERM");
|
|
12300
|
-
|
|
12300
|
+
_package.logger.info(`[SESSION] Task ${taskId} stopped`);
|
|
12301
12301
|
} catch (error) {
|
|
12302
|
-
|
|
12302
|
+
_package.logger.warn(`[SESSION] Failed to stop task ${taskId}:`, error);
|
|
12303
12303
|
}
|
|
12304
12304
|
this.pidToTrackedSession.delete(pid);
|
|
12305
12305
|
return true;
|
|
12306
12306
|
}
|
|
12307
|
-
|
|
12307
|
+
_package.logger.warn(`[SESSION] Task ${taskId} not found`);
|
|
12308
12308
|
return false;
|
|
12309
12309
|
}
|
|
12310
12310
|
pruneStaleSessions() {
|
|
@@ -12317,7 +12317,7 @@ class TaskWorkerManager {
|
|
|
12317
12317
|
}
|
|
12318
12318
|
}
|
|
12319
12319
|
shutdown() {
|
|
12320
|
-
|
|
12320
|
+
_package.logger.info("[SESSION] Shutting down all sessions");
|
|
12321
12321
|
for (const [pid, session] of this.pidToTrackedSession.entries()) {
|
|
12322
12322
|
try {
|
|
12323
12323
|
if (session.startedBy === "daemon" && session.childProcess) {
|
|
@@ -12326,7 +12326,7 @@ class TaskWorkerManager {
|
|
|
12326
12326
|
process.kill(pid, "SIGTERM");
|
|
12327
12327
|
}
|
|
12328
12328
|
} catch (error) {
|
|
12329
|
-
|
|
12329
|
+
_package.logger.warn(`[SESSION] Failed to stop PID ${pid}:`, error);
|
|
12330
12330
|
}
|
|
12331
12331
|
}
|
|
12332
12332
|
this.pidToTrackedSession.clear();
|
|
@@ -12340,7 +12340,7 @@ function setupGracefulShutdown(options) {
|
|
|
12340
12340
|
let requestShutdown;
|
|
12341
12341
|
const shutdownPromise = new Promise((resolve) => {
|
|
12342
12342
|
requestShutdown = (source, errorMessage) => {
|
|
12343
|
-
|
|
12343
|
+
_package.logger.info(`${prefix} Requesting shutdown (source: ${source}, errorMessage: ${errorMessage})`);
|
|
12344
12344
|
if (onShutdownRequest) {
|
|
12345
12345
|
onShutdownRequest(source, errorMessage);
|
|
12346
12346
|
}
|
|
@@ -12356,18 +12356,18 @@ function setupGracefulShutdown(options) {
|
|
|
12356
12356
|
registerSignalHandler("SIGINT");
|
|
12357
12357
|
registerSignalHandler("SIGTERM");
|
|
12358
12358
|
process.on("uncaughtException", (error) => {
|
|
12359
|
-
|
|
12360
|
-
|
|
12359
|
+
_package.logger.info(`${prefix} FATAL: Uncaught exception`, error);
|
|
12360
|
+
_package.logger.info(`${prefix} Stack trace: ${error.stack}`);
|
|
12361
12361
|
requestShutdown("exception", error.message);
|
|
12362
12362
|
});
|
|
12363
12363
|
process.on("unhandledRejection", (reason) => {
|
|
12364
|
-
|
|
12364
|
+
_package.logger.info(`${prefix} FATAL: Unhandled promise rejection`, reason);
|
|
12365
12365
|
const error = reason instanceof Error ? reason : new Error(`Unhandled promise rejection: ${reason}`);
|
|
12366
|
-
|
|
12366
|
+
_package.logger.info(`${prefix} Stack trace: ${error.stack}`);
|
|
12367
12367
|
requestShutdown("exception", error.message);
|
|
12368
12368
|
});
|
|
12369
12369
|
process.on("exit", (code) => {
|
|
12370
|
-
|
|
12370
|
+
_package.logger.info(`${prefix} Process exiting with code: ${code}`);
|
|
12371
12371
|
});
|
|
12372
12372
|
return {
|
|
12373
12373
|
requestShutdown,
|
|
@@ -12376,33 +12376,33 @@ function setupGracefulShutdown(options) {
|
|
|
12376
12376
|
}
|
|
12377
12377
|
|
|
12378
12378
|
async function startDaemon() {
|
|
12379
|
-
Object.assign(
|
|
12379
|
+
Object.assign(_package.logger, _package.createLogger({ type: "daemon" }));
|
|
12380
12380
|
const { requestShutdown, shutdownPromise } = setupGracefulShutdown({
|
|
12381
12381
|
processType: "daemon"
|
|
12382
12382
|
});
|
|
12383
12383
|
console.log("[DAEMON RUN] Starting daemon process...");
|
|
12384
|
-
|
|
12384
|
+
_package.logger.debug("[DAEMON RUN] Environment", getEnvironmentInfo());
|
|
12385
12385
|
const running = await isLatestDaemonRunning();
|
|
12386
12386
|
if (running) {
|
|
12387
12387
|
console.log("Daemon already running...");
|
|
12388
12388
|
process.exit(0);
|
|
12389
12389
|
}
|
|
12390
|
-
let daemonLockHandle = await
|
|
12390
|
+
let daemonLockHandle = await _package.machine.acquireDaemonLock(5, 200);
|
|
12391
12391
|
while (!daemonLockHandle) {
|
|
12392
12392
|
await stopDaemon();
|
|
12393
|
-
daemonLockHandle = await
|
|
12393
|
+
daemonLockHandle = await _package.machine.acquireDaemonLock(5, 200);
|
|
12394
12394
|
if (!daemonLockHandle) {
|
|
12395
|
-
|
|
12395
|
+
_package.logger.debug("[DAEMON RUN] cannot acquire daemon lock...");
|
|
12396
12396
|
process.exit(1);
|
|
12397
12397
|
}
|
|
12398
12398
|
}
|
|
12399
12399
|
try {
|
|
12400
12400
|
const caffeinateStarted = startCaffeinate();
|
|
12401
12401
|
if (caffeinateStarted) {
|
|
12402
|
-
|
|
12402
|
+
_package.logger.debug("[DAEMON RUN] Sleep prevention enabled");
|
|
12403
12403
|
}
|
|
12404
12404
|
const credentials = await authAndSetupMachineIfNeeded();
|
|
12405
|
-
|
|
12405
|
+
_package.logger.debug("[DAEMON RUN] Auth and machine setup complete");
|
|
12406
12406
|
const sessionManager = new TaskWorkerManager();
|
|
12407
12407
|
const { port: controlPort, stop: stopControlServer } = await startDaemonControlServer({
|
|
12408
12408
|
getChildren: () => sessionManager.getCurrentSessions(),
|
|
@@ -12414,15 +12414,15 @@ async function startDaemon() {
|
|
|
12414
12414
|
pid: process.pid,
|
|
12415
12415
|
port: controlPort,
|
|
12416
12416
|
startTime: (/* @__PURE__ */ new Date()).toLocaleString(),
|
|
12417
|
-
cliVersion:
|
|
12418
|
-
logPath:
|
|
12417
|
+
cliVersion: _package.packageJson.version,
|
|
12418
|
+
logPath: _package.getLogPath({ type: "daemon" })
|
|
12419
12419
|
};
|
|
12420
|
-
|
|
12421
|
-
|
|
12420
|
+
_package.machine.writeDaemonState(fileState);
|
|
12421
|
+
_package.logger.debug("[DAEMON RUN] Daemon state written");
|
|
12422
12422
|
const machineClient = new MachineClient(
|
|
12423
12423
|
{
|
|
12424
12424
|
machineId: credentials.machineId,
|
|
12425
|
-
serverUrl:
|
|
12425
|
+
serverUrl: _package.machine.serverUrl.replace(/^http/, "ws"),
|
|
12426
12426
|
path: "/v1/ws",
|
|
12427
12427
|
auth: shared.machineAuth(credentials.token, credentials.machineId),
|
|
12428
12428
|
keepAliveConfig: {
|
|
@@ -12439,32 +12439,32 @@ async function startDaemon() {
|
|
|
12439
12439
|
intervalMs: 3e4,
|
|
12440
12440
|
timeoutMs: 5e3
|
|
12441
12441
|
},
|
|
12442
|
-
logger: (message, ...args) =>
|
|
12442
|
+
logger: (message, ...args) => _package.logger.debug(`[DAEMON SOCKET] ${message}`, ...args)
|
|
12443
12443
|
},
|
|
12444
12444
|
sessionManager,
|
|
12445
12445
|
{ requestShutdown }
|
|
12446
12446
|
);
|
|
12447
12447
|
await machineClient.connect();
|
|
12448
|
-
|
|
12448
|
+
_package.logger.info("[DAEMON RUN] Machine client connected to server");
|
|
12449
12449
|
const cleanupAndShutdown = async (source, errorMessage) => {
|
|
12450
12450
|
await machineClient.disconnect();
|
|
12451
12451
|
await stopControlServer();
|
|
12452
12452
|
await cleanupDaemonState();
|
|
12453
12453
|
await stopCaffeinate();
|
|
12454
|
-
await
|
|
12455
|
-
|
|
12454
|
+
await _package.machine.releaseDaemonLock(daemonLockHandle);
|
|
12455
|
+
_package.logger.info("[DAEMON RUN] Cleanup completed, exiting process");
|
|
12456
12456
|
process.exit(0);
|
|
12457
12457
|
};
|
|
12458
|
-
|
|
12458
|
+
_package.logger.info("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");
|
|
12459
12459
|
const shutdownRequest = await shutdownPromise;
|
|
12460
12460
|
await cleanupAndShutdown(shutdownRequest.source, shutdownRequest.errorMessage);
|
|
12461
12461
|
} catch (error) {
|
|
12462
|
-
|
|
12462
|
+
_package.logger.info("[DAEMON RUN][FATAL] Failed somewhere unexpectedly - exiting with code 1", error);
|
|
12463
12463
|
process.exit(1);
|
|
12464
12464
|
}
|
|
12465
12465
|
}
|
|
12466
12466
|
|
|
12467
|
-
var require$$0 = /*@__PURE__*/getAugmentedNamespace(
|
|
12467
|
+
var require$$0 = /*@__PURE__*/getAugmentedNamespace(_package.logger$1);
|
|
12468
12468
|
|
|
12469
12469
|
const VALID_HOOK_NAMES = [
|
|
12470
12470
|
// SDK native hooks
|
|
@@ -12528,14 +12528,14 @@ function createWorkerEventHandlers(context) {
|
|
|
12528
12528
|
if (data.taskId !== context.taskId) {
|
|
12529
12529
|
return;
|
|
12530
12530
|
}
|
|
12531
|
-
|
|
12531
|
+
_package.logger.info(`[WORKER] Task ${context.taskId} cancelled`);
|
|
12532
12532
|
await context.stopTask();
|
|
12533
12533
|
},
|
|
12534
12534
|
"stop-task": async (data) => {
|
|
12535
12535
|
if (data.taskId !== context.taskId) {
|
|
12536
12536
|
return;
|
|
12537
12537
|
}
|
|
12538
|
-
|
|
12538
|
+
_package.logger.info(`[WORKER] Task ${context.taskId} stopped: ${data.reason || "no reason"}`);
|
|
12539
12539
|
await context.stopTask();
|
|
12540
12540
|
},
|
|
12541
12541
|
"task-message": async (data) => {
|
|
@@ -12674,7 +12674,7 @@ class WorkerClient {
|
|
|
12674
12674
|
toolInput
|
|
12675
12675
|
};
|
|
12676
12676
|
this.client.send("require-permission", permissionRequest);
|
|
12677
|
-
|
|
12677
|
+
_package.logger.info(`[AGENT] Permission requested for tool: ${toolName}`);
|
|
12678
12678
|
return eventId;
|
|
12679
12679
|
}
|
|
12680
12680
|
sendUpdateTaskAgentSessionId(agentSessionId) {
|
|
@@ -12692,7 +12692,7 @@ class WorkerClient {
|
|
|
12692
12692
|
title
|
|
12693
12693
|
};
|
|
12694
12694
|
this.client.send("change-task-title", event);
|
|
12695
|
-
|
|
12695
|
+
_package.logger.info(`[AGENT] Title changed to: ${title}`);
|
|
12696
12696
|
}
|
|
12697
12697
|
sendTaskArtifactsUpdated(commitHash, stats) {
|
|
12698
12698
|
const event = {
|
|
@@ -12703,7 +12703,7 @@ class WorkerClient {
|
|
|
12703
12703
|
stats
|
|
12704
12704
|
};
|
|
12705
12705
|
this.client.send("task-artifacts-updated", event);
|
|
12706
|
-
|
|
12706
|
+
_package.logger.info(`[AGENT] Task artifacts updated, commit: ${commitHash}, +${stats.totalInsertions}/-${stats.totalDeletions}`);
|
|
12707
12707
|
}
|
|
12708
12708
|
// sendGitPushResponse removed in new flow
|
|
12709
12709
|
async sendMergeRequest(summary, description) {
|
|
@@ -12713,12 +12713,12 @@ class WorkerClient {
|
|
|
12713
12713
|
summary,
|
|
12714
12714
|
description
|
|
12715
12715
|
};
|
|
12716
|
-
|
|
12716
|
+
_package.logger.info(`[MERGE] Sending merge-request event for task ${this.context.taskId}`);
|
|
12717
12717
|
const ack = await this.client.sendWithAck("merge-request", event);
|
|
12718
12718
|
if (!ack.success) {
|
|
12719
12719
|
throw new Error(`Failed to create pull request: ${ack.error || "Unknown error"}`);
|
|
12720
12720
|
}
|
|
12721
|
-
|
|
12721
|
+
_package.logger.info(`[MERGE] Pull request created: #${ack.data.pullRequestNumber}`);
|
|
12722
12722
|
return {
|
|
12723
12723
|
pullRequestNumber: ack.data.pullRequestNumber,
|
|
12724
12724
|
pullRequestUrl: ack.data.pullRequestUrl
|
|
@@ -12953,7 +12953,7 @@ async function setupWorkspace(options, hooks) {
|
|
|
12953
12953
|
shouldManageGit: false
|
|
12954
12954
|
};
|
|
12955
12955
|
}
|
|
12956
|
-
const workingDirectory =
|
|
12956
|
+
const workingDirectory = _package.machine.resolveProjectDir(cwd, userId, taskId);
|
|
12957
12957
|
if (gitUrl) {
|
|
12958
12958
|
const initialCommitHash = await setupGitRepository(
|
|
12959
12959
|
workingDirectory,
|
|
@@ -13013,11 +13013,11 @@ async function handleGitState(workingDirectory, userId, taskId, commitMessage) {
|
|
|
13013
13013
|
hadUncommittedChanges = true;
|
|
13014
13014
|
}
|
|
13015
13015
|
const currentCommitHash = await getCurrentCommitHash(workingDirectory);
|
|
13016
|
-
const initialHash = await
|
|
13016
|
+
const initialHash = await _package.machine.readInitialCommitHash(userId, taskId);
|
|
13017
13017
|
if (!initialHash) {
|
|
13018
13018
|
throw new Error(`Initial commit hash not found for task ${taskId}`);
|
|
13019
13019
|
}
|
|
13020
|
-
const dataDir =
|
|
13020
|
+
const dataDir = _package.machine.resolveDataDir(userId, taskId);
|
|
13021
13021
|
const patchPath = await generateAndSavePatch(
|
|
13022
13022
|
workingDirectory,
|
|
13023
13023
|
initialHash,
|
|
@@ -13400,7 +13400,7 @@ class ClaudeWorker {
|
|
|
13400
13400
|
if (this.options.input.dataEncryptionKey && this.options.secretKey) {
|
|
13401
13401
|
this.dataEncryptionKey = shared.decryptWithEphemeralKey(shared.decodeBase64(this.options.input.dataEncryptionKey), this.options.secretKey);
|
|
13402
13402
|
}
|
|
13403
|
-
const logger
|
|
13403
|
+
const logger = this.createLogger({ type: "worker", taskId });
|
|
13404
13404
|
try {
|
|
13405
13405
|
const hooks = await this.loadAgentHooks();
|
|
13406
13406
|
const workspaceResult = await setupWorkspace({
|
|
@@ -13414,7 +13414,7 @@ class ClaudeWorker {
|
|
|
13414
13414
|
shouldManageGit = workspaceResult.shouldManageGit;
|
|
13415
13415
|
initialCommitHash = workspaceResult.initialCommitHash;
|
|
13416
13416
|
if (initialCommitHash) {
|
|
13417
|
-
await
|
|
13417
|
+
await _package.machine.writeInitialCommitHash(userId, taskId, initialCommitHash);
|
|
13418
13418
|
this.log("info", "GIT", `Initial commit: ${initialCommitHash}`);
|
|
13419
13419
|
this.initialCommitHashForPR = initialCommitHash;
|
|
13420
13420
|
}
|
|
@@ -13471,7 +13471,7 @@ class ClaudeWorker {
|
|
|
13471
13471
|
workingDirectory,
|
|
13472
13472
|
shouldManageGit,
|
|
13473
13473
|
initialCommitHash,
|
|
13474
|
-
logger
|
|
13474
|
+
logger
|
|
13475
13475
|
};
|
|
13476
13476
|
this.coordinator = new MessageCoordinator({
|
|
13477
13477
|
workerType: "claude",
|
|
@@ -14047,7 +14047,7 @@ URL: ${result.pullRequestUrl}`
|
|
|
14047
14047
|
taskId,
|
|
14048
14048
|
machineId: this.credentials.machineId,
|
|
14049
14049
|
cwd,
|
|
14050
|
-
serverUrl:
|
|
14050
|
+
serverUrl: _package.machine.serverUrl.replace(/^http/, "ws"),
|
|
14051
14051
|
path: "/v1/ws",
|
|
14052
14052
|
auth: shared.workerAuth(this.credentials.token, this.credentials.machineId, taskId),
|
|
14053
14053
|
dataEncryptionKey: this.dataEncryptionKey
|
|
@@ -15821,8 +15821,8 @@ class CodexWorker {
|
|
|
15821
15821
|
let workingDirectory = process.cwd();
|
|
15822
15822
|
let shouldManageGit = false;
|
|
15823
15823
|
let initialCommitHash;
|
|
15824
|
-
const logger
|
|
15825
|
-
this.context = { ...this.context, logger
|
|
15824
|
+
const logger = this.createLogger({ type: "worker", taskId });
|
|
15825
|
+
this.context = { ...this.context, logger };
|
|
15826
15826
|
try {
|
|
15827
15827
|
const workspaceResult = await setupWorkspace({
|
|
15828
15828
|
gitUrl: this.options.input.gitUrl,
|
|
@@ -15835,7 +15835,7 @@ class CodexWorker {
|
|
|
15835
15835
|
shouldManageGit = workspaceResult.shouldManageGit;
|
|
15836
15836
|
initialCommitHash = workspaceResult.initialCommitHash;
|
|
15837
15837
|
if (initialCommitHash) {
|
|
15838
|
-
await
|
|
15838
|
+
await _package.machine.writeInitialCommitHash(userId, taskId, initialCommitHash);
|
|
15839
15839
|
this.log("info", "GIT", `Initial commit: ${initialCommitHash}`);
|
|
15840
15840
|
this.initialCommitHashForPR = initialCommitHash;
|
|
15841
15841
|
}
|
|
@@ -15891,7 +15891,7 @@ class CodexWorker {
|
|
|
15891
15891
|
workingDirectory,
|
|
15892
15892
|
shouldManageGit,
|
|
15893
15893
|
initialCommitHash,
|
|
15894
|
-
logger
|
|
15894
|
+
logger
|
|
15895
15895
|
};
|
|
15896
15896
|
this.coordinator = new MessageCoordinator({
|
|
15897
15897
|
workerType: "codex",
|
|
@@ -16300,7 +16300,7 @@ URL: ${result.pullRequestUrl}`);
|
|
|
16300
16300
|
} else if (block.type === "image" && block.source && block.source.url) {
|
|
16301
16301
|
const url = block.source.url;
|
|
16302
16302
|
try {
|
|
16303
|
-
const attachmentsDir =
|
|
16303
|
+
const attachmentsDir = _package.machine.resolveAttachmentsDir(
|
|
16304
16304
|
this.options.input.userId,
|
|
16305
16305
|
this.taskId
|
|
16306
16306
|
);
|
|
@@ -16440,7 +16440,7 @@ URL: ${result.pullRequestUrl}`);
|
|
|
16440
16440
|
taskId,
|
|
16441
16441
|
machineId: this.credentials.machineId,
|
|
16442
16442
|
cwd,
|
|
16443
|
-
serverUrl:
|
|
16443
|
+
serverUrl: _package.machine.serverUrl.replace(/^http/, "ws"),
|
|
16444
16444
|
path: "/v1/ws",
|
|
16445
16445
|
auth: shared.workerAuth(this.credentials.token, this.credentials.machineId, taskId),
|
|
16446
16446
|
dataEncryptionKey: this.dataEncryptionKey
|
|
@@ -16562,7 +16562,7 @@ const workerTypes = ["claude", "codex"];
|
|
|
16562
16562
|
const workerRegistry = {
|
|
16563
16563
|
claude: {
|
|
16564
16564
|
async run({ credentials, startedBy, userId, taskId, idleTimeoutSecond, secretKey }) {
|
|
16565
|
-
const input =
|
|
16565
|
+
const input = _package.machine.readTaskInput(userId, taskId);
|
|
16566
16566
|
const options = {
|
|
16567
16567
|
startedBy,
|
|
16568
16568
|
idleTimeoutSecond,
|
|
@@ -16574,7 +16574,7 @@ const workerRegistry = {
|
|
|
16574
16574
|
},
|
|
16575
16575
|
codex: {
|
|
16576
16576
|
async run({ credentials, startedBy, userId, taskId, idleTimeoutSecond, secretKey }) {
|
|
16577
|
-
const input =
|
|
16577
|
+
const input = _package.machine.readTaskInput(userId, taskId);
|
|
16578
16578
|
const options = {
|
|
16579
16579
|
startedBy,
|
|
16580
16580
|
idleTimeoutSecond,
|
|
@@ -16586,13 +16586,138 @@ const workerRegistry = {
|
|
|
16586
16586
|
}
|
|
16587
16587
|
};
|
|
16588
16588
|
|
|
16589
|
-
|
|
16589
|
+
async function checkForUpgrades() {
|
|
16590
|
+
const currentVersion = _package.packageJson.version;
|
|
16591
|
+
try {
|
|
16592
|
+
const output = child_process.execSync("npm view @agentrix/cli version", {
|
|
16593
|
+
encoding: "utf-8",
|
|
16594
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
16595
|
+
// Suppress stderr
|
|
16596
|
+
timeout: 5e3
|
|
16597
|
+
// 5 second timeout
|
|
16598
|
+
}).trim();
|
|
16599
|
+
const latestVersion = output;
|
|
16600
|
+
const hasUpgrade = compareVersions(latestVersion, currentVersion) > 0;
|
|
16601
|
+
return {
|
|
16602
|
+
hasUpgrade,
|
|
16603
|
+
currentVersion,
|
|
16604
|
+
latestVersion
|
|
16605
|
+
};
|
|
16606
|
+
} catch (error) {
|
|
16607
|
+
return {
|
|
16608
|
+
hasUpgrade: false,
|
|
16609
|
+
currentVersion,
|
|
16610
|
+
latestVersion: null
|
|
16611
|
+
};
|
|
16612
|
+
}
|
|
16613
|
+
}
|
|
16614
|
+
function compareVersions(v1, v2) {
|
|
16615
|
+
const parts1 = v1.split(".").map(Number);
|
|
16616
|
+
const parts2 = v2.split(".").map(Number);
|
|
16617
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
16618
|
+
const part1 = parts1[i] || 0;
|
|
16619
|
+
const part2 = parts2[i] || 0;
|
|
16620
|
+
if (part1 > part2) return 1;
|
|
16621
|
+
if (part1 < part2) return -1;
|
|
16622
|
+
}
|
|
16623
|
+
return 0;
|
|
16624
|
+
}
|
|
16625
|
+
function displayUpgradeNotification(result) {
|
|
16626
|
+
if (!result.hasUpgrade || !result.latestVersion) {
|
|
16627
|
+
return;
|
|
16628
|
+
}
|
|
16629
|
+
console.log("");
|
|
16630
|
+
console.log(chalk.yellow("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
16631
|
+
console.log(chalk.yellow("\u2502") + " " + chalk.bold("Upgrade Available") + " " + chalk.yellow("\u2502"));
|
|
16632
|
+
console.log(chalk.yellow("\u2502") + " " + chalk.yellow("\u2502"));
|
|
16633
|
+
console.log(chalk.yellow("\u2502") + ` Current: ${chalk.dim(result.currentVersion)} \u2192 Latest: ${chalk.green.bold(result.latestVersion)} ` + chalk.yellow("\u2502"));
|
|
16634
|
+
console.log(chalk.yellow("\u2502") + " " + chalk.yellow("\u2502"));
|
|
16635
|
+
console.log(chalk.yellow("\u2502") + " Run " + chalk.cyan.bold("agentrix upgrade") + " to upgrade " + chalk.yellow("\u2502"));
|
|
16636
|
+
console.log(chalk.yellow("\u2502") + " " + chalk.yellow("\u2502"));
|
|
16637
|
+
console.log(chalk.yellow("\u2502") + " To enable auto-upgrade, set: " + chalk.yellow("\u2502"));
|
|
16638
|
+
console.log(chalk.yellow("\u2502") + " " + chalk.dim("AGENTRIX_DISABLE_AUTO_UPGRADE=false") + " " + chalk.yellow("\u2502"));
|
|
16639
|
+
console.log(chalk.yellow("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
16640
|
+
console.log("");
|
|
16641
|
+
}
|
|
16642
|
+
function isAutoUpgradeDisabled() {
|
|
16643
|
+
return process.env.AGENTRIX_DISABLE_AUTO_UPGRADE === "true";
|
|
16644
|
+
}
|
|
16645
|
+
async function performAutoUpgrade() {
|
|
16646
|
+
try {
|
|
16647
|
+
const { execSync: execSync2 } = await import('child_process');
|
|
16648
|
+
console.log("");
|
|
16649
|
+
console.log(chalk.blue("\u{1F504} Auto-upgrading Agentrix CLI..."));
|
|
16650
|
+
let packageManager = "npm";
|
|
16651
|
+
try {
|
|
16652
|
+
execSync2("yarn --version", { stdio: "ignore" });
|
|
16653
|
+
packageManager = "yarn";
|
|
16654
|
+
} catch {
|
|
16655
|
+
}
|
|
16656
|
+
console.log(chalk.dim(` Using ${packageManager}...`));
|
|
16657
|
+
if (packageManager === "yarn") {
|
|
16658
|
+
execSync2("yarn global upgrade @agentrix/cli", { stdio: "inherit" });
|
|
16659
|
+
} else {
|
|
16660
|
+
execSync2("npm update -g @agentrix/cli", { stdio: "inherit" });
|
|
16661
|
+
}
|
|
16662
|
+
console.log(chalk.green("\u2713 Upgrade complete"));
|
|
16663
|
+
console.log("");
|
|
16664
|
+
return true;
|
|
16665
|
+
} catch (error) {
|
|
16666
|
+
console.log("");
|
|
16667
|
+
console.log(chalk.yellow("\u26A0\uFE0F Auto-upgrade failed"));
|
|
16668
|
+
console.log(chalk.dim(" You can upgrade manually with: agentrix upgrade"));
|
|
16669
|
+
console.log("");
|
|
16670
|
+
return false;
|
|
16671
|
+
}
|
|
16672
|
+
}
|
|
16673
|
+
|
|
16674
|
+
const cli = yargs(helpers.hideBin(process.argv)).scriptName("agentrix").version(_package.packageJson.version).usage("$0 <command> [options]").option("debug", {
|
|
16590
16675
|
alias: "d",
|
|
16591
16676
|
type: "boolean",
|
|
16592
16677
|
describe: "Use local-debug mode (plaintext, for debugging)",
|
|
16593
16678
|
global: true
|
|
16594
16679
|
}).help("help").alias("h", "help").alias("v", "version").strict().epilog("For more information, visit https://github.com/xmz-ai/agentrix-cli");
|
|
16595
|
-
void
|
|
16680
|
+
void _package.machine.getStatePaths;
|
|
16681
|
+
cli.command("upgrade", "Upgrade CLI to the latest version", {}, async (argv) => {
|
|
16682
|
+
console.log(chalk.dim(`Current version: ${_package.packageJson.version}`));
|
|
16683
|
+
const daemonRunning = await checkIfDaemonRunningAndCleanupStaleState();
|
|
16684
|
+
const upgraded = await performAutoUpgrade();
|
|
16685
|
+
if (!upgraded) {
|
|
16686
|
+
process.exit(1);
|
|
16687
|
+
}
|
|
16688
|
+
if (daemonRunning) {
|
|
16689
|
+
console.log(chalk.blue("Restarting daemon..."));
|
|
16690
|
+
await stopDaemon();
|
|
16691
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
16692
|
+
const daemonProcess = spawnAgentrixCLI(["daemon"], {
|
|
16693
|
+
detached: true,
|
|
16694
|
+
stdio: "ignore",
|
|
16695
|
+
env: process.env
|
|
16696
|
+
});
|
|
16697
|
+
daemonProcess.unref();
|
|
16698
|
+
let started = false;
|
|
16699
|
+
for (let i = 0; i < 50; i++) {
|
|
16700
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
16701
|
+
if (await checkIfDaemonRunningAndCleanupStaleState()) {
|
|
16702
|
+
started = true;
|
|
16703
|
+
break;
|
|
16704
|
+
}
|
|
16705
|
+
}
|
|
16706
|
+
if (started) {
|
|
16707
|
+
console.log(chalk.green("\u2713 Daemon restarted successfully"));
|
|
16708
|
+
} else {
|
|
16709
|
+
console.log(chalk.yellow("\u26A0\uFE0F Daemon may still be starting. Run 'agentrix status' to check."));
|
|
16710
|
+
}
|
|
16711
|
+
}
|
|
16712
|
+
try {
|
|
16713
|
+
const { version } = await Promise.resolve().then(function () { return require('./logger-BZmE9yGJ.cjs'); }).then(function (n) { return n._package; });
|
|
16714
|
+
console.log(chalk.green(`
|
|
16715
|
+
\u2713 Now running version: ${version}`));
|
|
16716
|
+
} catch {
|
|
16717
|
+
console.log(chalk.dim("\nRun 'agentrix --version' to see the new version"));
|
|
16718
|
+
}
|
|
16719
|
+
process.exit(0);
|
|
16720
|
+
});
|
|
16596
16721
|
cli.command("doctor", "System diagnostics & troubleshooting", {}, async (argv) => {
|
|
16597
16722
|
await runDoctorCommand();
|
|
16598
16723
|
process.exit(0);
|
|
@@ -16716,7 +16841,7 @@ cli.command(
|
|
|
16716
16841
|
}
|
|
16717
16842
|
const startedBy = argv["started-by"];
|
|
16718
16843
|
const credentials = await authAndSetupMachineIfNeeded();
|
|
16719
|
-
const secretKey = await
|
|
16844
|
+
const secretKey = await _package.machine.getSecretKey();
|
|
16720
16845
|
const userId = argv["user-id"];
|
|
16721
16846
|
const taskId = argv["task-id"];
|
|
16722
16847
|
const idleTimeoutSecond = argv["idle-timeout"];
|
|
@@ -16744,6 +16869,41 @@ cli.command(
|
|
|
16744
16869
|
}
|
|
16745
16870
|
process.exit(1);
|
|
16746
16871
|
}
|
|
16872
|
+
const skipUpgradeCheck = process.env.AGENTRIX_SKIP_UPGRADE_CHECK === "true";
|
|
16873
|
+
const autoUpgradeDisabled = isAutoUpgradeDisabled();
|
|
16874
|
+
let upgradeResult = {
|
|
16875
|
+
hasUpgrade: false,
|
|
16876
|
+
currentVersion: "",
|
|
16877
|
+
latestVersion: null
|
|
16878
|
+
};
|
|
16879
|
+
if (!skipUpgradeCheck) {
|
|
16880
|
+
upgradeResult = await checkForUpgrades();
|
|
16881
|
+
}
|
|
16882
|
+
if (upgradeResult.hasUpgrade) {
|
|
16883
|
+
if (autoUpgradeDisabled) {
|
|
16884
|
+
displayUpgradeNotification(upgradeResult);
|
|
16885
|
+
} else {
|
|
16886
|
+
const upgraded = await performAutoUpgrade();
|
|
16887
|
+
if (upgraded) {
|
|
16888
|
+
console.log(chalk.green("\u2713 Restarting with new version..."));
|
|
16889
|
+
console.log("");
|
|
16890
|
+
const { execSync } = await import('child_process');
|
|
16891
|
+
try {
|
|
16892
|
+
execSync("agentrix start", {
|
|
16893
|
+
stdio: "inherit",
|
|
16894
|
+
env: {
|
|
16895
|
+
...process.env,
|
|
16896
|
+
// Set flag to prevent infinite upgrade loop
|
|
16897
|
+
AGENTRIX_SKIP_UPGRADE_CHECK: "true"
|
|
16898
|
+
}
|
|
16899
|
+
});
|
|
16900
|
+
process.exit(0);
|
|
16901
|
+
} catch (error) {
|
|
16902
|
+
console.log(chalk.yellow("\u26A0\uFE0F Failed to restart, continuing with upgrade..."));
|
|
16903
|
+
}
|
|
16904
|
+
}
|
|
16905
|
+
}
|
|
16906
|
+
}
|
|
16747
16907
|
const wasRunning = await isLatestDaemonRunning();
|
|
16748
16908
|
if (!wasRunning) {
|
|
16749
16909
|
console.log("Starting Agentrix background service...");
|