@phnx-labs/agents-cli 1.20.72 → 1.20.74
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 +395 -0
- package/README.md +40 -4
- package/dist/bin/agents +0 -0
- package/dist/commands/activity.d.ts +12 -0
- package/dist/commands/activity.js +68 -0
- package/dist/commands/apply.d.ts +13 -0
- package/dist/commands/apply.js +28 -3
- package/dist/commands/browser.js +1 -1
- package/dist/commands/cloud.js +21 -11
- package/dist/commands/doctor.js +21 -5
- package/dist/commands/events.d.ts +11 -10
- package/dist/commands/events.js +30 -21
- package/dist/commands/exec.d.ts +34 -0
- package/dist/commands/exec.js +337 -39
- package/dist/commands/export.d.ts +11 -0
- package/dist/commands/export.js +215 -0
- package/dist/commands/feed.d.ts +13 -0
- package/dist/commands/feed.js +130 -29
- package/dist/commands/hq.d.ts +2 -0
- package/dist/commands/hq.js +58 -0
- package/dist/commands/import.js +51 -3
- package/dist/commands/lease.d.ts +19 -0
- package/dist/commands/lease.js +138 -11
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/mine.d.ts +27 -0
- package/dist/commands/mine.js +207 -0
- package/dist/commands/monitors.js +79 -49
- package/dist/commands/plugins.js +1 -0
- package/dist/commands/profiles.js +158 -0
- package/dist/commands/repo.js +2 -60
- package/dist/commands/resources.d.ts +5 -0
- package/dist/commands/resources.js +95 -0
- package/dist/commands/routines.d.ts +2 -0
- package/dist/commands/routines.js +139 -37
- package/dist/commands/secrets.js +234 -47
- package/dist/commands/send.d.ts +15 -0
- package/dist/commands/send.js +62 -0
- package/dist/commands/sessions-tail.d.ts +1 -0
- package/dist/commands/sessions-tail.js +20 -9
- package/dist/commands/sessions.js +18 -3
- package/dist/commands/setup-mine.d.ts +18 -0
- package/dist/commands/setup-mine.js +106 -0
- package/dist/commands/setup-share.js +2 -2
- package/dist/commands/setup.js +9 -2
- package/dist/commands/share.d.ts +8 -1
- package/dist/commands/share.js +122 -37
- package/dist/commands/ssh.d.ts +9 -0
- package/dist/commands/ssh.js +196 -26
- package/dist/commands/sync.js +1 -1
- package/dist/commands/teams.js +11 -2
- package/dist/commands/versions.js +36 -5
- package/dist/commands/view.js +75 -27
- package/dist/index.js +80 -10
- package/dist/lib/activity.d.ts +124 -0
- package/dist/lib/activity.js +542 -0
- package/dist/lib/agents.d.ts +35 -0
- package/dist/lib/agents.js +79 -6
- package/dist/lib/artifact-actions.d.ts +1 -1
- package/dist/lib/artifact-actions.js +1 -1
- package/dist/lib/ask-classifier.d.ts +2 -1
- package/dist/lib/ask-classifier.js +3 -3
- package/dist/lib/auth-health.d.ts +32 -4
- package/dist/lib/auth-health.js +40 -1
- package/dist/lib/auto-pull.js +8 -1
- package/dist/lib/brand.d.ts +40 -0
- package/dist/lib/brand.js +122 -0
- package/dist/lib/browser/drivers/ssh.js +4 -7
- package/dist/lib/browser/service.js +6 -8
- package/dist/lib/channels/providers/index.d.ts +2 -0
- package/dist/lib/channels/providers/index.js +20 -0
- package/dist/lib/channels/providers/mailbox.d.ts +2 -0
- package/dist/lib/channels/providers/mailbox.js +26 -0
- package/dist/lib/channels/providers/openclaw-telegram.d.ts +2 -0
- package/dist/lib/channels/providers/openclaw-telegram.js +34 -0
- package/dist/lib/channels/providers/rush.d.ts +6 -0
- package/dist/lib/channels/providers/rush.js +55 -0
- package/dist/lib/channels/registry.d.ts +42 -0
- package/dist/lib/channels/registry.js +20 -0
- package/dist/lib/channels/resolve.d.ts +11 -0
- package/dist/lib/channels/resolve.js +12 -0
- package/dist/lib/cli-resources.d.ts +18 -0
- package/dist/lib/cli-resources.js +53 -4
- package/dist/lib/cloud/codex.js +6 -3
- package/dist/lib/cloud/factory.d.ts +1 -0
- package/dist/lib/cloud/factory.js +10 -4
- package/dist/lib/cloud/rush.d.ts +3 -1
- package/dist/lib/cloud/rush.js +6 -1
- package/dist/lib/cloud/types.d.ts +2 -0
- package/dist/lib/codex-home.d.ts +35 -0
- package/dist/lib/codex-home.js +136 -0
- package/dist/lib/config-transfer.d.ts +16 -0
- package/dist/lib/config-transfer.js +56 -0
- package/dist/lib/crabbox/cli.d.ts +44 -0
- package/dist/lib/crabbox/cli.js +120 -20
- package/dist/lib/crabbox/lease.d.ts +52 -1
- package/dist/lib/crabbox/lease.js +117 -16
- package/dist/lib/crabbox/progress.d.ts +31 -0
- package/dist/lib/crabbox/progress.js +76 -0
- package/dist/lib/crabbox/runtimes.d.ts +4 -0
- package/dist/lib/crabbox/runtimes.js +33 -8
- package/dist/lib/crabbox/setup-copy.d.ts +87 -0
- package/dist/lib/crabbox/setup-copy.js +127 -0
- package/dist/lib/daemon.d.ts +5 -5
- package/dist/lib/daemon.js +9 -9
- package/dist/lib/drive-sync.js +6 -3
- package/dist/lib/event-stream.d.ts +36 -0
- package/dist/lib/event-stream.js +68 -0
- package/dist/lib/events.d.ts +1 -1
- package/dist/lib/exec.d.ts +11 -0
- package/dist/lib/exec.js +23 -2
- package/dist/lib/export.d.ts +72 -0
- package/dist/lib/export.js +269 -0
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +14 -9
- package/dist/lib/feed-ranking.d.ts +32 -0
- package/dist/lib/feed-ranking.js +224 -0
- package/dist/lib/feed.d.ts +35 -2
- package/dist/lib/feed.js +66 -3
- package/dist/lib/fleet/auth-sync.d.ts +53 -0
- package/dist/lib/fleet/auth-sync.js +92 -0
- package/dist/lib/fleet/remote-login.d.ts +187 -0
- package/dist/lib/fleet/remote-login.js +556 -0
- package/dist/lib/format.d.ts +30 -3
- package/dist/lib/format.js +34 -5
- package/dist/lib/fs-atomic.d.ts +7 -2
- package/dist/lib/fs-atomic.js +8 -12
- package/dist/lib/git.d.ts +16 -0
- package/dist/lib/git.js +79 -2
- package/dist/lib/heal.js +11 -3
- package/dist/lib/hosts/progress.d.ts +28 -10
- package/dist/lib/hosts/progress.js +79 -22
- package/dist/lib/hosts/remote-cmd.js +4 -0
- package/dist/lib/hq/floor.d.ts +87 -0
- package/dist/lib/hq/floor.js +226 -0
- package/dist/lib/import.d.ts +23 -0
- package/dist/lib/import.js +74 -2
- package/dist/lib/isolation-boundary-report.d.ts +10 -0
- package/dist/lib/isolation-boundary-report.js +35 -0
- package/dist/lib/menubar/install-menubar.js +14 -20
- package/dist/lib/notify.d.ts +1 -0
- package/dist/lib/notify.js +3 -3
- package/dist/lib/open-url.d.ts +2 -0
- package/dist/lib/open-url.js +19 -0
- package/dist/lib/openclaw-keychain.d.ts +56 -0
- package/dist/lib/openclaw-keychain.js +236 -0
- package/dist/lib/overdue.js +10 -0
- package/dist/lib/permissions.d.ts +44 -1
- package/dist/lib/permissions.js +284 -7
- package/dist/lib/project-launch.d.ts +6 -12
- package/dist/lib/project-launch.js +13 -228
- package/dist/lib/project-resources.d.ts +7 -0
- package/dist/lib/project-resources.js +306 -0
- package/dist/lib/pty-client.d.ts +27 -0
- package/dist/lib/pty-client.js +136 -10
- package/dist/lib/refresh.js +14 -10
- package/dist/lib/resource-profiles.d.ts +26 -0
- package/dist/lib/resource-profiles.js +157 -0
- package/dist/lib/resources/permissions.js +7 -1
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +1 -1
- package/dist/lib/resources.js +32 -3
- package/dist/lib/routines.d.ts +11 -0
- package/dist/lib/routines.js +56 -15
- package/dist/lib/runner.d.ts +1 -0
- package/dist/lib/runner.js +66 -5
- package/dist/lib/secrets/bundles.d.ts +16 -3
- package/dist/lib/secrets/bundles.js +206 -37
- package/dist/lib/secrets/icloud-import.d.ts +2 -2
- package/dist/lib/secrets/icloud-import.js +9 -6
- package/dist/lib/secrets/mcp.js +1 -1
- package/dist/lib/secrets/vault-age-helper.d.ts +1 -0
- package/dist/lib/secrets/vault-age-helper.js +34 -0
- package/dist/lib/secrets/vault.d.ts +49 -0
- package/dist/lib/secrets/vault.js +397 -0
- package/dist/lib/self-heal/checks/path.js +3 -1
- package/dist/lib/self-heal/checks/shadowing.js +10 -2
- package/dist/lib/self-heal/checks/shims.js +19 -11
- package/dist/lib/session/cloud.d.ts +2 -2
- package/dist/lib/session/cloud.js +2 -2
- package/dist/lib/session/db.d.ts +4 -0
- package/dist/lib/session/db.js +44 -7
- package/dist/lib/session/discover.d.ts +2 -0
- package/dist/lib/session/discover.js +114 -3
- package/dist/lib/session/stream-render.d.ts +3 -0
- package/dist/lib/session/stream-render.js +130 -0
- package/dist/lib/session/types.d.ts +6 -0
- package/dist/lib/share/analytics.d.ts +13 -0
- package/dist/lib/share/analytics.js +45 -0
- package/dist/lib/share/config.d.ts +19 -5
- package/dist/lib/share/config.js +44 -8
- package/dist/lib/share/provision.d.ts +58 -6
- package/dist/lib/share/provision.js +97 -22
- package/dist/lib/share/publish.d.ts +36 -13
- package/dist/lib/share/publish.js +55 -8
- package/dist/lib/share/worker-template.js +83 -17
- package/dist/lib/shims.d.ts +35 -0
- package/dist/lib/shims.js +159 -13
- package/dist/lib/ssh-exec.d.ts +14 -0
- package/dist/lib/ssh-exec.js +57 -0
- package/dist/lib/staleness/detectors/hooks.js +25 -1
- package/dist/lib/staleness/detectors/permissions.js +66 -0
- package/dist/lib/staleness/detectors/workflows.js +20 -0
- package/dist/lib/staleness/writers/hooks.js +58 -4
- package/dist/lib/staleness/writers/permissions.js +2 -2
- package/dist/lib/staleness/writers/skills.js +1 -1
- package/dist/lib/staleness/writers/sources.d.ts +10 -1
- package/dist/lib/staleness/writers/sources.js +68 -1
- package/dist/lib/star-nudge.d.ts +45 -0
- package/dist/lib/star-nudge.js +91 -0
- package/dist/lib/startup/command-registry.d.ts +7 -1
- package/dist/lib/startup/command-registry.js +19 -3
- package/dist/lib/state.d.ts +2 -0
- package/dist/lib/state.js +17 -4
- package/dist/lib/subagents-registry.d.ts +2 -0
- package/dist/lib/subagents-registry.js +3 -0
- package/dist/lib/teams/parsers.js +214 -6
- package/dist/lib/teams/supervisor.d.ts +7 -0
- package/dist/lib/teams/supervisor.js +2 -1
- package/dist/lib/template.d.ts +1 -1
- package/dist/lib/template.js +1 -1
- package/dist/lib/triggers/webhook.js +36 -3
- package/dist/lib/types.d.ts +84 -0
- package/dist/lib/uninstall.js +1 -45
- package/dist/lib/version.d.ts +40 -0
- package/dist/lib/version.js +94 -16
- package/dist/lib/versions.d.ts +24 -0
- package/dist/lib/versions.js +269 -78
- package/dist/lib/workflows.d.ts +2 -0
- package/dist/lib/workflows.js +88 -0
- package/package.json +2 -1
- package/dist/commands/daemon.d.ts +0 -10
- package/dist/commands/daemon.js +0 -121
package/dist/commands/apply.js
CHANGED
|
@@ -267,9 +267,13 @@ function reportResults(results) {
|
|
|
267
267
|
}
|
|
268
268
|
console.log(chalk.green('Fleet reconciled.'));
|
|
269
269
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
/**
|
|
271
|
+
* Attach the reconcile options + action to a command node. Shared by the
|
|
272
|
+
* top-level `agents apply` and its `agents fleet apply` alias so the two can
|
|
273
|
+
* never drift — identical flags, identical engine.
|
|
274
|
+
*/
|
|
275
|
+
export function configureApplyCommand(cmd) {
|
|
276
|
+
return cmd
|
|
273
277
|
.description('Reconcile the fleet to a declared profile: install agents, sync config, propagate login.')
|
|
274
278
|
.option('-f, --file <path>', 'Manifest file carrying a fleet: block (default: agents.yaml)')
|
|
275
279
|
.option('--plan', 'Show the reconcile plan and exit (no changes)')
|
|
@@ -292,6 +296,9 @@ export function registerApplyCommand(program) {
|
|
|
292
296
|
process.exit(1);
|
|
293
297
|
}
|
|
294
298
|
});
|
|
299
|
+
}
|
|
300
|
+
export function registerApplyCommand(program) {
|
|
301
|
+
const applyCmd = configureApplyCommand(program.command('apply'));
|
|
295
302
|
setHelpSections(applyCmd, {
|
|
296
303
|
examples: `
|
|
297
304
|
# Preview what would change across the fleet
|
|
@@ -305,3 +312,21 @@ export function registerApplyCommand(program) {
|
|
|
305
312
|
`,
|
|
306
313
|
});
|
|
307
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Surface `agents apply` under the fleet command tree as `agents fleet apply`
|
|
317
|
+
* (and `agents devices apply`). Same reconcile engine as the top-level command —
|
|
318
|
+
* a discoverability alias for users who reach for `fleet` as the verb. Kept in
|
|
319
|
+
* lockstep via {@link configureApplyCommand}.
|
|
320
|
+
*/
|
|
321
|
+
export function registerFleetApplyAlias(devicesCmd) {
|
|
322
|
+
const sub = configureApplyCommand(devicesCmd.command('apply'));
|
|
323
|
+
setHelpSections(sub, {
|
|
324
|
+
examples: `
|
|
325
|
+
# Preview the fleet reconcile
|
|
326
|
+
agents fleet apply --plan
|
|
327
|
+
|
|
328
|
+
# Reconcile every device to the profile
|
|
329
|
+
agents fleet apply -y
|
|
330
|
+
`,
|
|
331
|
+
});
|
|
332
|
+
}
|
package/dist/commands/browser.js
CHANGED
|
@@ -1420,7 +1420,7 @@ function registerTaskCommands(browser) {
|
|
|
1420
1420
|
process.exit(1);
|
|
1421
1421
|
}
|
|
1422
1422
|
try {
|
|
1423
|
-
const { env } = readAndResolveBundleEnv(parsed.bundle, { caller: 'browser type', keys: [parsed.key], agentOnly: isHeadlessSecretsContext() });
|
|
1423
|
+
const { env } = readAndResolveBundleEnv(parsed.bundle, { caller: 'browser type', keys: [parsed.key], keyMode: 'storage', agentOnly: isHeadlessSecretsContext() });
|
|
1424
1424
|
if (!(parsed.key in env)) {
|
|
1425
1425
|
console.error(`Key "${parsed.key}" not in bundle "${parsed.bundle}".`);
|
|
1426
1426
|
process.exit(1);
|
package/dist/commands/cloud.js
CHANGED
|
@@ -10,6 +10,7 @@ import { MissingTargetError, MAX_IMAGES_PER_DISPATCH } from '../lib/cloud/types.
|
|
|
10
10
|
import { normalizeTriggerEvent, validateTrigger, writeJob, jobExists, GITHUB_TRIGGER_EVENTS } from '../lib/routines.js';
|
|
11
11
|
import { machineId } from '../lib/machine-id.js';
|
|
12
12
|
import { emit } from '../lib/events.js';
|
|
13
|
+
import { shareRuntimeEnv } from '../lib/share/config.js';
|
|
13
14
|
/** Map a supported image file extension to its wire mimeType. Rejects anything else. */
|
|
14
15
|
function imageMimeFromPath(file) {
|
|
15
16
|
const ext = path.extname(file).toLowerCase();
|
|
@@ -155,6 +156,8 @@ Examples:
|
|
|
155
156
|
})
|
|
156
157
|
.option('--branch <name>', 'Target git branch')
|
|
157
158
|
.option('--on <event>', 'Register this run as an event trigger instead of dispatching now: pull_request (pr), push, issue_comment, workflow_run. Persists a trigger-bound routine.')
|
|
159
|
+
.option('--action <name>', 'GitHub webhook action filter for --on triggers (e.g. labeled)')
|
|
160
|
+
.option('--label <name>', 'GitHub label filter for --on triggers')
|
|
158
161
|
.option('--name <name>', 'Routine name to register under (with --on). Defaults to a generated name.')
|
|
159
162
|
.option('-p, --prompt <text>', 'Inline prompt (alternative to positional argument)')
|
|
160
163
|
.option('--timeout <duration>', 'Kill after duration (e.g., 30m, 2h)')
|
|
@@ -205,7 +208,7 @@ Examples:
|
|
|
205
208
|
// Resolve prompt: --prompt flag, positional arg, or file
|
|
206
209
|
let prompt = options.prompt || positionalPrompt;
|
|
207
210
|
if (!prompt)
|
|
208
|
-
die('Prompt is required. Pass it as an argument or with --prompt.');
|
|
211
|
+
die('Prompt is required. Pass it as an argument or with --prompt.', 1, { json, hint: 'agents cloud run "<task>" --repo <owner/repo>' });
|
|
209
212
|
// If prompt is a file path, read it and tell the user
|
|
210
213
|
if (fs.existsSync(prompt) && fs.statSync(prompt).isFile()) {
|
|
211
214
|
const filePath = prompt;
|
|
@@ -220,7 +223,7 @@ Examples:
|
|
|
220
223
|
// something to the host provider, so it implies --provider host rather
|
|
221
224
|
// than silently riding along to a cloud backend that would ignore it.
|
|
222
225
|
if (options.host && options.provider && options.provider !== 'host') {
|
|
223
|
-
die(`--host targets your own machines (--provider host), not ${options.provider}. Drop --host, or use --provider host
|
|
226
|
+
die(`--host targets your own machines (--provider host), not ${options.provider}. Drop --host, or use --provider host.`, 1, { json });
|
|
224
227
|
}
|
|
225
228
|
const explicitProvider = options.provider ?? (options.host ? 'host' : undefined);
|
|
226
229
|
// Agent-aware: with no --provider, the agent routes to its native cloud
|
|
@@ -245,6 +248,9 @@ Examples:
|
|
|
245
248
|
model: options.model,
|
|
246
249
|
providerOptions: {},
|
|
247
250
|
};
|
|
251
|
+
const shareEnv = shareRuntimeEnv({ agentOnly: true });
|
|
252
|
+
if (shareEnv)
|
|
253
|
+
dispatchOptions.env = shareEnv;
|
|
248
254
|
if (options.env)
|
|
249
255
|
dispatchOptions.providerOptions.env = options.env;
|
|
250
256
|
if (options.computer)
|
|
@@ -272,21 +278,25 @@ Examples:
|
|
|
272
278
|
if (options.on) {
|
|
273
279
|
const event = normalizeTriggerEvent(options.on);
|
|
274
280
|
if (!event) {
|
|
275
|
-
die(`Unknown --on event "${options.on}". Use one of: ${GITHUB_TRIGGER_EVENTS.join(', ')} (aliases: pr, comment, workflow)
|
|
281
|
+
die(`Unknown --on event "${options.on}". Use one of: ${GITHUB_TRIGGER_EVENTS.join(', ')} (aliases: pr, comment, workflow).`, 1, { json });
|
|
276
282
|
}
|
|
277
283
|
const trigger = { type: 'github_event', event: event };
|
|
278
284
|
if (repoValues[0])
|
|
279
285
|
trigger.repo = repoValues[0];
|
|
280
286
|
if (options.branch)
|
|
281
287
|
trigger.branch = options.branch;
|
|
288
|
+
if (options.action)
|
|
289
|
+
trigger.action = options.action;
|
|
290
|
+
if (options.label)
|
|
291
|
+
trigger.label = options.label;
|
|
282
292
|
const triggerErrors = validateTrigger(trigger);
|
|
283
293
|
if (triggerErrors.length > 0)
|
|
284
|
-
die(`Invalid trigger: ${triggerErrors.join(', ')}
|
|
294
|
+
die(`Invalid trigger: ${triggerErrors.join(', ')}`, 1, { json });
|
|
285
295
|
dispatchOptions.trigger = trigger;
|
|
286
296
|
const routineName = options.name
|
|
287
297
|
|| `cloud-${event}-${(repoValues[0] || 'any').replace(/[^a-z0-9]+/gi, '-')}`.toLowerCase();
|
|
288
298
|
if (jobExists(routineName)) {
|
|
289
|
-
die(`A routine named "${routineName}" already exists. Pass --name to register under a different name
|
|
299
|
+
die(`A routine named "${routineName}" already exists. Pass --name to register under a different name.`, 1, { json });
|
|
290
300
|
}
|
|
291
301
|
const routine = {
|
|
292
302
|
name: routineName,
|
|
@@ -329,15 +339,15 @@ Examples:
|
|
|
329
339
|
const caps = provider.capabilities();
|
|
330
340
|
if (imagePaths.length > 0) {
|
|
331
341
|
if (!caps.images)
|
|
332
|
-
die(`${provider.name} does not support image attachments
|
|
342
|
+
die(`${provider.name} does not support image attachments.`, 1, { json });
|
|
333
343
|
if (imagePaths.length > MAX_IMAGES_PER_DISPATCH) {
|
|
334
|
-
die(`Too many images: ${imagePaths.length}. Max is ${MAX_IMAGES_PER_DISPATCH} per dispatch
|
|
344
|
+
die(`Too many images: ${imagePaths.length}. Max is ${MAX_IMAGES_PER_DISPATCH} per dispatch.`, 1, { json });
|
|
335
345
|
}
|
|
336
346
|
dispatchOptions.images = imagePaths.map(readImageAttachment);
|
|
337
347
|
}
|
|
338
348
|
if (skillIds.length > 0) {
|
|
339
349
|
if (!caps.skills)
|
|
340
|
-
die(`${provider.name} does not support ride-along skills
|
|
350
|
+
die(`${provider.name} does not support ride-along skills.`, 1, { json });
|
|
341
351
|
dispatchOptions.skills = skillIds.map(parseSkillRef);
|
|
342
352
|
}
|
|
343
353
|
// Dispatch. On a missing pre-provisioned target (Codex env / Factory
|
|
@@ -362,18 +372,18 @@ Examples:
|
|
|
362
372
|
if (err instanceof MissingTargetError) {
|
|
363
373
|
const picked = await pickMissingTarget(provider, err, json);
|
|
364
374
|
if (!picked) {
|
|
365
|
-
die(err.guidance ? `${err.message}\n\n${err.guidance}` : err.message);
|
|
375
|
+
die(err.guidance ? `${err.message}\n\n${err.guidance}` : err.message, 1, { json });
|
|
366
376
|
}
|
|
367
377
|
dispatchOptions.providerOptions[err.kind] = picked;
|
|
368
378
|
try {
|
|
369
379
|
task = await dispatchOnce();
|
|
370
380
|
}
|
|
371
381
|
catch (err2) {
|
|
372
|
-
die(err2.message);
|
|
382
|
+
die(err2.message, 1, { json });
|
|
373
383
|
}
|
|
374
384
|
}
|
|
375
385
|
else {
|
|
376
|
-
die(err.message);
|
|
386
|
+
die(err.message, 1, { json });
|
|
377
387
|
}
|
|
378
388
|
}
|
|
379
389
|
// Persist locally
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IsolationBoundaryError } from '../lib/shims.js';
|
|
2
|
+
import { explainIsolationBoundary } from '../lib/isolation-boundary-report.js';
|
|
1
3
|
import { addHostOption } from '../lib/hosts/option.js';
|
|
2
4
|
import { buildRemoteAgentsInvocation } from '../lib/hosts/remote-cmd.js';
|
|
3
5
|
import { loadDevices, isControlDevice } from '../lib/devices/registry.js';
|
|
@@ -352,13 +354,13 @@ function parseTargetArg(arg) {
|
|
|
352
354
|
const versions = listInstalledVersions(agent);
|
|
353
355
|
if (versions.length === 0)
|
|
354
356
|
return { error: `${AGENTS[agent].name} has no installed versions. Run \`agents add ${agent}@<version>\` first.` };
|
|
355
|
-
return { agent, versions };
|
|
357
|
+
return { agent, versions, versionExplicit: false };
|
|
356
358
|
}
|
|
357
359
|
if (versionPart === 'default') {
|
|
358
360
|
const def = getGlobalDefault(agent);
|
|
359
361
|
if (!def)
|
|
360
362
|
return { error: `${AGENTS[agent].name} has no default version pinned. Run \`agents use ${agent}@<version>\`.` };
|
|
361
|
-
return { agent, versions: [def] };
|
|
363
|
+
return { agent, versions: [def], versionExplicit: true };
|
|
362
364
|
}
|
|
363
365
|
const spec = parseAgentSpec(`${agent}@${versionPart}`);
|
|
364
366
|
if (!spec)
|
|
@@ -366,7 +368,7 @@ function parseTargetArg(arg) {
|
|
|
366
368
|
if (!isVersionInstalled(agent, versionPart)) {
|
|
367
369
|
return { error: `${AGENTS[agent].name}@${versionPart} is not installed. Installed: ${listInstalledVersions(agent).join(', ') || '(none)'}` };
|
|
368
370
|
}
|
|
369
|
-
return { agent, versions: [versionPart] };
|
|
371
|
+
return { agent, versions: [versionPart], versionExplicit: true };
|
|
370
372
|
}
|
|
371
373
|
function parseKindFilter(arg) {
|
|
372
374
|
if (!arg)
|
|
@@ -601,10 +603,14 @@ async function runFix(parsed, opts) {
|
|
|
601
603
|
// left to heal's neutral default rather than process.cwd().
|
|
602
604
|
if (!opts.json)
|
|
603
605
|
console.log(chalk.bold('Healing…'));
|
|
606
|
+
// `agents doctor <agent> --fix` is a SWEEP, same as the bare form — leave the
|
|
607
|
+
// version list to heal() so it applies its isolated-copy filter. Passing the
|
|
608
|
+
// enumerated list here would smuggle isolated versions past that filter.
|
|
609
|
+
// A named version (`<agent>@<version>`) is explicit consent and is passed through.
|
|
604
610
|
const result = await heal({
|
|
605
611
|
mode: 'full',
|
|
606
612
|
agent: parsed?.agent,
|
|
607
|
-
versions: parsed?.versions,
|
|
613
|
+
versions: parsed?.versionExplicit ? parsed.versions : undefined,
|
|
608
614
|
});
|
|
609
615
|
if (opts.json) {
|
|
610
616
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -686,7 +692,17 @@ export function registerDoctorCommand(program) {
|
|
|
686
692
|
// adoptShadowingLauncher resolves the launcher itself (PATH shadow, then
|
|
687
693
|
// the durable ~/.local/bin symlink), so it forces the take-over even when
|
|
688
694
|
// this shell's PATH already has the shim first.
|
|
689
|
-
|
|
695
|
+
let result;
|
|
696
|
+
try {
|
|
697
|
+
result = adoptShadowingLauncher(agent);
|
|
698
|
+
}
|
|
699
|
+
catch (err) {
|
|
700
|
+
if (err instanceof IsolationBoundaryError) {
|
|
701
|
+
explainIsolationBoundary(err);
|
|
702
|
+
process.exit(1);
|
|
703
|
+
}
|
|
704
|
+
throw err;
|
|
705
|
+
}
|
|
690
706
|
if (result.adopted) {
|
|
691
707
|
console.log(chalk.green(`Adopted ${AGENTS[agent].cliCommand} launcher (${result.launcher} -> shim). Original recorded for --release; version management now wins regardless of PATH order.`));
|
|
692
708
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agents events` — read the
|
|
2
|
+
* `agents events` — read the unified event stream.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* `agents <module> <cmd>` invocation plus
|
|
6
|
-
* version installs
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* One stream over BOTH operational events (`~/.agents/events.jsonl`: every
|
|
5
|
+
* `agents <module> <cmd>` invocation plus typed events like secrets access,
|
|
6
|
+
* version installs) AND agent-semantic events (the per-session activity logs:
|
|
7
|
+
* plans, PRs, worktrees, sub-agents, artifacts). Each is stamped with who ran
|
|
8
|
+
* it and from where. This is the audit trail for "who accessed a secret /
|
|
9
|
+
* created a team" AND the activity trail for "what did the agents just do".
|
|
10
10
|
*
|
|
11
|
-
* Filter by `--module` (top-level group, e.g. teams
|
|
12
|
-
*
|
|
13
|
-
* `--
|
|
11
|
+
* Filter by `--module` (top-level group, e.g. teams; `activity` for agent
|
|
12
|
+
* events), `--command` (path prefix), `--event` (typed event), `--agent`, and
|
|
13
|
+
* `--since`. `--audit` restricts to operational events only. `--follow` tails
|
|
14
|
+
* today's operational log live.
|
|
14
15
|
*/
|
|
15
16
|
import type { Command } from 'commander';
|
|
16
17
|
export declare function registerEventsCommand(program: Command): void;
|
package/dist/commands/events.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agents events` — read the
|
|
2
|
+
* `agents events` — read the unified event stream.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* `agents <module> <cmd>` invocation plus
|
|
6
|
-
* version installs
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* One stream over BOTH operational events (`~/.agents/events.jsonl`: every
|
|
5
|
+
* `agents <module> <cmd>` invocation plus typed events like secrets access,
|
|
6
|
+
* version installs) AND agent-semantic events (the per-session activity logs:
|
|
7
|
+
* plans, PRs, worktrees, sub-agents, artifacts). Each is stamped with who ran
|
|
8
|
+
* it and from where. This is the audit trail for "who accessed a secret /
|
|
9
|
+
* created a team" AND the activity trail for "what did the agents just do".
|
|
10
10
|
*
|
|
11
|
-
* Filter by `--module` (top-level group, e.g. teams
|
|
12
|
-
*
|
|
13
|
-
* `--
|
|
11
|
+
* Filter by `--module` (top-level group, e.g. teams; `activity` for agent
|
|
12
|
+
* events), `--command` (path prefix), `--event` (typed event), `--agent`, and
|
|
13
|
+
* `--since`. `--audit` restricts to operational events only. `--follow` tails
|
|
14
|
+
* today's operational log live.
|
|
14
15
|
*/
|
|
15
16
|
import chalk from 'chalk';
|
|
16
17
|
import * as fs from 'fs';
|
|
17
|
-
import {
|
|
18
|
+
import { getLogsPath } from '../lib/events.js';
|
|
19
|
+
import { readUnifiedEvents } from '../lib/event-stream.js';
|
|
18
20
|
/** Parse `--since`: relative offsets (30s/5m/2h/7d/4w) or an ISO/absolute date. */
|
|
19
21
|
function parseSince(s) {
|
|
20
22
|
const m = s.match(/^(\d+)([smhdw])$/);
|
|
@@ -42,6 +44,11 @@ function detailFor(r) {
|
|
|
42
44
|
if (r.command)
|
|
43
45
|
return r.command;
|
|
44
46
|
const bits = [];
|
|
47
|
+
// Agent-semantic (activity) events carry detail/url instead of a command.
|
|
48
|
+
if (typeof r.detail === 'string')
|
|
49
|
+
bits.push(r.detail);
|
|
50
|
+
if (typeof r.url === 'string')
|
|
51
|
+
bits.push(chalk.gray(r.url));
|
|
45
52
|
if (typeof r.team === 'string')
|
|
46
53
|
bits.push(`team=${r.team}`);
|
|
47
54
|
if (typeof r.bundle === 'string')
|
|
@@ -66,23 +73,24 @@ function renderRow(r) {
|
|
|
66
73
|
export function registerEventsCommand(program) {
|
|
67
74
|
program
|
|
68
75
|
.command('events')
|
|
69
|
-
.description('Read the
|
|
70
|
-
.option('--module <name>', 'Only events from this
|
|
76
|
+
.description('Read the unified event stream (operational + agent activity)')
|
|
77
|
+
.option('--module <name>', 'Only events from this group (e.g. teams, secrets, activity)')
|
|
71
78
|
.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, [])
|
|
79
|
+
.option('--event <type>', 'Only this typed event (repeatable, e.g. secrets.get, pr.opened)', collect, [])
|
|
73
80
|
.option('--agent <name>', 'Only events tagged with this agent')
|
|
74
81
|
.option('--since <time>', 'Only events newer than this (e.g. 2h, 7d, or ISO date)')
|
|
82
|
+
.option('--audit', 'Operational events only (skip agent activity)')
|
|
75
83
|
.option('--limit <n>', 'Max records to show (default 50)', '50')
|
|
76
84
|
.option('--json', 'Output raw records as JSON')
|
|
77
|
-
.option('-f, --follow', "Tail today's log live")
|
|
85
|
+
.option('-f, --follow', "Tail today's operational log live")
|
|
78
86
|
.addHelpText('after', `
|
|
79
87
|
Examples:
|
|
80
|
-
agents events
|
|
81
|
-
agents events --module
|
|
88
|
+
agents events Everything — ops + agent activity
|
|
89
|
+
agents events --module activity Agent activity only (plans / PRs / worktrees)
|
|
90
|
+
agents events --audit Operational events only (secrets / teams / ...)
|
|
91
|
+
agents events --event pr.opened --since 7d
|
|
82
92
|
agents events --module secrets Every secret accessed or revealed
|
|
83
|
-
agents events
|
|
84
|
-
agents events --event secrets.get --since 7d --json
|
|
85
|
-
agents events -f Live tail`)
|
|
93
|
+
agents events -f Live tail (operational)`)
|
|
86
94
|
.action(async (options) => {
|
|
87
95
|
if (options.follow) {
|
|
88
96
|
await followLog();
|
|
@@ -97,13 +105,14 @@ Examples:
|
|
|
97
105
|
console.error(chalk.red(err.message));
|
|
98
106
|
process.exit(2);
|
|
99
107
|
}
|
|
100
|
-
const records =
|
|
108
|
+
const records = readUnifiedEvents({
|
|
101
109
|
startDate,
|
|
102
110
|
eventTypes: options.event && options.event.length ? options.event : undefined,
|
|
103
111
|
agent: options.agent,
|
|
104
112
|
command: options.command,
|
|
105
113
|
module: options.module,
|
|
106
114
|
limit,
|
|
115
|
+
includeActivity: !options.audit,
|
|
107
116
|
});
|
|
108
117
|
if (options.json) {
|
|
109
118
|
console.log(JSON.stringify(records, null, 2));
|
package/dist/commands/exec.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare function runAccountPickerConflicts(options: {
|
|
|
21
21
|
strategy?: string;
|
|
22
22
|
balanced?: boolean;
|
|
23
23
|
lease?: string | boolean;
|
|
24
|
+
box?: string;
|
|
24
25
|
host?: string;
|
|
25
26
|
device?: string;
|
|
26
27
|
on?: string;
|
|
@@ -34,6 +35,39 @@ export interface CopyCredsGateHost {
|
|
|
34
35
|
/** `devices` = registered Tailscale fleet host; `local` = ssh-config/inline. */
|
|
35
36
|
provider?: string;
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Whether `cwd` is inside a git work tree.
|
|
40
|
+
*
|
|
41
|
+
* `--lease` / `--box` sync the working directory to the box through crabbox,
|
|
42
|
+
* which enumerates the files to copy with `git ls-files`. Outside a git repo
|
|
43
|
+
* that exits 128 (`fatal: not a git repository`) and the whole run dies at
|
|
44
|
+
* "build sync file list: exit status 128" — AFTER the box is provisioned and
|
|
45
|
+
* billed. Checking this up front lets the caller fail fast, before provisioning.
|
|
46
|
+
*/
|
|
47
|
+
export declare function isInsideGitWorkTree(cwd: string): boolean;
|
|
48
|
+
/** Absolute git toplevel for `cwd`, or null when it is not a git repo. */
|
|
49
|
+
export declare function gitToplevel(cwd: string): string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Network mode for a `--lease` run (F5, RUSH-1924). `--tailscale` forces the
|
|
52
|
+
* tailnet, `--no-tailscale` forces public, and neither (undefined) defaults to
|
|
53
|
+
* the tailnet ONLY in a reuse context (`--reuse`, `--box`, or a picked warm
|
|
54
|
+
* box) — a one-shot solo `--lease` stays public. Pure so it is unit-testable;
|
|
55
|
+
* the caller downgrades to `'public'` when no auth key is configured.
|
|
56
|
+
*/
|
|
57
|
+
export declare function computeNetMode(opts: {
|
|
58
|
+
tailscale?: boolean;
|
|
59
|
+
reuseContext: boolean;
|
|
60
|
+
}): 'public' | 'tailscale';
|
|
61
|
+
/** True when `repoRoot` is in the remembered always-fresh set. Pure. */
|
|
62
|
+
export declare function isAlwaysFreshRepo(repos: string[], repoRoot: string): boolean;
|
|
63
|
+
/** Add `repoRoot` to the always-fresh set (idempotent). Pure. */
|
|
64
|
+
export declare function addAlwaysFreshRepo(repos: string[], repoRoot: string): string[];
|
|
65
|
+
/** Path to the always-fresh state file under the USER agents dir (CLI-written per-user preference, never the maintainer-owned `.system` repo). */
|
|
66
|
+
export declare function leaseFreshReposPath(): string;
|
|
67
|
+
/** Read the remembered always-fresh repo roots (empty on any read/parse error). */
|
|
68
|
+
export declare function readAlwaysFreshRepos(): string[];
|
|
69
|
+
/** Persist the always-fresh repo roots. Best-effort — never throws. */
|
|
70
|
+
export declare function writeAlwaysFreshRepos(repos: string[]): void;
|
|
37
71
|
/** Outcome of the `--copy-creds` security gate (RUSH-1767). */
|
|
38
72
|
export interface CopyCredsGateDecision {
|
|
39
73
|
/** Ship credentials? True only when the host key is pinned in the managed store. */
|