@phnx-labs/agents-cli 1.22.6 → 1.22.8
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 +131 -1
- package/README.md +7 -0
- package/dist/bin/agents +0 -0
- package/dist/commands/browser.js +61 -0
- package/dist/commands/exec.js +83 -16
- package/dist/commands/feed.d.ts +2 -1
- package/dist/commands/feed.js +47 -20
- package/dist/commands/focus.js +22 -1
- package/dist/commands/harness.d.ts +0 -1
- package/dist/commands/harness.js +60 -4
- package/dist/commands/models.js +2 -2
- package/dist/commands/monitors.js +2 -2
- package/dist/commands/projects.js +122 -107
- package/dist/commands/routines.js +2 -2
- package/dist/commands/run-account-picker.js +2 -0
- package/dist/commands/secrets.js +1 -1
- package/dist/commands/sessions-backfill.d.ts +33 -0
- package/dist/commands/sessions-backfill.js +83 -1
- package/dist/commands/sessions-stats.d.ts +36 -0
- package/dist/commands/sessions-stats.js +263 -0
- package/dist/commands/sessions.d.ts +1 -1
- package/dist/commands/sessions.js +21 -1
- package/dist/commands/snapshot.d.ts +11 -0
- package/dist/commands/snapshot.js +107 -0
- package/dist/commands/teams.js +2 -1
- package/dist/commands/view.d.ts +9 -1
- package/dist/commands/view.js +63 -12
- package/dist/index.js +4 -2
- package/dist/lib/activity.js +2 -2
- package/dist/lib/agents.js +68 -11
- package/dist/lib/analytics/recipes.js +11 -5
- package/dist/lib/browser/ipc.js +2 -0
- package/dist/lib/browser/profiles.d.ts +15 -7
- package/dist/lib/browser/profiles.js +53 -12
- package/dist/lib/browser/remote-control.d.ts +35 -0
- package/dist/lib/browser/remote-control.js +48 -0
- package/dist/lib/browser/service.d.ts +19 -0
- package/dist/lib/browser/service.js +19 -1
- package/dist/lib/browser/types.d.ts +14 -2
- package/dist/lib/byok-usage.d.ts +38 -0
- package/dist/lib/byok-usage.js +117 -0
- package/dist/lib/capabilities.js +1 -1
- package/dist/lib/device-config.js +8 -0
- package/dist/lib/exec.d.ts +20 -0
- package/dist/lib/exec.js +73 -8
- package/dist/lib/feed-outcome.d.ts +1 -0
- package/dist/lib/feed-outcome.js +2 -0
- package/dist/lib/feed-post.js +1 -1
- package/dist/lib/feed-ranking.d.ts +1 -0
- package/dist/lib/feed-ranking.js +4 -0
- package/dist/lib/feed.d.ts +4 -1
- package/dist/lib/feed.js +25 -0
- package/dist/lib/hosts/passthrough.d.ts +10 -1
- package/dist/lib/hosts/passthrough.js +23 -3
- package/dist/lib/hosts/remote-cmd.js +1 -0
- package/dist/lib/mcp.js +6 -1
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/model-tiers.js +4 -1
- package/dist/lib/models.js +63 -0
- package/dist/lib/placement.d.ts +82 -0
- package/dist/lib/placement.js +188 -0
- package/dist/lib/profiles.d.ts +73 -10
- package/dist/lib/profiles.js +133 -15
- package/dist/lib/project-focus.d.ts +9 -0
- package/dist/lib/project-focus.js +23 -0
- package/dist/lib/project-key.d.ts +1 -1
- package/dist/lib/project-key.js +1 -1
- package/dist/lib/project-probe.d.ts +18 -0
- package/dist/lib/project-probe.js +46 -0
- package/dist/lib/project-status.d.ts +56 -0
- package/dist/lib/project-status.js +125 -18
- package/dist/lib/resources/mcp.js +3 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/rotate.d.ts +19 -4
- package/dist/lib/rotate.js +24 -1
- package/dist/lib/routines.d.ts +2 -0
- package/dist/lib/runner.d.ts +3 -0
- package/dist/lib/runner.js +90 -7
- 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/audit.js +1 -1
- package/dist/lib/secrets/index.d.ts +1 -0
- package/dist/lib/secrets/index.js +29 -15
- package/dist/lib/secrets/remote.d.ts +1 -1
- package/dist/lib/secrets/remote.js +1 -1
- package/dist/lib/session/active.d.ts +2 -0
- package/dist/lib/session/bash-command.d.ts +2 -3
- package/dist/lib/session/db.d.ts +92 -1
- package/dist/lib/session/db.js +230 -1
- package/dist/lib/session/digest.d.ts +1 -1
- package/dist/lib/session/digest.js +1 -1
- package/dist/lib/share/publish.js +24 -0
- package/dist/lib/snapshot.d.ts +103 -0
- package/dist/lib/snapshot.js +99 -0
- package/dist/lib/startup/command-registry.d.ts +1 -1
- package/dist/lib/startup/command-registry.js +2 -2
- package/dist/lib/subagents-registry.js +3 -0
- package/dist/lib/types.d.ts +11 -2
- package/dist/lib/usage.d.ts +5 -0
- package/dist/lib/usage.js +3 -3
- package/package.json +1 -1
- package/dist/commands/activity.d.ts +0 -87
- package/dist/commands/activity.js +0 -346
package/dist/commands/feed.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { ensureFeedPublishHook, listAskStats, listBlocks, recordNotified, buildDeclaredBlock, publishBlock, } from '../lib/feed.js';
|
|
3
3
|
import { ensureActivityLogHook, readRecentActivity, formatActivityLine, formatProgressUpdate, mergeActivityEvents, parseActivityPayload, } from '../lib/activity.js';
|
|
4
|
+
import { projectKeyFromCwd } from '../lib/project-key.js';
|
|
4
5
|
import { postFeedStatus } from '../lib/feed-post.js';
|
|
5
6
|
import { parseFeedPostLevel, planFeedBroadcast, runFeedBroadcast, effectiveBroadcastConfig, blockBroadcastContext, blockDeliveryFailure, } from '../lib/feed-broadcast.js';
|
|
6
7
|
import { getSessionById } from '../lib/session/db.js';
|
|
@@ -215,6 +216,7 @@ export function sessionHintsFromActive(sessions) {
|
|
|
215
216
|
prNumber: s.pr?.number,
|
|
216
217
|
prUrl: s.pr?.url,
|
|
217
218
|
worktreeSlug: s.worktree?.slug,
|
|
219
|
+
project: s.cwd ? projectKeyFromCwd(s.cwd) : undefined,
|
|
218
220
|
}));
|
|
219
221
|
}
|
|
220
222
|
export function registerFeedCommand(program) {
|
|
@@ -228,6 +230,7 @@ export function registerFeedCommand(program) {
|
|
|
228
230
|
.option('--local', 'Only this machine -- skip the cross-machine SSH fan-out')
|
|
229
231
|
.option('-H, --host <target...>', 'Scope to remote machine(s) over SSH; repeatable')
|
|
230
232
|
.option('--device <target...>', 'Alias for --host; repeatable')
|
|
233
|
+
.option('--project <name>', 'Scope the feed to one project/repo (matches cwd basename, case-insensitive)')
|
|
231
234
|
.option('--dispatch', 'Run stall suppression + default-on-no-answer policy and urgent notifications')
|
|
232
235
|
.option('--pause <id>', 'Pause a runaway/needy local process (SIGSTOP) or cancel a cloud task')
|
|
233
236
|
.option('--kill <id>', 'Kill a runaway/needy local process (SIGTERM) or cancel a cloud task');
|
|
@@ -317,7 +320,13 @@ docs/06-observability.md.
|
|
|
317
320
|
// it the ask would scroll away like any other update.
|
|
318
321
|
let outcomes;
|
|
319
322
|
if (flags.blocked) {
|
|
320
|
-
const block = buildDeclaredBlock(
|
|
323
|
+
const block = buildDeclaredBlock({
|
|
324
|
+
sessionId: event.sessionId,
|
|
325
|
+
mailboxId: event.mailboxId,
|
|
326
|
+
host: event.host,
|
|
327
|
+
runtime: event.runtime,
|
|
328
|
+
cwd: event.cwd,
|
|
329
|
+
}, {
|
|
321
330
|
// Prefer title as the front-loaded ask on the phone; body is detail.
|
|
322
331
|
text: event.title
|
|
323
332
|
? (event.detail ? `${event.title}: ${event.detail}` : event.title)
|
|
@@ -399,12 +408,12 @@ docs/06-observability.md.
|
|
|
399
408
|
if (filter === 'all') {
|
|
400
409
|
console.log();
|
|
401
410
|
renderUpdatesView(await gatherStatusPosts({
|
|
402
|
-
limit: UPDATES_VIEW_LIMIT, hosts: opts.host, local: opts.local, includeLocal, self,
|
|
403
|
-
}));
|
|
411
|
+
limit: UPDATES_VIEW_LIMIT, hosts: opts.host, local: opts.local, includeLocal, self, project: opts.project,
|
|
412
|
+
}), opts.project);
|
|
404
413
|
return;
|
|
405
414
|
}
|
|
406
415
|
if (includeLocal)
|
|
407
|
-
renderActivityLane();
|
|
416
|
+
renderActivityLane(opts.project);
|
|
408
417
|
};
|
|
409
418
|
// Updates view: deliberate progress posts only (blocks are decisions, not
|
|
410
419
|
// announcements). Short-circuits the block pipeline — no dispatch policy —
|
|
@@ -425,7 +434,7 @@ docs/06-observability.md.
|
|
|
425
434
|
console.log(JSON.stringify(updates, null, 2));
|
|
426
435
|
return;
|
|
427
436
|
}
|
|
428
|
-
renderUpdatesView(updates);
|
|
437
|
+
renderUpdatesView(updates, opts.project);
|
|
429
438
|
return;
|
|
430
439
|
}
|
|
431
440
|
// Active sessions feed both the GC sweep and outcome enrichment (ticket/PR).
|
|
@@ -487,7 +496,10 @@ docs/06-observability.md.
|
|
|
487
496
|
blocks = mergeFeedBlocks(visibleLocalBlocks, remote.items);
|
|
488
497
|
}
|
|
489
498
|
}
|
|
490
|
-
blocks = rankFeedBlocks(blocks, localSignals);
|
|
499
|
+
blocks = rankFeedBlocks(blocks, localSignals).filter((b) => blockMatchesProject(b, opts.project));
|
|
500
|
+
const dispatchBlocksProject = opts.project
|
|
501
|
+
? dispatchBlocks.filter((b) => blockMatchesProject(b, opts.project))
|
|
502
|
+
: dispatchBlocks;
|
|
491
503
|
const digest = suppressionDigest(preparedLocal.filter);
|
|
492
504
|
if (digest && !opts.json) {
|
|
493
505
|
console.log(chalk.dim(digest));
|
|
@@ -495,7 +507,7 @@ docs/06-observability.md.
|
|
|
495
507
|
if (opts.dispatch) {
|
|
496
508
|
const policy = loadPolicy();
|
|
497
509
|
const now = new Date();
|
|
498
|
-
for (const b of
|
|
510
|
+
for (const b of dispatchBlocksProject) {
|
|
499
511
|
// Wrap per-block policy so one malformed block (e.g. a crafted
|
|
500
512
|
// mailboxId that throws in mailboxDir) can't abort the whole loop and
|
|
501
513
|
// strand every remaining block's dispatch.
|
|
@@ -540,7 +552,7 @@ docs/06-observability.md.
|
|
|
540
552
|
}
|
|
541
553
|
// Shared fleet-comms masthead (same family as `agents mailboxes`).
|
|
542
554
|
console.log(masthead({
|
|
543
|
-
title: 'they need you',
|
|
555
|
+
title: opts.project ? `${opts.project} needs you` : 'they need you',
|
|
544
556
|
accent: 'amber',
|
|
545
557
|
host: self,
|
|
546
558
|
right: formatFeedMastheadRight(blocks),
|
|
@@ -630,6 +642,18 @@ export function resolveFeedFilter(raw) {
|
|
|
630
642
|
return 'all';
|
|
631
643
|
return 'needs';
|
|
632
644
|
}
|
|
645
|
+
/** True when a block belongs to the requested project (case-insensitive). */
|
|
646
|
+
function blockMatchesProject(block, project) {
|
|
647
|
+
if (!project)
|
|
648
|
+
return true;
|
|
649
|
+
return (block.project ?? '').toLowerCase() === project.toLowerCase();
|
|
650
|
+
}
|
|
651
|
+
/** True when an activity event belongs to the requested project (case-insensitive). */
|
|
652
|
+
function eventMatchesProject(ev, project) {
|
|
653
|
+
if (!project)
|
|
654
|
+
return true;
|
|
655
|
+
return ((ev.project ?? projectKeyFromCwd(ev.cwd) ?? '')).toLowerCase() === project.toLowerCase();
|
|
656
|
+
}
|
|
633
657
|
/**
|
|
634
658
|
* Render one activity event in the lane: deliberate progress posts
|
|
635
659
|
* (`status.posted`) use the rich multi-line {@link formatProgressUpdate}; hook
|
|
@@ -668,30 +692,33 @@ function readStatusPosts(limit) {
|
|
|
668
692
|
* uses; `--local` (or the no-fanout env guard on a peer) keeps it to this box.
|
|
669
693
|
*/
|
|
670
694
|
async function gatherStatusPosts(opts) {
|
|
671
|
-
const local = opts.includeLocal
|
|
695
|
+
const local = opts.includeLocal
|
|
696
|
+
? readStatusPosts(opts.limit).filter((ev) => eventMatchesProject(ev, opts.project))
|
|
697
|
+
: [];
|
|
672
698
|
const forceLocal = opts.local === true || process.env[FEED_NO_FANOUT_ENV] === '1';
|
|
673
699
|
if (forceLocal)
|
|
674
|
-
return local;
|
|
700
|
+
return local.slice(0, opts.limit);
|
|
675
701
|
const remoteHosts = opts.hosts?.length ? remoteFeedHostsToDial(opts.hosts, opts.self) : undefined;
|
|
676
702
|
if (opts.hosts?.length && (!remoteHosts || remoteHosts.length === 0))
|
|
677
|
-
return local;
|
|
703
|
+
return local.slice(0, opts.limit);
|
|
678
704
|
const remote = await gatherRemoteAgentsJson({
|
|
679
705
|
args: ['feed', '--filter', 'updates', '--json'],
|
|
680
706
|
noFanoutEnv: FEED_NO_FANOUT_ENV,
|
|
681
707
|
hosts: remoteHosts,
|
|
682
708
|
parse: parseActivityPayload,
|
|
683
709
|
});
|
|
684
|
-
|
|
710
|
+
const merged = mergeActivityEvents(local, remote.items).filter((ev) => eventMatchesProject(ev, opts.project));
|
|
711
|
+
return merged.slice(0, opts.limit);
|
|
685
712
|
}
|
|
686
713
|
/**
|
|
687
714
|
* Render the **Updates** view: deliberate progress posts only (`status.posted`),
|
|
688
715
|
* recency-ordered, with rich identity chips. Pure `file.edited` / git-hook noise
|
|
689
716
|
* is excluded so operators see announcements, not tool churn.
|
|
690
717
|
*/
|
|
691
|
-
function renderUpdatesView(updates) {
|
|
718
|
+
function renderUpdatesView(updates, project) {
|
|
692
719
|
const hosts = new Set(updates.map((e) => e.host).filter(Boolean));
|
|
693
720
|
console.log(masthead({
|
|
694
|
-
title: 'updates',
|
|
721
|
+
title: project ? `${project} updates` : 'updates',
|
|
695
722
|
accent: 'cyan',
|
|
696
723
|
host: hosts.size > 1 ? `${hosts.size} machines` : (updates[0]?.host ?? machineId()),
|
|
697
724
|
right: `${updates.length} post${updates.length === 1 ? '' : 's'}`,
|
|
@@ -712,16 +739,16 @@ function renderUpdatesView(updates) {
|
|
|
712
739
|
* activity logs. Read-only tail of the logs -- no transcript re-parsing. Silent
|
|
713
740
|
* when empty.
|
|
714
741
|
*/
|
|
715
|
-
function renderActivityLane(limit = 6) {
|
|
742
|
+
function renderActivityLane(project, limit = 6) {
|
|
716
743
|
const events = readRecentActivity({
|
|
717
744
|
sinceMs: Date.now() - 24 * 60 * 60 * 1000,
|
|
718
|
-
limit,
|
|
745
|
+
limit: limit * (project ? 4 : 1),
|
|
719
746
|
tier: 'milestone',
|
|
720
|
-
});
|
|
747
|
+
}).filter((ev) => eventMatchesProject(ev, project));
|
|
721
748
|
if (events.length === 0)
|
|
722
749
|
return;
|
|
723
|
-
console.log(chalk.bold('\n recent activity'));
|
|
724
|
-
for (const ev of events)
|
|
750
|
+
console.log(chalk.bold(project ? `\n recent activity · ${project}` : '\n recent activity'));
|
|
751
|
+
for (const ev of events.slice(0, limit))
|
|
725
752
|
renderActivityEntry(ev);
|
|
726
|
-
console.log(chalk.gray(' → agents
|
|
753
|
+
console.log(chalk.gray(' → agents feed --project ' + (project ?? '<project>') + ' for the full stream'));
|
|
727
754
|
}
|
package/dist/commands/focus.js
CHANGED
|
@@ -20,8 +20,9 @@ import { runOnPeer } from '../lib/session/remote-list.js';
|
|
|
20
20
|
import { discoverSessions } from '../lib/session/discover.js';
|
|
21
21
|
import { openSurfaces, currentContext, availableBackends, detectCurrentBackend, } from '../lib/terminal/index.js';
|
|
22
22
|
import { isInteractiveTerminal } from './utils.js';
|
|
23
|
+
import { setHelpSections } from '../lib/help.js';
|
|
23
24
|
export function registerFocusCommand(program) {
|
|
24
|
-
program
|
|
25
|
+
const cmd = program
|
|
25
26
|
.command('focus')
|
|
26
27
|
.argument('[id]', 'Short/full session id to focus; omit for an interactive picker')
|
|
27
28
|
.option('--local', 'Only this machine (skip the cross-host sweep)')
|
|
@@ -30,6 +31,26 @@ export function registerFocusCommand(program) {
|
|
|
30
31
|
.action(async (id, opts) => {
|
|
31
32
|
await focusAction(id, opts);
|
|
32
33
|
});
|
|
34
|
+
setHelpSections(cmd, {
|
|
35
|
+
examples: `
|
|
36
|
+
# Jump to a live session (attach pane/tab, or open a new tab and resume)
|
|
37
|
+
agents sessions focus a1b2c3d4
|
|
38
|
+
|
|
39
|
+
# Attach only — refuse if nothing is joinable (old sessions go)
|
|
40
|
+
agents sessions focus a1b2c3d4 --attach-only
|
|
41
|
+
|
|
42
|
+
# Pick from live sessions on this machine only
|
|
43
|
+
agents sessions focus --local
|
|
44
|
+
`,
|
|
45
|
+
notes: `
|
|
46
|
+
Lifecycle siblings (not synonyms):
|
|
47
|
+
focus live jump (default "take me there")
|
|
48
|
+
focus --attach-only attach only; never fork (replaces go)
|
|
49
|
+
detach / attach interactive ↔ headless presence
|
|
50
|
+
resume multi-select history → tabs
|
|
51
|
+
run --resume single scripted continue
|
|
52
|
+
`,
|
|
53
|
+
});
|
|
33
54
|
}
|
|
34
55
|
/**
|
|
35
56
|
* Which fallback fires when a session has no attach rail. `--attach-only` (the old
|
package/dist/commands/harness.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import chalk from 'chalk';
|
|
14
14
|
import { addProfile, ensureProviderToken } from './profiles.js';
|
|
15
|
-
import { listProfiles, readProfile, writeProfile, deleteProfile, profileExists, profileHostLabel, profileProviderLabel, profileModelLabel, profileAuthLabel, profileLabel, forkProfile, profileFromHostModel, authEnvKeyForHost, getProfilePath, validateProfileName, } from '../lib/profiles.js';
|
|
15
|
+
import { listProfiles, readProfile, writeProfile, deleteProfile, profileExists, profileHostLabel, profileProviderLabel, profileModelLabel, profileAuthLabel, profileLabel, forkProfile, profileFromHostModel, authEnvKeyForHost, getProfilePath, validateProfileName, editProfile, renameProfile, } from '../lib/profiles.js';
|
|
16
16
|
import { listPresets } from '../lib/profiles-presets.js';
|
|
17
17
|
import { AGENTS, ALL_AGENT_IDS, resolveAgentName } from '../lib/agents.js';
|
|
18
18
|
/** Short capability summary for a native harness — its supported run modes. */
|
|
@@ -58,7 +58,6 @@ export function buildFork(source, name, opts) {
|
|
|
58
58
|
baseUrl: opts.baseUrl,
|
|
59
59
|
provider: opts.authProvider,
|
|
60
60
|
version: opts.version,
|
|
61
|
-
label: opts.label,
|
|
62
61
|
description: opts.description,
|
|
63
62
|
});
|
|
64
63
|
}
|
|
@@ -75,7 +74,6 @@ export function buildFork(source, name, opts) {
|
|
|
75
74
|
baseUrl: opts.baseUrl,
|
|
76
75
|
provider: opts.authProvider,
|
|
77
76
|
authEnvVar: opts.authProvider ? authEnvKeyForHostOrThrow(host) : undefined,
|
|
78
|
-
label: opts.label,
|
|
79
77
|
description: opts.description ?? `Forked from ${host}: ${opts.model}`,
|
|
80
78
|
});
|
|
81
79
|
}
|
|
@@ -147,7 +145,6 @@ Examples:
|
|
|
147
145
|
.option('--base-url <url>', 'Custom endpoint base URL (claude/codex hosts)')
|
|
148
146
|
.option('--auth-provider <provider>', 'Attach a keychain-backed API key under this provider')
|
|
149
147
|
.option('--version <version>', 'Pin the host CLI version (e.g., 1.16.0)')
|
|
150
|
-
.option('--label <text>', 'Human-facing name shown by `agents view` (defaults to <name>)')
|
|
151
148
|
.option('--description <text>', 'One-line description')
|
|
152
149
|
.option('--key-stdin', 'Read the API key from stdin instead of prompting (for scripts/CI)')
|
|
153
150
|
.option('--force', 'Overwrite an existing harness with the same name')
|
|
@@ -249,4 +246,63 @@ Examples:
|
|
|
249
246
|
}
|
|
250
247
|
console.log(chalk.green(`Harness '${name}' removed.`));
|
|
251
248
|
});
|
|
249
|
+
cmd
|
|
250
|
+
.command('edit <name>')
|
|
251
|
+
.description('Edit a custom harness in place (model, endpoint, host version, description).')
|
|
252
|
+
// Flags mirror ForkProfileOptions exactly — `editProfile` reuses
|
|
253
|
+
// `forkProfile`'s override logic, so anything it does not accept would be a
|
|
254
|
+
// flag that parses and does nothing. There is deliberately no --label: the
|
|
255
|
+
// header `agents view` prints is derived from the harness name.
|
|
256
|
+
.option('--model <id>', 'Swap the pinned model (e.g., meta/muse-spark-2.0)')
|
|
257
|
+
.option('--base-url <url>', 'Set or replace the endpoint base URL (claude/codex hosts)')
|
|
258
|
+
.option('--version <ver>', 'Re-pin the host CLI version. Empty string unpins (tracks latest).')
|
|
259
|
+
.option('--description <text>', 'Set the one-line description')
|
|
260
|
+
.addHelpText('after', `
|
|
261
|
+
Examples:
|
|
262
|
+
# Upgrade the pinned model
|
|
263
|
+
agents harness edit spark --model meta/muse-spark-2.0
|
|
264
|
+
|
|
265
|
+
# Point to a new private endpoint
|
|
266
|
+
agents harness edit corp --base-url https://gw.corp/v2
|
|
267
|
+
|
|
268
|
+
# Track the host's latest instead of a pinned version
|
|
269
|
+
agents harness edit spark --version ""
|
|
270
|
+
|
|
271
|
+
# The display name is derived from the harness name, so to change it, rename:
|
|
272
|
+
agents harness rename spark muse-spark
|
|
273
|
+
`)
|
|
274
|
+
.action((name, opts) => {
|
|
275
|
+
try {
|
|
276
|
+
const edited = editProfile(readProfile(name), opts);
|
|
277
|
+
writeProfile(edited);
|
|
278
|
+
console.log(chalk.green(`Harness '${name}' updated.`));
|
|
279
|
+
console.log(chalk.gray(`Model: ${profileModelLabel(edited)}`));
|
|
280
|
+
}
|
|
281
|
+
catch (err) {
|
|
282
|
+
console.error(chalk.red(err.message));
|
|
283
|
+
process.exit(1);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
cmd
|
|
287
|
+
.command('rename <name> <new-name>')
|
|
288
|
+
.description('Rename a custom harness — updates the file name and its internal name field.')
|
|
289
|
+
.addHelpText('after', `
|
|
290
|
+
Examples:
|
|
291
|
+
# Rename 'spark' to 'muse'
|
|
292
|
+
agents harness rename spark muse
|
|
293
|
+
|
|
294
|
+
# Rename then run under the new name
|
|
295
|
+
agents harness rename deepseek ds && agents run ds "hello"
|
|
296
|
+
`)
|
|
297
|
+
.action((name, newName) => {
|
|
298
|
+
try {
|
|
299
|
+
renameProfile(name, newName);
|
|
300
|
+
console.log(chalk.green(`Harness '${name}' renamed to '${newName}'.`));
|
|
301
|
+
console.log(chalk.gray(`Run: agents run ${newName} "hello"`));
|
|
302
|
+
}
|
|
303
|
+
catch (err) {
|
|
304
|
+
console.error(chalk.red(err.message));
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
252
308
|
}
|
package/dist/commands/models.js
CHANGED
|
@@ -16,13 +16,13 @@ import { setTierOverride, clearTierOverride, listTierOverrides } from '../lib/mo
|
|
|
16
16
|
import { getModelPricing } from '../lib/pricing/index.js';
|
|
17
17
|
import { terminalWidth, truncateToWidth, stringWidth } from '../lib/session/width.js';
|
|
18
18
|
import { wrapJoined } from './inspect.js';
|
|
19
|
-
const MODEL_CAPABLE_AGENTS = ['claude', 'codex', 'opencode', 'cursor', 'openclaw', 'antigravity', 'kimi', 'grok', 'droid'];
|
|
19
|
+
const MODEL_CAPABLE_AGENTS = ['claude', 'codex', 'opencode', 'cursor', 'openclaw', 'antigravity', 'kimi', 'grok', 'droid', 'pi'];
|
|
20
20
|
/**
|
|
21
21
|
* Agents that don't necessarily install under ~/.agents/versions (cursor ships
|
|
22
22
|
* via a curl script). For these, fall back to the PATH binary and synthesize
|
|
23
23
|
* a version label from the install path so cache keys stay stable.
|
|
24
24
|
*/
|
|
25
|
-
const PATH_ONLY_AGENTS = new Set(['cursor']);
|
|
25
|
+
const PATH_ONLY_AGENTS = new Set(['cursor', 'pi']);
|
|
26
26
|
/** Derive a version label from the PATH-installed binary location for agents without managed versions. */
|
|
27
27
|
function fallbackPathVersion(agent) {
|
|
28
28
|
const src = locateModelSource(agent, 'unresolved');
|
|
@@ -315,9 +315,9 @@ export function registerMonitorsCommands(program) {
|
|
|
315
315
|
.option('--notify [channel]', 'Notify the owner (notify.owner); [channel] overrides the owner channel')
|
|
316
316
|
.option('--webhook-out <url>', 'POST the event to this URL')
|
|
317
317
|
// PLACEMENT / hygiene
|
|
318
|
-
.option('--device <name>', 'OWNER
|
|
318
|
+
.option('--device <name>', 'OWNER (not body placement) — the single machine that evaluates + fires (exactly-once). See docs/00-concepts.md#placement.')
|
|
319
319
|
.option('--devices <list>', 'Allowlist (comma-separated): each device fires independently')
|
|
320
|
-
.option('--run-on <host>', '
|
|
320
|
+
.option('--run-on <host>', 'BODY placement — execute the ACTION on this machine over SSH (same idea as run --where device:<host>)')
|
|
321
321
|
.option('--rate-limit <spec>', 'Auto-pause if it fires more than N/<interval> (e.g. 5/1m)')
|
|
322
322
|
.option('--disabled', 'Create the monitor paused (enable later with resume)')
|
|
323
323
|
.action(async (nameOrPath, options) => {
|