@phnx-labs/agents-cli 1.20.78 → 1.20.82
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 +487 -0
- package/README.md +25 -25
- package/dist/bin/agents +0 -0
- package/dist/commands/activity.d.ts +9 -0
- package/dist/commands/activity.js +153 -24
- package/dist/commands/apply.js +11 -4
- package/dist/commands/cli.js +1 -1
- package/dist/commands/commands.d.ts +1 -1
- package/dist/commands/commands.js +7 -6
- package/dist/commands/defaults.js +3 -11
- package/dist/commands/doctor.d.ts +65 -0
- package/dist/commands/doctor.js +575 -31
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.js +24 -5
- package/dist/commands/feed.d.ts +4 -0
- package/dist/commands/feed.js +87 -11
- package/dist/commands/harness.js +2 -2
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +8 -4
- package/dist/commands/logs.js +6 -0
- package/dist/commands/models.js +1 -1
- package/dist/commands/packages.js +6 -6
- package/dist/commands/permissions.js +1 -1
- package/dist/commands/profiles.js +1 -1
- package/dist/commands/pull.d.ts +1 -1
- package/dist/commands/pull.js +4 -4
- package/dist/commands/repo.d.ts +78 -0
- package/dist/commands/repo.js +187 -11
- package/dist/commands/routines.js +12 -2
- package/dist/commands/rules.js +13 -12
- package/dist/commands/secrets.d.ts +3 -1
- package/dist/commands/secrets.js +100 -32
- package/dist/commands/sessions-inject.d.ts +7 -4
- package/dist/commands/sessions-inject.js +18 -18
- package/dist/commands/sessions-picker.js +32 -3
- package/dist/commands/sessions-resume.d.ts +16 -0
- package/dist/commands/sessions-resume.js +14 -13
- package/dist/commands/sessions.d.ts +31 -0
- package/dist/commands/sessions.js +141 -16
- package/dist/commands/set.d.ts +15 -0
- package/dist/commands/set.js +79 -0
- package/dist/commands/setup-fleet.d.ts +21 -0
- package/dist/commands/setup-fleet.js +201 -0
- package/dist/commands/setup-secrets.d.ts +20 -0
- package/dist/commands/setup-secrets.js +223 -0
- package/dist/commands/setup.js +17 -3
- package/dist/commands/skills.js +1 -1
- package/dist/commands/sync.js +7 -2
- package/dist/commands/teams-picker.js +0 -1
- package/dist/commands/teams.d.ts +33 -1
- package/dist/commands/teams.js +208 -44
- package/dist/commands/versions.js +10 -5
- package/dist/commands/view.d.ts +1 -0
- package/dist/commands/view.js +11 -0
- package/dist/index.js +5 -8
- package/dist/lib/acp/harnesses.js +0 -7
- package/dist/lib/activity.d.ts +156 -0
- package/dist/lib/activity.js +282 -0
- package/dist/lib/agents.d.ts +9 -2
- package/dist/lib/agents.js +72 -63
- package/dist/lib/browser/service.js +3 -0
- package/dist/lib/browser/types.d.ts +7 -0
- package/dist/lib/capabilities.js +6 -2
- package/dist/lib/crabbox/lease.js +2 -2
- package/dist/lib/crabbox/setup-copy.d.ts +4 -4
- package/dist/lib/crabbox/setup-copy.js +4 -4
- package/dist/lib/daemon.d.ts +18 -0
- package/dist/lib/daemon.js +47 -6
- package/dist/lib/devices/fleet.d.ts +1 -1
- package/dist/lib/devices/fleet.js +1 -1
- package/dist/lib/doctor-diff.d.ts +20 -0
- package/dist/lib/doctor-diff.js +6 -1
- package/dist/lib/drift.d.ts +31 -11
- package/dist/lib/drift.js +58 -7
- package/dist/lib/events.d.ts +8 -1
- package/dist/lib/events.js +10 -1
- package/dist/lib/exec.js +35 -8
- package/dist/lib/feed-post.d.ts +28 -1
- package/dist/lib/feed-post.js +110 -2
- package/dist/lib/fleet/apply.js +8 -1
- package/dist/lib/fleet/auth-sync.d.ts +18 -1
- package/dist/lib/fleet/auth-sync.js +25 -11
- package/dist/lib/fleet/remote-login.js +5 -0
- package/dist/lib/git.d.ts +14 -14
- package/dist/lib/git.js +41 -44
- package/dist/lib/hooks.d.ts +42 -0
- package/dist/lib/hooks.js +137 -93
- package/dist/lib/hosts/dispatch.d.ts +28 -1
- package/dist/lib/hosts/dispatch.js +33 -5
- package/dist/lib/hosts/option.js +2 -2
- package/dist/lib/hosts/passthrough.d.ts +22 -1
- package/dist/lib/hosts/passthrough.js +238 -13
- package/dist/lib/hosts/run-target.d.ts +2 -0
- package/dist/lib/hosts/run-target.js +1 -0
- package/dist/lib/hq/floor.d.ts +1 -1
- package/dist/lib/hq/floor.js +6 -1
- package/dist/lib/mcp.js +3 -71
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/notify-desktop.d.ts +15 -0
- package/dist/lib/menubar/notify-desktop.js +41 -5
- package/dist/lib/merged-resources.d.ts +11 -0
- package/dist/{commands/resources.js → lib/merged-resources.js} +11 -19
- package/dist/lib/permissions.d.ts +0 -32
- package/dist/lib/permissions.js +4 -157
- package/dist/lib/picker.js +1 -1
- package/dist/lib/platform/process.d.ts +16 -5
- package/dist/lib/platform/process.js +54 -0
- package/dist/lib/plugins.d.ts +0 -8
- package/dist/lib/plugins.js +4 -110
- package/dist/lib/project-resources.js +4 -1
- package/dist/lib/refresh.d.ts +5 -3
- package/dist/lib/refresh.js +7 -5
- package/dist/lib/resources/commands.js +4 -1
- package/dist/lib/resources/mcp.js +0 -4
- package/dist/lib/resources/permissions.d.ts +1 -1
- package/dist/lib/resources/permissions.js +1 -5
- package/dist/lib/resources/rules.js +4 -1
- package/dist/lib/resources/skills.js +4 -1
- package/dist/lib/resources/subagents.js +4 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/routines.d.ts +20 -0
- package/dist/lib/routines.js +6 -0
- package/dist/lib/run-defaults.d.ts +1 -0
- package/dist/lib/run-defaults.js +9 -0
- package/dist/lib/runner.d.ts +0 -12
- package/dist/lib/runner.js +49 -10
- 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/agent.d.ts +16 -0
- package/dist/lib/secrets/agent.js +105 -3
- package/dist/lib/secrets/audit.d.ts +46 -0
- package/dist/lib/secrets/audit.js +56 -0
- package/dist/lib/secrets/bundles.d.ts +11 -8
- package/dist/lib/secrets/bundles.js +31 -23
- package/dist/lib/secrets/index.d.ts +2 -1
- package/dist/lib/secrets/index.js +8 -2
- package/dist/lib/secrets/remote.d.ts +75 -2
- package/dist/lib/secrets/remote.js +139 -5
- package/dist/lib/secrets/sync.js +3 -3
- package/dist/lib/session/active.d.ts +110 -26
- package/dist/lib/session/active.js +161 -50
- package/dist/lib/session/actor-sidecar.d.ts +23 -0
- package/dist/lib/session/actor-sidecar.js +101 -0
- package/dist/lib/session/db.d.ts +4 -1
- package/dist/lib/session/db.js +65 -8
- package/dist/lib/session/discover.d.ts +4 -0
- package/dist/lib/session/discover.js +13 -0
- package/dist/lib/session/hook-sessions.d.ts +9 -0
- package/dist/lib/session/hook-sessions.js +57 -8
- package/dist/lib/session/pid-registry.d.ts +13 -0
- package/dist/lib/session/render.d.ts +2 -0
- package/dist/lib/session/render.js +1 -1
- package/dist/lib/session/types.d.ts +16 -0
- package/dist/lib/staleness/detectors/commands.js +2 -2
- package/dist/lib/staleness/detectors/permissions.js +1 -45
- package/dist/lib/staleness/writers/commands.js +4 -5
- package/dist/lib/staleness/writers/hooks.js +1 -1
- package/dist/lib/startup/command-registry.d.ts +1 -2
- package/dist/lib/startup/command-registry.js +2 -4
- package/dist/lib/subagents-registry.js +5 -12
- package/dist/lib/subagents.d.ts +0 -10
- package/dist/lib/subagents.js +0 -12
- package/dist/lib/teams/agents.d.ts +0 -2
- package/dist/lib/teams/agents.js +10 -27
- package/dist/lib/teams/index.d.ts +1 -1
- package/dist/lib/teams/index.js +1 -1
- package/dist/lib/types.d.ts +17 -9
- package/dist/lib/usage.d.ts +28 -5
- package/dist/lib/usage.js +271 -8
- package/dist/lib/versions.js +7 -1
- package/dist/lib/watchdog/watchdog.d.ts +1 -1
- package/dist/lib/watchdog/watchdog.js +25 -13
- package/package.json +1 -2
- package/dist/commands/check.d.ts +0 -15
- package/dist/commands/check.js +0 -180
- package/dist/commands/resources.d.ts +0 -5
package/dist/commands/events.js
CHANGED
|
@@ -76,7 +76,7 @@ export function registerEventsCommand(program) {
|
|
|
76
76
|
.description('Read the unified event stream (operational + agent activity)')
|
|
77
77
|
.option('--module <name>', 'Only events from this group (e.g. teams, secrets, activity)')
|
|
78
78
|
.option('--command <path>', 'Only this command path — prefix match (e.g. "teams create")')
|
|
79
|
-
.option('--event <type>', 'Only this typed event (repeatable, e.g. secrets.get, pr.opened)', collect, [])
|
|
79
|
+
.option('--event <type>', 'Only this typed event (repeatable, e.g. secrets.get, secrets.unlocked, pr.opened)', collect, [])
|
|
80
80
|
.option('--agent <name>', 'Only events tagged with this agent')
|
|
81
81
|
.option('--since <time>', 'Only events newer than this (e.g. 2h, 7d, or ISO date)')
|
|
82
82
|
.option('--audit', 'Operational events only (skip agent activity)')
|
package/dist/commands/exec.js
CHANGED
|
@@ -11,7 +11,7 @@ import { setHelpSections } from '../lib/help.js';
|
|
|
11
11
|
import { isInteractiveTerminal, isPromptCancelled, requireInteractiveSelection } from './utils.js';
|
|
12
12
|
import { getUserAgentsDir } from '../lib/state.js';
|
|
13
13
|
import { parseLoopInterval } from '../lib/loop.js';
|
|
14
|
-
import { AGENTS } from '../lib/agents.js';
|
|
14
|
+
import { AGENTS, resolveAgentName, isAgentHardDeprecated, hardDeprecationError } from '../lib/agents.js';
|
|
15
15
|
import { recordDispatchedRun } from '../lib/audit/log.js';
|
|
16
16
|
import { maybeShowStarNudge } from '../lib/star-nudge.js';
|
|
17
17
|
import { warnUnpushedWork, shouldWarnUnpushed } from '../lib/warn-unpushed.js';
|
|
@@ -372,10 +372,10 @@ export function registerRunCommand(program) {
|
|
|
372
372
|
.option('--no-tmux', 'Spawn the agent directly instead of wrapping it in the shared tmux session. Same effect as --raw / AGENTS_NO_TMUX=1. Use this to see the agent\'s full startup output when a launch is failing.')
|
|
373
373
|
.option('--disable-tmux', 'Alias for --no-tmux.')
|
|
374
374
|
.option('--timeout <duration>', 'Kill the agent after this duration (e.g., 30m, 1h, 2h30m)')
|
|
375
|
-
.option('--fallback <agents>', 'Comma-separated agents to try on rate-limit failure. Each entry accepts an optional @version pin (e.g., codex@0.116.0,
|
|
375
|
+
.option('--fallback <agents>', 'Comma-separated agents to try on rate-limit failure. Each entry accepts an optional @version pin (e.g., codex@0.116.0,antigravity). The primary runs first; if it exits with a rate-limit error, the next agent picks up via /continue handoff.')
|
|
376
376
|
.option('-b, --balanced', 'Shortcut for --strategy balanced. Ignored when @version is pinned.')
|
|
377
377
|
.option('--strategy <strategy>', 'Version/account selection strategy: pinned | available | balanced. Defaults to run.<agent>.strategy, then balanced (spreads load across healthy accounts and skips any that are rate-limited). (Legacy `rotate` accepted as alias for `balanced`.)')
|
|
378
|
-
.option('--acp', 'Route through the Agent Client Protocol instead of direct exec. Supported for
|
|
378
|
+
.option('--acp', 'Route through the Agent Client Protocol instead of direct exec. Supported for claude via @zed-industries/claude-code-acp adapter. Unified event stream; emits ndjson when --json.')
|
|
379
379
|
.option('-y, --yes', 'Skip the interactive budget-confirm prompt (require_confirm_over). Never skips a hard budget block.', false)
|
|
380
380
|
.option('--loop', 'Re-inject the prompt/entrypoint each iteration until a stop condition (issue #332). Guards (--max-iterations, --budget, --until) are enforced outside the agent. Writes a checkpoint after every iteration for --resume-checkpoint.')
|
|
381
381
|
.option('--resume-checkpoint <file>', 'Resume a killed loop run from its checkpoint.json. Continues from the last completed iteration, reusing the same runId, session id, prompt, and loop config.')
|
|
@@ -464,7 +464,7 @@ export function registerRunCommand(program) {
|
|
|
464
464
|
installed account for this run. Rows show identity, login state, plan,
|
|
465
465
|
and available limits; unsafe accounts stay visible but disabled.
|
|
466
466
|
|
|
467
|
-
Fallback: --fallback codex,
|
|
467
|
+
Fallback: --fallback codex,antigravity retries on rate-limit failure via /continue handoff. Each entry accepts @version.
|
|
468
468
|
|
|
469
469
|
Resume: --resume <id> continues a prior conversation (full or partial id; omit to pick interactively). claude/codex resume natively; others replay via a /continue first message. Add a prompt to continue headlessly.
|
|
470
470
|
|
|
@@ -502,6 +502,12 @@ export function registerRunCommand(program) {
|
|
|
502
502
|
console.error(chalk.red(`Invalid account picker target: ${agentSpec}. Use agents run <agent>@.`));
|
|
503
503
|
process.exit(1);
|
|
504
504
|
}
|
|
505
|
+
// Hard-deprecated harnesses cannot be run — point the user at the successor.
|
|
506
|
+
const runBaseAgentId = resolveAgentName(normalizedAgentSpec.split('@')[0]);
|
|
507
|
+
if (runBaseAgentId && isAgentHardDeprecated(runBaseAgentId)) {
|
|
508
|
+
console.error(chalk.red(hardDeprecationError(runBaseAgentId)));
|
|
509
|
+
process.exit(1);
|
|
510
|
+
}
|
|
505
511
|
// Account-picker conflict check runs BEFORE device=auto may set balanced,
|
|
506
512
|
// so an implicit balanced preference never surfaces as a fake
|
|
507
513
|
// "cannot be combined with --balanced" when the user only typed trailing @.
|
|
@@ -965,8 +971,19 @@ export function registerRunCommand(program) {
|
|
|
965
971
|
// Working directory on the host: an explicit --remote-cwd is used
|
|
966
972
|
// verbatim; --cwd/--project are made portable (a local-home absolute
|
|
967
973
|
// becomes `~/…` so the remote shell re-roots it at ITS home).
|
|
974
|
+
//
|
|
975
|
+
// With neither flag, mirror the LOCAL cwd's home-relative path onto
|
|
976
|
+
// the host (deriveMirroredCwd). Otherwise every host run starts in the
|
|
977
|
+
// remote `$HOME` — launch an agent from a repo and it opens with no
|
|
978
|
+
// project, and you `cd` by hand every time. The same checkout at the
|
|
979
|
+
// same home-relative path on both boxes is the normal fleet layout, so
|
|
980
|
+
// the mirror usually hits; when the host lacks that directory the run
|
|
981
|
+
// falls back to the remote home rather than failing.
|
|
968
982
|
const { toRemotePortable } = await import('../lib/project-root.js');
|
|
969
|
-
const
|
|
983
|
+
const { deriveMirroredCwd } = await import('../lib/hosts/dispatch.js');
|
|
984
|
+
const explicitHostCwd = options.remoteCwd ?? (options.cwd ? toRemotePortable(options.cwd) : undefined);
|
|
985
|
+
const hostCwd = explicitHostCwd ?? deriveMirroredCwd(process.cwd());
|
|
986
|
+
const mirrorHostCwd = explicitHostCwd === undefined;
|
|
970
987
|
const hostAddDirs = options.addDir.length > 0 ? options.addDir.map(toRemotePortable) : undefined;
|
|
971
988
|
// `--resume [id]`: commander yields the string id, or `true` when the
|
|
972
989
|
// flag is passed bare. A bare resume needs the interactive picker,
|
|
@@ -1104,6 +1121,7 @@ export function registerRunCommand(program) {
|
|
|
1104
1121
|
yes: options.yes,
|
|
1105
1122
|
acp: options.acp,
|
|
1106
1123
|
remoteCwd: hostCwd,
|
|
1124
|
+
mirrorCwd: mirrorHostCwd,
|
|
1107
1125
|
sessionId: hostSessionId,
|
|
1108
1126
|
name: options.name,
|
|
1109
1127
|
resume: resumeId,
|
|
@@ -1190,6 +1208,7 @@ export function registerRunCommand(program) {
|
|
|
1190
1208
|
acp: options.acp,
|
|
1191
1209
|
autoSecrets: options.autoSecrets,
|
|
1192
1210
|
remoteCwd: hostCwd,
|
|
1211
|
+
mirrorCwd: mirrorHostCwd,
|
|
1193
1212
|
name: options.name,
|
|
1194
1213
|
resume: resumeId,
|
|
1195
1214
|
sessionId: options.sessionId,
|
package/dist/commands/feed.d.ts
CHANGED
|
@@ -59,3 +59,7 @@ export declare function sessionHintsFromActive(sessions: Array<{
|
|
|
59
59
|
};
|
|
60
60
|
}>): SessionOutcomeHint[];
|
|
61
61
|
export declare function registerFeedCommand(program: Command): void;
|
|
62
|
+
/** Feed view selector (RUSH-2015): decisions, progress, or both. */
|
|
63
|
+
export type FeedFilter = 'needs' | 'updates' | 'all';
|
|
64
|
+
/** Normalize a raw --filter value; unknown/empty falls back to the default. */
|
|
65
|
+
export declare function resolveFeedFilter(raw: string | undefined): FeedFilter;
|
package/dist/commands/feed.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { ensureFeedPublishHook, listAskStats, listBlocks, recordNotified } from '../lib/feed.js';
|
|
3
|
-
import { ensureActivityLogHook, readRecentActivity, formatActivityLine } from '../lib/activity.js';
|
|
3
|
+
import { ensureActivityLogHook, readRecentActivity, formatActivityLine, formatProgressUpdate } from '../lib/activity.js';
|
|
4
4
|
import { postFeedStatus } from '../lib/feed-post.js';
|
|
5
5
|
import { enrichBlocksFromSessions, groupBlocksByOutcome, isUnambiguousOutcomeAnswer, openBlocksForOutcome, stampBlockOutcomes, } from '../lib/feed-outcome.js';
|
|
6
6
|
import { classifyBlock, filterBlocksForFeed, suppressionDigest, } from '../lib/ask-classifier.js';
|
|
@@ -219,6 +219,7 @@ export function registerFeedCommand(program) {
|
|
|
219
219
|
.command('feed')
|
|
220
220
|
.description('Open blocks (needs you) + agent status posts (feed post)')
|
|
221
221
|
.option('--json', 'Output as JSON (each block stamped with its outcome + ask class)')
|
|
222
|
+
.option('--filter <view>', 'What to show: needs (default) · updates · all', 'needs')
|
|
222
223
|
.option('--flat', 'List one block per agent instead of grouping by outcome')
|
|
223
224
|
.option('--all', 'Include stalls/FYIs that policy would suppress (default: hide them)')
|
|
224
225
|
.option('--local', 'Only this machine -- skip the cross-machine SSH fan-out')
|
|
@@ -232,11 +233,13 @@ export function registerFeedCommand(program) {
|
|
|
232
233
|
.description('Post a status update to the fleet activity stream (for agents)')
|
|
233
234
|
.argument('<text...>', 'What just happened — one short human line')
|
|
234
235
|
.option('--session <id>', 'Session id escape hatch (default: auto from env / pid registry)')
|
|
236
|
+
.option('--attach <path-or-url...>', 'Attach an artifact (local file or URL); repeatable')
|
|
235
237
|
.option('--json', 'Emit the written event as JSON')
|
|
236
238
|
.addHelpText('after', `
|
|
237
239
|
Examples:
|
|
238
240
|
# Inside an agents-cli run (session identity is already in the env):
|
|
239
241
|
agents feed post "CHANGELOG pushed; watching CI and mac-mini E2E"
|
|
242
|
+
agents feed post "cover render ready" --attach ./out/cover.png
|
|
240
243
|
agents feed post "ready for review" --json
|
|
241
244
|
|
|
242
245
|
# Outside a run, pass the session explicitly:
|
|
@@ -251,18 +254,20 @@ Domain facts (tickets, PRs) are not CLI flags — join them on the session at re
|
|
|
251
254
|
// parent.opts().json — not the child. Read both.
|
|
252
255
|
const flags = {
|
|
253
256
|
session: opts?.session ?? cmd?.opts?.()?.session,
|
|
257
|
+
attach: opts?.attach ?? cmd?.opts?.()?.attach,
|
|
254
258
|
json: Boolean(opts?.json ?? cmd?.opts?.()?.json ?? cmd?.parent?.opts?.()?.json),
|
|
255
259
|
};
|
|
256
260
|
try {
|
|
257
261
|
const { event } = postFeedStatus({
|
|
258
262
|
text: Array.isArray(textParts) ? textParts.join(' ') : String(textParts ?? ''),
|
|
259
263
|
sessionId: flags.session,
|
|
264
|
+
attach: flags.attach,
|
|
260
265
|
});
|
|
261
266
|
if (flags.json) {
|
|
262
267
|
console.log(JSON.stringify(event, null, 2));
|
|
263
268
|
return;
|
|
264
269
|
}
|
|
265
|
-
console.log(
|
|
270
|
+
console.log(formatProgressUpdate(event));
|
|
266
271
|
}
|
|
267
272
|
catch (err) {
|
|
268
273
|
console.error(chalk.red(err.message));
|
|
@@ -273,6 +278,7 @@ Domain facts (tickets, PRs) are not CLI flags — join them on the session at re
|
|
|
273
278
|
if (opts.device?.length)
|
|
274
279
|
opts.host = [...(opts.host ?? []), ...opts.device];
|
|
275
280
|
const self = machineId();
|
|
281
|
+
const filter = resolveFeedFilter(opts.filter);
|
|
276
282
|
const includeLocal = shouldIncludeLocalFeed(opts.host, self);
|
|
277
283
|
const setupWarnings = [];
|
|
278
284
|
if (includeLocal) {
|
|
@@ -299,6 +305,22 @@ Domain facts (tickets, PRs) are not CLI flags — join them on the session at re
|
|
|
299
305
|
}
|
|
300
306
|
}
|
|
301
307
|
}
|
|
308
|
+
// Updates view: deliberate progress posts only, over the local activity
|
|
309
|
+
// timeline (blocks are decisions, not announcements). Short-circuit the
|
|
310
|
+
// whole block pipeline — no remote fan-out, no dispatch policy.
|
|
311
|
+
if (filter === 'updates') {
|
|
312
|
+
for (const warning of setupWarnings) {
|
|
313
|
+
console.error(chalk.yellow(`Feed hook setup warning: ${warning}`));
|
|
314
|
+
}
|
|
315
|
+
if (opts.json) {
|
|
316
|
+
const updates = readRecentActivity({ sinceMs: Date.now() - 7 * 24 * 60 * 60 * 1000, limit: 100 })
|
|
317
|
+
.filter((e) => e.event === 'status.posted');
|
|
318
|
+
console.log(JSON.stringify(updates, null, 2));
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
renderUpdatesView();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
302
324
|
// Active sessions feed both the GC sweep and outcome enrichment (ticket/PR).
|
|
303
325
|
let sessions = [];
|
|
304
326
|
if (includeLocal) {
|
|
@@ -406,8 +428,14 @@ Domain facts (tickets, PRs) are not CLI flags — join them on the session at re
|
|
|
406
428
|
}
|
|
407
429
|
if (blocks.length === 0) {
|
|
408
430
|
console.log(chalk.gray(digest ? 'No open blocks after stall suppression.' : 'No open blocks.'));
|
|
409
|
-
if (includeLocal)
|
|
410
|
-
|
|
431
|
+
if (includeLocal) {
|
|
432
|
+
if (filter === 'all') {
|
|
433
|
+
console.log();
|
|
434
|
+
renderUpdatesView();
|
|
435
|
+
}
|
|
436
|
+
else
|
|
437
|
+
renderActivityLane();
|
|
438
|
+
}
|
|
411
439
|
return;
|
|
412
440
|
}
|
|
413
441
|
// Shared fleet-comms masthead (same family as `agents mailboxes`).
|
|
@@ -430,22 +458,70 @@ Domain facts (tickets, PRs) are not CLI flags — join them on the session at re
|
|
|
430
458
|
});
|
|
431
459
|
for (const g of groups)
|
|
432
460
|
renderOutcomeGroup(g, self);
|
|
433
|
-
if (includeLocal)
|
|
434
|
-
|
|
461
|
+
if (includeLocal) {
|
|
462
|
+
if (filter === 'all') {
|
|
463
|
+
console.log();
|
|
464
|
+
renderUpdatesView();
|
|
465
|
+
}
|
|
466
|
+
else
|
|
467
|
+
renderActivityLane();
|
|
468
|
+
}
|
|
435
469
|
});
|
|
436
470
|
}
|
|
471
|
+
/** Normalize a raw --filter value; unknown/empty falls back to the default. */
|
|
472
|
+
export function resolveFeedFilter(raw) {
|
|
473
|
+
const v = (raw ?? '').trim().toLowerCase();
|
|
474
|
+
if (v === 'updates' || v === 'update')
|
|
475
|
+
return 'updates';
|
|
476
|
+
if (v === 'all')
|
|
477
|
+
return 'all';
|
|
478
|
+
return 'needs';
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Render one activity event in the lane: deliberate progress posts
|
|
482
|
+
* (`status.posted`) use the rich multi-line {@link formatProgressUpdate}; hook
|
|
483
|
+
* milestones (PR, commit, …) keep the compact {@link formatActivityLine}.
|
|
484
|
+
*/
|
|
485
|
+
function renderActivityEntry(ev) {
|
|
486
|
+
if (ev.event === 'status.posted') {
|
|
487
|
+
console.log(formatProgressUpdate(ev));
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
console.log(formatActivityLine(ev, { showHost: true }));
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Render the **Updates** view: deliberate progress posts only (`status.posted`),
|
|
495
|
+
* recency-ordered, with rich identity chips. Pure `file.edited` / git-hook noise
|
|
496
|
+
* is excluded so operators see announcements, not tool churn.
|
|
497
|
+
*/
|
|
498
|
+
function renderUpdatesView(limit = 30) {
|
|
499
|
+
const updates = readRecentActivity({ sinceMs: Date.now() - 7 * 24 * 60 * 60 * 1000, limit })
|
|
500
|
+
.filter((e) => e.event === 'status.posted');
|
|
501
|
+
console.log(masthead({ title: 'updates', accent: 'cyan', host: machineId(), right: `${updates.length} post${updates.length === 1 ? '' : 's'}` }));
|
|
502
|
+
console.log();
|
|
503
|
+
if (updates.length === 0) {
|
|
504
|
+
console.log(chalk.gray(' No progress updates yet. Agents post them with `agents feed post "…"`.'));
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
for (const ev of updates) {
|
|
508
|
+
console.log(formatProgressUpdate(ev));
|
|
509
|
+
console.log();
|
|
510
|
+
}
|
|
511
|
+
}
|
|
437
512
|
/**
|
|
438
513
|
* Print a compact "recent activity" lane under the feed: the last few milestone
|
|
439
|
-
* events (plans, PRs, worktrees, sub-agents) from the append-only
|
|
440
|
-
* Read-only tail of the logs -- no transcript re-parsing. Silent
|
|
514
|
+
* events (plans, PRs, worktrees, sub-agents, progress posts) from the append-only
|
|
515
|
+
* activity logs. Read-only tail of the logs -- no transcript re-parsing. Silent
|
|
516
|
+
* when empty.
|
|
441
517
|
*/
|
|
442
|
-
function renderActivityLane() {
|
|
443
|
-
const events = readRecentActivity({ sinceMs: Date.now() - 24 * 60 * 60 * 1000, limit
|
|
518
|
+
function renderActivityLane(limit = 6) {
|
|
519
|
+
const events = readRecentActivity({ sinceMs: Date.now() - 24 * 60 * 60 * 1000, limit })
|
|
444
520
|
.filter((e) => e.tier === 'milestone');
|
|
445
521
|
if (events.length === 0)
|
|
446
522
|
return;
|
|
447
523
|
console.log(chalk.bold('\n recent activity'));
|
|
448
524
|
for (const ev of events)
|
|
449
|
-
|
|
525
|
+
renderActivityEntry(ev);
|
|
450
526
|
console.log(chalk.gray(' → agents activity for the full stream'));
|
|
451
527
|
}
|
package/dist/commands/harness.js
CHANGED
|
@@ -26,7 +26,7 @@ export function registerHarnessCommands(program) {
|
|
|
26
26
|
.alias('harnesses')
|
|
27
27
|
.description('Custom harnesses — name a (host CLI + model) combo and run it like a native agent type.')
|
|
28
28
|
.addHelpText('after', `
|
|
29
|
-
A custom harness pins a host CLI (opencode, claude, codex, grok,
|
|
29
|
+
A custom harness pins a host CLI (opencode, claude, codex, grok, antigravity, ...) to a
|
|
30
30
|
model and gives it a name. 'agents run <name>' then behaves like a native agent
|
|
31
31
|
type, and 'agents repo push user' syncs it to every device.
|
|
32
32
|
|
|
@@ -49,7 +49,7 @@ Examples:
|
|
|
49
49
|
cmd
|
|
50
50
|
.command('add <name>')
|
|
51
51
|
.description('Create a custom harness from a host + model (or apply a built-in preset).')
|
|
52
|
-
.option('--host <agent>', 'Host CLI to run under (opencode, claude, codex, grok,
|
|
52
|
+
.option('--host <agent>', 'Host CLI to run under (opencode, claude, codex, grok, antigravity, ...) — pair with --model')
|
|
53
53
|
.option('--model <id>', 'Model id to pin on the host (e.g., meta/muse-spark-1.1) — pair with --host')
|
|
54
54
|
.option('--base-url <url>', 'Custom endpoint base URL (claude/codex hosts)')
|
|
55
55
|
.option('--auth-provider <provider>', 'Attach a keychain-backed API key under this provider (for private endpoints)')
|
package/dist/commands/hooks.js
CHANGED
|
@@ -221,7 +221,7 @@ When to use:
|
|
|
221
221
|
hooksCmd
|
|
222
222
|
.command('add [source]')
|
|
223
223
|
.description('Install hooks from a source (GitHub, local) or pick from central storage')
|
|
224
|
-
.option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or
|
|
224
|
+
.option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or antigravity@default')
|
|
225
225
|
.option('--names <list>', 'Hook names from ~/.agents/hooks/ (comma-separated)')
|
|
226
226
|
.option('-y, --yes', 'Skip all prompts')
|
|
227
227
|
.addHelpText('after', `
|
package/dist/commands/import.js
CHANGED
|
@@ -29,8 +29,8 @@ import * as fs from 'fs';
|
|
|
29
29
|
import * as os from 'os';
|
|
30
30
|
import * as path from 'path';
|
|
31
31
|
import { confirm } from '@inquirer/prompts';
|
|
32
|
-
import {
|
|
33
|
-
import { AGENTS, getCliPath, getCliVersion, agentLabel, resolveAgentName } from '../lib/agents.js';
|
|
32
|
+
import { MANAGED_AGENT_IDS } from '../lib/agents.js';
|
|
33
|
+
import { AGENTS, getCliPath, getCliVersion, agentLabel, resolveAgentName, isAgentHardDeprecated, hardDeprecationError } from '../lib/agents.js';
|
|
34
34
|
import { getVersionDir } from '../lib/versions.js';
|
|
35
35
|
import { finalizeImport, importAgentBinary, importAgentConfig, importInstallScriptBinary, seedIsolatedConfigFromLocal, isValidImportVersion, resolvePackageDirFromBinary, } from '../lib/import.js';
|
|
36
36
|
import { isPromptCancelled, isInteractiveTerminal } from './utils.js';
|
|
@@ -38,7 +38,11 @@ async function runImport(agentArg, opts) {
|
|
|
38
38
|
const agentId = resolveAgentName(agentArg);
|
|
39
39
|
if (!agentId) {
|
|
40
40
|
console.error(chalk.red(`Unknown agent: ${agentArg}`));
|
|
41
|
-
console.error(chalk.gray(`Known agents: ${
|
|
41
|
+
console.error(chalk.gray(`Known agents: ${MANAGED_AGENT_IDS.join(', ')}`));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
if (isAgentHardDeprecated(agentId)) {
|
|
45
|
+
console.error(chalk.red(hardDeprecationError(agentId)));
|
|
42
46
|
process.exit(1);
|
|
43
47
|
}
|
|
44
48
|
const agent = AGENTS[agentId];
|
|
@@ -340,7 +344,7 @@ When to use:
|
|
|
340
344
|
under agents-cli management without reinstalling. Creates a symlink farm
|
|
341
345
|
pointing at the existing install — nothing is copied or moved (except the
|
|
342
346
|
agent's config dir, which is moved into the version's home). Works for both
|
|
343
|
-
npm-style packages (claude, codex,
|
|
347
|
+
npm-style packages (claude, codex, opencode, openclaw) and
|
|
344
348
|
installScript-based agents (grok, antigravity, cursor, kiro, goose).
|
|
345
349
|
`)
|
|
346
350
|
.action((...args) => withIsolationBoundary(() => runImport(...args)));
|
package/dist/commands/logs.js
CHANGED
|
@@ -358,6 +358,12 @@ async function runStats(opts) {
|
|
|
358
358
|
console.log(` ${k.padEnd(30)} ${v}`);
|
|
359
359
|
}
|
|
360
360
|
}
|
|
361
|
+
if (Object.keys(s.byActor).length) {
|
|
362
|
+
console.log(chalk.bold('\n By actor:'));
|
|
363
|
+
for (const [k, v] of Object.entries(s.byActor).sort((a, b) => b[1] - a[1])) {
|
|
364
|
+
console.log(` ${k.padEnd(30)} ${v}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
361
367
|
console.log();
|
|
362
368
|
}
|
|
363
369
|
/** Register the top-level `agents logs` command. */
|
package/dist/commands/models.js
CHANGED
|
@@ -13,7 +13,7 @@ import { listInstalledVersions, getGlobalDefault, resolveVersion, resolveVersion
|
|
|
13
13
|
import { getModelCatalog, locateModelSource } from '../lib/models.js';
|
|
14
14
|
import { terminalWidth, truncateToWidth, stringWidth } from '../lib/session/width.js';
|
|
15
15
|
import { wrapJoined } from './inspect.js';
|
|
16
|
-
const MODEL_CAPABLE_AGENTS = ['claude', 'codex', '
|
|
16
|
+
const MODEL_CAPABLE_AGENTS = ['claude', 'codex', 'opencode', 'cursor', 'openclaw', 'antigravity', 'kimi'];
|
|
17
17
|
/**
|
|
18
18
|
* Agents that don't necessarily install under ~/.agents/versions (cursor ships
|
|
19
19
|
* via a curl script). For these, fall back to the PATH binary and synthesize
|
|
@@ -10,7 +10,7 @@ import * as path from 'path';
|
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import ora from 'ora';
|
|
12
12
|
import { getAgentsDir, getEnabledExtraRepos } from '../lib/state.js';
|
|
13
|
-
import { AGENTS,
|
|
13
|
+
import { AGENTS, getAllCliStates, agentLabel, } from '../lib/agents.js';
|
|
14
14
|
import { capableAgents } from '../lib/capabilities.js';
|
|
15
15
|
import { DEFAULT_REGISTRIES } from '../lib/types.js';
|
|
16
16
|
import { getRegistries, setRegistry, removeRegistry, search as searchRegistries, resolvePackage, validatedNpmSpec, validatedPyPISpec, buildSkillIndex, verifySkillIntegrity, parseOwnerRepoFromRemote, } from '../lib/registry.js';
|
|
@@ -419,7 +419,7 @@ the sha256 in the index and abort on mismatch.
|
|
|
419
419
|
console.log(chalk.gray('\n Register + search + install:'));
|
|
420
420
|
console.log(` ${chalk.green(`agents registry add skill ${registryName} ${rawUrl}`)}`);
|
|
421
421
|
console.log(` ${chalk.green(`agents search ${index.skills[0].name} --type skill`)}`);
|
|
422
|
-
console.log(` ${chalk.green(`agents install skill:${index.skills[0].name} --agents claude,codex,
|
|
422
|
+
console.log(` ${chalk.green(`agents install skill:${index.skills[0].name} --agents claude,codex,cursor`)}`);
|
|
423
423
|
});
|
|
424
424
|
// ==========================================================================
|
|
425
425
|
// INSTALL COMMAND (unified package installation)
|
|
@@ -427,7 +427,7 @@ the sha256 in the index and abort on mismatch.
|
|
|
427
427
|
program
|
|
428
428
|
.command('install <identifier>')
|
|
429
429
|
.description('Install a package by registry name (mcp:notion), GitHub URL (gh:user/repo), or skill identifier')
|
|
430
|
-
.option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or
|
|
430
|
+
.option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or cursor@default')
|
|
431
431
|
.option('--types <list>', 'When source is a repo: comma-separated resource types to install (skills,workflows,commands,hooks,permissions,subagents,mcp)')
|
|
432
432
|
.option('--names <list>', 'When source is a repo: comma-separated resource names within the selected types')
|
|
433
433
|
.option('-y, --yes', 'Auto-install any missing agent versions without prompting')
|
|
@@ -624,10 +624,10 @@ When to use:
|
|
|
624
624
|
console.log(` ${count} ${kind}`);
|
|
625
625
|
}
|
|
626
626
|
const gitCliStates = await getAllCliStates();
|
|
627
|
-
const installedAgents =
|
|
627
|
+
const installedAgents = capableAgents('commands').filter((id) => gitCliStates[id]?.installed || listInstalledVersions(id).length > 0);
|
|
628
628
|
let targets;
|
|
629
629
|
if (options.agents) {
|
|
630
|
-
const resolved = await resolveInstalledAgentTargetsAutoInstalling(options.agents,
|
|
630
|
+
const resolved = await resolveInstalledAgentTargetsAutoInstalling(options.agents, capableAgents('commands'), { yes: options.yes });
|
|
631
631
|
if (!resolved) {
|
|
632
632
|
console.log(chalk.gray('Cancelled.'));
|
|
633
633
|
return;
|
|
@@ -635,7 +635,7 @@ When to use:
|
|
|
635
635
|
targets = resolved;
|
|
636
636
|
}
|
|
637
637
|
else {
|
|
638
|
-
targets = resolveConfiguredAgentTargets(installedAgents, undefined,
|
|
638
|
+
targets = resolveConfiguredAgentTargets(installedAgents, undefined, capableAgents('commands'));
|
|
639
639
|
}
|
|
640
640
|
if (targets.selectedAgents.length === 0) {
|
|
641
641
|
console.log(chalk.yellow('\nNo agents selected.'));
|
|
@@ -208,7 +208,7 @@ When to use:
|
|
|
208
208
|
permissionsCmd
|
|
209
209
|
.command('add [source]')
|
|
210
210
|
.description('Import permissions from an agent config, YAML, or GitHub, then apply to versions')
|
|
211
|
-
.option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or
|
|
211
|
+
.option('-a, --agents <list>', 'Targets: claude, codex@0.116.0, or antigravity@default')
|
|
212
212
|
.option('--names <list>', 'Permission set names from ~/.agents/permissions/ (comma-separated)')
|
|
213
213
|
.option('--all', 'Apply to all installed versions instead of just defaults')
|
|
214
214
|
.option('--replace', 'Replace managed permission block instead of merging (drops rules no longer in the set)')
|
|
@@ -272,7 +272,7 @@ export function registerProfilesCommands(program) {
|
|
|
272
272
|
.command('profiles')
|
|
273
273
|
.description('Named bundles of (host CLI, endpoint, model, auth) — run Kimi/DeepSeek/Qwen/etc through Claude Code without a proxy.')
|
|
274
274
|
.addHelpText('after', `
|
|
275
|
-
A profile pins a host CLI (claude, codex,
|
|
275
|
+
A profile pins a host CLI (claude, codex, antigravity, ...) to a non-default endpoint
|
|
276
276
|
and model, with a keychain-backed API key. Running 'agents run <profile>' spawns
|
|
277
277
|
the host CLI with the right env vars — no plaintext tokens, no local proxy.
|
|
278
278
|
|
package/dist/commands/pull.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* etc.). It is replaced by the explicit split:
|
|
7
7
|
*
|
|
8
8
|
* - `agents repo pull <alias>` — git fetch+ff on system / user / extra
|
|
9
|
-
* - `agents
|
|
9
|
+
* - `agents sync [--local] [agent]` — re-materialize installed version homes
|
|
10
10
|
* - `agents setup` — first-time bootstrap
|
|
11
11
|
*
|
|
12
12
|
* The command is kept registered so old muscle-memory invocations get a clear
|
package/dist/commands/pull.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* etc.). It is replaced by the explicit split:
|
|
7
7
|
*
|
|
8
8
|
* - `agents repo pull <alias>` — git fetch+ff on system / user / extra
|
|
9
|
-
* - `agents
|
|
9
|
+
* - `agents sync [--local] [agent]` — re-materialize installed version homes
|
|
10
10
|
* - `agents setup` — first-time bootstrap
|
|
11
11
|
*
|
|
12
12
|
* The command is kept registered so old muscle-memory invocations get a clear
|
|
@@ -15,20 +15,20 @@
|
|
|
15
15
|
import { setHelpSections } from '../lib/help.js';
|
|
16
16
|
const REDIRECT = 'agents-cli: "agents pull" was removed.\n' +
|
|
17
17
|
' Git pull a repo: agents repo pull <alias> (system | user | <extra>)\n' +
|
|
18
|
-
' Re-materialize: agents
|
|
18
|
+
' Re-materialize: agents sync --local (all agents; or: agents sync <agent>)\n' +
|
|
19
19
|
' First-time setup: agents setup\n\n';
|
|
20
20
|
/** Register the deprecated `agents pull` command as a hard-error redirect. */
|
|
21
21
|
export function registerPullCommand(program) {
|
|
22
22
|
const pullCmd = program
|
|
23
23
|
.command('pull [agent]')
|
|
24
|
-
.description('Removed. See `agents repo pull` + `agents
|
|
24
|
+
.description('Removed. See `agents repo pull` + `agents sync`.')
|
|
25
25
|
.option('-y, --yes', '(no-op)')
|
|
26
26
|
.option('--skip-clis', '(no-op)');
|
|
27
27
|
setHelpSections(pullCmd, {
|
|
28
28
|
notes: `
|
|
29
29
|
Removed. Equivalents:
|
|
30
30
|
agents repo pull <alias> git pull (system | user | extra)
|
|
31
|
-
agents
|
|
31
|
+
agents sync --local re-materialize version homes (or: agents sync <agent>)
|
|
32
32
|
agents setup first-time bootstrap
|
|
33
33
|
`,
|
|
34
34
|
});
|
package/dist/commands/repo.d.ts
CHANGED
|
@@ -69,10 +69,88 @@ export declare function formatResourceDelta(entries: {
|
|
|
69
69
|
action: ChangeAction;
|
|
70
70
|
file: string;
|
|
71
71
|
}[], maxParts?: number): string;
|
|
72
|
+
/** One side of a divergence: the resource delta plus the raw commit count (fallback). */
|
|
73
|
+
interface RepoDivergence {
|
|
74
|
+
delta: ResourceDelta;
|
|
75
|
+
commits: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Structured status for one repo. `raw` is a free-form trailer for special cases
|
|
79
|
+
* (missing repo, no git remote, error) that don't fit the columns; otherwise the
|
|
80
|
+
* fields feed whichever layout (table / cards) the terminal width selects.
|
|
81
|
+
*/
|
|
82
|
+
export interface RepoRow {
|
|
83
|
+
alias: string;
|
|
84
|
+
raw?: string;
|
|
85
|
+
branch?: string;
|
|
86
|
+
tracking?: boolean;
|
|
87
|
+
pull?: RepoDivergence;
|
|
88
|
+
push?: RepoDivergence;
|
|
89
|
+
clean?: boolean;
|
|
90
|
+
local?: ResourceDelta;
|
|
91
|
+
url?: string;
|
|
92
|
+
commit?: string;
|
|
93
|
+
}
|
|
72
94
|
/** `owner/repo` from a git URL, for the compact card header. Falls back to the raw URL. */
|
|
73
95
|
export declare function repoSlug(url: string): string;
|
|
74
96
|
/** Pack colored phrases into `, `-joined lines no wider than `width`. */
|
|
75
97
|
export declare function wrapPhrases(parts: string[], width: number): string[];
|
|
98
|
+
/** Options shared by `agents repo list` and the `agents repo status` alias. */
|
|
99
|
+
export interface RepoStatusOptions {
|
|
100
|
+
verbose?: boolean;
|
|
101
|
+
json?: boolean;
|
|
102
|
+
/** Fan out across every reachable fleet device (`--devices-all`/`--hosts-all`). */
|
|
103
|
+
devicesAll?: boolean;
|
|
104
|
+
hostsAll?: boolean;
|
|
105
|
+
/** `all`, or a comma-separated device list (`--devices`/`--hosts`). */
|
|
106
|
+
devices?: string;
|
|
107
|
+
hosts?: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Per-device repo status — the unit of the `--devices-all` fleet fan-out. One
|
|
111
|
+
* entry per device: its parsed repo rows when reachable, or `reachable: false`
|
|
112
|
+
* when the peer could not be queried (kept in the model so the table can mark it).
|
|
113
|
+
*/
|
|
114
|
+
export interface DeviceRepoStatus {
|
|
115
|
+
device: string;
|
|
116
|
+
reachable: boolean;
|
|
117
|
+
rows?: RepoRow[];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Recursion guard for the fleet fan-out, passed as an env var (not a CLI flag)
|
|
121
|
+
* so an OLDER remote `agents` that predates this feature ignores it harmlessly
|
|
122
|
+
* instead of erroring on an unknown option. A peer new enough to fan out reads
|
|
123
|
+
* it and answers only for itself. Mirrors `NO_FANOUT_ENV` in remote-active.ts.
|
|
124
|
+
*/
|
|
125
|
+
export declare const NO_REPO_FANOUT_ENV = "AGENTS_REPO_LOCAL";
|
|
126
|
+
/**
|
|
127
|
+
* Parse one peer's `repo status --json` stdout (a RepoRow[]) into a single
|
|
128
|
+
* device entry tagged with `machine`. Defensive against version skew: non-JSON
|
|
129
|
+
* or a non-array yields no entry, and non-object rows are dropped rather than
|
|
130
|
+
* throwing. Exported for unit testing without a live tailnet.
|
|
131
|
+
*/
|
|
132
|
+
export declare function parseRemoteRepoRows(stdout: string, machine: string): DeviceRepoStatus[];
|
|
133
|
+
/**
|
|
134
|
+
* Render the fleet repo-status table: one row per (device, repo), with the
|
|
135
|
+
* device name shown once per group. SYNC and CHANGES reuse the same compact
|
|
136
|
+
* cells as the local wide table (`↓N (…) ↑N` / `clean` / `~N edits`), and an
|
|
137
|
+
* unreachable device collapses to a single `unreachable` marker row. Pure — no
|
|
138
|
+
* I/O — so the aggregation/formatting is unit-testable without live devices.
|
|
139
|
+
*/
|
|
140
|
+
export declare function renderDeviceStatusRows(results: DeviceRepoStatus[]): string[];
|
|
141
|
+
/** Where a `repo status` run should report: this machine only, or the fleet. */
|
|
142
|
+
type DeviceIntent = {
|
|
143
|
+
all: true;
|
|
144
|
+
} | {
|
|
145
|
+
hosts: string[];
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Read the device-scope flags into an intent, or null for the default local-only
|
|
149
|
+
* run. `--devices-all`/`--hosts-all` (and `--devices all`/`--hosts all`) sweep
|
|
150
|
+
* every reachable peer; `--devices box1,box2` targets an explicit list. A peer
|
|
151
|
+
* carrying {@link NO_REPO_FANOUT_ENV} never fans out again (recursion guard).
|
|
152
|
+
*/
|
|
153
|
+
export declare function resolveDeviceIntent(opts: RepoStatusOptions): DeviceIntent | null;
|
|
76
154
|
/** Register the `agents repos` command tree (`repo` is a convenience alias). */
|
|
77
155
|
export declare function registerRepoCommands(program: Command): void;
|
|
78
156
|
export {};
|