@phnx-labs/agents-cli 1.19.2 → 1.20.3
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 +140 -0
- package/README.md +72 -12
- 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/cloud.js +1 -1
- package/dist/commands/commands.js +27 -10
- 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 +38 -18
- package/dist/commands/factory.d.ts +3 -14
- package/dist/commands/factory.js +3 -3
- package/dist/commands/feedback.d.ts +7 -0
- package/dist/commands/feedback.js +89 -0
- package/dist/commands/helper.d.ts +12 -0
- package/dist/commands/helper.js +87 -0
- package/dist/commands/hooks.js +89 -10
- package/dist/commands/mcp.js +166 -10
- package/dist/commands/packages.js +196 -27
- package/dist/commands/permissions.js +21 -6
- package/dist/commands/plugins.js +11 -4
- package/dist/commands/profiles.d.ts +8 -0
- package/dist/commands/profiles.js +118 -5
- package/dist/commands/prune.js +39 -160
- package/dist/commands/pull.js +58 -5
- package/dist/commands/routines.js +107 -14
- package/dist/commands/rules.js +8 -4
- package/dist/commands/secrets-migrate.d.ts +24 -0
- package/dist/commands/secrets-migrate.js +198 -0
- package/dist/commands/secrets-sync.d.ts +11 -0
- package/dist/commands/secrets-sync.js +155 -0
- package/dist/commands/secrets.js +79 -46
- 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 +25 -8
- package/dist/commands/subagents.js +69 -49
- package/dist/commands/teams.js +61 -10
- package/dist/commands/utils.d.ts +33 -0
- package/dist/commands/utils.js +139 -0
- package/dist/commands/versions.d.ts +4 -3
- package/dist/commands/versions.js +134 -130
- package/dist/commands/view.d.ts +6 -0
- package/dist/commands/view.js +175 -19
- package/dist/commands/workflows.js +29 -6
- package/dist/computer.js +0 -0
- package/dist/index.js +38 -6
- package/dist/lib/acp/client.js +6 -1
- package/dist/lib/acp/harnesses.js +8 -0
- package/dist/lib/agents.d.ts +4 -0
- package/dist/lib/agents.js +125 -34
- package/dist/lib/auto-pull-worker.js +18 -1
- 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 +46 -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 +2 -2
- package/dist/lib/browser/ipc.d.ts +8 -1
- package/dist/lib/browser/ipc.js +37 -28
- package/dist/lib/browser/profiles.d.ts +16 -3
- package/dist/lib/browser/profiles.js +44 -4
- package/dist/lib/browser/service.d.ts +3 -0
- package/dist/lib/browser/service.js +40 -5
- package/dist/lib/browser/types.d.ts +11 -4
- package/dist/lib/cli-resources.d.ts +137 -0
- package/dist/lib/cli-resources.js +477 -0
- package/dist/lib/cloud/factory.d.ts +1 -1
- package/dist/lib/cloud/factory.js +1 -1
- 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/events.d.ts +16 -2
- package/dist/lib/events.js +33 -2
- package/dist/lib/exec.d.ts +42 -13
- package/dist/lib/exec.js +127 -33
- package/dist/lib/help.js +11 -5
- package/dist/lib/hooks/cache.d.ts +38 -0
- package/dist/lib/hooks/cache.js +242 -0
- package/dist/lib/hooks/profile.d.ts +33 -0
- package/dist/lib/hooks/profile.js +129 -0
- package/dist/lib/hooks.d.ts +0 -10
- package/dist/lib/hooks.js +246 -11
- package/dist/lib/mcp.d.ts +15 -0
- package/dist/lib/mcp.js +46 -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.d.ts +13 -0
- package/dist/lib/permissions.js +55 -1
- package/dist/lib/plugin-marketplace.js +1 -1
- package/dist/lib/plugins.js +15 -1
- package/dist/lib/profiles-presets.d.ts +26 -0
- package/dist/lib/profiles-presets.js +216 -0
- package/dist/lib/profiles.d.ts +34 -0
- package/dist/lib/profiles.js +112 -1
- 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 +47 -0
- package/dist/lib/routines-format.js +194 -0
- package/dist/lib/routines.d.ts +8 -2
- package/dist/lib/routines.js +34 -14
- package/dist/lib/runner.js +83 -15
- 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/Agents CLI.app/Contents/_CodeSignature/CodeResources +1 -9
- package/dist/lib/secrets/bundles.d.ts +34 -17
- package/dist/lib/secrets/bundles.js +210 -36
- package/dist/lib/secrets/index.d.ts +49 -30
- package/dist/lib/secrets/index.js +126 -115
- package/dist/lib/secrets/install-helper.d.ts +45 -0
- package/dist/lib/secrets/install-helper.js +165 -0
- package/dist/lib/secrets/linux.js +4 -4
- package/dist/lib/secrets/sync.d.ts +56 -0
- package/dist/lib/secrets/sync.js +180 -0
- 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/render.js +4 -4
- package/dist/lib/session/types.d.ts +2 -2
- package/dist/lib/session/types.js +1 -1
- package/dist/lib/shims.d.ts +5 -2
- package/dist/lib/shims.js +70 -38
- package/dist/lib/state.d.ts +14 -2
- package/dist/lib/state.js +51 -20
- package/dist/lib/teams/agents.d.ts +5 -4
- package/dist/lib/teams/agents.js +48 -22
- package/dist/lib/teams/api.d.ts +2 -1
- package/dist/lib/teams/api.js +4 -3
- 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 +63 -4
- package/dist/lib/types.js +8 -3
- package/dist/lib/usage.d.ts +27 -2
- package/dist/lib/usage.js +100 -17
- package/dist/lib/versions.d.ts +45 -3
- package/dist/lib/versions.js +455 -60
- package/package.json +15 -14
- package/scripts/install-helper.js +97 -0
- package/scripts/postinstall.js +16 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/embedded.provisionprofile +0 -0
- package/npm-shrinkwrap.json +0 -3162
package/dist/commands/view.js
CHANGED
|
@@ -3,9 +3,9 @@ import ora from 'ora';
|
|
|
3
3
|
import * as fs from 'fs';
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { AGENTS, ALL_AGENT_IDS, getAllCliStates, getAccountInfo, resolveAgentName, formatAgentError, agentLabel, colorAgent, } from '../lib/agents.js';
|
|
6
|
-
import { formatUsageSection, formatUsageSummary, getUsageInfoForIdentity, getUsageInfoByIdentity, getUsageLookupKey, } from '../lib/usage.js';
|
|
6
|
+
import { formatUsageSection, formatUsageSummary, formatUsageStatusBadge, 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, getProjectOnlyResources, 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';
|
|
@@ -16,8 +16,33 @@ import { isGitRepo, getGitSyncStatus } from '../lib/git.js';
|
|
|
16
16
|
import { getCentralRulesFileName } from '../lib/rules/rules.js';
|
|
17
17
|
import { composeRulesFromState } from '../lib/rules/compose.js';
|
|
18
18
|
import { getConfiguredRunStrategy } from '../lib/rotate.js';
|
|
19
|
+
import { listProfiles, profileSummary } from '../lib/profiles.js';
|
|
19
20
|
import { confirm } from '@inquirer/prompts';
|
|
20
21
|
import { formatPath, isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
22
|
+
/**
|
|
23
|
+
* Group profile summaries by their host harness, optionally filtered to a
|
|
24
|
+
* single agent. Profile YAMLs that fail validation are silently skipped by
|
|
25
|
+
* `listProfiles` so this never throws on a malformed file.
|
|
26
|
+
*/
|
|
27
|
+
function getProfilesByAgent(filterAgentId) {
|
|
28
|
+
const byAgent = new Map();
|
|
29
|
+
for (const profile of listProfiles()) {
|
|
30
|
+
if (filterAgentId && profile.host.agent !== filterAgentId)
|
|
31
|
+
continue;
|
|
32
|
+
const summary = profileSummary(profile);
|
|
33
|
+
const existing = byAgent.get(profile.host.agent);
|
|
34
|
+
if (existing)
|
|
35
|
+
existing.push(summary);
|
|
36
|
+
else
|
|
37
|
+
byAgent.set(profile.host.agent, [summary]);
|
|
38
|
+
}
|
|
39
|
+
return byAgent;
|
|
40
|
+
}
|
|
41
|
+
/** Build the usage-column equivalent for a profile row: "profile <model>". */
|
|
42
|
+
function profileKindAndModel(model, planWidth) {
|
|
43
|
+
const kind = 'profile'.padEnd(Math.max(planWidth, 'profile'.length));
|
|
44
|
+
return `${kind} ${model}`;
|
|
45
|
+
}
|
|
21
46
|
function termLink(text, filePath) {
|
|
22
47
|
const url = `file://${filePath}`;
|
|
23
48
|
return `\x1b]8;;${url}\x1b\\${text}\x1b]8;;\x1b\\`;
|
|
@@ -88,6 +113,32 @@ function getProjectVersionFromCwd(agent) {
|
|
|
88
113
|
return null;
|
|
89
114
|
}
|
|
90
115
|
}
|
|
116
|
+
function getProfileSummaries(filterAgentId) {
|
|
117
|
+
return listProfiles()
|
|
118
|
+
.filter((profile) => !filterAgentId || profile.host.agent === filterAgentId)
|
|
119
|
+
.map(profileSummary);
|
|
120
|
+
}
|
|
121
|
+
function renderProfilesSection(profiles) {
|
|
122
|
+
if (profiles.length === 0)
|
|
123
|
+
return;
|
|
124
|
+
const nameWidth = Math.max(4, ...profiles.map((p) => p.name.length));
|
|
125
|
+
const hostWidth = Math.max(4, ...profiles.map((p) => p.host.length));
|
|
126
|
+
const providerWidth = Math.max(8, ...profiles.map((p) => p.provider.length));
|
|
127
|
+
console.log(chalk.bold('Profiles\n'));
|
|
128
|
+
console.log(` ${chalk.gray('NAME'.padEnd(nameWidth))} ` +
|
|
129
|
+
`${chalk.gray('HOST'.padEnd(hostWidth))} ` +
|
|
130
|
+
`${chalk.gray('PROVIDER'.padEnd(providerWidth))} ` +
|
|
131
|
+
chalk.gray('MODEL'));
|
|
132
|
+
for (const profile of profiles) {
|
|
133
|
+
console.log(` ${chalk.cyan(profile.name.padEnd(nameWidth))} ` +
|
|
134
|
+
`${profile.host.padEnd(hostWidth)} ` +
|
|
135
|
+
`${profile.provider.padEnd(providerWidth)} ` +
|
|
136
|
+
chalk.gray(profile.model));
|
|
137
|
+
}
|
|
138
|
+
console.log(chalk.gray('\n Run: agents run <profile> [prompt]'));
|
|
139
|
+
console.log(chalk.gray(' agents profiles view <profile>'));
|
|
140
|
+
console.log();
|
|
141
|
+
}
|
|
91
142
|
/**
|
|
92
143
|
* Show installed versions for one or all agents.
|
|
93
144
|
* Called when: `agents view` or `agents view claude`
|
|
@@ -101,6 +152,8 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
101
152
|
spinner.stop();
|
|
102
153
|
const agentsToShow = filterAgentId ? [filterAgentId] : ALL_AGENT_IDS;
|
|
103
154
|
const showPaths = !!filterAgentId;
|
|
155
|
+
const profilesByAgent = getProfilesByAgent(filterAgentId);
|
|
156
|
+
const profileSummaries = [...profilesByAgent.values()].flat();
|
|
104
157
|
// Auto-heal stale versioned aliases. Pre-v2 aliases (e.g. pre-CLAUDE_CONFIG_DIR
|
|
105
158
|
// claude shims) silently route login through the default version's symlinked
|
|
106
159
|
// home, so `agents view` would never reflect the right account. Regenerate on
|
|
@@ -190,15 +243,20 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
190
243
|
// Separate version-managed from globally-installed agents
|
|
191
244
|
const versionManaged = [];
|
|
192
245
|
const globallyInstalled = [];
|
|
246
|
+
const profileOnly = [];
|
|
193
247
|
for (const agentId of agentsToShow) {
|
|
194
248
|
const versions = listInstalledVersions(agentId);
|
|
195
249
|
const cliState = cliStates[agentId];
|
|
250
|
+
const hasProfiles = (profilesByAgent.get(agentId)?.length ?? 0) > 0;
|
|
196
251
|
if (versions.length > 0) {
|
|
197
252
|
versionManaged.push(agentId);
|
|
198
253
|
}
|
|
199
254
|
else if (cliState?.installed) {
|
|
200
255
|
globallyInstalled.push(agentId);
|
|
201
256
|
}
|
|
257
|
+
else if (hasProfiles) {
|
|
258
|
+
profileOnly.push(agentId);
|
|
259
|
+
}
|
|
202
260
|
}
|
|
203
261
|
// Show version-managed agents
|
|
204
262
|
if (versionManaged.length > 0) {
|
|
@@ -207,6 +265,7 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
207
265
|
let maxEmail = 0;
|
|
208
266
|
let maxPlanWidth = 3;
|
|
209
267
|
let maxUsageWidth = 0;
|
|
268
|
+
let maxStatusWidth = 0;
|
|
210
269
|
for (const agentId of versionManaged) {
|
|
211
270
|
const versions = listInstalledVersions(agentId);
|
|
212
271
|
const globalDefault = getGlobalDefault(agentId);
|
|
@@ -220,8 +279,14 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
220
279
|
if (info?.plan)
|
|
221
280
|
maxPlanWidth = Math.max(maxPlanWidth, info.plan.length);
|
|
222
281
|
}
|
|
282
|
+
// Profile rows share these columns with version rows so they line up.
|
|
283
|
+
for (const profile of profilesByAgent.get(agentId) ?? []) {
|
|
284
|
+
maxVerLabel = Math.max(maxVerLabel, profile.name.length);
|
|
285
|
+
maxEmail = Math.max(maxEmail, profile.auth.length);
|
|
286
|
+
maxPlanWidth = Math.max(maxPlanWidth, 'profile'.length);
|
|
287
|
+
}
|
|
223
288
|
}
|
|
224
|
-
// Second pass: compute max visible usage
|
|
289
|
+
// Second pass: compute max visible usage + status widths (now that maxPlanWidth is settled)
|
|
225
290
|
for (const agentId of versionManaged) {
|
|
226
291
|
const versions = listInstalledVersions(agentId);
|
|
227
292
|
for (const v of versions) {
|
|
@@ -231,6 +296,12 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
231
296
|
const usageInfo = usageKey ? usageByKey.get(usageKey) : undefined;
|
|
232
297
|
const usageStr = formatUsageSummary(info?.plan || null, usageInfo?.snapshot || null, maxPlanWidth);
|
|
233
298
|
maxUsageWidth = Math.max(maxUsageWidth, visibleWidth(usageStr));
|
|
299
|
+
const statusStr = formatUsageStatusBadge(info?.usageStatus);
|
|
300
|
+
maxStatusWidth = Math.max(maxStatusWidth, visibleWidth(statusStr));
|
|
301
|
+
}
|
|
302
|
+
for (const profile of profilesByAgent.get(agentId) ?? []) {
|
|
303
|
+
const usageEquivalent = profileKindAndModel(profile.model, maxPlanWidth);
|
|
304
|
+
maxUsageWidth = Math.max(maxUsageWidth, visibleWidth(usageEquivalent));
|
|
234
305
|
}
|
|
235
306
|
}
|
|
236
307
|
for (const agentId of versionManaged) {
|
|
@@ -280,6 +351,11 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
280
351
|
const usagePad = ' '.repeat(Math.max(0, maxUsageWidth - visibleWidth(usageStr)));
|
|
281
352
|
parts.push(usageStr + usagePad);
|
|
282
353
|
}
|
|
354
|
+
const statusStr = formatUsageStatusBadge(vInfo?.usageStatus);
|
|
355
|
+
if (maxStatusWidth > 0) {
|
|
356
|
+
const statusPad = ' '.repeat(Math.max(0, maxStatusWidth - visibleWidth(statusStr)));
|
|
357
|
+
parts.push(statusStr + statusPad);
|
|
358
|
+
}
|
|
283
359
|
if (hasActive)
|
|
284
360
|
parts.push(activeStr);
|
|
285
361
|
}
|
|
@@ -289,6 +365,18 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
289
365
|
console.log(chalk.gray(` ${versionDir}`));
|
|
290
366
|
}
|
|
291
367
|
}
|
|
368
|
+
// Profile rows share the same columns as versions: name | auth | "profile"+model.
|
|
369
|
+
// No status badge, no last-active — profiles don't accumulate usage state.
|
|
370
|
+
for (const profile of profilesByAgent.get(agentId) ?? []) {
|
|
371
|
+
const nameCol = chalk.cyan(profile.name.padEnd(maxVerLabel));
|
|
372
|
+
const authCol = chalk.gray(profile.auth.padEnd(maxEmail));
|
|
373
|
+
const usageEquivalent = profileKindAndModel(profile.model, maxPlanWidth);
|
|
374
|
+
const usagePad = ' '.repeat(Math.max(0, maxUsageWidth - visibleWidth(usageEquivalent)));
|
|
375
|
+
console.log(` ${nameCol} ${authCol} ${chalk.gray(usageEquivalent + usagePad)}`);
|
|
376
|
+
if (showPaths) {
|
|
377
|
+
console.log(chalk.gray(` ${profile.path}`));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
292
380
|
// Check for project override
|
|
293
381
|
const projectVersion = getProjectVersionFromCwd(agentId);
|
|
294
382
|
if (projectVersion && projectVersion !== globalDefault) {
|
|
@@ -305,6 +393,19 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
305
393
|
const cliState = cliStates[agentId];
|
|
306
394
|
return `${cliState?.version || 'installed'} (global)`.length;
|
|
307
395
|
}));
|
|
396
|
+
// Pre-pass: max badge width so rows with `lastActive` line up whether or
|
|
397
|
+
// not THIS row carries a throttle badge. Without this, the row that DOES
|
|
398
|
+
// have "out of credits" shifts every other row's `lastActive` left by
|
|
399
|
+
// ~16 chars, exactly what the version-managed block at maxStatusWidth
|
|
400
|
+
// already solves above.
|
|
401
|
+
let gMaxStatusWidth = 0;
|
|
402
|
+
for (const agentId of globallyInstalled) {
|
|
403
|
+
const gInfoRaw = globalInfoMap.get(agentId);
|
|
404
|
+
const gInfo = gInfoRaw ? mergeCanonical(gInfoRaw) : undefined;
|
|
405
|
+
const w = visibleWidth(formatUsageStatusBadge(gInfo?.usageStatus));
|
|
406
|
+
if (w > gMaxStatusWidth)
|
|
407
|
+
gMaxStatusWidth = w;
|
|
408
|
+
}
|
|
308
409
|
for (const agentId of globallyInstalled) {
|
|
309
410
|
const agent = AGENTS[agentId];
|
|
310
411
|
const cliState = cliStates[agentId];
|
|
@@ -323,25 +424,77 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
323
424
|
parts.push(gInfo?.email ? chalk.cyan(gInfo.email) : '');
|
|
324
425
|
if (gUsageStr || gActiveStr)
|
|
325
426
|
parts.push(gUsageStr);
|
|
427
|
+
const gStatusStr = formatUsageStatusBadge(gInfo?.usageStatus);
|
|
428
|
+
if (gMaxStatusWidth > 0) {
|
|
429
|
+
const statusPad = ' '.repeat(Math.max(0, gMaxStatusWidth - visibleWidth(gStatusStr)));
|
|
430
|
+
parts.push(gStatusStr + statusPad);
|
|
431
|
+
}
|
|
326
432
|
if (gActiveStr)
|
|
327
433
|
parts.push(gActiveStr);
|
|
328
434
|
console.log(parts.join(' '));
|
|
329
435
|
if (showPaths && cliState?.path) {
|
|
330
436
|
console.log(chalk.gray(` ${cliState.path}`));
|
|
331
437
|
}
|
|
438
|
+
// Profile rows under a globally-installed harness. Use a simpler
|
|
439
|
+
// alignment here since this section doesn't share column state with
|
|
440
|
+
// the version-managed block.
|
|
441
|
+
const profilesHere = profilesByAgent.get(agentId) ?? [];
|
|
442
|
+
if (profilesHere.length > 0) {
|
|
443
|
+
const nameWidth = Math.max(globalMaxVerLabel, ...profilesHere.map((p) => p.name.length));
|
|
444
|
+
const authWidth = Math.max(...profilesHere.map((p) => p.auth.length));
|
|
445
|
+
for (const profile of profilesHere) {
|
|
446
|
+
console.log(` ${chalk.cyan(profile.name.padEnd(nameWidth))} ` +
|
|
447
|
+
`${chalk.gray(profile.auth.padEnd(authWidth))} ` +
|
|
448
|
+
`${chalk.gray('profile')} ` +
|
|
449
|
+
chalk.gray(profile.model));
|
|
450
|
+
if (showPaths) {
|
|
451
|
+
console.log(chalk.gray(` ${profile.path}`));
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
332
455
|
if (agent.npmPackage && cliState?.version) {
|
|
333
456
|
console.log(chalk.gray(` Manage: agents add ${agentId}@${cliState.version} -y`));
|
|
334
457
|
}
|
|
335
458
|
console.log();
|
|
336
459
|
}
|
|
337
460
|
}
|
|
461
|
+
// Agents with no install but with profiles defined — render under the same
|
|
462
|
+
// harness header so users find them where they look.
|
|
463
|
+
if (profileOnly.length > 0) {
|
|
464
|
+
if (versionManaged.length === 0 && globallyInstalled.length === 0) {
|
|
465
|
+
console.log(chalk.bold('Profile-only Agents\n'));
|
|
466
|
+
}
|
|
467
|
+
for (const agentId of profileOnly) {
|
|
468
|
+
const profilesHere = profilesByAgent.get(agentId) ?? [];
|
|
469
|
+
console.log(` ${chalk.bold(agentLabel(agentId))}${chalk.yellow(' (profile only)')}`);
|
|
470
|
+
const nameWidth = Math.max(...profilesHere.map((p) => p.name.length));
|
|
471
|
+
const authWidth = Math.max(...profilesHere.map((p) => p.auth.length));
|
|
472
|
+
for (const profile of profilesHere) {
|
|
473
|
+
console.log(` ${chalk.cyan(profile.name.padEnd(nameWidth))} ` +
|
|
474
|
+
`${chalk.gray(profile.auth.padEnd(authWidth))} ` +
|
|
475
|
+
`${chalk.gray('profile')} ` +
|
|
476
|
+
chalk.gray(profile.model));
|
|
477
|
+
if (showPaths) {
|
|
478
|
+
console.log(chalk.gray(` ${profile.path}`));
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
console.log();
|
|
482
|
+
}
|
|
483
|
+
}
|
|
338
484
|
// If filtering to a specific agent and not found
|
|
339
|
-
if (filterAgentId &&
|
|
485
|
+
if (filterAgentId &&
|
|
486
|
+
versionManaged.length === 0 &&
|
|
487
|
+
globallyInstalled.length === 0 &&
|
|
488
|
+
profileOnly.length === 0) {
|
|
340
489
|
console.log(` ${chalk.bold(agentLabel(filterAgentId))}: ${chalk.gray('not installed')}`);
|
|
341
490
|
console.log();
|
|
342
491
|
}
|
|
343
492
|
// No agents installed at all
|
|
344
|
-
if (versionManaged.length === 0 &&
|
|
493
|
+
if (versionManaged.length === 0 &&
|
|
494
|
+
globallyInstalled.length === 0 &&
|
|
495
|
+
profileOnly.length === 0 &&
|
|
496
|
+
profileSummaries.length === 0 &&
|
|
497
|
+
!filterAgentId) {
|
|
345
498
|
console.log(chalk.gray(' No agent CLIs installed.'));
|
|
346
499
|
console.log(chalk.gray(' Run: agents add claude@latest'));
|
|
347
500
|
console.log();
|
|
@@ -363,10 +516,11 @@ async function showInstalledVersions(filterAgentId) {
|
|
|
363
516
|
if (defaultVersion) {
|
|
364
517
|
const available = getAvailableResources();
|
|
365
518
|
const synced = getActuallySyncedResources(filterAgentId, defaultVersion);
|
|
366
|
-
const
|
|
519
|
+
const projectOnly = getProjectOnlyResources();
|
|
520
|
+
const newResources = getNewResources(available, synced, projectOnly);
|
|
367
521
|
if (hasNewResources(newResources, filterAgentId, defaultVersion)) {
|
|
368
522
|
try {
|
|
369
|
-
const selection = await promptNewResourceSelection(filterAgentId, newResources);
|
|
523
|
+
const selection = await promptNewResourceSelection(filterAgentId, newResources, defaultVersion);
|
|
370
524
|
if (selection && Object.keys(selection).length > 0) {
|
|
371
525
|
const result = syncResourcesToVersion(filterAgentId, defaultVersion, selection);
|
|
372
526
|
const synced = [];
|
|
@@ -742,6 +896,7 @@ async function collectAgentsJson(filterAgentId) {
|
|
|
742
896
|
email: info.email,
|
|
743
897
|
plan: info.plan,
|
|
744
898
|
usageStatus: info.usageStatus,
|
|
899
|
+
overageCredits: info.overageCredits,
|
|
745
900
|
windows: snapshot
|
|
746
901
|
? snapshot.windows.map((w) => ({
|
|
747
902
|
key: w.key,
|
|
@@ -758,6 +913,7 @@ async function collectAgentsJson(filterAgentId) {
|
|
|
758
913
|
else
|
|
759
914
|
byAgent.set(agentId, [entry]);
|
|
760
915
|
}
|
|
916
|
+
const profilesByAgent = getProfilesByAgent(filterAgentId);
|
|
761
917
|
const out = [];
|
|
762
918
|
for (const agentId of agentsToShow) {
|
|
763
919
|
const versions = byAgent.get(agentId) ?? [];
|
|
@@ -766,7 +922,7 @@ async function collectAgentsJson(filterAgentId) {
|
|
|
766
922
|
return a.isDefault ? -1 : 1;
|
|
767
923
|
return compareVersions(b.version, a.version);
|
|
768
924
|
});
|
|
769
|
-
out.push({ agent: agentId, versions });
|
|
925
|
+
out.push({ agent: agentId, versions, profiles: profilesByAgent.get(agentId) ?? [] });
|
|
770
926
|
}
|
|
771
927
|
return out;
|
|
772
928
|
}
|
|
@@ -833,13 +989,12 @@ async function buildAgentPrunePlan(agentId) {
|
|
|
833
989
|
return { agentId, toPrune, skippedDefaults };
|
|
834
990
|
}
|
|
835
991
|
async function executePrunePlan(plan) {
|
|
836
|
-
|
|
992
|
+
const moved = [];
|
|
837
993
|
for (const p of plan.toPrune) {
|
|
838
|
-
console.log(chalk.gray(`Removing ${agentLabel(p.agentId)}@${p.version}...`));
|
|
839
994
|
const ok = removeVersion(p.agentId, p.version);
|
|
840
995
|
if (ok) {
|
|
841
|
-
console.log(chalk.green(`
|
|
842
|
-
|
|
996
|
+
console.log(chalk.green(`Moved ${agentLabel(p.agentId)}@${p.version} to trash`));
|
|
997
|
+
moved.push({ agent: p.agentId, version: p.version });
|
|
843
998
|
}
|
|
844
999
|
else {
|
|
845
1000
|
console.log(chalk.yellow(`Already gone: ${agentLabel(p.agentId)}@${p.version}`));
|
|
@@ -848,7 +1003,7 @@ async function executePrunePlan(plan) {
|
|
|
848
1003
|
if (listInstalledVersions(plan.agentId).length === 0) {
|
|
849
1004
|
removeShim(plan.agentId);
|
|
850
1005
|
}
|
|
851
|
-
return
|
|
1006
|
+
return moved;
|
|
852
1007
|
}
|
|
853
1008
|
function printPrunePlan(plan, isFirst) {
|
|
854
1009
|
if (plan.skippedDefaults.length > 0) {
|
|
@@ -897,7 +1052,7 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
897
1052
|
return;
|
|
898
1053
|
}
|
|
899
1054
|
const totalCandidates = actionable.reduce((n, plan) => n + plan.toPrune.length, 0);
|
|
900
|
-
|
|
1055
|
+
const allMoved = [];
|
|
901
1056
|
let isFirst = true;
|
|
902
1057
|
let processedAny = false;
|
|
903
1058
|
for (const plan of actionable) {
|
|
@@ -916,10 +1071,10 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
916
1071
|
if (!isInteractiveTerminal()) {
|
|
917
1072
|
console.log(chalk.red('Refusing to prune in a non-interactive shell without --yes.'));
|
|
918
1073
|
if (filterAgentId) {
|
|
919
|
-
console.log(chalk.gray(`Re-run with: agents prune ${filterAgentId} --dry-run`));
|
|
1074
|
+
console.log(chalk.gray(`Re-run with: agents prune cleanup ${filterAgentId} --dry-run`));
|
|
920
1075
|
}
|
|
921
1076
|
else {
|
|
922
|
-
console.log(chalk.gray('Re-run with: agents prune --dry-run'));
|
|
1077
|
+
console.log(chalk.gray('Re-run with: agents prune cleanup --dry-run'));
|
|
923
1078
|
}
|
|
924
1079
|
process.exit(1);
|
|
925
1080
|
}
|
|
@@ -943,7 +1098,7 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
943
1098
|
break;
|
|
944
1099
|
}
|
|
945
1100
|
}
|
|
946
|
-
|
|
1101
|
+
allMoved.push(...(await executePrunePlan(plan)));
|
|
947
1102
|
processedAny = true;
|
|
948
1103
|
isFirst = false;
|
|
949
1104
|
console.log();
|
|
@@ -953,7 +1108,8 @@ export async function pruneDuplicates(filterAgentId, yes, dryRun) {
|
|
|
953
1108
|
return;
|
|
954
1109
|
}
|
|
955
1110
|
if (processedAny) {
|
|
956
|
-
console.log(chalk.bold(`Pruned ${
|
|
1111
|
+
console.log(chalk.bold(`Pruned ${allMoved.length} version${allMoved.length === 1 ? '' : 's'}.`));
|
|
1112
|
+
printTrashFooter(allMoved);
|
|
957
1113
|
}
|
|
958
1114
|
}
|
|
959
1115
|
/**
|
|
@@ -1009,7 +1165,7 @@ export async function viewAction(agentArg, options) {
|
|
|
1009
1165
|
// --json ignores the @version suffix (detailed resource view is not yet
|
|
1010
1166
|
// exposed as structured data). Emit the version list for the agent.
|
|
1011
1167
|
const data = await collectAgentsJson(agentId);
|
|
1012
|
-
console.log(JSON.stringify(data[0] ?? { agent: agentId, versions: [] }, null, 2));
|
|
1168
|
+
console.log(JSON.stringify(data[0] ?? { agent: agentId, versions: [], profiles: [] }, null, 2));
|
|
1013
1169
|
return;
|
|
1014
1170
|
}
|
|
1015
1171
|
if (requestedVersion) {
|
|
@@ -7,9 +7,9 @@ import { select, checkbox } from '@inquirer/prompts';
|
|
|
7
7
|
import { resolveAgentName, agentLabel } from '../lib/agents.js';
|
|
8
8
|
import { cloneRepo } from '../lib/git.js';
|
|
9
9
|
import { WORKFLOW_CAPABLE_AGENTS, discoverWorkflowsFromRepo, installWorkflowCentrally, removeWorkflow, listInstalledWorkflows, listWorkflowsForAgent, removeWorkflowFromVersion, iterWorkflowsCapableVersions, } from '../lib/workflows.js';
|
|
10
|
-
import { getVersionHomePath, getGlobalDefault, resolveVersionAlias, syncResourcesToVersion, promptAgentVersionSelection,
|
|
10
|
+
import { getVersionHomePath, getGlobalDefault, resolveVersionAlias, syncResourcesToVersion, promptAgentVersionSelection, } from '../lib/versions.js';
|
|
11
11
|
import { recordVersionResources, getUserWorkflowsDir } from '../lib/state.js';
|
|
12
|
-
import { isPromptCancelled, isInteractiveTerminal, requireInteractiveSelection, printWithPager, promptRemovalTargets, } from './utils.js';
|
|
12
|
+
import { isPromptCancelled, isInteractiveTerminal, requireInteractiveSelection, printWithPager, promptRemovalTargets, parseCommaSeparatedList, resolveAgentTargetsAutoInstalling, } from './utils.js';
|
|
13
13
|
import { showResourceList, buildTargetsSection, } from './resource-view.js';
|
|
14
14
|
/** Register the `agents workflows` command tree (list, view, add, remove). */
|
|
15
15
|
export function registerWorkflowsCommands(program) {
|
|
@@ -92,18 +92,25 @@ Examples:
|
|
|
92
92
|
workflowsCmd
|
|
93
93
|
.command('add [source]')
|
|
94
94
|
.description('Install workflows from a source (GitHub, local) or pick from central storage')
|
|
95
|
-
.option('-a, --agents <list>', 'Targets: claude, claude@2.1.138')
|
|
95
|
+
.option('-a, --agents <list>', 'Targets: claude, claude@2.1.138, claude@all, all')
|
|
96
|
+
.option('--names <list>', 'Workflow names from the source (comma-separated)')
|
|
96
97
|
.option('-y, --yes', 'Skip confirmation prompts')
|
|
97
98
|
.addHelpText('after', `
|
|
98
99
|
Examples:
|
|
99
100
|
# Install from GitHub
|
|
100
101
|
agents workflows add gh:user/workflows
|
|
101
102
|
|
|
103
|
+
# Pluck specific workflows from a multi-workflow repo
|
|
104
|
+
agents workflows add gh:user/workflows --names rdev,plan
|
|
105
|
+
|
|
102
106
|
# Install a local workflow directory (must contain WORKFLOW.md)
|
|
103
107
|
agents workflows add ./rdev
|
|
104
108
|
|
|
105
109
|
# Install and sync to a specific version
|
|
106
110
|
agents workflows add gh:user/workflows --agents claude@2.1.138
|
|
111
|
+
|
|
112
|
+
# Install across every installed Claude version
|
|
113
|
+
agents workflows add gh:user/workflows --agents claude@all
|
|
107
114
|
`)
|
|
108
115
|
.action(async (source, options) => {
|
|
109
116
|
try {
|
|
@@ -156,11 +163,23 @@ Examples:
|
|
|
156
163
|
}
|
|
157
164
|
spinner.succeed('Using local path');
|
|
158
165
|
}
|
|
159
|
-
|
|
166
|
+
let discovered = discoverWorkflowsFromRepo(localPath);
|
|
160
167
|
if (discovered.length === 0) {
|
|
161
168
|
console.log(chalk.yellow('No workflows found (looking for WORKFLOW.md files)'));
|
|
162
169
|
return;
|
|
163
170
|
}
|
|
171
|
+
// --names filter: pluck specific workflows from a multi-workflow source.
|
|
172
|
+
const requestedNames = parseCommaSeparatedList(options.names);
|
|
173
|
+
if (requestedNames.length > 0) {
|
|
174
|
+
const discoveredNames = new Set(discovered.map((w) => w.name));
|
|
175
|
+
const missing = requestedNames.filter((n) => !discoveredNames.has(n));
|
|
176
|
+
if (missing.length > 0) {
|
|
177
|
+
console.log(chalk.red(`\nWorkflow(s) not found in source: ${missing.join(', ')}`));
|
|
178
|
+
console.log(chalk.gray(`Available: ${[...discoveredNames].join(', ')}`));
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
discovered = discovered.filter((w) => requestedNames.includes(w.name));
|
|
182
|
+
}
|
|
164
183
|
console.log(chalk.bold(`\nFound ${discovered.length} workflow(s):`));
|
|
165
184
|
for (const w of discovered) {
|
|
166
185
|
console.log(`\n ${chalk.cyan(w.name)}: ${w.frontmatter.description || 'no description'}`);
|
|
@@ -191,13 +210,17 @@ Examples:
|
|
|
191
210
|
let selectedAgents;
|
|
192
211
|
let versionSelections;
|
|
193
212
|
if (options.agents) {
|
|
194
|
-
const result =
|
|
213
|
+
const result = await resolveAgentTargetsAutoInstalling(options.agents, WORKFLOW_CAPABLE_AGENTS, { yes: options.yes });
|
|
214
|
+
if (!result) {
|
|
215
|
+
console.log(chalk.gray('Cancelled.'));
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
195
218
|
selectedAgents = result.selectedAgents;
|
|
196
219
|
versionSelections = result.versionSelections;
|
|
197
220
|
}
|
|
198
221
|
else {
|
|
199
222
|
const result = await promptAgentVersionSelection(WORKFLOW_CAPABLE_AGENTS, {
|
|
200
|
-
skipPrompts: options.yes
|
|
223
|
+
skipPrompts: options.yes,
|
|
201
224
|
});
|
|
202
225
|
selectedAgents = result.selectedAgents;
|
|
203
226
|
versionSelections = result.versionSelections;
|
package/dist/computer.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
@@ -59,6 +59,7 @@ import { registerPullCommand } from './commands/pull.js';
|
|
|
59
59
|
import { registerRepoCommands } from './commands/repo.js';
|
|
60
60
|
import { registerSetupCommand, runSetup } from './commands/setup.js';
|
|
61
61
|
import { registerStatusCommand } from './commands/status.js';
|
|
62
|
+
import { registerFeedbackCommand } from './commands/feedback.js';
|
|
62
63
|
import { registerViewCommand } from './commands/view.js';
|
|
63
64
|
import { registerCommandsCommands } from './commands/commands.js';
|
|
64
65
|
import { registerHooksCommands } from './commands/hooks.js';
|
|
@@ -66,6 +67,7 @@ import { registerSkillsCommands } from './commands/skills.js';
|
|
|
66
67
|
import { registerRulesCommands } from './commands/rules.js';
|
|
67
68
|
import { registerPermissionsCommands } from './commands/permissions.js';
|
|
68
69
|
import { registerMcpCommands } from './commands/mcp.js';
|
|
70
|
+
import { registerCliCommands } from './commands/cli.js';
|
|
69
71
|
import { registerVersionsCommands } from './commands/versions.js';
|
|
70
72
|
import { registerImportCommand } from './commands/import.js';
|
|
71
73
|
import { registerPackagesCommands } from './commands/packages.js';
|
|
@@ -88,6 +90,7 @@ import { registerBrowserCommand } from './commands/browser.js';
|
|
|
88
90
|
import { registerComputerCommand } from './commands/computer.js';
|
|
89
91
|
import { registerProfilesCommands } from './commands/profiles.js';
|
|
90
92
|
import { registerSecretsCommands } from './commands/secrets.js';
|
|
93
|
+
import { registerHelperCommand } from './commands/helper.js';
|
|
91
94
|
import { registerFactoryCommands } from './commands/factory.js';
|
|
92
95
|
import { registerUsageCommand } from './commands/usage.js';
|
|
93
96
|
import { registerAliasCommand } from './commands/alias.js';
|
|
@@ -120,11 +123,12 @@ Quick start:
|
|
|
120
123
|
agents sessions Browse past sessions across all agents
|
|
121
124
|
|
|
122
125
|
Agent versions:
|
|
123
|
-
add <agent>[@version] Install an agent CLI (e.g. agents add codex)
|
|
126
|
+
add <agent>[@version] Install an agent CLI (e.g. agents add grok or agents add codex)
|
|
124
127
|
import <agent> Adopt an existing global install (npm/homebrew) into agents-cli
|
|
125
|
-
|
|
128
|
+
prune <agent>[@version] Uninstall a version
|
|
129
|
+
remove <agent>[@version] Alias for prune
|
|
126
130
|
use <agent>@<version> Set the default version
|
|
127
|
-
prune [target]
|
|
131
|
+
prune cleanup [target] Remove orphan resources and older duplicate version installs
|
|
128
132
|
trash Inspect and restore soft-deleted version directories
|
|
129
133
|
view [agent[@version]] List versions, or inspect one in detail
|
|
130
134
|
|
|
@@ -171,7 +175,7 @@ Automation tips:
|
|
|
171
175
|
Pass explicit names/IDs Avoid pickers: agents sessions <id> --markdown
|
|
172
176
|
Use --yes for defaults Auto-accept sync/default prompts on add/use/pull
|
|
173
177
|
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
|
|
178
|
+
Use agent@version targets e.g. --agents grok@0.1.218,claude@2.1.79,codex@default
|
|
175
179
|
Non-TTY shells apply defaults Omitted required selections fail with a plain hint
|
|
176
180
|
|
|
177
181
|
Options:
|
|
@@ -361,7 +365,13 @@ async function promptUpgrade(latestVersion) {
|
|
|
361
365
|
console.log();
|
|
362
366
|
}
|
|
363
367
|
}
|
|
364
|
-
/**
|
|
368
|
+
/**
|
|
369
|
+
* Background update check — fires once per 24h cache window.
|
|
370
|
+
* Network: GET registry.npmjs.org/@phnx-labs/agents-cli/latest.
|
|
371
|
+
* Disable: set AGENTS_CLI_DISABLE_AUTO_UPDATE=1 in shell rc.
|
|
372
|
+
*
|
|
373
|
+
* Fire-and-forget; never blocks the CLI's foreground operation.
|
|
374
|
+
*/
|
|
365
375
|
function refreshUpdateCacheInBackground() {
|
|
366
376
|
fetch('https://registry.npmjs.org/@phnx-labs/agents-cli/latest', {
|
|
367
377
|
signal: AbortSignal.timeout(2000),
|
|
@@ -501,6 +511,7 @@ async function maybeBootstrapShimIntegration(requestedCommand) {
|
|
|
501
511
|
// Register all commands
|
|
502
512
|
registerViewCommand(program);
|
|
503
513
|
registerStatusCommand(program);
|
|
514
|
+
registerFeedbackCommand(program);
|
|
504
515
|
registerCommandsCommands(program);
|
|
505
516
|
registerHooksCommands(program);
|
|
506
517
|
registerSkillsCommands(program);
|
|
@@ -529,6 +540,7 @@ program
|
|
|
529
540
|
await program.parseAsync(['node', 'agents', ...args]);
|
|
530
541
|
});
|
|
531
542
|
registerMcpCommands(program);
|
|
543
|
+
registerCliCommands(program);
|
|
532
544
|
registerSubagentsCommands(program);
|
|
533
545
|
registerPluginsCommands(program);
|
|
534
546
|
registerWorkflowsCommands(program);
|
|
@@ -556,6 +568,7 @@ program
|
|
|
556
568
|
});
|
|
557
569
|
registerProfilesCommands(program);
|
|
558
570
|
registerSecretsCommands(program);
|
|
571
|
+
registerHelperCommand(program);
|
|
559
572
|
registerBetaCommands(program);
|
|
560
573
|
registerSyncCommand(program);
|
|
561
574
|
registerRefreshRulesCommand(program);
|
|
@@ -726,7 +739,13 @@ if (firstRun) {
|
|
|
726
739
|
// Every command requires the system repo to be cloned first. `setup` is the
|
|
727
740
|
// only exemption — it's the command that does the cloning.
|
|
728
741
|
const SETUP_EXEMPT_COMMANDS = new Set(['setup', 'help']);
|
|
729
|
-
|
|
742
|
+
// Help and version output are pure documentation — they must never gate on
|
|
743
|
+
// setup, otherwise `agents <cmd> --help` becomes useless on a fresh box.
|
|
744
|
+
const helpOrVersionRequested = passedArgs.some((arg) => arg === '--help' || arg === '-h' || arg === '--version' || arg === '-V');
|
|
745
|
+
if (!firstRun &&
|
|
746
|
+
requestedCommand &&
|
|
747
|
+
!SETUP_EXEMPT_COMMANDS.has(requestedCommand) &&
|
|
748
|
+
!helpOrVersionRequested) {
|
|
730
749
|
const { ensureInitialized } = await import('./commands/setup.js');
|
|
731
750
|
await ensureInitialized(program);
|
|
732
751
|
}
|
|
@@ -771,5 +790,18 @@ catch (err) {
|
|
|
771
790
|
if (err instanceof Error && err.name === 'ExitPromptError') {
|
|
772
791
|
process.exit(130);
|
|
773
792
|
}
|
|
793
|
+
// Browser-daemon-not-running and CDP-not-reachable surface as typed errors
|
|
794
|
+
// from src/lib/browser/. Don't dump a Node stacktrace for these — they are
|
|
795
|
+
// user-actionable, not engineering bugs. See issues #41 and #43.
|
|
796
|
+
if (err instanceof Error) {
|
|
797
|
+
const isBrowserDaemonNotRunning = err.name === 'BrowserDaemonNotRunningError';
|
|
798
|
+
const isBrowserCdpUnreachable = err.name === 'BrowserCdpConnectionError';
|
|
799
|
+
const isBrowserIpcDown = err.message.startsWith('IPC error:') &&
|
|
800
|
+
(err.message.includes('ECONNREFUSED') || err.message.includes('ENOENT'));
|
|
801
|
+
if (isBrowserDaemonNotRunning || isBrowserCdpUnreachable || isBrowserIpcDown) {
|
|
802
|
+
console.error(err.message);
|
|
803
|
+
process.exit(1);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
774
806
|
throw err;
|
|
775
807
|
}
|
package/dist/lib/acp/client.js
CHANGED
|
@@ -82,7 +82,12 @@ function buildClient(opts) {
|
|
|
82
82
|
return {};
|
|
83
83
|
},
|
|
84
84
|
async requestPermission(params) {
|
|
85
|
-
|
|
85
|
+
// `skip` (formerly `full`) and `auto` blanket-approve; in `auto` the
|
|
86
|
+
// upstream model has its own classifier so we just say "allow once" and
|
|
87
|
+
// let it decide. `edit` says allow_once. `plan` should never reach here
|
|
88
|
+
// (canWrite gates writes earlier), but if it does we cancel.
|
|
89
|
+
const skipAll = mode === 'skip';
|
|
90
|
+
const optionId = skipAll
|
|
86
91
|
? (params.options.find(o => o.kind === 'allow_always')?.optionId
|
|
87
92
|
?? params.options[0]?.optionId)
|
|
88
93
|
: params.options.find(o => o.kind === 'allow_once')?.optionId;
|
|
@@ -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).
|
package/dist/lib/agents.d.ts
CHANGED
|
@@ -156,6 +156,10 @@ interface McpConfigEntry {
|
|
|
156
156
|
type?: string;
|
|
157
157
|
url?: string;
|
|
158
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Get user-scoped MCP config path for an agent.
|
|
161
|
+
*/
|
|
162
|
+
export declare function getUserMcpConfigPath(agentId: AgentId): string;
|
|
159
163
|
/**
|
|
160
164
|
* Get MCP config path for a specific HOME directory (used for version-managed agents).
|
|
161
165
|
*/
|