@phnx-labs/agents-cli 1.20.34 → 1.20.36
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 +113 -0
- package/LICENSE +185 -21
- package/README.md +13 -5
- package/dist/commands/audit.d.ts +14 -0
- package/dist/commands/audit.js +68 -0
- package/dist/commands/browser.js +82 -8
- package/dist/commands/check.d.ts +15 -0
- package/dist/commands/check.js +84 -0
- package/dist/commands/cloud.js +143 -3
- package/dist/commands/computer-actions.d.ts +15 -0
- package/dist/commands/computer-actions.js +120 -22
- package/dist/commands/computer.js +81 -0
- package/dist/commands/cost.js +17 -12
- package/dist/commands/daemon.js +4 -1
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +54 -97
- package/dist/commands/events.d.ts +16 -0
- package/dist/commands/events.js +173 -0
- package/dist/commands/exec.d.ts +19 -0
- package/dist/commands/exec.js +283 -12
- package/dist/commands/hosts.js +37 -29
- package/dist/commands/inspect.d.ts +2 -0
- package/dist/commands/inspect.js +62 -16
- package/dist/commands/lock.d.ts +12 -0
- package/dist/commands/lock.js +70 -0
- package/dist/commands/logs.d.ts +17 -0
- package/dist/commands/logs.js +139 -0
- package/dist/commands/message.d.ts +15 -0
- package/dist/commands/message.js +56 -0
- package/dist/commands/models.d.ts +3 -0
- package/dist/commands/models.js +27 -8
- package/dist/commands/permissions.js +9 -2
- package/dist/commands/repo.d.ts +34 -0
- package/dist/commands/repo.js +243 -65
- package/dist/commands/resource-view.d.ts +20 -0
- package/dist/commands/resource-view.js +90 -28
- package/dist/commands/routines.js +101 -5
- package/dist/commands/secrets-migrate.js +106 -57
- package/dist/commands/secrets.d.ts +31 -18
- package/dist/commands/secrets.js +196 -91
- package/dist/commands/serve.d.ts +10 -0
- package/dist/commands/serve.js +37 -0
- package/dist/commands/sessions-inject.d.ts +14 -0
- package/dist/commands/sessions-inject.js +111 -0
- package/dist/commands/sessions-picker.d.ts +2 -0
- package/dist/commands/sessions-picker.js +24 -3
- package/dist/commands/sessions-resume.d.ts +2 -0
- package/dist/commands/sessions-resume.js +221 -0
- package/dist/commands/sessions-tail.d.ts +10 -0
- package/dist/commands/sessions-tail.js +11 -0
- package/dist/commands/sessions.d.ts +143 -1
- package/dist/commands/sessions.js +628 -80
- package/dist/commands/setup.js +4 -2
- package/dist/commands/sync.d.ts +3 -1
- package/dist/commands/sync.js +156 -4
- package/dist/commands/teams.js +217 -0
- package/dist/commands/versions.js +2 -4
- package/dist/commands/view.d.ts +3 -0
- package/dist/commands/view.js +19 -8
- package/dist/commands/wallet.d.ts +6 -0
- package/dist/commands/wallet.js +22 -5
- package/dist/commands/watchdog.d.ts +18 -0
- package/dist/commands/watchdog.js +238 -0
- package/dist/index.js +82 -32
- package/dist/lib/agents.js +30 -9
- package/dist/lib/audit/log.d.ts +92 -0
- package/dist/lib/audit/log.js +177 -0
- package/dist/lib/auto-pull.js +2 -1
- package/dist/lib/browser/cdp.js +5 -1
- package/dist/lib/browser/chrome.d.ts +10 -0
- package/dist/lib/browser/chrome.js +18 -7
- package/dist/lib/browser/drivers/ssh.d.ts +8 -0
- package/dist/lib/browser/drivers/ssh.js +77 -16
- package/dist/lib/browser/har.d.ts +84 -0
- package/dist/lib/browser/har.js +77 -0
- package/dist/lib/browser/ipc.d.ts +3 -0
- package/dist/lib/browser/ipc.js +37 -12
- package/dist/lib/browser/profiles.d.ts +1 -1
- package/dist/lib/browser/profiles.js +8 -10
- package/dist/lib/browser/refs.d.ts +65 -0
- package/dist/lib/browser/refs.js +73 -1
- package/dist/lib/browser/runtime-state.js +1 -0
- package/dist/lib/browser/service.d.ts +38 -2
- package/dist/lib/browser/service.js +183 -23
- package/dist/lib/browser/types.d.ts +14 -1
- package/dist/lib/budget/live-cloud.d.ts +42 -0
- package/dist/lib/budget/live-cloud.js +79 -0
- package/dist/lib/budget/live-team.d.ts +31 -0
- package/dist/lib/budget/live-team.js +115 -0
- package/dist/lib/cloud/codex.js +4 -0
- package/dist/lib/cloud/rush.d.ts +12 -1
- package/dist/lib/cloud/rush.js +13 -3
- package/dist/lib/cloud/types.d.ts +9 -0
- package/dist/lib/computer/dispatch.d.ts +8 -0
- package/dist/lib/computer/dispatch.js +125 -0
- package/dist/lib/computer/loop.d.ts +62 -0
- package/dist/lib/computer/loop.js +98 -0
- package/dist/lib/computer/model.d.ts +44 -0
- package/dist/lib/computer/model.js +157 -0
- package/dist/lib/concurrency.d.ts +19 -0
- package/dist/lib/concurrency.js +33 -0
- package/dist/lib/daemon.d.ts +92 -0
- package/dist/lib/daemon.js +222 -18
- package/dist/lib/devices/connect.d.ts +3 -2
- package/dist/lib/devices/connect.js +5 -3
- package/dist/lib/devices/registry.d.ts +7 -0
- package/dist/lib/devices/registry.js +24 -0
- package/dist/lib/devices/tailscale.js +1 -1
- package/dist/lib/drift.d.ts +52 -0
- package/dist/lib/drift.js +112 -0
- package/dist/lib/events.d.ts +10 -3
- package/dist/lib/events.js +101 -24
- package/dist/lib/exec.d.ts +17 -0
- package/dist/lib/exec.js +100 -12
- package/dist/lib/git.d.ts +27 -0
- package/dist/lib/git.js +56 -1
- package/dist/lib/hooks/cache.d.ts +6 -0
- package/dist/lib/hooks/cache.js +54 -12
- package/dist/lib/hooks.d.ts +27 -0
- package/dist/lib/hooks.js +135 -10
- package/dist/lib/hosts/dispatch.d.ts +15 -0
- package/dist/lib/hosts/dispatch.js +45 -13
- package/dist/lib/hosts/logs.d.ts +16 -0
- package/dist/lib/hosts/logs.js +74 -0
- package/dist/lib/hosts/option.js +1 -1
- package/dist/lib/hosts/passthrough.js +3 -1
- package/dist/lib/hosts/progress.d.ts +66 -0
- package/dist/lib/hosts/progress.js +125 -17
- package/dist/lib/hosts/ready.d.ts +51 -7
- package/dist/lib/hosts/ready.js +98 -25
- package/dist/lib/hosts/reconcile.d.ts +53 -0
- package/dist/lib/hosts/reconcile.js +81 -0
- package/dist/lib/hosts/registry.d.ts +19 -2
- package/dist/lib/hosts/registry.js +58 -2
- package/dist/lib/hosts/remote-cmd.d.ts +62 -1
- package/dist/lib/hosts/remote-cmd.js +70 -1
- package/dist/lib/hosts/remote-os.d.ts +17 -0
- package/dist/lib/hosts/remote-os.js +30 -0
- package/dist/lib/hosts/session-index.d.ts +34 -0
- package/dist/lib/hosts/session-index.js +56 -0
- package/dist/lib/hosts/tasks.d.ts +22 -0
- package/dist/lib/hosts/tasks.js +29 -0
- package/dist/lib/lock.d.ts +93 -0
- package/dist/lib/lock.js +207 -0
- package/dist/lib/loop.js +16 -1
- package/dist/lib/machine-id.d.ts +21 -0
- package/dist/lib/machine-id.js +26 -0
- package/dist/lib/mailbox-target.d.ts +36 -0
- package/dist/lib/mailbox-target.js +45 -0
- package/dist/lib/mailbox.d.ts +47 -0
- package/dist/lib/mailbox.js +194 -0
- package/dist/lib/mcp.d.ts +5 -0
- package/dist/lib/mcp.js +24 -8
- package/dist/lib/migrate.d.ts +19 -0
- package/dist/lib/migrate.js +134 -26
- package/dist/lib/overdue.js +3 -0
- package/dist/lib/permissions.d.ts +4 -0
- package/dist/lib/permissions.js +35 -0
- package/dist/lib/picker.d.ts +26 -0
- package/dist/lib/picker.js +127 -0
- package/dist/lib/platform/exec.d.ts +46 -0
- package/dist/lib/platform/exec.js +74 -0
- package/dist/lib/platform/process.d.ts +31 -0
- package/dist/lib/platform/process.js +34 -1
- package/dist/lib/platform/winpath.js +2 -0
- package/dist/lib/plugin-marketplace.d.ts +30 -0
- package/dist/lib/plugin-marketplace.js +215 -2
- package/dist/lib/plugins.d.ts +5 -0
- package/dist/lib/plugins.js +61 -10
- package/dist/lib/profiles.d.ts +25 -0
- package/dist/lib/profiles.js +22 -6
- package/dist/lib/pty-client.js +2 -1
- package/dist/lib/rotate.d.ts +61 -0
- package/dist/lib/rotate.js +52 -0
- package/dist/lib/routines.d.ts +40 -2
- package/dist/lib/routines.js +66 -8
- package/dist/lib/runner.d.ts +11 -2
- package/dist/lib/runner.js +49 -7
- package/dist/lib/scheduler.js +6 -1
- package/dist/lib/secrets/bundles.d.ts +60 -4
- package/dist/lib/secrets/bundles.js +131 -12
- package/dist/lib/secrets/filestore.d.ts +3 -0
- package/dist/lib/secrets/filestore.js +42 -16
- package/dist/lib/secrets/index.d.ts +43 -2
- package/dist/lib/secrets/index.js +102 -3
- package/dist/lib/secrets/mcp.d.ts +93 -0
- package/dist/lib/secrets/mcp.js +205 -0
- package/dist/lib/secrets/remote.js +12 -5
- package/dist/lib/secrets/sync.js +83 -4
- package/dist/lib/secrets/windows.js +14 -3
- package/dist/lib/serve/data.d.ts +81 -0
- package/dist/lib/serve/data.js +91 -0
- package/dist/lib/serve/page.d.ts +7 -0
- package/dist/lib/serve/page.js +140 -0
- package/dist/lib/serve/server.d.ts +46 -0
- package/dist/lib/serve/server.js +115 -0
- package/dist/lib/session/active.d.ts +61 -0
- package/dist/lib/session/active.js +196 -17
- package/dist/lib/session/discover.d.ts +37 -0
- package/dist/lib/session/discover.js +204 -27
- package/dist/lib/session/inject.d.ts +18 -0
- package/dist/lib/session/inject.js +21 -0
- package/dist/lib/session/parse.d.ts +6 -0
- package/dist/lib/session/parse.js +286 -2
- package/dist/lib/session/pid-registry.d.ts +22 -0
- package/dist/lib/session/pid-registry.js +104 -0
- package/dist/lib/session/provenance.d.ts +14 -2
- package/dist/lib/session/provenance.js +39 -8
- package/dist/lib/session/remote-active.d.ts +26 -0
- package/dist/lib/session/remote-active.js +153 -0
- package/dist/lib/session/remote-list.d.ts +51 -0
- package/dist/lib/session/remote-list.js +213 -0
- package/dist/lib/session/remote.d.ts +7 -1
- package/dist/lib/session/remote.js +18 -8
- package/dist/lib/session/render.js +1 -1
- package/dist/lib/session/sync/config.d.ts +1 -7
- package/dist/lib/session/sync/config.js +4 -11
- package/dist/lib/session/types.d.ts +18 -1
- package/dist/lib/session/types.js +1 -1
- package/dist/lib/shims.d.ts +44 -6
- package/dist/lib/shims.js +143 -57
- package/dist/lib/ssh-exec.d.ts +26 -3
- package/dist/lib/ssh-exec.js +47 -3
- package/dist/lib/ssh-tunnel.d.ts +24 -5
- package/dist/lib/ssh-tunnel.js +62 -63
- package/dist/lib/staleness/writers/hooks.js +1 -1
- package/dist/lib/startup/command-registry.d.ts +8 -0
- package/dist/lib/startup/command-registry.js +17 -1
- package/dist/lib/state.d.ts +13 -0
- package/dist/lib/state.js +103 -9
- package/dist/lib/sync-umbrella.d.ts +14 -7
- package/dist/lib/sync-umbrella.js +17 -9
- package/dist/lib/teams/forEach.d.ts +110 -0
- package/dist/lib/teams/forEach.js +186 -0
- package/dist/lib/teams/index.d.ts +1 -0
- package/dist/lib/teams/index.js +1 -0
- package/dist/lib/teams/pr-watch.d.ts +226 -0
- package/dist/lib/teams/pr-watch.js +371 -0
- package/dist/lib/teams/registry.js +25 -9
- package/dist/lib/teams/supervisor.d.ts +14 -1
- package/dist/lib/teams/supervisor.js +19 -0
- package/dist/lib/teams/worktree.d.ts +9 -0
- package/dist/lib/teams/worktree.js +32 -0
- package/dist/lib/terminal/backends/ghostty.d.ts +6 -0
- package/dist/lib/terminal/backends/ghostty.js +69 -0
- package/dist/lib/terminal/backends/index.d.ts +19 -0
- package/dist/lib/terminal/backends/index.js +31 -0
- package/dist/lib/terminal/backends/iterm.d.ts +6 -0
- package/dist/lib/terminal/backends/iterm.js +62 -0
- package/dist/lib/terminal/backends/tmux.d.ts +14 -0
- package/dist/lib/terminal/backends/tmux.js +23 -0
- package/dist/lib/terminal/backends/vscodium-agent.d.ts +31 -0
- package/dist/lib/terminal/backends/vscodium-agent.js +72 -0
- package/dist/lib/terminal/engine.d.ts +39 -0
- package/dist/lib/terminal/engine.js +54 -0
- package/dist/lib/terminal/index.d.ts +17 -0
- package/dist/lib/terminal/index.js +8 -0
- package/dist/lib/terminal/inject.d.ts +204 -0
- package/dist/lib/terminal/inject.js +247 -0
- package/dist/lib/terminal/policy.d.ts +11 -0
- package/dist/lib/terminal/policy.js +11 -0
- package/dist/lib/terminal/quote.d.ts +11 -0
- package/dist/lib/terminal/quote.js +13 -0
- package/dist/lib/terminal/resolve.d.ts +64 -0
- package/dist/lib/terminal/resolve.js +90 -0
- package/dist/lib/terminal/shell.d.ts +6 -0
- package/dist/lib/terminal/shell.js +23 -0
- package/dist/lib/terminal/transport.d.ts +15 -0
- package/dist/lib/terminal/transport.js +40 -0
- package/dist/lib/terminal/types.d.ts +59 -0
- package/dist/lib/terminal/types.js +13 -0
- package/dist/lib/triggers/webhook.d.ts +85 -0
- package/dist/lib/triggers/webhook.js +141 -0
- package/dist/lib/types.d.ts +7 -0
- package/dist/lib/versions.d.ts +30 -3
- package/dist/lib/versions.js +129 -18
- package/dist/lib/watchdog/index.d.ts +3 -0
- package/dist/lib/watchdog/index.js +5 -0
- package/dist/lib/watchdog/read.d.ts +35 -0
- package/dist/lib/watchdog/read.js +149 -0
- package/dist/lib/watchdog/runner.d.ts +127 -0
- package/dist/lib/watchdog/runner.js +322 -0
- package/dist/lib/watchdog/watchdog.d.ts +40 -0
- package/dist/lib/watchdog/watchdog.js +166 -0
- package/dist/lib/watchdog/watchdogTail.d.ts +5 -0
- package/dist/lib/watchdog/watchdogTail.js +154 -0
- package/dist/lib/whats-new.d.ts +9 -0
- package/dist/lib/whats-new.js +35 -0
- package/dist/lib/workflows.d.ts +166 -0
- package/dist/lib/workflows.js +193 -0
- package/package.json +5 -4
package/dist/commands/doctor.js
CHANGED
|
@@ -4,106 +4,50 @@ import { checkAllClis } from '../lib/teams/agents.js';
|
|
|
4
4
|
import { AGENTS, ALL_AGENT_IDS, resolveAgentName, formatAgentError } from '../lib/agents.js';
|
|
5
5
|
import { getGlobalDefault, getVersionHomePath, isVersionInstalled, listInstalledVersions, parseAgentSpec, } from '../lib/versions.js';
|
|
6
6
|
import { loadManifest, isStale } from '../lib/staleness/index.js';
|
|
7
|
-
import { diffVersionCommands, iterCommandsCapableVersions } from '../lib/commands.js';
|
|
8
|
-
import { diffVersionSkills, iterSkillsCapableVersions } from '../lib/skills.js';
|
|
9
|
-
import { iterHooksCapableVersions, listUnmanagedHooksInVersionHome } from '../lib/hooks.js';
|
|
10
7
|
import { diffVersionResources, DOCTOR_ALL_KINDS, } from '../lib/doctor-diff.js';
|
|
8
|
+
import { checkSyncStatus, countOrphans } from '../lib/drift.js';
|
|
11
9
|
import { unifiedDiff, colorizeUnifiedDiff } from '../lib/diff-text.js';
|
|
12
10
|
import { listCliStatus } from '../lib/cli-resources.js';
|
|
13
11
|
import { setHelpSections } from '../lib/help.js';
|
|
14
12
|
import { heal, healChangedAnything } from '../lib/heal.js';
|
|
15
13
|
import { blocksLocalScripts, getEffectiveExecutionPolicy } from '../lib/platform/winpath.js';
|
|
14
|
+
import { terminalWidth, truncateToWidth, stringWidth, padToWidth } from '../lib/session/width.js';
|
|
16
15
|
import * as fs from 'fs';
|
|
17
16
|
const AGENT_NAMES = Object.fromEntries(ALL_AGENT_IDS.map((id) => [id, AGENTS[id].name]));
|
|
18
17
|
// ─── overview mode (no target) ────────────────────────────────────────────────
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// invalid manifest, or the bundled skills/commands missing from the mirror —
|
|
22
|
-
// the system-repo plugin content that matters most). Other kinds collapse to
|
|
23
|
-
// compact counts so the readout stays scannable.
|
|
24
|
-
function divergenceLines(report) {
|
|
25
|
-
const lines = [];
|
|
26
|
-
for (const p of report.kinds.plugins) {
|
|
27
|
-
if (p.status === 'missing')
|
|
28
|
-
lines.push(`plugin ${p.name} — not installed`);
|
|
29
|
-
else if (p.status === 'diff')
|
|
30
|
-
lines.push(`plugin ${p.name} — ${p.detail ?? 'mirror drifted'}`);
|
|
31
|
-
}
|
|
32
|
-
const counts = [];
|
|
33
|
-
for (const kind of ['commands', 'skills', 'hooks', 'rules', 'mcp', 'permissions', 'subagents']) {
|
|
34
|
-
const rows = report.kinds[kind];
|
|
35
|
-
const miss = rows.filter((r) => r.status === 'missing').length;
|
|
36
|
-
const dif = rows.filter((r) => r.status === 'diff').length;
|
|
37
|
-
const bits = [];
|
|
38
|
-
if (miss)
|
|
39
|
-
bits.push(`${miss} missing`);
|
|
40
|
-
if (dif)
|
|
41
|
-
bits.push(`${dif} drifted`);
|
|
42
|
-
if (bits.length)
|
|
43
|
-
counts.push(`${kind} ${bits.join('/')}`);
|
|
44
|
-
}
|
|
45
|
-
if (counts.length)
|
|
46
|
-
lines.push(counts.join(' · '));
|
|
47
|
-
return lines;
|
|
18
|
+
function collapseWhitespace(s) {
|
|
19
|
+
return s.replace(/\s+/g, ' ').trim();
|
|
48
20
|
}
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
rows.push(row);
|
|
21
|
+
export function wrapLine(prefix, text, width = terminalWidth()) {
|
|
22
|
+
const words = collapseWhitespace(text).split(' ').filter(Boolean);
|
|
23
|
+
if (words.length === 0)
|
|
24
|
+
return [prefix.trimEnd()];
|
|
25
|
+
const continuation = ' '.repeat(stringWidth(prefix));
|
|
26
|
+
const lines = [];
|
|
27
|
+
let linePrefix = prefix;
|
|
28
|
+
let line = prefix;
|
|
29
|
+
let hasWord = false;
|
|
30
|
+
for (const word of words) {
|
|
31
|
+
const room = Math.max(1, width - stringWidth(linePrefix));
|
|
32
|
+
const piece = stringWidth(word) > room ? truncateToWidth(word, room) : word;
|
|
33
|
+
const candidate = hasWord ? `${line} ${piece}` : `${line}${piece}`;
|
|
34
|
+
if (hasWord && stringWidth(candidate) > width) {
|
|
35
|
+
lines.push(line);
|
|
36
|
+
linePrefix = continuation;
|
|
37
|
+
line = continuation + piece;
|
|
38
|
+
hasWord = true;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
line = candidate;
|
|
42
|
+
hasWord = true;
|
|
72
43
|
}
|
|
73
44
|
}
|
|
74
|
-
|
|
45
|
+
lines.push(line);
|
|
46
|
+
return lines;
|
|
75
47
|
}
|
|
76
|
-
function
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
const key = `${agent}@${version}`;
|
|
80
|
-
let row = byKey.get(key);
|
|
81
|
-
if (!row) {
|
|
82
|
-
row = { agent, version, commands: 0, skills: 0, hooks: 0 };
|
|
83
|
-
byKey.set(key, row);
|
|
84
|
-
}
|
|
85
|
-
return row;
|
|
86
|
-
};
|
|
87
|
-
for (const { agent, version } of iterCommandsCapableVersions()) {
|
|
88
|
-
const diff = diffVersionCommands(agent, version);
|
|
89
|
-
if (diff.orphans.length > 0)
|
|
90
|
-
ensure(agent, version).commands = diff.orphans.length;
|
|
91
|
-
}
|
|
92
|
-
for (const { agent, version } of iterSkillsCapableVersions()) {
|
|
93
|
-
const diff = diffVersionSkills(agent, version);
|
|
94
|
-
if (diff.orphans.length > 0)
|
|
95
|
-
ensure(agent, version).skills = diff.orphans.length;
|
|
96
|
-
}
|
|
97
|
-
// Orphan hooks are scripts in the version home that no agents.yaml/hooks.yaml
|
|
98
|
-
// entry registers — so the registrar never wires them to an event and they
|
|
99
|
-
// never fire. (Distinct from the source-diff `diffVersionHooks().orphans`,
|
|
100
|
-
// which false-flags valid system-sourced registered hooks.)
|
|
101
|
-
for (const { agent, version } of iterHooksCapableVersions()) {
|
|
102
|
-
const dead = listUnmanagedHooksInVersionHome(agent, version);
|
|
103
|
-
if (dead.length > 0)
|
|
104
|
-
ensure(agent, version).hooks = dead.length;
|
|
105
|
-
}
|
|
106
|
-
return Array.from(byKey.values()).filter((r) => r.commands + r.skills + r.hooks > 0);
|
|
48
|
+
function printWrappedLine(prefix, text) {
|
|
49
|
+
for (const line of wrapLine(prefix, text))
|
|
50
|
+
console.log(chalk.gray(line));
|
|
107
51
|
}
|
|
108
52
|
function renderOverviewText(clis, syncRows, orphanRows, hostClis) {
|
|
109
53
|
console.log(chalk.bold('Agent CLIs'));
|
|
@@ -130,7 +74,7 @@ function renderOverviewText(clis, syncRows, orphanRows, hostClis) {
|
|
|
130
74
|
}
|
|
131
75
|
}
|
|
132
76
|
if (hidden.length > 0) {
|
|
133
|
-
|
|
77
|
+
printWrappedLine(' ', `+${hidden.length} more supported (${hidden.join(', ')}) — \`agents add <name>\` to manage`);
|
|
134
78
|
}
|
|
135
79
|
console.log();
|
|
136
80
|
console.log(chalk.bold('Sync status (installed versions)'));
|
|
@@ -162,7 +106,7 @@ function renderOverviewText(clis, syncRows, orphanRows, hostClis) {
|
|
|
162
106
|
// Version homes are reconciled only by management commands, so point at one
|
|
163
107
|
// rather than promising an auto-sync that never happens.
|
|
164
108
|
if (anyOutOfSync) {
|
|
165
|
-
|
|
109
|
+
printWrappedLine(' ', 'Reconcile with `agents doctor <agent>@<version> --fix` or `agents sync <agent>@<version>` (not applied on launch).');
|
|
166
110
|
}
|
|
167
111
|
}
|
|
168
112
|
console.log();
|
|
@@ -199,10 +143,17 @@ function renderOverviewText(clis, syncRows, orphanRows, hostClis) {
|
|
|
199
143
|
const label = manifest.name.padEnd(nameWidth);
|
|
200
144
|
const src = chalk.gray(`[${manifest.source}]`);
|
|
201
145
|
if (installed) {
|
|
202
|
-
|
|
146
|
+
const prefix = ` ${chalk.green('ready')} ${label} ${src}`;
|
|
147
|
+
const desc = manifest.description
|
|
148
|
+
? ` ${truncateToWidth(collapseWhitespace(manifest.description), Math.max(1, terminalWidth() - stringWidth(prefix) - 2))}`
|
|
149
|
+
: '';
|
|
150
|
+
console.log(prefix + chalk.gray(desc));
|
|
203
151
|
}
|
|
204
152
|
else {
|
|
205
|
-
|
|
153
|
+
const prefix = ` ${chalk.red('miss ')} ${label} ${src}`;
|
|
154
|
+
const msg = `not installed — run \`agents cli install ${manifest.name}\``;
|
|
155
|
+
const budget = Math.max(1, terminalWidth() - stringWidth(prefix) - 2);
|
|
156
|
+
console.log(prefix + chalk.gray(` ${truncateToWidth(msg, budget)}`));
|
|
206
157
|
}
|
|
207
158
|
}
|
|
208
159
|
}
|
|
@@ -357,8 +308,12 @@ function renderKindSection(kind, rows, layers, options) {
|
|
|
357
308
|
}
|
|
358
309
|
for (const r of visible) {
|
|
359
310
|
const src = sourceLabel(r, layers);
|
|
360
|
-
const
|
|
361
|
-
|
|
311
|
+
const name = padToWidth(truncateToWidth(r.name, 28), 28);
|
|
312
|
+
const prefix = ` ${statusLabel(r.status)} ${name} ${src}`;
|
|
313
|
+
const detail = r.detail
|
|
314
|
+
? chalk.gray(` ${truncateToWidth(collapseWhitespace(r.detail), Math.max(1, terminalWidth() - stringWidth(prefix) - 2))}`)
|
|
315
|
+
: '';
|
|
316
|
+
console.log(prefix + detail);
|
|
362
317
|
if (options.showDiff && r.status === 'diff' && r.sourcePath && r.homePath) {
|
|
363
318
|
const expected = readExpectedForDiff(kind, r);
|
|
364
319
|
const actual = safeRead(r.homePath);
|
|
@@ -395,8 +350,10 @@ function readExpectedForDiff(kind, row) {
|
|
|
395
350
|
function renderTargetText(report, options) {
|
|
396
351
|
const label = `${AGENT_NAMES[report.agent] || report.agent}@${report.version}`;
|
|
397
352
|
console.log(chalk.bold(label));
|
|
398
|
-
|
|
399
|
-
|
|
353
|
+
const homePrefix = ' home: ';
|
|
354
|
+
const cwdPrefix = ' cwd: ';
|
|
355
|
+
console.log(chalk.gray(homePrefix + truncateToWidth(report.home, Math.max(1, terminalWidth() - stringWidth(homePrefix)))));
|
|
356
|
+
console.log(chalk.gray(cwdPrefix + truncateToWidth(report.cwd, Math.max(1, terminalWidth() - stringWidth(cwdPrefix)))));
|
|
400
357
|
const layerStr = [
|
|
401
358
|
report.layers.project ? `project=${report.layers.project}` : null,
|
|
402
359
|
`user=${report.layers.user}`,
|
|
@@ -405,7 +362,7 @@ function renderTargetText(report, options) {
|
|
|
405
362
|
? `extras=[${report.layers.extras.map((e) => e.alias).join(',')}]`
|
|
406
363
|
: null,
|
|
407
364
|
].filter(Boolean).join(' ');
|
|
408
|
-
|
|
365
|
+
printWrappedLine(' layers: ', layerStr);
|
|
409
366
|
// Staleness manifest verdict — single-line summary from the staleness
|
|
410
367
|
// library, sitting alongside the detailed per-resource diff below.
|
|
411
368
|
const manifest = loadManifest(report.agent, report.version);
|
|
@@ -446,7 +403,7 @@ function renderTargetText(report, options) {
|
|
|
446
403
|
}
|
|
447
404
|
else {
|
|
448
405
|
console.log(` Verdict: ${verdictParts.join(', ')}.`);
|
|
449
|
-
|
|
406
|
+
printWrappedLine(' ', `Run \`agents doctor ${report.agent}@${report.version} --fix\` to heal, or \`agents prune cleanup\` to drop extras.`);
|
|
450
407
|
}
|
|
451
408
|
}
|
|
452
409
|
// ─── fix / heal mode ───────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agents events` — read the structured audit/event log.
|
|
3
|
+
*
|
|
4
|
+
* The event log (`~/.agents/.cache/logs/events-YYYY-MM-DD.jsonl`) records every
|
|
5
|
+
* `agents <module> <cmd>` invocation plus richer typed events (secrets access,
|
|
6
|
+
* version installs, ...), each stamped with who ran it and from where (OS user,
|
|
7
|
+
* local vs SSH, remote client IP). This command reads it back — the audit trail
|
|
8
|
+
* for "who accessed a secret / created a team / started an agent, and from which
|
|
9
|
+
* host?".
|
|
10
|
+
*
|
|
11
|
+
* Filter by `--module` (top-level group, e.g. teams), `--command` (path prefix,
|
|
12
|
+
* e.g. "teams create"), `--event` (typed event), `--agent`, and `--since`.
|
|
13
|
+
* `--follow` tails today's log live.
|
|
14
|
+
*/
|
|
15
|
+
import type { Command } from 'commander';
|
|
16
|
+
export declare function registerEventsCommand(program: Command): void;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agents events` — read the structured audit/event log.
|
|
3
|
+
*
|
|
4
|
+
* The event log (`~/.agents/.cache/logs/events-YYYY-MM-DD.jsonl`) records every
|
|
5
|
+
* `agents <module> <cmd>` invocation plus richer typed events (secrets access,
|
|
6
|
+
* version installs, ...), each stamped with who ran it and from where (OS user,
|
|
7
|
+
* local vs SSH, remote client IP). This command reads it back — the audit trail
|
|
8
|
+
* for "who accessed a secret / created a team / started an agent, and from which
|
|
9
|
+
* host?".
|
|
10
|
+
*
|
|
11
|
+
* Filter by `--module` (top-level group, e.g. teams), `--command` (path prefix,
|
|
12
|
+
* e.g. "teams create"), `--event` (typed event), `--agent`, and `--since`.
|
|
13
|
+
* `--follow` tails today's log live.
|
|
14
|
+
*/
|
|
15
|
+
import chalk from 'chalk';
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import { query, getLogsPath } from '../lib/events.js';
|
|
18
|
+
/** Parse `--since`: relative offsets (30s/5m/2h/7d/4w) or an ISO/absolute date. */
|
|
19
|
+
function parseSince(s) {
|
|
20
|
+
const m = s.match(/^(\d+)([smhdw])$/);
|
|
21
|
+
if (m) {
|
|
22
|
+
const n = parseInt(m[1], 10);
|
|
23
|
+
const unitMs = {
|
|
24
|
+
s: 1000, m: 60_000, h: 3_600_000, d: 86_400_000, w: 604_800_000,
|
|
25
|
+
};
|
|
26
|
+
return new Date(Date.now() - n * unitMs[m[2]]);
|
|
27
|
+
}
|
|
28
|
+
const ms = Date.parse(s);
|
|
29
|
+
if (isNaN(ms))
|
|
30
|
+
throw new Error(`Invalid --since value: ${s} (use e.g. 2h, 7d, or an ISO date)`);
|
|
31
|
+
return new Date(ms);
|
|
32
|
+
}
|
|
33
|
+
/** How the run reached this host — 'local' or 'ssh 203.0.113.7'. */
|
|
34
|
+
function originLabel(r) {
|
|
35
|
+
if (r.transport === 'ssh') {
|
|
36
|
+
return chalk.yellow(`ssh${r.sshClientIp ? ' ' + r.sshClientIp : ''}`);
|
|
37
|
+
}
|
|
38
|
+
return chalk.gray('local');
|
|
39
|
+
}
|
|
40
|
+
/** The most useful one-line detail for a record, by event family. */
|
|
41
|
+
function detailFor(r) {
|
|
42
|
+
if (r.command)
|
|
43
|
+
return r.command;
|
|
44
|
+
const bits = [];
|
|
45
|
+
if (typeof r.team === 'string')
|
|
46
|
+
bits.push(`team=${r.team}`);
|
|
47
|
+
if (typeof r.bundle === 'string')
|
|
48
|
+
bits.push(`bundle=${r.bundle}`);
|
|
49
|
+
if (typeof r.skill === 'string')
|
|
50
|
+
bits.push(`skill=${r.skill}`);
|
|
51
|
+
if (typeof r.version === 'string')
|
|
52
|
+
bits.push(`v=${r.version}`);
|
|
53
|
+
if (typeof r.profile === 'string')
|
|
54
|
+
bits.push(`profile=${r.profile}`);
|
|
55
|
+
if (typeof r.error === 'string')
|
|
56
|
+
bits.push(chalk.red(r.error));
|
|
57
|
+
return bits.join(' ');
|
|
58
|
+
}
|
|
59
|
+
function renderRow(r) {
|
|
60
|
+
const time = chalk.gray(r.ts.slice(0, 19).replace('T', ' '));
|
|
61
|
+
const user = `${r.osUser ?? '?'}@${r.hostname}`;
|
|
62
|
+
const ev = r.event.startsWith('error') ? chalk.red(r.event) : chalk.cyan(r.event);
|
|
63
|
+
const agent = r.agent ? chalk.gray(` ${r.agent}`) : '';
|
|
64
|
+
return `${time} ${originLabel(r).padEnd(24)} ${user.padEnd(22)} ${ev.padEnd(26)}${agent} ${detailFor(r)}`;
|
|
65
|
+
}
|
|
66
|
+
export function registerEventsCommand(program) {
|
|
67
|
+
program
|
|
68
|
+
.command('events')
|
|
69
|
+
.description('Read the structured audit/event log (who ran what, from where)')
|
|
70
|
+
.option('--module <name>', 'Only events from this command group (e.g. teams, secrets)')
|
|
71
|
+
.option('--command <path>', 'Only this command path — prefix match (e.g. "teams create")')
|
|
72
|
+
.option('--event <type>', 'Only this typed event (repeatable, e.g. secrets.get)', collect, [])
|
|
73
|
+
.option('--agent <name>', 'Only events tagged with this agent')
|
|
74
|
+
.option('--since <time>', 'Only events newer than this (e.g. 2h, 7d, or ISO date)')
|
|
75
|
+
.option('--limit <n>', 'Max records to show (default 50)', '50')
|
|
76
|
+
.option('--json', 'Output raw records as JSON')
|
|
77
|
+
.option('-f, --follow', "Tail today's log live")
|
|
78
|
+
.addHelpText('after', `
|
|
79
|
+
Examples:
|
|
80
|
+
agents events Recent activity across everything
|
|
81
|
+
agents events --module teams Team lifecycle (create / add / disband)
|
|
82
|
+
agents events --module secrets Every secret accessed or revealed
|
|
83
|
+
agents events --command "teams create" Just team creations
|
|
84
|
+
agents events --event secrets.get --since 7d --json
|
|
85
|
+
agents events -f Live tail`)
|
|
86
|
+
.action(async (options) => {
|
|
87
|
+
if (options.follow) {
|
|
88
|
+
await followLog();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const limit = Math.max(1, parseInt(options.limit ?? '50', 10) || 50);
|
|
92
|
+
let startDate;
|
|
93
|
+
try {
|
|
94
|
+
startDate = options.since ? parseSince(options.since) : undefined;
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
console.error(chalk.red(err.message));
|
|
98
|
+
process.exit(2);
|
|
99
|
+
}
|
|
100
|
+
const records = query({
|
|
101
|
+
startDate,
|
|
102
|
+
eventTypes: options.event && options.event.length ? options.event : undefined,
|
|
103
|
+
agent: options.agent,
|
|
104
|
+
command: options.command,
|
|
105
|
+
module: options.module,
|
|
106
|
+
limit,
|
|
107
|
+
});
|
|
108
|
+
if (options.json) {
|
|
109
|
+
console.log(JSON.stringify(records, null, 2));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (records.length === 0) {
|
|
113
|
+
console.log(chalk.gray('No matching events.'));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// query() returns newest-first; print oldest-first so a tail reads naturally.
|
|
117
|
+
for (const r of records.slice().reverse())
|
|
118
|
+
console.log(renderRow(r));
|
|
119
|
+
console.log(chalk.gray(`\n${records.length} event(s). Log: ${getLogsPath()}`));
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/** commander repeatable-option collector. */
|
|
123
|
+
function collect(value, previous) {
|
|
124
|
+
return previous.concat([value]);
|
|
125
|
+
}
|
|
126
|
+
/** Tail today's event file, printing new lines as they land. */
|
|
127
|
+
async function followLog() {
|
|
128
|
+
const today = new Date();
|
|
129
|
+
const file = `${getLogsPath()}/events-${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}.jsonl`;
|
|
130
|
+
let offset = 0;
|
|
131
|
+
try {
|
|
132
|
+
offset = fs.statSync(file).size;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// File may not exist yet — start at 0 and pick it up on first write.
|
|
136
|
+
}
|
|
137
|
+
console.log(chalk.gray(`Tailing ${file} — Ctrl-C to stop`));
|
|
138
|
+
const drain = () => {
|
|
139
|
+
let size = 0;
|
|
140
|
+
try {
|
|
141
|
+
size = fs.statSync(file).size;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (size <= offset) {
|
|
147
|
+
if (size < offset)
|
|
148
|
+
offset = 0; // rotated/truncated
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const fd = fs.openSync(file, 'r');
|
|
152
|
+
try {
|
|
153
|
+
const buf = Buffer.alloc(size - offset);
|
|
154
|
+
fs.readSync(fd, buf, 0, buf.length, offset);
|
|
155
|
+
offset = size;
|
|
156
|
+
for (const line of buf.toString('utf-8').split('\n').filter(Boolean)) {
|
|
157
|
+
try {
|
|
158
|
+
console.log(renderRow(JSON.parse(line)));
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Skip malformed lines.
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
fs.closeSync(fd);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
// Poll — simpler and more portable than fs.watch across platforms/editors.
|
|
170
|
+
await new Promise(() => {
|
|
171
|
+
setInterval(drain, 500);
|
|
172
|
+
});
|
|
173
|
+
}
|
package/dist/commands/exec.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* injection, and multi-agent fallback chains for rate-limit resilience.
|
|
7
7
|
*/
|
|
8
8
|
import { type Command } from 'commander';
|
|
9
|
+
import type { ExecEffort } from '../lib/exec.js';
|
|
9
10
|
/**
|
|
10
11
|
* Build the LoopConfig the driver consumes from CLI flags and/or a workflow's
|
|
11
12
|
* `loop:` frontmatter block (issue #332). Returns undefined when neither source
|
|
@@ -26,5 +27,23 @@ export declare function buildLoopConfig(flags: {
|
|
|
26
27
|
}, workflowLoop?: import('../lib/workflows.js').LoopConfigRaw): import('../lib/loop.js').LoopConfig | undefined;
|
|
27
28
|
/** Map a loop stop reason to a process exit code. condition-met/max are clean exits. */
|
|
28
29
|
export declare function loopExitCode(stoppedBy: import('../lib/loop.js').LoopStoppedBy): number;
|
|
30
|
+
/**
|
|
31
|
+
* Drive a workflow's declarative `for_each:` fan-out end-to-end (issue #343).
|
|
32
|
+
*
|
|
33
|
+
* Runs the producer, expands one stage teammate per produced item (respecting
|
|
34
|
+
* `max_items` / `DEFAULT_FOR_EACH_CAP`, surfacing any truncation — never a
|
|
35
|
+
* silent cap), stages them into a fresh team via the existing `runForEach`
|
|
36
|
+
* bridge, then drives the teams supervisor until the DAG drains. When a verify
|
|
37
|
+
* panel is declared, tallies each item's `keep_if` gate from the skeptics'
|
|
38
|
+
* terminal status and logs which items survived.
|
|
39
|
+
*
|
|
40
|
+
* Reuses the teams substrate wholesale — no new orchestration engine. Returns
|
|
41
|
+
* the process exit code (0 on drain, 1 on producer failure / non-drain).
|
|
42
|
+
*/
|
|
43
|
+
export declare function runWorkflowForEach(spec: import('../lib/workflows.js').ForEachSpec, opts: {
|
|
44
|
+
workflowName: string;
|
|
45
|
+
cwd: string;
|
|
46
|
+
effort?: ExecEffort;
|
|
47
|
+
}): Promise<number>;
|
|
29
48
|
/** Register the `agents run <agent> [prompt]` command. */
|
|
30
49
|
export declare function registerRunCommand(program: Command): void;
|