@phnx-labs/agents-cli 1.22.0 → 1.22.1
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/CHANGELOG.md +69 -0
- package/dist/bin/agents +0 -0
- package/dist/commands/doctor.js +34 -2
- package/dist/commands/projects.js +103 -65
- package/dist/lib/app-bundle-install.d.ts +17 -0
- package/dist/lib/app-bundle-install.js +94 -0
- package/dist/lib/devices/doctor-findings.js +12 -4
- package/dist/lib/devices/doctor-overview-cache.d.ts +45 -0
- package/dist/lib/devices/doctor-overview-cache.js +168 -0
- package/dist/lib/devices/fleet.js +7 -2
- package/dist/lib/devices/self-host.d.ts +9 -0
- package/dist/lib/devices/self-host.js +61 -0
- package/dist/lib/hosts/passthrough.js +8 -6
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.js +27 -23
- package/dist/lib/project-status.d.ts +7 -0
- package/dist/lib/project-status.js +9 -0
- package/dist/lib/projects.d.ts +11 -2
- package/dist/lib/projects.js +57 -9
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/install-helper.js +28 -31
- package/dist/lib/versions.js +69 -22
- package/package.json +1 -1
package/dist/lib/versions.js
CHANGED
|
@@ -1267,34 +1267,23 @@ export function isVersionIsolated(agent, version) {
|
|
|
1267
1267
|
return fs.existsSync(getIsolatedMarkerPath(agent, version));
|
|
1268
1268
|
}
|
|
1269
1269
|
/**
|
|
1270
|
-
*
|
|
1271
|
-
*
|
|
1272
|
-
*
|
|
1273
|
-
* its generic platform copy into the target version's isolated home so
|
|
1274
|
-
* `listInstalledVersions` and the shim resolve the right binary.
|
|
1270
|
+
* Move any `grok-<installedVersion>-...` binary (and its generic platform
|
|
1271
|
+
* copy) found directly under `sourceDownloads` into `targetDownloads`.
|
|
1272
|
+
* Returns true if the versioned binary was moved.
|
|
1275
1273
|
*/
|
|
1276
|
-
function
|
|
1277
|
-
const hostGrokLink = path.join(getHomeDir(), agentConfigDirName('grok'));
|
|
1278
|
-
let sourceDownloads;
|
|
1279
|
-
try {
|
|
1280
|
-
sourceDownloads = path.join(fs.readlinkSync(hostGrokLink), 'downloads');
|
|
1281
|
-
}
|
|
1282
|
-
catch {
|
|
1283
|
-
sourceDownloads = path.join(hostGrokLink, 'downloads');
|
|
1284
|
-
}
|
|
1285
|
-
const targetDownloads = path.join(getVersionHomePath('grok', installedVersion), agentConfigDirName('grok'), 'downloads');
|
|
1274
|
+
function tryMoveGrokDownloads(sourceDownloads, targetDownloads, installedVersion) {
|
|
1286
1275
|
if (!fs.existsSync(sourceDownloads))
|
|
1287
|
-
return;
|
|
1276
|
+
return false;
|
|
1288
1277
|
if (path.resolve(sourceDownloads) === path.resolve(targetDownloads))
|
|
1289
|
-
return;
|
|
1278
|
+
return false;
|
|
1290
1279
|
const entries = fs.readdirSync(sourceDownloads).filter((e) => e.startsWith('grok-'));
|
|
1291
1280
|
if (entries.length === 0)
|
|
1292
|
-
return;
|
|
1293
|
-
fs.mkdirSync(targetDownloads, { recursive: true });
|
|
1281
|
+
return false;
|
|
1294
1282
|
const escapedVersion = installedVersion.replace(/\./g, '\\.');
|
|
1295
1283
|
const versionedPattern = new RegExp(`^grok-${escapedVersion}-`);
|
|
1296
1284
|
const movedPaths = [];
|
|
1297
|
-
// Move the versioned binary first
|
|
1285
|
+
// Move the versioned binary first — only create the target dir once we
|
|
1286
|
+
// know there is something to move into it.
|
|
1298
1287
|
for (const entry of entries) {
|
|
1299
1288
|
if (!versionedPattern.test(entry))
|
|
1300
1289
|
continue;
|
|
@@ -1303,6 +1292,7 @@ function relocateGrokBinaryToVersionHome(installedVersion) {
|
|
|
1303
1292
|
if (fs.existsSync(dst))
|
|
1304
1293
|
continue;
|
|
1305
1294
|
try {
|
|
1295
|
+
fs.mkdirSync(targetDownloads, { recursive: true });
|
|
1306
1296
|
fs.renameSync(src, dst);
|
|
1307
1297
|
movedPaths.push(dst);
|
|
1308
1298
|
}
|
|
@@ -1311,7 +1301,7 @@ function relocateGrokBinaryToVersionHome(installedVersion) {
|
|
|
1311
1301
|
}
|
|
1312
1302
|
}
|
|
1313
1303
|
if (movedPaths.length === 0)
|
|
1314
|
-
return;
|
|
1304
|
+
return false;
|
|
1315
1305
|
// The installer also creates a generic platform binary (e.g. grok-macos-aarch64)
|
|
1316
1306
|
// that is a copy of the versioned binary. Move it too if its size matches.
|
|
1317
1307
|
const movedSize = fs.statSync(movedPaths[0]).size;
|
|
@@ -1331,6 +1321,42 @@ function relocateGrokBinaryToVersionHome(installedVersion) {
|
|
|
1331
1321
|
/* ignore per-file failures */
|
|
1332
1322
|
}
|
|
1333
1323
|
}
|
|
1324
|
+
return true;
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Grok's official installer writes into ~/.grok/downloads, which (because we
|
|
1328
|
+
* symlink ~/.grok to the active version home) resolves to the PREVIOUS default
|
|
1329
|
+
* home during `agents add grok@<new>`. Move the freshly-downloaded binary and
|
|
1330
|
+
* its generic platform copy into the target version's isolated home so
|
|
1331
|
+
* `listInstalledVersions` and the shim resolve the right binary.
|
|
1332
|
+
*
|
|
1333
|
+
* Self-healing: if `~/.grok`'s current target has nothing matching (e.g. a
|
|
1334
|
+
* PAST install mislabeled `installedVersion` as the literal string 'latest',
|
|
1335
|
+
* whose regex never matched the real filename, stranding the binary in
|
|
1336
|
+
* whatever version was default at the time), sweep every other installed
|
|
1337
|
+
* grok version home for the missing file before giving up.
|
|
1338
|
+
*/
|
|
1339
|
+
function relocateGrokBinaryToVersionHome(installedVersion) {
|
|
1340
|
+
const hostGrokLink = path.join(getHomeDir(), agentConfigDirName('grok'));
|
|
1341
|
+
let sourceDownloads;
|
|
1342
|
+
try {
|
|
1343
|
+
sourceDownloads = path.join(fs.readlinkSync(hostGrokLink), 'downloads');
|
|
1344
|
+
}
|
|
1345
|
+
catch {
|
|
1346
|
+
sourceDownloads = path.join(hostGrokLink, 'downloads');
|
|
1347
|
+
}
|
|
1348
|
+
const targetDownloads = path.join(getVersionHomePath('grok', installedVersion), agentConfigDirName('grok'), 'downloads');
|
|
1349
|
+
if (tryMoveGrokDownloads(sourceDownloads, targetDownloads, installedVersion))
|
|
1350
|
+
return;
|
|
1351
|
+
for (const version of listInstalledVersions('grok')) {
|
|
1352
|
+
if (version === installedVersion)
|
|
1353
|
+
continue;
|
|
1354
|
+
const candidate = path.join(getVersionHomePath('grok', version), agentConfigDirName('grok'), 'downloads');
|
|
1355
|
+
if (path.resolve(candidate) === path.resolve(sourceDownloads))
|
|
1356
|
+
continue; // already tried
|
|
1357
|
+
if (tryMoveGrokDownloads(candidate, targetDownloads, installedVersion))
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1334
1360
|
}
|
|
1335
1361
|
/**
|
|
1336
1362
|
* Install a specific version of an agent.
|
|
@@ -1376,7 +1402,28 @@ export async function installVersion(agent, version, onProgress, opts) {
|
|
|
1376
1402
|
await execAsync(script, { timeout: 120000 });
|
|
1377
1403
|
}
|
|
1378
1404
|
if (version === 'latest') {
|
|
1379
|
-
|
|
1405
|
+
// A freshly-installed self-updating binary (grok, …) can take a
|
|
1406
|
+
// moment to become resolvable on PATH right after the installer
|
|
1407
|
+
// exits — retry briefly rather than silently falling back to the
|
|
1408
|
+
// literal string 'latest'. That fallback used to corrupt version
|
|
1409
|
+
// bookkeeping downstream: it creates a bogus `versions/<agent>/latest/`
|
|
1410
|
+
// dir, and for grok specifically defeats relocateGrokBinaryToVersionHome
|
|
1411
|
+
// (its exact-filename regex can never match `grok-latest-...`), which
|
|
1412
|
+
// permanently strands the real downloaded binary in the PREVIOUS
|
|
1413
|
+
// default's downloads dir.
|
|
1414
|
+
let probed = await getCliVersionFromPath(agent);
|
|
1415
|
+
for (let attempt = 0; !probed && attempt < 2; attempt++) {
|
|
1416
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
1417
|
+
probed = await getCliVersionFromPath(agent);
|
|
1418
|
+
}
|
|
1419
|
+
if (!probed) {
|
|
1420
|
+
return {
|
|
1421
|
+
success: false,
|
|
1422
|
+
installedVersion: version,
|
|
1423
|
+
error: `${agentConfig.name} installed but its version could not be determined after several attempts.`,
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
installedVersion = probed;
|
|
1380
1427
|
// Fold any stale literal `latest` dir from an earlier probe-failed
|
|
1381
1428
|
// install into the real version so it stops shadowing `agents view`.
|
|
1382
1429
|
await reconcileStaleLatestDir(agent, installedVersion);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phnx-labs/agents-cli",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.1",
|
|
4
4
|
"description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|