@phnx-labs/agents-cli 1.20.27 → 1.20.28
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 +3 -0
- package/dist/commands/doctor.js +57 -4
- package/dist/commands/exec.d.ts +1 -1
- package/dist/commands/exec.js +177 -6
- package/dist/commands/hosts.d.ts +11 -0
- package/dist/commands/hosts.js +229 -0
- package/dist/commands/repo.d.ts +29 -0
- package/dist/commands/repo.js +174 -38
- package/dist/commands/secrets.d.ts +2 -7
- package/dist/commands/secrets.js +15 -23
- package/dist/commands/sessions.d.ts +2 -0
- package/dist/commands/sessions.js +7 -24
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.js +22 -5
- package/dist/commands/view.js +27 -11
- package/dist/index.js +2 -1
- package/dist/lib/agents.d.ts +1 -0
- package/dist/lib/agents.js +44 -4
- package/dist/lib/browser/drivers/ssh.d.ts +47 -2
- package/dist/lib/browser/drivers/ssh.js +113 -24
- package/dist/lib/browser/profiles.js +28 -1
- package/dist/lib/browser/runtime-state.js +28 -8
- package/dist/lib/browser/types.d.ts +10 -1
- package/dist/lib/cli-resources.js +10 -1
- package/dist/lib/doctor-diff.d.ts +12 -0
- package/dist/lib/doctor-diff.js +89 -2
- package/dist/lib/exec.d.ts +27 -0
- package/dist/lib/exec.js +62 -19
- package/dist/lib/hooks.d.ts +17 -0
- package/dist/lib/hooks.js +127 -3
- package/dist/lib/hosts/dispatch.d.ts +26 -0
- package/dist/lib/hosts/dispatch.js +71 -0
- package/dist/lib/hosts/progress.d.ts +21 -0
- package/dist/lib/hosts/progress.js +49 -0
- package/dist/lib/hosts/providers/local.d.ts +17 -0
- package/dist/lib/hosts/providers/local.js +81 -0
- package/dist/lib/hosts/ready.d.ts +37 -0
- package/dist/lib/hosts/ready.js +88 -0
- package/dist/lib/hosts/registry.d.ts +22 -0
- package/dist/lib/hosts/registry.js +65 -0
- package/dist/lib/hosts/ssh-config.d.ts +37 -0
- package/dist/lib/hosts/ssh-config.js +157 -0
- package/dist/lib/hosts/tasks.d.ts +32 -0
- package/dist/lib/hosts/tasks.js +58 -0
- package/dist/lib/hosts/types.d.ts +51 -0
- package/dist/lib/hosts/types.js +21 -0
- package/dist/lib/loop.d.ts +9 -0
- package/dist/lib/loop.js +13 -1
- package/dist/lib/mcp.js +12 -3
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/migrate.js +9 -5
- package/dist/lib/platform/exec.d.ts +10 -0
- package/dist/lib/platform/exec.js +17 -0
- package/dist/lib/platform/index.d.ts +1 -0
- package/dist/lib/platform/index.js +1 -0
- package/dist/lib/platform/links.d.ts +15 -0
- package/dist/lib/platform/links.js +42 -0
- package/dist/lib/platform/paths.d.ts +18 -0
- package/dist/lib/platform/paths.js +22 -0
- package/dist/lib/platform/posixpath.d.ts +28 -0
- package/dist/lib/platform/posixpath.js +153 -0
- package/dist/lib/plugins.d.ts +10 -0
- package/dist/lib/plugins.js +1 -1
- package/dist/lib/project-launch.js +6 -3
- package/dist/lib/sandbox.js +5 -2
- package/dist/lib/self-update.js +7 -2
- package/dist/lib/session/db.d.ts +23 -0
- package/dist/lib/session/db.js +76 -1
- package/dist/lib/session/discover.d.ts +26 -0
- package/dist/lib/session/discover.js +75 -4
- package/dist/lib/session/relative-time.d.ts +7 -0
- package/dist/lib/session/relative-time.js +28 -0
- package/dist/lib/session/remote.d.ts +31 -3
- package/dist/lib/session/remote.js +121 -14
- package/dist/lib/ssh-exec.d.ts +45 -0
- package/dist/lib/ssh-exec.js +61 -0
- package/dist/lib/startup/command-registry.d.ts +1 -0
- package/dist/lib/startup/command-registry.js +2 -0
- package/dist/lib/types.d.ts +21 -0
- package/dist/lib/versions.d.ts +6 -2
- package/dist/lib/versions.js +8 -4
- package/package.json +1 -1
- package/scripts/postinstall.js +62 -0
|
@@ -45,6 +45,7 @@ export const loadPty = async () => (await import('../../commands/pty.js')).regis
|
|
|
45
45
|
export const loadTmux = async () => (await import('../../commands/tmux.js')).registerTmuxCommands;
|
|
46
46
|
export const loadBrowser = async () => (await import('../../commands/browser.js')).registerBrowserCommand;
|
|
47
47
|
export const loadComputer = async () => (await import('../../commands/computer.js')).registerComputerCommand;
|
|
48
|
+
export const loadHosts = async () => (await import('../../commands/hosts.js')).registerHostsCommand;
|
|
48
49
|
export const loadPull = async () => (await import('../../commands/pull.js')).registerPullCommand;
|
|
49
50
|
export const loadPush = async () => (await import('../../commands/push.js')).registerPushCommand;
|
|
50
51
|
export const loadRepo = async () => (await import('../../commands/repo.js')).registerRepoCommands;
|
|
@@ -126,6 +127,7 @@ export const COMMAND_LOADERS = {
|
|
|
126
127
|
tmux: [loadTmux],
|
|
127
128
|
browser: [loadBrowser],
|
|
128
129
|
computer: [loadComputer],
|
|
130
|
+
hosts: [loadHosts],
|
|
129
131
|
pull: [loadPull],
|
|
130
132
|
push: [loadPush],
|
|
131
133
|
repo: [loadRepo],
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -612,6 +612,27 @@ export interface Meta {
|
|
|
612
612
|
* lives separately in ~/.agents/.cache/browser/<profile>/.
|
|
613
613
|
*/
|
|
614
614
|
browser?: Record<string, BrowserProfileConfig>;
|
|
615
|
+
/**
|
|
616
|
+
* Agent-host registry keyed by host name (`agents hosts`). Portable user
|
|
617
|
+
* config synced with `agents repo push/pull`. For `ssh-config` hosts this is
|
|
618
|
+
* just an overlay (caps/os) — the connection details stay in ~/.ssh/config and
|
|
619
|
+
* are never copied. `inline` hosts carry their own address/user.
|
|
620
|
+
*/
|
|
621
|
+
hosts?: Record<string, HostEntry>;
|
|
622
|
+
}
|
|
623
|
+
/** Persisted agent-host entry in agents.yaml (overlay or inline). */
|
|
624
|
+
export interface HostEntry {
|
|
625
|
+
/** `ssh-config`: reach via the bare name (ssh resolves). `inline`: use address/user below. */
|
|
626
|
+
source: 'ssh-config' | 'inline';
|
|
627
|
+
/** SSH-reachable target — inline hosts only (ssh-config hosts omit it). */
|
|
628
|
+
address?: string;
|
|
629
|
+
/** SSH user — inline hosts only. */
|
|
630
|
+
user?: string;
|
|
631
|
+
/** Captured at enroll probe. */
|
|
632
|
+
os?: string;
|
|
633
|
+
/** Free-form capability tags for routing (e.g. ['gpu']). */
|
|
634
|
+
caps?: string[];
|
|
635
|
+
addedAt?: string;
|
|
615
636
|
}
|
|
616
637
|
/** Browser profile definition stored in agents.yaml. */
|
|
617
638
|
export interface BrowserProfileConfig {
|
package/dist/lib/versions.d.ts
CHANGED
|
@@ -241,12 +241,16 @@ export declare function resolveVersion(agent: AgentId, projectPath?: string): st
|
|
|
241
241
|
/**
|
|
242
242
|
* Normalize a user-supplied @version token across CLI subcommands.
|
|
243
243
|
*
|
|
244
|
-
* undefined / "" / "default"
|
|
244
|
+
* undefined / "" / "default" / "pinned" -> undefined (caller falls back to project pin or global default)
|
|
245
|
+
* "any" -> undefined (caller imposes no version constraint — e.g. resume across any version)
|
|
245
246
|
* "latest" -> highest installed version (process.exit if none installed)
|
|
246
247
|
* "oldest" -> lowest installed version (process.exit if none installed)
|
|
247
248
|
* "x.y.z" (installed) -> "x.y.z"
|
|
248
249
|
* "x.y.z" (not installed) -> process.exit with installed-list hint
|
|
249
250
|
*
|
|
251
|
+
* `pinned` is a synonym for `default`: both name the project pin / global
|
|
252
|
+
* default, which the caller resolves.
|
|
253
|
+
*
|
|
250
254
|
* Use this anywhere the user can type `agents <cmd> claude@<token>` to keep the
|
|
251
255
|
* vocabulary consistent. Subcommands with different semantics for `latest`
|
|
252
256
|
* (install/remove/use, where `latest` means npm-latest) keep their existing
|
|
@@ -255,7 +259,7 @@ export declare function resolveVersion(agent: AgentId, projectPath?: string): st
|
|
|
255
259
|
export declare function resolveVersionAlias(agent: AgentId, raw: string | undefined | null): string | undefined;
|
|
256
260
|
/**
|
|
257
261
|
* Loose variant of resolveVersionAlias for record-filter contexts (sessions,
|
|
258
|
-
* team history). Same `default`/`latest`/`oldest` semantics, but explicit
|
|
262
|
+
* team history). Same `default`/`pinned`/`latest`/`oldest` semantics, but explicit
|
|
259
263
|
* versions pass through unchanged so historical records of uninstalled versions
|
|
260
264
|
* remain queryable.
|
|
261
265
|
*/
|
package/dist/lib/versions.js
CHANGED
|
@@ -1363,19 +1363,23 @@ export function resolveVersion(agent, projectPath) {
|
|
|
1363
1363
|
/**
|
|
1364
1364
|
* Normalize a user-supplied @version token across CLI subcommands.
|
|
1365
1365
|
*
|
|
1366
|
-
* undefined / "" / "default"
|
|
1366
|
+
* undefined / "" / "default" / "pinned" -> undefined (caller falls back to project pin or global default)
|
|
1367
|
+
* "any" -> undefined (caller imposes no version constraint — e.g. resume across any version)
|
|
1367
1368
|
* "latest" -> highest installed version (process.exit if none installed)
|
|
1368
1369
|
* "oldest" -> lowest installed version (process.exit if none installed)
|
|
1369
1370
|
* "x.y.z" (installed) -> "x.y.z"
|
|
1370
1371
|
* "x.y.z" (not installed) -> process.exit with installed-list hint
|
|
1371
1372
|
*
|
|
1373
|
+
* `pinned` is a synonym for `default`: both name the project pin / global
|
|
1374
|
+
* default, which the caller resolves.
|
|
1375
|
+
*
|
|
1372
1376
|
* Use this anywhere the user can type `agents <cmd> claude@<token>` to keep the
|
|
1373
1377
|
* vocabulary consistent. Subcommands with different semantics for `latest`
|
|
1374
1378
|
* (install/remove/use, where `latest` means npm-latest) keep their existing
|
|
1375
1379
|
* parsing.
|
|
1376
1380
|
*/
|
|
1377
1381
|
export function resolveVersionAlias(agent, raw) {
|
|
1378
|
-
if (!raw || raw === 'default')
|
|
1382
|
+
if (!raw || raw === 'default' || raw === 'pinned' || raw === 'any')
|
|
1379
1383
|
return undefined;
|
|
1380
1384
|
if (raw === 'latest' || raw === 'oldest') {
|
|
1381
1385
|
const installed = listInstalledVersions(agent);
|
|
@@ -1399,12 +1403,12 @@ export function resolveVersionAlias(agent, raw) {
|
|
|
1399
1403
|
}
|
|
1400
1404
|
/**
|
|
1401
1405
|
* Loose variant of resolveVersionAlias for record-filter contexts (sessions,
|
|
1402
|
-
* team history). Same `default`/`latest`/`oldest` semantics, but explicit
|
|
1406
|
+
* team history). Same `default`/`pinned`/`latest`/`oldest` semantics, but explicit
|
|
1403
1407
|
* versions pass through unchanged so historical records of uninstalled versions
|
|
1404
1408
|
* remain queryable.
|
|
1405
1409
|
*/
|
|
1406
1410
|
export function resolveVersionAliasLoose(agent, raw) {
|
|
1407
|
-
if (!raw || raw === 'default')
|
|
1411
|
+
if (!raw || raw === 'default' || raw === 'pinned' || raw === 'any')
|
|
1408
1412
|
return undefined;
|
|
1409
1413
|
if (raw === 'latest' || raw === 'oldest') {
|
|
1410
1414
|
const installed = listInstalledVersions(agent);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phnx-labs/agents-cli",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.28",
|
|
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",
|
package/scripts/postinstall.js
CHANGED
|
@@ -239,6 +239,10 @@ To enable version-aware shims, add this to your shell config:
|
|
|
239
239
|
console.log(` Installed shorthands: ${written.join(', ')}`);
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
+
if (process.platform !== 'win32') {
|
|
243
|
+
await ensureAgentsResolvablePosix();
|
|
244
|
+
}
|
|
245
|
+
|
|
242
246
|
await healLongRunningProcesses();
|
|
243
247
|
|
|
244
248
|
const version = getVersion();
|
|
@@ -252,6 +256,64 @@ To enable version-aware shims, add this to your shell config:
|
|
|
252
256
|
}
|
|
253
257
|
}
|
|
254
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Make the `agents` command resolvable in a *login* shell on POSIX.
|
|
261
|
+
*
|
|
262
|
+
* `agents`/`ag` reach PATH only through npm's bin symlink in the npm global-bin
|
|
263
|
+
* dir. Under nvm (and other per-user node prefixes) that dir is missing from a
|
|
264
|
+
* non-interactive login shell's PATH, so `bash -lc 'agents …'` fails with
|
|
265
|
+
* command-not-found — which breaks `agents secrets export --host` (it runs
|
|
266
|
+
* `bash -lc 'agents secrets import …'` on the remote) and the routines daemon
|
|
267
|
+
* (src/lib/daemon.ts falls back to bare `agents`). This is the POSIX symmetric
|
|
268
|
+
* counterpart of the Windows branch in main() that registers npm's global-bin
|
|
269
|
+
* dir on the user PATH.
|
|
270
|
+
*
|
|
271
|
+
* Self-heal, not a prompt: it fires ONLY when `agents` is otherwise
|
|
272
|
+
* unresolvable — the genuinely-broken state — so it acts decisively, exactly
|
|
273
|
+
* like the Windows PATH registration. The symlink never clobbers a dev build
|
|
274
|
+
* (scripts/install.sh) or any real file. Skipped in CI (ephemeral homes) and
|
|
275
|
+
* when AGENTS_NO_HEAL=1.
|
|
276
|
+
*/
|
|
277
|
+
async function ensureAgentsResolvablePosix() {
|
|
278
|
+
if (process.env.CI || process.env.AGENTS_NO_HEAL === '1') return;
|
|
279
|
+
try {
|
|
280
|
+
const { localBinDir, ensureLocalBinSymlink, loginShellResolves, dirOnLoginPath } =
|
|
281
|
+
await import('../dist/lib/platform/posixpath.js');
|
|
282
|
+
|
|
283
|
+
// macOS/homebrew, system-node Linux, and dev-build users already resolve it.
|
|
284
|
+
if (loginShellResolves('agents')) return;
|
|
285
|
+
|
|
286
|
+
const binDir = localBinDir();
|
|
287
|
+
const results = ['agents', 'ag'].map((name) => ensureLocalBinSymlink(name, AGENTS_BIN, binDir));
|
|
288
|
+
if (!results.some((r) => r.created)) return; // nothing we could safely link
|
|
289
|
+
|
|
290
|
+
if (dirOnLoginPath(binDir)) {
|
|
291
|
+
console.log(`\n Linked 'agents' into ${binDir} (already on the login PATH) so 'bash -lc agents' resolves.`);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// ~/.local/bin isn't on the *bash* login PATH yet. The consumers run
|
|
296
|
+
// `bash -lc`, so add it to the file a bash login shell reads (~/.bash_profile
|
|
297
|
+
// when present, else ~/.profile) — not the interactive $SHELL rc, which for a
|
|
298
|
+
// zsh user (.zshrc) bash would never source.
|
|
299
|
+
const bashRc = fs.existsSync(path.join(HOME, '.bash_profile'))
|
|
300
|
+
? path.join(HOME, '.bash_profile')
|
|
301
|
+
: path.join(HOME, '.profile');
|
|
302
|
+
const marker = '# agents-cli: ensure ~/.local/bin on PATH (so the agents command resolves)';
|
|
303
|
+
let already = false;
|
|
304
|
+
try {
|
|
305
|
+
already = fs.existsSync(bashRc) && fs.readFileSync(bashRc, 'utf-8').includes(marker);
|
|
306
|
+
} catch { /* unreadable rc — fall through and append */ }
|
|
307
|
+
if (!already) {
|
|
308
|
+
fs.appendFileSync(bashRc, `\n${marker}\nexport PATH="${binDir}:$PATH"\n`);
|
|
309
|
+
}
|
|
310
|
+
console.log(`\n Linked 'agents' into ${binDir} and added it to PATH in ${path.basename(bashRc)}.`);
|
|
311
|
+
console.log(` Restart your shell (or run: source ~/${path.basename(bashRc)}) to pick it up.`);
|
|
312
|
+
} catch {
|
|
313
|
+
/* best-effort: a failure here must never break the install */
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
255
317
|
/**
|
|
256
318
|
* Self-heal long-running processes onto the just-installed code (macOS).
|
|
257
319
|
*
|