@phnx-labs/agents-cli 1.19.2 → 1.20.0
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 +67 -0
- package/README.md +69 -9
- package/dist/browser.js +0 -0
- package/dist/commands/browser.js +88 -16
- package/dist/commands/cli.d.ts +14 -0
- package/dist/commands/cli.js +244 -0
- package/dist/commands/commands.js +3 -3
- package/dist/commands/computer.js +18 -1
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/exec.js +3 -3
- package/dist/commands/factory.d.ts +3 -14
- package/dist/commands/factory.js +3 -3
- package/dist/commands/hooks.js +3 -3
- package/dist/commands/plugins.js +11 -4
- package/dist/commands/profiles.js +1 -1
- package/dist/commands/prune.js +39 -160
- package/dist/commands/pull.js +56 -3
- package/dist/commands/routines.js +106 -13
- package/dist/commands/secrets.js +5 -7
- package/dist/commands/sessions.d.ts +28 -0
- package/dist/commands/sessions.js +98 -33
- package/dist/commands/setup.d.ts +1 -0
- package/dist/commands/setup.js +37 -28
- package/dist/commands/skills.js +3 -3
- package/dist/commands/teams.js +13 -0
- package/dist/commands/versions.d.ts +4 -3
- package/dist/commands/versions.js +131 -127
- package/dist/commands/view.js +12 -12
- package/dist/computer.js +0 -0
- package/dist/index.js +34 -6
- package/dist/lib/acp/harnesses.js +8 -0
- package/dist/lib/agents.js +110 -23
- package/dist/lib/browser/cdp.d.ts +8 -1
- package/dist/lib/browser/cdp.js +40 -3
- package/dist/lib/browser/chrome.d.ts +13 -0
- package/dist/lib/browser/chrome.js +42 -3
- package/dist/lib/browser/domain-skills.d.ts +51 -0
- package/dist/lib/browser/domain-skills.js +157 -0
- package/dist/lib/browser/drivers/local.js +45 -4
- package/dist/lib/browser/drivers/ssh.js +1 -1
- package/dist/lib/browser/ipc.d.ts +8 -1
- package/dist/lib/browser/ipc.js +37 -28
- package/dist/lib/browser/profiles.d.ts +13 -0
- package/dist/lib/browser/profiles.js +41 -1
- package/dist/lib/browser/service.d.ts +3 -0
- package/dist/lib/browser/service.js +21 -5
- package/dist/lib/browser/types.d.ts +7 -0
- package/dist/lib/cli-resources.d.ts +109 -0
- package/dist/lib/cli-resources.js +255 -0
- package/dist/lib/cloud/rush.js +5 -5
- package/dist/lib/command-skills.js +0 -2
- package/dist/lib/computer-rpc.d.ts +3 -0
- package/dist/lib/computer-rpc.js +53 -0
- package/dist/lib/daemon.js +20 -0
- package/dist/lib/exec.d.ts +3 -2
- package/dist/lib/exec.js +44 -9
- package/dist/lib/hooks.js +182 -0
- package/dist/lib/mcp.js +6 -0
- package/dist/lib/migrate.js +1 -1
- package/dist/lib/overdue.d.ts +26 -0
- package/dist/lib/overdue.js +101 -0
- package/dist/lib/permissions.js +5 -1
- package/dist/lib/plugin-marketplace.js +1 -1
- package/dist/lib/profiles-presets.js +37 -0
- package/dist/lib/resources/mcp.js +37 -0
- package/dist/lib/resources.d.ts +1 -1
- package/dist/lib/rotate.js +10 -4
- package/dist/lib/routines-format.d.ts +35 -0
- package/dist/lib/routines-format.js +173 -0
- package/dist/lib/routines.d.ts +7 -1
- package/dist/lib/routines.js +32 -12
- package/dist/lib/runner.js +19 -5
- package/dist/lib/scheduler.js +8 -1
- 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/bundles.d.ts +22 -1
- package/dist/lib/secrets/bundles.js +234 -36
- package/dist/lib/secrets/index.d.ts +6 -11
- package/dist/lib/secrets/index.js +107 -87
- package/dist/lib/session/active.d.ts +8 -0
- package/dist/lib/session/active.js +3 -2
- package/dist/lib/session/db.d.ts +0 -4
- package/dist/lib/session/db.js +0 -26
- package/dist/lib/session/parse.d.ts +1 -0
- package/dist/lib/session/parse.js +44 -0
- package/dist/lib/session/types.d.ts +1 -1
- package/dist/lib/session/types.js +1 -1
- package/dist/lib/shims.d.ts +1 -1
- package/dist/lib/shims.js +66 -4
- package/dist/lib/state.d.ts +0 -1
- package/dist/lib/state.js +2 -15
- package/dist/lib/teams/agents.js +1 -1
- package/dist/lib/teams/parsers.d.ts +1 -1
- package/dist/lib/teams/parsers.js +153 -3
- package/dist/lib/teams/summarizer.js +18 -2
- package/dist/lib/teams/worktree.js +14 -3
- package/dist/lib/types.d.ts +6 -3
- package/dist/lib/types.js +6 -3
- package/dist/lib/versions.d.ts +10 -2
- package/dist/lib/versions.js +227 -35
- package/package.json +7 -7
- package/npm-shrinkwrap.json +0 -3162
|
@@ -7,7 +7,7 @@ import { AGENTS, ALL_AGENT_IDS, getAccountEmail, getAccountInfo, agentLabel, } f
|
|
|
7
7
|
import { formatUsageSummary, getUsageInfoForIdentity, getUsageInfoByIdentity, getUsageLookupKey, } from '../lib/usage.js';
|
|
8
8
|
import { viewAction } from './view.js';
|
|
9
9
|
import { readManifest, writeManifest, createDefaultManifest } from '../lib/manifest.js';
|
|
10
|
-
import { installVersion, removeVersion, listInstalledVersions, isVersionInstalled, isLatestInstalled, getGlobalDefault, setGlobalDefault, getVersionHomePath, getVersionDir, syncResourcesToVersion, parseAgentSpec, promptResourceSelection, promptNewResourceSelection, getAvailableResources, getActuallySyncedResources, getNewResources, hasNewResources, } from '../lib/versions.js';
|
|
10
|
+
import { installVersion, removeVersion, listInstalledVersions, isVersionInstalled, isLatestInstalled, getGlobalDefault, setGlobalDefault, getVersionHomePath, getVersionDir, syncResourcesToVersion, parseAgentSpec, promptResourceSelection, promptNewResourceSelection, getAvailableResources, getActuallySyncedResources, getNewResources, hasNewResources, printTrashFooter, } from '../lib/versions.js';
|
|
11
11
|
import { createShim, createVersionedAlias, removeShim, shimExists, getShimsDir, getShimPath, getPathShadowingExecutable, isShimsInPath, getPathSetupInstructions, addShimsToPath, switchConfigSymlink, switchHomeFileSymlinks, } from '../lib/shims.js';
|
|
12
12
|
import { isInteractiveTerminal, isPromptCancelled, requireInteractiveSelection } from './utils.js';
|
|
13
13
|
import { tryAutoPull } from '../lib/git.js';
|
|
@@ -93,7 +93,130 @@ function warnIfShimShadowed(agent) {
|
|
|
93
93
|
console.log(chalk.gray(` Managed shim: ${getShimPath(agent)}`));
|
|
94
94
|
console.log(chalk.gray(` ${getPathSetupInstructions().split('\n').join('\n ')}`));
|
|
95
95
|
}
|
|
96
|
-
|
|
96
|
+
async function versionPruneAction(specs, options, commandName) {
|
|
97
|
+
const isProject = options.project;
|
|
98
|
+
const moved = [];
|
|
99
|
+
for (const spec of specs) {
|
|
100
|
+
const parsed = parseAgentSpec(spec);
|
|
101
|
+
if (!parsed) {
|
|
102
|
+
console.log(chalk.red(`Invalid agent: ${spec}`));
|
|
103
|
+
console.log(chalk.gray(`Format: <agent>[@version]. Available: ${ALL_AGENT_IDS.join(', ')}`));
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const { agent, version } = parsed;
|
|
107
|
+
const agentConfig = AGENTS[agent];
|
|
108
|
+
if (version === 'latest' || !spec.includes('@')) {
|
|
109
|
+
const versions = listInstalledVersions(agent);
|
|
110
|
+
if (versions.length === 0) {
|
|
111
|
+
console.log(chalk.gray(`No versions of ${agentLabel(agentConfig.id)} installed`));
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (!isInteractiveTerminal()) {
|
|
115
|
+
requireInteractiveSelection(`Selecting ${agentLabel(agentConfig.id)} versions to ${commandName}`, [
|
|
116
|
+
`agents ${commandName} ${agent}@${versions[0]}`,
|
|
117
|
+
]);
|
|
118
|
+
}
|
|
119
|
+
const globalDefault = getGlobalDefault(agent);
|
|
120
|
+
const sortedVersions = [...versions].sort((a, b) => {
|
|
121
|
+
if (a === globalDefault)
|
|
122
|
+
return -1;
|
|
123
|
+
if (b === globalDefault)
|
|
124
|
+
return 1;
|
|
125
|
+
return 0;
|
|
126
|
+
});
|
|
127
|
+
try {
|
|
128
|
+
const toRemove = await checkbox({
|
|
129
|
+
message: `Select ${agentLabel(agentConfig.id)} versions to ${commandName}:`,
|
|
130
|
+
choices: sortedVersions.map((v) => ({
|
|
131
|
+
name: v === globalDefault ? `${v} ${chalk.green('(default)')}` : v,
|
|
132
|
+
value: v,
|
|
133
|
+
checked: false,
|
|
134
|
+
})),
|
|
135
|
+
});
|
|
136
|
+
if (toRemove.length === 0) {
|
|
137
|
+
console.log(chalk.gray('No versions selected'));
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
for (const v of toRemove) {
|
|
141
|
+
const versionDir = getVersionDir(agent, v);
|
|
142
|
+
removeVersion(agent, v);
|
|
143
|
+
fixSessionFilePaths(agent, v, versionDir);
|
|
144
|
+
console.log(chalk.green(`Moved ${agentLabel(agentConfig.id)}@${v} to trash`));
|
|
145
|
+
moved.push({ agent, version: v });
|
|
146
|
+
}
|
|
147
|
+
if (globalDefault && toRemove.includes(globalDefault)) {
|
|
148
|
+
setGlobalDefault(agent, undefined);
|
|
149
|
+
console.log(chalk.yellow(`Default version removed. Run: agents use ${agent}@<version> to set a new default`));
|
|
150
|
+
}
|
|
151
|
+
const remaining = listInstalledVersions(agent);
|
|
152
|
+
if (remaining.length === 0) {
|
|
153
|
+
removeShim(agent);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
if (isPromptCancelled(err)) {
|
|
158
|
+
console.log(chalk.gray('Cancelled'));
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
throw err;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (!isVersionInstalled(agent, version)) {
|
|
165
|
+
console.log(chalk.gray(`${agentLabel(agentConfig.id)}@${version} not installed`));
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const versionDir = getVersionDir(agent, version);
|
|
169
|
+
removeVersion(agent, version);
|
|
170
|
+
fixSessionFilePaths(agent, version, versionDir);
|
|
171
|
+
console.log(chalk.green(`Moved ${agentLabel(agentConfig.id)}@${version} to trash`));
|
|
172
|
+
moved.push({ agent, version });
|
|
173
|
+
const remaining = listInstalledVersions(agent);
|
|
174
|
+
if (remaining.length === 0) {
|
|
175
|
+
removeShim(agent);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (isProject) {
|
|
179
|
+
const projectManifestPath = path.join(process.cwd(), '.agents', 'agents.yaml');
|
|
180
|
+
if (fs.existsSync(projectManifestPath)) {
|
|
181
|
+
const manifest = readManifest(process.cwd());
|
|
182
|
+
if (manifest?.agents?.[agent]) {
|
|
183
|
+
delete manifest.agents[agent];
|
|
184
|
+
writeManifest(process.cwd(), manifest);
|
|
185
|
+
console.log(chalk.gray(` Removed from .agents/agents.yaml`));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
printTrashFooter(moved);
|
|
191
|
+
}
|
|
192
|
+
function configureVersionPruneCommand(cmd, commandName) {
|
|
193
|
+
const isAlias = commandName === 'remove';
|
|
194
|
+
cmd
|
|
195
|
+
.description(isAlias
|
|
196
|
+
? 'Alias for agents prune. Uninstalls agent CLI versions.'
|
|
197
|
+
: 'Uninstall agent CLI versions. Moves version data to trash for recovery.')
|
|
198
|
+
.option('-p, --project', 'Also clear the pinned version from .agents/agents.yaml in the current project');
|
|
199
|
+
setHelpSections(cmd, {
|
|
200
|
+
examples: `
|
|
201
|
+
# Prune a specific version
|
|
202
|
+
agents ${commandName} claude@2.0.50
|
|
203
|
+
|
|
204
|
+
# Pick interactively if you omit the version
|
|
205
|
+
agents ${commandName} claude
|
|
206
|
+
|
|
207
|
+
# Prune and also clear the project pin
|
|
208
|
+
agents ${commandName} claude@2.0.50 --project
|
|
209
|
+
`,
|
|
210
|
+
notes: `
|
|
211
|
+
- Pruned version directories move to trash with their home/ data intact.
|
|
212
|
+
- Session file paths are rewritten so session history remains readable.
|
|
213
|
+
- Removing the default version unsets the default; run 'agents use' to pick a new one.
|
|
214
|
+
- Reinstall any time with 'agents add'.
|
|
215
|
+
`,
|
|
216
|
+
});
|
|
217
|
+
cmd.action((specs, options) => versionPruneAction(specs, options, commandName));
|
|
218
|
+
}
|
|
219
|
+
/** Register `agents add`, `agents prune`, `agents remove`, `agents use`, and `agents list` (deprecated). */
|
|
97
220
|
export function registerVersionsCommands(program) {
|
|
98
221
|
const addCmd = program
|
|
99
222
|
.command('add <specs...>')
|
|
@@ -195,9 +318,9 @@ export function registerVersionsCommands(program) {
|
|
|
195
318
|
selection = userSelection;
|
|
196
319
|
}
|
|
197
320
|
}
|
|
198
|
-
else if (hasNewResources(newResources, agent)) {
|
|
321
|
+
else if (hasNewResources(newResources, agent, installedVersion)) {
|
|
199
322
|
// Some synced, but NEW resources available - prompt for new only
|
|
200
|
-
const userSelection = await promptNewResourceSelection(agent, newResources);
|
|
323
|
+
const userSelection = await promptNewResourceSelection(agent, newResources, installedVersion);
|
|
201
324
|
if (userSelection) {
|
|
202
325
|
selection = userSelection;
|
|
203
326
|
}
|
|
@@ -311,127 +434,8 @@ export function registerVersionsCommands(program) {
|
|
|
311
434
|
}
|
|
312
435
|
}
|
|
313
436
|
});
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
.description('Uninstall agent CLI versions. Frees disk space and removes the version\'s auth token.')
|
|
317
|
-
.option('-p, --project', 'Also clear the pinned version from .agents/agents.yaml in the current project');
|
|
318
|
-
setHelpSections(removeCmd, {
|
|
319
|
-
examples: `
|
|
320
|
-
# Remove a specific version
|
|
321
|
-
agents remove claude@2.0.50
|
|
322
|
-
|
|
323
|
-
# Pick interactively if you omit the version
|
|
324
|
-
agents remove claude
|
|
325
|
-
|
|
326
|
-
# Remove and also clear the project pin
|
|
327
|
-
agents remove claude@2.0.50 --project
|
|
328
|
-
`,
|
|
329
|
-
notes: `
|
|
330
|
-
- Removing the default version unsets the default; run 'agents use' to pick a new one.
|
|
331
|
-
- Reinstall any time with 'agents add'.
|
|
332
|
-
`,
|
|
333
|
-
});
|
|
334
|
-
removeCmd.action(async (specs, options) => {
|
|
335
|
-
const isProject = options.project;
|
|
336
|
-
for (const spec of specs) {
|
|
337
|
-
const parsed = parseAgentSpec(spec);
|
|
338
|
-
if (!parsed) {
|
|
339
|
-
console.log(chalk.red(`Invalid agent: ${spec}`));
|
|
340
|
-
console.log(chalk.gray(`Format: <agent>[@version]. Available: ${ALL_AGENT_IDS.join(', ')}`));
|
|
341
|
-
continue;
|
|
342
|
-
}
|
|
343
|
-
const { agent, version } = parsed;
|
|
344
|
-
const agentConfig = AGENTS[agent];
|
|
345
|
-
if (version === 'latest' || !spec.includes('@')) {
|
|
346
|
-
// Show picker for which versions to remove
|
|
347
|
-
const versions = listInstalledVersions(agent);
|
|
348
|
-
if (versions.length === 0) {
|
|
349
|
-
console.log(chalk.gray(`No versions of ${agentLabel(agentConfig.id)} installed`));
|
|
350
|
-
continue;
|
|
351
|
-
}
|
|
352
|
-
if (!isInteractiveTerminal()) {
|
|
353
|
-
requireInteractiveSelection(`Selecting ${agentLabel(agentConfig.id)} versions to remove`, [
|
|
354
|
-
`agents remove ${agent}@${versions[0]}`,
|
|
355
|
-
]);
|
|
356
|
-
}
|
|
357
|
-
const globalDefault = getGlobalDefault(agent);
|
|
358
|
-
// Sort versions with default first
|
|
359
|
-
const sortedVersions = [...versions].sort((a, b) => {
|
|
360
|
-
if (a === globalDefault)
|
|
361
|
-
return -1;
|
|
362
|
-
if (b === globalDefault)
|
|
363
|
-
return 1;
|
|
364
|
-
return 0;
|
|
365
|
-
});
|
|
366
|
-
try {
|
|
367
|
-
const toRemove = await checkbox({
|
|
368
|
-
message: `Select ${agentLabel(agentConfig.id)} versions to remove:`,
|
|
369
|
-
choices: sortedVersions.map((v) => ({
|
|
370
|
-
name: v === globalDefault ? `${v} ${chalk.green('(default)')}` : v,
|
|
371
|
-
value: v,
|
|
372
|
-
checked: false, // All unchecked by default
|
|
373
|
-
})),
|
|
374
|
-
});
|
|
375
|
-
if (toRemove.length === 0) {
|
|
376
|
-
console.log(chalk.gray('No versions selected'));
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
for (const v of toRemove) {
|
|
380
|
-
const versionDir = getVersionDir(agent, v);
|
|
381
|
-
removeVersion(agent, v);
|
|
382
|
-
fixSessionFilePaths(agent, v, versionDir);
|
|
383
|
-
console.log(chalk.green(`Removed ${agentLabel(agentConfig.id)}@${v}`));
|
|
384
|
-
}
|
|
385
|
-
// Check if default was removed
|
|
386
|
-
if (globalDefault && toRemove.includes(globalDefault)) {
|
|
387
|
-
setGlobalDefault(agent, undefined);
|
|
388
|
-
console.log(chalk.yellow(`Default version removed. Run: agents use ${agent}@<version> to set a new default`));
|
|
389
|
-
}
|
|
390
|
-
// Remove shim if no versions left
|
|
391
|
-
const remaining = listInstalledVersions(agent);
|
|
392
|
-
if (remaining.length === 0) {
|
|
393
|
-
removeShim(agent);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
catch (err) {
|
|
397
|
-
if (isPromptCancelled(err)) {
|
|
398
|
-
console.log(chalk.gray('Cancelled'));
|
|
399
|
-
continue;
|
|
400
|
-
}
|
|
401
|
-
throw err;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
// Remove specific version
|
|
406
|
-
if (!isVersionInstalled(agent, version)) {
|
|
407
|
-
console.log(chalk.gray(`${agentLabel(agentConfig.id)}@${version} not installed`));
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
const versionDir = getVersionDir(agent, version);
|
|
411
|
-
removeVersion(agent, version);
|
|
412
|
-
fixSessionFilePaths(agent, version, versionDir);
|
|
413
|
-
console.log(chalk.green(`Removed ${agentLabel(agentConfig.id)}@${version}`));
|
|
414
|
-
// Remove shim if no versions left
|
|
415
|
-
const remaining = listInstalledVersions(agent);
|
|
416
|
-
if (remaining.length === 0) {
|
|
417
|
-
removeShim(agent);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
// Update project manifest if -p flag
|
|
422
|
-
if (isProject) {
|
|
423
|
-
const projectManifestPath = path.join(process.cwd(), '.agents', 'agents.yaml');
|
|
424
|
-
if (fs.existsSync(projectManifestPath)) {
|
|
425
|
-
const manifest = readManifest(process.cwd());
|
|
426
|
-
if (manifest?.agents?.[agent]) {
|
|
427
|
-
delete manifest.agents[agent];
|
|
428
|
-
writeManifest(process.cwd(), manifest);
|
|
429
|
-
console.log(chalk.gray(` Removed from .agents/agents.yaml`));
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
});
|
|
437
|
+
configureVersionPruneCommand(program.command('prune <specs...>'), 'prune');
|
|
438
|
+
configureVersionPruneCommand(program.command('remove <specs...>', { hidden: true }), 'remove');
|
|
435
439
|
const useCmd = program
|
|
436
440
|
.command('use <agent> [version]')
|
|
437
441
|
.description('Switch the active version for an agent. This is the only command that sets the default.')
|
|
@@ -638,9 +642,9 @@ export function registerVersionsCommands(program) {
|
|
|
638
642
|
}
|
|
639
643
|
}
|
|
640
644
|
}
|
|
641
|
-
else if (hasNewResources(newResources, agentId)) {
|
|
645
|
+
else if (hasNewResources(newResources, agentId, finalVersion)) {
|
|
642
646
|
// Has synced before, but NEW items available
|
|
643
|
-
const userSelection = await promptNewResourceSelection(agentId, newResources);
|
|
647
|
+
const userSelection = await promptNewResourceSelection(agentId, newResources, finalVersion);
|
|
644
648
|
if (userSelection && Object.keys(userSelection).length > 0) {
|
|
645
649
|
const syncResult = syncResourcesToVersion(agentId, finalVersion, userSelection);
|
|
646
650
|
const syncedTypes = [];
|
package/dist/commands/view.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as path from 'path';
|
|
|
5
5
|
import { AGENTS, ALL_AGENT_IDS, getAllCliStates, getAccountInfo, resolveAgentName, formatAgentError, agentLabel, colorAgent, } from '../lib/agents.js';
|
|
6
6
|
import { formatUsageSection, formatUsageSummary, getUsageInfoForIdentity, getUsageInfoByIdentity, getUsageLookupKey, } from '../lib/usage.js';
|
|
7
7
|
import { readManifest } from '../lib/manifest.js';
|
|
8
|
-
import { listInstalledVersions, listInstalledVersionDirs, getGlobalDefault, getVersionHomePath, getVersionDir, resolveVersionAlias, getAvailableResources, getActuallySyncedResources, getNewResources, hasNewResources, promptNewResourceSelection, syncResourcesToVersion, removeVersion, } from '../lib/versions.js';
|
|
8
|
+
import { listInstalledVersions, listInstalledVersionDirs, getGlobalDefault, getVersionHomePath, getVersionDir, resolveVersionAlias, getAvailableResources, getActuallySyncedResources, getNewResources, hasNewResources, promptNewResourceSelection, syncResourcesToVersion, removeVersion, printTrashFooter, } from '../lib/versions.js';
|
|
9
9
|
import { getShimsDir, isShimsInPath, ensureVersionedAliasCurrent, removeShim, } from '../lib/shims.js';
|
|
10
10
|
import { getAgentResources } from '../lib/resources.js';
|
|
11
11
|
import { WORKFLOW_CAPABLE_AGENTS } from '../lib/workflows.js';
|
|
@@ -366,7 +366,7 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
366
366
|
const newResources = getNewResources(available, synced);
|
|
367
367
|
if (hasNewResources(newResources, filterAgentId, defaultVersion)) {
|
|
368
368
|
try {
|
|
369
|
-
const selection = await promptNewResourceSelection(filterAgentId, newResources);
|
|
369
|
+
const selection = await promptNewResourceSelection(filterAgentId, newResources, defaultVersion);
|
|
370
370
|
if (selection && Object.keys(selection).length > 0) {
|
|
371
371
|
const result = syncResourcesToVersion(filterAgentId, defaultVersion, selection);
|
|
372
372
|
const synced = [];
|
|
@@ -833,13 +833,12 @@ async function buildAgentPrunePlan(agentId) {
|
|
|
833
833
|
return { agentId, toPrune, skippedDefaults };
|
|
834
834
|
}
|
|
835
835
|
async function executePrunePlan(plan) {
|
|
836
|
-
|
|
836
|
+
const moved = [];
|
|
837
837
|
for (const p of plan.toPrune) {
|
|
838
|
-
console.log(chalk.gray(`Removing ${agentLabel(p.agentId)}@${p.version}...`));
|
|
839
838
|
const ok = removeVersion(p.agentId, p.version);
|
|
840
839
|
if (ok) {
|
|
841
|
-
console.log(chalk.green(`
|
|
842
|
-
|
|
840
|
+
console.log(chalk.green(`Moved ${agentLabel(p.agentId)}@${p.version} to trash`));
|
|
841
|
+
moved.push({ agent: p.agentId, version: p.version });
|
|
843
842
|
}
|
|
844
843
|
else {
|
|
845
844
|
console.log(chalk.yellow(`Already gone: ${agentLabel(p.agentId)}@${p.version}`));
|
|
@@ -848,7 +847,7 @@ async function executePrunePlan(plan) {
|
|
|
848
847
|
if (listInstalledVersions(plan.agentId).length === 0) {
|
|
849
848
|
removeShim(plan.agentId);
|
|
850
849
|
}
|
|
851
|
-
return
|
|
850
|
+
return moved;
|
|
852
851
|
}
|
|
853
852
|
function printPrunePlan(plan, isFirst) {
|
|
854
853
|
if (plan.skippedDefaults.length > 0) {
|
|
@@ -897,7 +896,7 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
897
896
|
return;
|
|
898
897
|
}
|
|
899
898
|
const totalCandidates = actionable.reduce((n, plan) => n + plan.toPrune.length, 0);
|
|
900
|
-
|
|
899
|
+
const allMoved = [];
|
|
901
900
|
let isFirst = true;
|
|
902
901
|
let processedAny = false;
|
|
903
902
|
for (const plan of actionable) {
|
|
@@ -916,10 +915,10 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
916
915
|
if (!isInteractiveTerminal()) {
|
|
917
916
|
console.log(chalk.red('Refusing to prune in a non-interactive shell without --yes.'));
|
|
918
917
|
if (filterAgentId) {
|
|
919
|
-
console.log(chalk.gray(`Re-run with: agents prune ${filterAgentId} --dry-run`));
|
|
918
|
+
console.log(chalk.gray(`Re-run with: agents prune cleanup ${filterAgentId} --dry-run`));
|
|
920
919
|
}
|
|
921
920
|
else {
|
|
922
|
-
console.log(chalk.gray('Re-run with: agents prune --dry-run'));
|
|
921
|
+
console.log(chalk.gray('Re-run with: agents prune cleanup --dry-run'));
|
|
923
922
|
}
|
|
924
923
|
process.exit(1);
|
|
925
924
|
}
|
|
@@ -943,7 +942,7 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
943
942
|
break;
|
|
944
943
|
}
|
|
945
944
|
}
|
|
946
|
-
|
|
945
|
+
allMoved.push(...(await executePrunePlan(plan)));
|
|
947
946
|
processedAny = true;
|
|
948
947
|
isFirst = false;
|
|
949
948
|
console.log();
|
|
@@ -953,7 +952,8 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
953
952
|
return;
|
|
954
953
|
}
|
|
955
954
|
if (processedAny) {
|
|
956
|
-
console.log(chalk.bold(`Pruned ${
|
|
955
|
+
console.log(chalk.bold(`Pruned ${allMoved.length} version${allMoved.length === 1 ? '' : 's'}.`));
|
|
956
|
+
printTrashFooter(allMoved);
|
|
957
957
|
}
|
|
958
958
|
}
|
|
959
959
|
/**
|
package/dist/computer.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
@@ -66,6 +66,7 @@ import { registerSkillsCommands } from './commands/skills.js';
|
|
|
66
66
|
import { registerRulesCommands } from './commands/rules.js';
|
|
67
67
|
import { registerPermissionsCommands } from './commands/permissions.js';
|
|
68
68
|
import { registerMcpCommands } from './commands/mcp.js';
|
|
69
|
+
import { registerCliCommands } from './commands/cli.js';
|
|
69
70
|
import { registerVersionsCommands } from './commands/versions.js';
|
|
70
71
|
import { registerImportCommand } from './commands/import.js';
|
|
71
72
|
import { registerPackagesCommands } from './commands/packages.js';
|
|
@@ -120,11 +121,12 @@ Quick start:
|
|
|
120
121
|
agents sessions Browse past sessions across all agents
|
|
121
122
|
|
|
122
123
|
Agent versions:
|
|
123
|
-
add <agent>[@version] Install an agent CLI (e.g. agents add codex)
|
|
124
|
+
add <agent>[@version] Install an agent CLI (e.g. agents add grok or agents add codex)
|
|
124
125
|
import <agent> Adopt an existing global install (npm/homebrew) into agents-cli
|
|
125
|
-
|
|
126
|
+
prune <agent>[@version] Uninstall a version
|
|
127
|
+
remove <agent>[@version] Alias for prune
|
|
126
128
|
use <agent>@<version> Set the default version
|
|
127
|
-
prune [target]
|
|
129
|
+
prune cleanup [target] Remove orphan resources and older duplicate version installs
|
|
128
130
|
trash Inspect and restore soft-deleted version directories
|
|
129
131
|
view [agent[@version]] List versions, or inspect one in detail
|
|
130
132
|
|
|
@@ -171,7 +173,7 @@ Automation tips:
|
|
|
171
173
|
Pass explicit names/IDs Avoid pickers: agents sessions <id> --markdown
|
|
172
174
|
Use --yes for defaults Auto-accept sync/default prompts on add/use/pull
|
|
173
175
|
Use --names for central items e.g. agents commands add --names review-pr,debug
|
|
174
|
-
Use agent@version targets e.g. --agents claude@2.1.79,codex@default
|
|
176
|
+
Use agent@version targets e.g. --agents grok@0.1.218,claude@2.1.79,codex@default
|
|
175
177
|
Non-TTY shells apply defaults Omitted required selections fail with a plain hint
|
|
176
178
|
|
|
177
179
|
Options:
|
|
@@ -361,7 +363,13 @@ async function promptUpgrade(latestVersion) {
|
|
|
361
363
|
console.log();
|
|
362
364
|
}
|
|
363
365
|
}
|
|
364
|
-
/**
|
|
366
|
+
/**
|
|
367
|
+
* Background update check — fires once per 24h cache window.
|
|
368
|
+
* Network: GET registry.npmjs.org/@phnx-labs/agents-cli/latest.
|
|
369
|
+
* Disable: set AGENTS_CLI_DISABLE_AUTO_UPDATE=1 in shell rc.
|
|
370
|
+
*
|
|
371
|
+
* Fire-and-forget; never blocks the CLI's foreground operation.
|
|
372
|
+
*/
|
|
365
373
|
function refreshUpdateCacheInBackground() {
|
|
366
374
|
fetch('https://registry.npmjs.org/@phnx-labs/agents-cli/latest', {
|
|
367
375
|
signal: AbortSignal.timeout(2000),
|
|
@@ -529,6 +537,7 @@ program
|
|
|
529
537
|
await program.parseAsync(['node', 'agents', ...args]);
|
|
530
538
|
});
|
|
531
539
|
registerMcpCommands(program);
|
|
540
|
+
registerCliCommands(program);
|
|
532
541
|
registerSubagentsCommands(program);
|
|
533
542
|
registerPluginsCommands(program);
|
|
534
543
|
registerWorkflowsCommands(program);
|
|
@@ -726,7 +735,13 @@ if (firstRun) {
|
|
|
726
735
|
// Every command requires the system repo to be cloned first. `setup` is the
|
|
727
736
|
// only exemption — it's the command that does the cloning.
|
|
728
737
|
const SETUP_EXEMPT_COMMANDS = new Set(['setup', 'help']);
|
|
729
|
-
|
|
738
|
+
// Help and version output are pure documentation — they must never gate on
|
|
739
|
+
// setup, otherwise `agents <cmd> --help` becomes useless on a fresh box.
|
|
740
|
+
const helpOrVersionRequested = passedArgs.some((arg) => arg === '--help' || arg === '-h' || arg === '--version' || arg === '-V');
|
|
741
|
+
if (!firstRun &&
|
|
742
|
+
requestedCommand &&
|
|
743
|
+
!SETUP_EXEMPT_COMMANDS.has(requestedCommand) &&
|
|
744
|
+
!helpOrVersionRequested) {
|
|
730
745
|
const { ensureInitialized } = await import('./commands/setup.js');
|
|
731
746
|
await ensureInitialized(program);
|
|
732
747
|
}
|
|
@@ -771,5 +786,18 @@ catch (err) {
|
|
|
771
786
|
if (err instanceof Error && err.name === 'ExitPromptError') {
|
|
772
787
|
process.exit(130);
|
|
773
788
|
}
|
|
789
|
+
// Browser-daemon-not-running and CDP-not-reachable surface as typed errors
|
|
790
|
+
// from src/lib/browser/. Don't dump a Node stacktrace for these — they are
|
|
791
|
+
// user-actionable, not engineering bugs. See issues #41 and #43.
|
|
792
|
+
if (err instanceof Error) {
|
|
793
|
+
const isBrowserDaemonNotRunning = err.name === 'BrowserDaemonNotRunningError';
|
|
794
|
+
const isBrowserCdpUnreachable = err.name === 'BrowserCdpConnectionError';
|
|
795
|
+
const isBrowserIpcDown = err.message.startsWith('IPC error:') &&
|
|
796
|
+
(err.message.includes('ECONNREFUSED') || err.message.includes('ENOENT'));
|
|
797
|
+
if (isBrowserDaemonNotRunning || isBrowserCdpUnreachable || isBrowserIpcDown) {
|
|
798
|
+
console.error(err.message);
|
|
799
|
+
process.exit(1);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
774
802
|
throw err;
|
|
775
803
|
}
|
|
@@ -50,6 +50,14 @@ export const ACP_HARNESSES = {
|
|
|
50
50
|
confidence: 'documented',
|
|
51
51
|
source: 'https://docs.openclaw.ai/tools/acp-agents',
|
|
52
52
|
},
|
|
53
|
+
grok: {
|
|
54
|
+
command: 'grok',
|
|
55
|
+
args: ['agent', 'stdio'],
|
|
56
|
+
installHint: 'see https://docs.x.ai/build/cli',
|
|
57
|
+
confidence: 'documented',
|
|
58
|
+
source: 'https://docs.x.ai/build/cli/headless-scripting',
|
|
59
|
+
},
|
|
60
|
+
// antigravity: no documented ACP support (May 2026).
|
|
53
61
|
// goose: ACP over HTTP via `goosed`, not a clean stdio subcommand.
|
|
54
62
|
// copilot, kiro: excluded for now (not installed in the reference environment,
|
|
55
63
|
// no local verification possible).
|