@phnx-labs/agents-cli 1.18.6 → 1.19.1
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 +13 -2
- package/README.md +22 -20
- package/dist/commands/browser.js +25 -2
- package/dist/commands/cloud.js +3 -3
- package/dist/commands/computer.d.ts +6 -0
- package/dist/commands/computer.js +477 -0
- package/dist/commands/doctor.js +19 -17
- package/dist/commands/exec.js +37 -59
- package/dist/commands/factory.js +12 -5
- package/dist/commands/import.js +6 -1
- package/dist/commands/mcp.js +9 -4
- package/dist/commands/packages.d.ts +3 -0
- package/dist/commands/packages.js +20 -12
- package/dist/commands/permissions.d.ts +2 -0
- package/dist/commands/permissions.js +20 -1
- package/dist/commands/plugins.d.ts +2 -0
- package/dist/commands/plugins.js +23 -4
- package/dist/commands/profiles.js +1 -1
- package/dist/commands/pty.js +126 -112
- package/dist/commands/pull.js +29 -25
- package/dist/commands/repo.js +24 -26
- package/dist/commands/routines.js +29 -26
- package/dist/commands/secrets.js +66 -73
- package/dist/commands/sessions-tail.js +21 -22
- package/dist/commands/sessions.js +36 -68
- package/dist/commands/setup.js +20 -24
- package/dist/commands/teams.js +30 -39
- package/dist/commands/versions.js +60 -68
- package/dist/commands/worktree.d.ts +20 -0
- package/dist/commands/worktree.js +242 -0
- package/dist/computer.d.ts +2 -0
- package/dist/computer.js +7 -0
- package/dist/index.js +70 -26
- package/dist/lib/agents.d.ts +4 -1
- package/dist/lib/agents.js +23 -5
- package/dist/lib/browser/cdp.d.ts +15 -1
- package/dist/lib/browser/cdp.js +77 -8
- package/dist/lib/browser/chrome.js +17 -24
- package/dist/lib/browser/drivers/ssh.d.ts +1 -0
- package/dist/lib/browser/drivers/ssh.js +20 -8
- package/dist/lib/browser/ipc.js +38 -5
- package/dist/lib/browser/profiles.js +34 -2
- package/dist/lib/browser/runtime-state.d.ts +1 -2
- package/dist/lib/browser/runtime-state.js +11 -3
- package/dist/lib/browser/service.d.ts +5 -0
- package/dist/lib/browser/service.js +32 -4
- package/dist/lib/browser/types.d.ts +1 -1
- package/dist/lib/browser/upload.d.ts +2 -0
- package/dist/lib/browser/upload.js +34 -0
- package/dist/lib/cloud/rush.d.ts +2 -1
- package/dist/lib/cloud/rush.js +28 -9
- package/dist/lib/computer-rpc.d.ts +24 -0
- package/dist/lib/computer-rpc.js +263 -0
- package/dist/lib/daemon.js +7 -7
- package/dist/lib/exec.d.ts +2 -1
- package/dist/lib/exec.js +3 -2
- package/dist/lib/fs-atomic.d.ts +18 -0
- package/dist/lib/fs-atomic.js +76 -0
- package/dist/lib/git.js +2 -4
- package/dist/lib/help.d.ts +15 -0
- package/dist/lib/help.js +41 -0
- package/dist/lib/hooks/match.d.ts +1 -0
- package/dist/lib/hooks/match.js +57 -12
- package/dist/lib/hooks.d.ts +1 -0
- package/dist/lib/hooks.js +27 -10
- package/dist/lib/import.d.ts +1 -0
- package/dist/lib/import.js +7 -0
- package/dist/lib/manifest.js +27 -1
- package/dist/lib/mcp.d.ts +14 -0
- package/dist/lib/mcp.js +79 -14
- package/dist/lib/migrate.js +3 -3
- package/dist/lib/models.js +3 -1
- package/dist/lib/permissions.d.ts +5 -0
- package/dist/lib/permissions.js +35 -0
- package/dist/lib/plugin-marketplace.d.ts +3 -1
- package/dist/lib/plugin-marketplace.js +36 -1
- package/dist/lib/plugins.d.ts +19 -1
- package/dist/lib/plugins.js +99 -8
- package/dist/lib/redact.d.ts +4 -0
- package/dist/lib/redact.js +18 -0
- package/dist/lib/registry.d.ts +2 -0
- package/dist/lib/registry.js +15 -0
- package/dist/lib/sandbox.js +15 -5
- package/dist/lib/secrets/bundles.d.ts +7 -12
- package/dist/lib/secrets/bundles.js +45 -29
- package/dist/lib/secrets/index.js +4 -4
- package/dist/lib/session/cloud.d.ts +2 -0
- package/dist/lib/session/cloud.js +34 -6
- package/dist/lib/session/parse.js +7 -2
- package/dist/lib/session/render.d.ts +4 -1
- package/dist/lib/session/render.js +81 -35
- package/dist/lib/shims.d.ts +5 -2
- package/dist/lib/shims.js +29 -7
- package/dist/lib/state.d.ts +5 -5
- package/dist/lib/state.js +43 -13
- package/dist/lib/teams/agents.js +1 -1
- package/dist/lib/types.d.ts +4 -3
- package/dist/lib/types.js +0 -2
- package/dist/lib/versions.js +65 -40
- package/dist/lib/workflows.d.ts +7 -0
- package/dist/lib/workflows.js +42 -1
- package/npm-shrinkwrap.json +3162 -0
- package/package.json +32 -26
- package/scripts/postinstall.js +8 -2
package/dist/commands/pty.js
CHANGED
|
@@ -19,61 +19,65 @@ import chalk from 'chalk';
|
|
|
19
19
|
import { ptyRequest, unescapeInput } from '../lib/pty-client.js';
|
|
20
20
|
import { isPtyServerRunning, runPtyServer, getPtyPidPath, getPtyLogPath } from '../lib/pty-server.js';
|
|
21
21
|
import * as fs from 'fs';
|
|
22
|
+
import { setHelpSections } from '../lib/help.js';
|
|
22
23
|
/** Register the `agents pty` command tree. */
|
|
23
24
|
export function registerPtyCommands(program) {
|
|
24
25
|
const pty = program
|
|
25
26
|
.command('pty')
|
|
26
|
-
.description('Drive interactive terminal programs from AI agents. Use this for REPLs, TUIs, or anything needing a real terminal.')
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
.description('Drive interactive terminal programs from AI agents. Use this for REPLs, TUIs, or anything needing a real terminal.');
|
|
28
|
+
setHelpSections(pty, {
|
|
29
|
+
examples: `
|
|
30
|
+
# Start a session (returns a session ID)
|
|
31
|
+
SID=$(agents pty start)
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
# Run a command (non-blocking)
|
|
34
|
+
agents pty exec $SID "python3"
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
# Wait, then see what's on screen (clean text, no ANSI)
|
|
37
|
+
sleep 1 && agents pty screen $SID
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
# Type input (supports escapes: \\n \\t \\e \\xHH)
|
|
40
|
+
agents pty write $SID "print('hello')\\n"
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
# Read again
|
|
43
|
+
agents pty screen $SID
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
# Clean up
|
|
46
|
+
agents pty stop $SID
|
|
47
|
+
`,
|
|
48
|
+
notes: `
|
|
49
|
+
Use cases:
|
|
50
|
+
- Drive REPLs (python, node, irb) from agent code
|
|
51
|
+
- Automate TUI programs (npm init, interactive wizards)
|
|
52
|
+
- Test CLI tools that require a real PTY
|
|
53
|
+
- Run the 'agents' CLI itself from another agent
|
|
46
54
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- Run the 'agents' CLI itself from another agent
|
|
52
|
-
|
|
53
|
-
The PTY server auto-starts on first use and runs in the background.
|
|
54
|
-
Use 'agents pty server status' to check health.
|
|
55
|
-
`);
|
|
55
|
+
The PTY server auto-starts on first use and runs in the background.
|
|
56
|
+
Health: 'agents pty server status'.
|
|
57
|
+
`,
|
|
58
|
+
});
|
|
56
59
|
// --- Session lifecycle ---
|
|
57
|
-
pty
|
|
60
|
+
const startCmd = pty
|
|
58
61
|
.command('start')
|
|
59
62
|
.description('Start a new PTY session and return its ID. The session persists until you stop it.')
|
|
60
63
|
.option('-r, --rows <n>', 'Terminal height in rows', '24')
|
|
61
64
|
.option('-c, --cols <n>', 'Terminal width in columns', '120')
|
|
62
65
|
.option('-s, --shell <shell>', 'Shell to launch (defaults to $SHELL, e.g., zsh, bash)')
|
|
63
66
|
.option('-d, --cwd <dir>', 'Working directory for the shell')
|
|
64
|
-
.option('--json', 'Output full session metadata as JSON')
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
.option('--json', 'Output full session metadata as JSON');
|
|
68
|
+
setHelpSections(startCmd, {
|
|
69
|
+
examples: `
|
|
70
|
+
# Start a session and capture its ID
|
|
71
|
+
SID=$(agents pty start)
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
# Start a Python REPL in a specific directory
|
|
74
|
+
agents pty start --shell python3 --cwd /tmp
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
# Start a wider terminal for TUI programs
|
|
77
|
+
agents pty start --cols 160 --rows 40
|
|
78
|
+
`,
|
|
79
|
+
});
|
|
80
|
+
startCmd.action(async (opts) => {
|
|
77
81
|
const params = {
|
|
78
82
|
rows: parseInt(opts.rows, 10),
|
|
79
83
|
cols: parseInt(opts.cols, 10),
|
|
@@ -94,23 +98,24 @@ Examples:
|
|
|
94
98
|
console.log(res.id);
|
|
95
99
|
}
|
|
96
100
|
});
|
|
97
|
-
pty
|
|
101
|
+
const execCmd = pty
|
|
98
102
|
.command('exec <id> <command>')
|
|
99
103
|
.description('Send a command to a PTY session. Returns immediately (non-blocking). Use screen or read to see output.')
|
|
100
104
|
.option('--wait <ms>', 'Wait this many milliseconds then return the screen (convenience for quick commands)', '0')
|
|
101
|
-
.option('--json', 'Output as JSON')
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
.option('--json', 'Output as JSON');
|
|
106
|
+
setHelpSections(execCmd, {
|
|
107
|
+
examples: `
|
|
108
|
+
# Run a command and return immediately
|
|
109
|
+
agents pty exec $SID "ls -la"
|
|
106
110
|
|
|
107
|
-
|
|
108
|
-
|
|
111
|
+
# Run a command and wait 500ms to see output
|
|
112
|
+
agents pty exec $SID "git status" --wait 500
|
|
109
113
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
# Start a long-running process (returns right away)
|
|
115
|
+
agents pty exec $SID "npm run dev"
|
|
116
|
+
`,
|
|
117
|
+
});
|
|
118
|
+
execCmd.action(async (id, command, opts) => {
|
|
114
119
|
const res = await ptyRequest('exec', id, { command });
|
|
115
120
|
if (!res.ok) {
|
|
116
121
|
console.error(chalk.red(res.error));
|
|
@@ -132,20 +137,21 @@ Examples:
|
|
|
132
137
|
console.log(JSON.stringify(res));
|
|
133
138
|
}
|
|
134
139
|
});
|
|
135
|
-
pty
|
|
140
|
+
const readCmd = pty
|
|
136
141
|
.command('read <id>')
|
|
137
142
|
.description('Read raw output from the PTY (includes ANSI codes). Use screen for clean text instead.')
|
|
138
143
|
.option('-m, --ms <ms>', 'Wait up to this many milliseconds for new output (50-5000)', '200')
|
|
139
|
-
.option('--json', 'Output as JSON')
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
.option('--json', 'Output as JSON');
|
|
145
|
+
setHelpSections(readCmd, {
|
|
146
|
+
examples: `
|
|
147
|
+
# Read pending output (wait up to 200ms)
|
|
148
|
+
agents pty read $SID
|
|
144
149
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
# Read with longer wait for slow commands
|
|
151
|
+
agents pty read $SID --ms 1000
|
|
152
|
+
`,
|
|
153
|
+
});
|
|
154
|
+
readCmd.action(async (id, opts) => {
|
|
149
155
|
const ms = parseInt(opts.ms, 10);
|
|
150
156
|
const res = await ptyRequest('read', id, { ms });
|
|
151
157
|
if (!res.ok) {
|
|
@@ -160,29 +166,30 @@ Examples:
|
|
|
160
166
|
process.stdout.write(res.output);
|
|
161
167
|
}
|
|
162
168
|
});
|
|
163
|
-
pty
|
|
169
|
+
const writeCmd = pty
|
|
164
170
|
.command('write <id> <input>')
|
|
165
171
|
.description('Send keystrokes to the PTY (like typing into the terminal). Processes escape sequences by default.')
|
|
166
172
|
.option('--raw', 'Send input literally without processing \\n \\t \\e \\xHH escape codes')
|
|
167
|
-
.option('--json', 'Output as JSON')
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
.option('--json', 'Output as JSON');
|
|
174
|
+
setHelpSections(writeCmd, {
|
|
175
|
+
examples: `
|
|
176
|
+
# Send Enter key
|
|
177
|
+
agents pty write $SID "\\n"
|
|
172
178
|
|
|
173
|
-
|
|
174
|
-
|
|
179
|
+
# Type a command and press Enter
|
|
180
|
+
agents pty write $SID "ls -la\\n"
|
|
175
181
|
|
|
176
|
-
|
|
177
|
-
|
|
182
|
+
# Send Ctrl-C (interrupt signal)
|
|
183
|
+
agents pty write $SID "\\x03"
|
|
178
184
|
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
# Send Escape key
|
|
186
|
+
agents pty write $SID "\\e"
|
|
181
187
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
188
|
+
# Send literal backslash-n (not newline)
|
|
189
|
+
agents pty write $SID "\\\\n" --raw
|
|
190
|
+
`,
|
|
191
|
+
});
|
|
192
|
+
writeCmd.action(async (id, input, opts) => {
|
|
186
193
|
const processed = opts.raw ? input : unescapeInput(input);
|
|
187
194
|
const res = await ptyRequest('write', id, { input: processed });
|
|
188
195
|
if (!res.ok) {
|
|
@@ -193,21 +200,23 @@ Examples:
|
|
|
193
200
|
console.log(JSON.stringify(res));
|
|
194
201
|
}
|
|
195
202
|
});
|
|
196
|
-
pty
|
|
203
|
+
const screenCmd = pty
|
|
197
204
|
.command('screen <id>')
|
|
198
205
|
.description('Render the terminal screen as clean text (no ANSI codes). This is what a human sees looking at the terminal.')
|
|
199
|
-
.option('--json', 'Output as JSON (includes cursor position and dimensions)')
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
# Get screen with cursor position as JSON
|
|
206
|
-
agents pty screen $SID --json
|
|
206
|
+
.option('--json', 'Output as JSON (includes cursor position and dimensions)');
|
|
207
|
+
setHelpSections(screenCmd, {
|
|
208
|
+
examples: `
|
|
209
|
+
# See what's currently on screen
|
|
210
|
+
agents pty screen $SID
|
|
207
211
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
# Get screen with cursor position as JSON
|
|
213
|
+
agents pty screen $SID --json
|
|
214
|
+
`,
|
|
215
|
+
notes: `
|
|
216
|
+
Use this (not read) when you want clean text for an LLM to parse.
|
|
217
|
+
`,
|
|
218
|
+
});
|
|
219
|
+
screenCmd.action(async (id, opts) => {
|
|
211
220
|
const res = await ptyRequest('screen', id);
|
|
212
221
|
if (!res.ok) {
|
|
213
222
|
console.error(chalk.red(res.error));
|
|
@@ -220,21 +229,22 @@ Use this (not read) when you want clean text for an LLM to parse.
|
|
|
220
229
|
console.log(res.screen);
|
|
221
230
|
}
|
|
222
231
|
});
|
|
223
|
-
pty
|
|
232
|
+
const signalCmd = pty
|
|
224
233
|
.command('signal <id> [signal]')
|
|
225
|
-
.description('Send a POSIX signal to the running process. Defaults to INT (Ctrl-C).')
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
234
|
+
.description('Send a POSIX signal to the running process. Defaults to INT (Ctrl-C).');
|
|
235
|
+
setHelpSections(signalCmd, {
|
|
236
|
+
examples: `
|
|
237
|
+
# Send Ctrl-C (interrupt)
|
|
238
|
+
agents pty signal $SID INT
|
|
230
239
|
|
|
231
|
-
|
|
232
|
-
|
|
240
|
+
# Terminate gracefully
|
|
241
|
+
agents pty signal $SID TERM
|
|
233
242
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
243
|
+
# Force kill
|
|
244
|
+
agents pty signal $SID KILL
|
|
245
|
+
`,
|
|
246
|
+
});
|
|
247
|
+
signalCmd.action(async (id, signal) => {
|
|
238
248
|
const res = await ptyRequest('signal', id, { signal: signal || 'INT' });
|
|
239
249
|
if (!res.ok) {
|
|
240
250
|
console.error(chalk.red(res.error));
|
|
@@ -259,14 +269,16 @@ Examples:
|
|
|
259
269
|
}
|
|
260
270
|
console.log(`${res.cols}x${res.rows}`);
|
|
261
271
|
});
|
|
262
|
-
pty
|
|
272
|
+
const stopCmd = pty
|
|
263
273
|
.command('stop <id>')
|
|
264
|
-
.description('Stop a PTY session and clean up. The session ID becomes invalid.')
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
274
|
+
.description('Stop a PTY session and clean up. The session ID becomes invalid.');
|
|
275
|
+
setHelpSections(stopCmd, {
|
|
276
|
+
examples: `
|
|
277
|
+
# Stop a session by ID
|
|
278
|
+
agents pty stop $SID
|
|
279
|
+
`,
|
|
280
|
+
});
|
|
281
|
+
stopCmd.action(async (id) => {
|
|
270
282
|
const res = await ptyRequest('stop', id);
|
|
271
283
|
if (!res.ok) {
|
|
272
284
|
console.error(chalk.red(res.error));
|
|
@@ -274,15 +286,17 @@ Example:
|
|
|
274
286
|
}
|
|
275
287
|
});
|
|
276
288
|
// --- Session listing ---
|
|
277
|
-
pty
|
|
289
|
+
const listCmd = pty
|
|
278
290
|
.command('list')
|
|
279
291
|
.description('List all active PTY sessions (running or idle).')
|
|
280
|
-
.option('--json', 'Output as JSON')
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
292
|
+
.option('--json', 'Output as JSON');
|
|
293
|
+
setHelpSections(listCmd, {
|
|
294
|
+
examples: `
|
|
295
|
+
# List all active sessions
|
|
296
|
+
agents pty list
|
|
297
|
+
`,
|
|
298
|
+
});
|
|
299
|
+
listCmd.action(async (opts) => {
|
|
286
300
|
const res = await ptyRequest('list');
|
|
287
301
|
if (!res.ok) {
|
|
288
302
|
console.error(chalk.red(res.error));
|
package/dist/commands/pull.js
CHANGED
|
@@ -16,6 +16,7 @@ import * as path from 'path';
|
|
|
16
16
|
import { installVersion, listInstalledVersions, getGlobalDefault, setGlobalDefault, getVersionHomePath, syncResourcesToVersion, getAvailableResources, getActuallySyncedResources, getNewResources, hasNewResources, promptNewResourceSelection, promptResourceSelection, resolveConfiguredAgentTargets, } from '../lib/versions.js';
|
|
17
17
|
import { ensureShimCurrent, isShimsInPath, addShimsToPath, getPathSetupInstructions, switchConfigSymlink, switchHomeFileSymlinks, } from '../lib/shims.js';
|
|
18
18
|
import { parseHookManifest, registerHooksToSettings } from '../lib/hooks.js';
|
|
19
|
+
import { setHelpSections } from '../lib/help.js';
|
|
19
20
|
import { select } from '@inquirer/prompts';
|
|
20
21
|
import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
21
22
|
/**
|
|
@@ -45,37 +46,40 @@ function migratePromptcutsToRoot(agentsDir) {
|
|
|
45
46
|
}
|
|
46
47
|
/** Register the `agents pull` command. */
|
|
47
48
|
export function registerPullCommand(program) {
|
|
48
|
-
program
|
|
49
|
+
const pullCmd = program
|
|
49
50
|
.command('pull [agent]')
|
|
50
|
-
.description('
|
|
51
|
+
.description('Sync your user repo at ~/.agents/ and refresh installed agent CLIs. (Deprecated — prefer \'agents repo pull\' and \'agents setup\'.)')
|
|
51
52
|
.option('-y, --yes', 'Auto-sync all resources without prompting')
|
|
52
|
-
.option('--skip-clis', 'Pull config changes but do not install or upgrade agent CLIs')
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
.option('--skip-clis', 'Pull config changes but do not install or upgrade agent CLIs');
|
|
54
|
+
setHelpSections(pullCmd, {
|
|
55
|
+
examples: `
|
|
56
|
+
# First time: clone the system repo into ~/.agents-system/
|
|
57
|
+
agents pull
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
# Sync only one agent's config
|
|
60
|
+
agents pull claude
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
# Non-interactive (scripts / CI)
|
|
63
|
+
agents pull -y
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
# Sync config without touching installed CLI versions
|
|
66
|
+
agents pull --skip-clis
|
|
67
|
+
`,
|
|
68
|
+
notes: `
|
|
69
|
+
Deprecated. Use:
|
|
70
|
+
agents setup first-time setup
|
|
71
|
+
agents repo pull force-sync now
|
|
72
|
+
agents repo push push your user repo
|
|
68
73
|
|
|
69
|
-
What it syncs:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.action(async (arg1, options) => {
|
|
74
|
+
What it syncs:
|
|
75
|
+
- CLI versions listed in agents.yaml
|
|
76
|
+
- Commands, skills, hooks
|
|
77
|
+
- MCP server configs
|
|
78
|
+
- Memory/rules files
|
|
79
|
+
- Permissions groups
|
|
80
|
+
`,
|
|
81
|
+
});
|
|
82
|
+
pullCmd.action(async (arg1, options) => {
|
|
79
83
|
// Deprecation banner — `agents pull` is on its way out. agents-cli now
|
|
80
84
|
// auto-syncs the system repo in the background and surfaces upstream
|
|
81
85
|
// changes for user/extra repos as one-line notices. Repo lifecycle is
|
package/dist/commands/repo.js
CHANGED
|
@@ -6,6 +6,7 @@ import * as os from 'os';
|
|
|
6
6
|
import simpleGit from 'simple-git';
|
|
7
7
|
import { confirm, input } from '@inquirer/prompts';
|
|
8
8
|
import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
9
|
+
import { setHelpSections } from '../lib/help.js';
|
|
9
10
|
const HOME = os.homedir();
|
|
10
11
|
/**
|
|
11
12
|
* Resolve a target argument to an absolute path.
|
|
@@ -56,38 +57,35 @@ async function getShortCommit(repoDir) {
|
|
|
56
57
|
export function registerRepoCommands(program) {
|
|
57
58
|
const repoCmd = program
|
|
58
59
|
.command('repo')
|
|
59
|
-
.description('Manage extra DotAgent repos alongside ~/.agents/ (for private or team skills)')
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
wins on name collisions.
|
|
60
|
+
.description('Manage extra DotAgent repos alongside ~/.agents/ (for private or team skills).');
|
|
61
|
+
setHelpSections(repoCmd, {
|
|
62
|
+
examples: `
|
|
63
|
+
# Scaffold an editable repo (default: ~/.agents/)
|
|
64
|
+
agents repo init
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
agents repo init
|
|
66
|
+
# Scaffold a named repo at ~/.agents-work/
|
|
67
|
+
agents repo init work
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
# Register an existing repo (clones to ~/.agents-<alias>/)
|
|
70
|
+
agents repo add gh:yourname/.agents-work
|
|
72
71
|
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
# Register with a custom alias
|
|
73
|
+
agents repo add git@github.com:acme/team-skills.git --as acme
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
# See what's registered
|
|
76
|
+
agents repo list
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
# Temporarily disable without deleting
|
|
79
|
+
agents repo disable acme
|
|
80
|
+
`,
|
|
81
|
+
notes: `
|
|
82
|
+
Managed extras live at ~/.agents-<alias>/ as peer dirs to ~/.agents/. User-owned
|
|
83
|
+
repos can also live anywhere and be registered by path.
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
agents repo disable acme
|
|
87
|
-
|
|
88
|
-
# Unregister it
|
|
89
|
-
agents repo remove acme
|
|
90
|
-
`);
|
|
85
|
+
Resolution: skills/commands/hooks merge into agent version homes after the user
|
|
86
|
+
repo's, so ~/.agents/ wins on name collisions.
|
|
87
|
+
`,
|
|
88
|
+
});
|
|
91
89
|
repoCmd
|
|
92
90
|
.command('init [target]')
|
|
93
91
|
.description('Create a user-owned repo from a template and register it as an extra')
|
|
@@ -17,6 +17,7 @@ import { safeJoin } from '../lib/paths.js';
|
|
|
17
17
|
import { executeJob } from '../lib/runner.js';
|
|
18
18
|
import { JobScheduler } from '../lib/scheduler.js';
|
|
19
19
|
import { isInteractiveTerminal, requireInteractiveSelection } from './utils.js';
|
|
20
|
+
import { setHelpSections } from '../lib/help.js';
|
|
20
21
|
/** Start or reload the background scheduler so newly-added jobs fire on time. */
|
|
21
22
|
function ensureSchedulerRunning() {
|
|
22
23
|
if (isDaemonRunning()) {
|
|
@@ -75,36 +76,38 @@ async function pickJob(message, filter, alternatives = []) {
|
|
|
75
76
|
export function registerRoutinesCommands(program) {
|
|
76
77
|
const routinesCmd = program
|
|
77
78
|
.command('routines')
|
|
78
|
-
.description('Schedule agents to run on a cron schedule or at a specific time. The scheduler auto-starts on first add.')
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- what task to give the agent (the prompt)
|
|
84
|
-
- execution constraints (mode, effort, timeout)
|
|
79
|
+
.description('Schedule agents to run on a cron schedule or at a specific time. The scheduler auto-starts on first add.');
|
|
80
|
+
setHelpSections(routinesCmd, {
|
|
81
|
+
examples: `
|
|
82
|
+
# Cron routine: Claude every weekday at 9 AM (scheduler auto-starts)
|
|
83
|
+
agents routines add daily-standup --schedule "0 9 * * 1-5" --agent claude --prompt "Draft standup from git log"
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
# One-shot: Codex tomorrow at 2:30 PM, then never again
|
|
86
|
+
agents routines add hotfix-review --at "14:30" --agent codex --prompt "Review hotfix PR #42"
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
agents routines add daily-standup --schedule "0 9 * * 1-5" --agent claude --prompt "Draft standup update from git log"
|
|
88
|
+
# Create from YAML (for complex routines with multiple settings)
|
|
89
|
+
agents routines add weekly-report.yml
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
# List all routines and their next run times
|
|
92
|
+
agents routines list
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
# Run a routine right now in the foreground (ignores schedule)
|
|
95
|
+
agents routines run daily-standup
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
# Check whether the scheduler is running
|
|
98
|
+
agents routines status
|
|
99
|
+
`,
|
|
100
|
+
notes: `
|
|
101
|
+
A routine is a YAML file that schedules an agent invocation. It specifies:
|
|
102
|
+
- which agent to run (claude, codex, gemini, ...)
|
|
103
|
+
- when to run (cron schedule or one-shot time)
|
|
104
|
+
- what task to give the agent (the prompt)
|
|
105
|
+
- execution constraints (mode, effort, timeout)
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
agents routines run daily-standup
|
|
107
|
-
`);
|
|
107
|
+
The background scheduler auto-starts the first time you add a routine.
|
|
108
|
+
Manage it with 'agents routines start|stop|status'.
|
|
109
|
+
`,
|
|
110
|
+
});
|
|
108
111
|
routinesCmd
|
|
109
112
|
.command('list')
|
|
110
113
|
.description('See all scheduled jobs, when they run next, and their last execution status')
|
|
@@ -570,10 +573,10 @@ Examples:
|
|
|
570
573
|
.option('-f, --follow', 'Stream log output in real time (like tail -f)')
|
|
571
574
|
.action(async (options) => {
|
|
572
575
|
if (options.follow) {
|
|
573
|
-
const {
|
|
576
|
+
const { spawn } = await import('child_process');
|
|
574
577
|
const { getDaemonDir } = await import('../lib/state.js');
|
|
575
578
|
const logPath = path.join(getDaemonDir(), 'logs.jsonl');
|
|
576
|
-
const child =
|
|
579
|
+
const child = spawn('tail', ['-f', logPath]);
|
|
577
580
|
child.stdout?.pipe(process.stdout);
|
|
578
581
|
child.stderr?.pipe(process.stderr);
|
|
579
582
|
child.on('exit', () => process.exit(0));
|