@phnx-labs/agents-cli 1.22.41 → 1.22.43
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 +86 -0
- package/README.md +10 -4
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +25 -7
- package/dist/cli/command-registry.d.ts +2 -3
- package/dist/cli/command-registry.js +4 -8
- package/dist/commands/accounts.d.ts +29 -0
- package/dist/commands/accounts.js +220 -29
- package/dist/commands/alias.d.ts +7 -4
- package/dist/commands/alias.js +34 -9
- package/dist/commands/auth.d.ts +9 -0
- package/dist/commands/auth.js +108 -0
- package/dist/commands/browser-sessions-picker.js +42 -62
- package/dist/commands/browser.js +30 -38
- package/dist/commands/computer-actions.d.ts +1 -1
- package/dist/commands/computer-actions.js +1 -1
- package/dist/commands/computer-sessions-picker.js +32 -55
- package/dist/commands/computer.d.ts +1 -1
- package/dist/commands/computer.js +22 -8
- package/dist/commands/daemon.js +1 -1
- package/dist/commands/doctor.d.ts +5 -3
- package/dist/commands/doctor.js +23 -8
- package/dist/commands/exec.js +3 -2
- package/dist/commands/feed.js +2 -31
- package/dist/commands/harness.js +3 -3
- package/dist/commands/hooks.js +1 -1
- package/dist/commands/import.js +1 -1
- package/dist/commands/insights.js +163 -85
- package/dist/commands/inspect.js +2 -2
- package/dist/commands/mine.js +1 -1
- package/dist/commands/monitors.js +1 -1
- package/dist/commands/org.d.ts +6 -0
- package/dist/commands/org.js +175 -0
- package/dist/commands/packages.js +1 -1
- package/dist/commands/profiles.js +2 -2
- package/dist/commands/prune.js +1 -1
- package/dist/commands/routines.js +44 -26
- package/dist/commands/run-account-picker.d.ts +19 -0
- package/dist/commands/run-account-picker.js +81 -0
- package/dist/commands/sessions-picker-factory.d.ts +40 -0
- package/dist/commands/sessions-picker-factory.js +67 -0
- package/dist/commands/sessions-picker.js +124 -122
- package/dist/commands/setup-browser.js +4 -4
- package/dist/commands/setup-mine.js +1 -1
- package/dist/commands/setup-preferences.js +2 -2
- package/dist/commands/setup.js +10 -4
- package/dist/commands/snapshot.d.ts +1 -1
- package/dist/commands/snapshot.js +4 -4
- package/dist/commands/status.d.ts +4 -2
- package/dist/commands/status.js +10 -7
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.js +30 -3
- package/dist/commands/versions.js +1 -1
- package/dist/commands/view.js +7 -1
- package/dist/commands/webhook.js +1 -1
- package/dist/lib/account-capabilities.d.ts +10 -0
- package/dist/lib/account-capabilities.js +34 -0
- package/dist/lib/accounting/rotate.d.ts +5 -3
- package/dist/lib/accounting/rotate.js +36 -7
- package/dist/lib/accounting/usage.d.ts +18 -4
- package/dist/lib/accounting/usage.js +138 -27
- package/dist/lib/agent-spec/agents.d.ts +584 -0
- package/dist/lib/agent-spec/agents.js +3127 -0
- package/dist/lib/agent-spec/provider.js +1 -1
- package/dist/lib/agents.d.ts +2 -584
- package/dist/lib/agents.js +2 -3127
- package/dist/lib/browser/drivers/local.d.ts +8 -2
- package/dist/lib/browser/drivers/local.js +8 -2
- package/dist/lib/browser/drivers/ssh.d.ts +8 -2
- package/dist/lib/browser/drivers/ssh.js +10 -4
- package/dist/lib/browser/hygiene.d.ts +1 -1
- package/dist/lib/browser/hygiene.js +5 -1
- package/dist/lib/browser/profiles.d.ts +74 -1
- package/dist/lib/browser/profiles.js +114 -5
- package/dist/lib/browser/runtime-state.d.ts +11 -5
- package/dist/lib/browser/runtime-state.js +13 -9
- package/dist/lib/browser/service.d.ts +68 -30
- package/dist/lib/browser/service.js +305 -194
- package/dist/lib/browser/types.d.ts +95 -3
- package/dist/lib/browser/types.js +51 -0
- package/dist/lib/catchup.js +1 -1
- package/dist/lib/cloud/rush.d.ts +0 -15
- package/dist/lib/cloud/rush.js +0 -35
- package/dist/lib/computer/actions.d.ts +1 -1
- package/dist/lib/computer/actions.js +1 -1
- package/dist/lib/{computer-rpc.js → computer/computer-rpc.js} +5 -5
- package/dist/lib/computer/dispatch.d.ts +1 -1
- package/dist/lib/computer/download.d.ts +1 -1
- package/dist/lib/computer/download.js +3 -3
- package/dist/lib/{ssh-tunnel.d.ts → computer/ssh-tunnel.d.ts} +1 -1
- package/dist/lib/{ssh-tunnel.js → computer/ssh-tunnel.js} +12 -12
- package/dist/lib/crabbox/runtimes.d.ts +6 -2
- package/dist/lib/crabbox/runtimes.js +21 -5
- package/dist/lib/daemon/daemon.js +87 -59
- package/dist/lib/{runner.d.ts → daemon/runner.d.ts} +28 -11
- package/dist/lib/{runner.js → daemon/runner.js} +143 -123
- package/dist/lib/devices/doctor-findings.d.ts +1 -1
- package/dist/lib/devices/doctor-findings.js +4 -4
- package/dist/lib/devices/fleet-inventory.js +1 -1
- package/dist/lib/devices/harness-inventory.js +1 -1
- package/dist/lib/devices/health-report.js +1 -1
- package/dist/lib/devices/registry.js +4 -22
- package/dist/lib/doctor-diff.d.ts +1 -1
- package/dist/lib/doctor-diff.js +1 -1
- package/dist/lib/drift-sync.d.ts +1 -1
- package/dist/lib/drift-sync.js +2 -2
- package/dist/lib/drift.d.ts +1 -1
- package/dist/lib/drift.js +1 -1
- package/dist/lib/entitlement.d.ts +31 -0
- package/dist/lib/entitlement.js +137 -0
- package/dist/lib/exec.js +52 -205
- package/dist/lib/feed/feed.js +2 -8
- package/dist/lib/format.d.ts +9 -0
- package/dist/lib/format.js +16 -0
- package/dist/lib/fs-atomic.d.ts +7 -0
- package/dist/lib/fs-atomic.js +9 -0
- package/dist/lib/github/pr-mergeable.d.ts +49 -0
- package/dist/lib/github/pr-mergeable.js +157 -0
- package/dist/lib/github/pr-verdict.d.ts +67 -0
- package/dist/lib/github/pr-verdict.js +72 -0
- package/dist/lib/harness/adapter.d.ts +161 -0
- package/dist/lib/harness/adapter.js +47 -0
- package/dist/lib/harness/adapters/claude.d.ts +2 -0
- package/dist/lib/harness/adapters/claude.js +110 -0
- package/dist/lib/harness/adapters/codex.d.ts +2 -0
- package/dist/lib/harness/adapters/codex.js +83 -0
- package/dist/lib/harness/adapters/copilot.d.ts +2 -0
- package/dist/lib/harness/adapters/copilot.js +23 -0
- package/dist/lib/harness/adapters/cursor.d.ts +2 -0
- package/dist/lib/harness/adapters/cursor.js +38 -0
- package/dist/lib/harness/adapters/droid.d.ts +2 -0
- package/dist/lib/harness/adapters/droid.js +17 -0
- package/dist/lib/harness/adapters/grok.d.ts +2 -0
- package/dist/lib/harness/adapters/grok.js +14 -0
- package/dist/lib/harness/adapters/kimi.d.ts +2 -0
- package/dist/lib/harness/adapters/kimi.js +49 -0
- package/dist/lib/harness/adapters/muse.d.ts +2 -0
- package/dist/lib/harness/adapters/muse.js +44 -0
- package/dist/lib/harness/adapters/opencode.d.ts +2 -0
- package/dist/lib/harness/adapters/opencode.js +14 -0
- package/dist/lib/harness/exec-config-version.d.ts +8 -0
- package/dist/lib/harness/exec-config-version.js +22 -0
- package/dist/lib/harness/index.d.ts +1 -0
- package/dist/lib/harness/index.js +34 -0
- package/dist/lib/{hooks.d.ts → hooks/install.d.ts} +1 -1
- package/dist/lib/{hooks.js → hooks/install.js} +11 -11
- package/dist/lib/hosts/passthrough.d.ts +10 -0
- package/dist/lib/hosts/passthrough.js +28 -6
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/import.js +1 -1
- package/dist/lib/installations/index.d.ts +4 -4
- package/dist/lib/installations/index.js +3 -4
- package/dist/lib/installations/migrate.js +6 -6
- package/dist/lib/{shims.d.ts → installations/shims.d.ts} +2 -2
- package/dist/lib/{shims.js → installations/shims.js} +13 -115
- package/dist/lib/installations/store.d.ts +141 -3
- package/dist/lib/installations/store.js +475 -5
- package/dist/lib/installations/versions.d.ts +40 -125
- package/dist/lib/installations/versions.js +57 -462
- package/dist/lib/isolation-boundary-report.d.ts +1 -1
- package/dist/lib/isolation-boundary-report.js +1 -1
- package/dist/lib/mailbox-gc.js +2 -3
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.js +19 -8
- package/dist/lib/monitors/config.d.ts +2 -2
- package/dist/lib/monitors/config.js +3 -2
- package/dist/lib/monitors/dispatch.d.ts +1 -1
- package/dist/lib/monitors/dispatch.js +2 -2
- package/dist/lib/monitors/state.d.ts +1 -1
- package/dist/lib/origin-machine.d.ts +18 -0
- package/dist/lib/origin-machine.js +34 -0
- package/dist/lib/perf/db.js +1 -1
- package/dist/lib/perf/spool.js +1 -1
- package/dist/lib/plugins/plugins.js +1 -1
- package/dist/lib/plugins/skills.js +1 -1
- package/dist/lib/prix-account.d.ts +158 -0
- package/dist/lib/prix-account.js +214 -0
- package/dist/lib/profiles.d.ts +7 -0
- package/dist/lib/profiles.js +26 -1
- package/dist/lib/project-key.js +2 -2
- package/dist/lib/project-launch.js +1 -1
- package/dist/lib/refresh.js +2 -2
- package/dist/lib/resource-inventory.d.ts +1 -1
- package/dist/lib/resource-inventory.js +1 -1
- package/dist/lib/rules/rules.js +1 -1
- package/dist/lib/sandbox.d.ts +24 -0
- package/dist/lib/sandbox.js +101 -0
- package/dist/lib/scheduling/routines.d.ts +18 -9
- package/dist/lib/scheduling/routines.js +17 -9
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/agent.js +9 -1
- package/dist/lib/secrets/index.js +1 -1
- package/dist/lib/secrets/list-filter.js +1 -1
- package/dist/lib/self-heal/checks/hook-runtime.js +1 -1
- package/dist/lib/self-heal/checks/path.js +1 -1
- package/dist/lib/self-heal/checks/shadowing.js +1 -1
- package/dist/lib/self-heal/checks/shims.js +1 -1
- package/dist/lib/service-manifest.d.ts +20 -0
- package/dist/lib/service-manifest.js +34 -0
- package/dist/lib/session/cloud.js +1 -1
- package/dist/lib/session/db.js +1 -1
- package/dist/lib/session/discover.d.ts +39 -0
- package/dist/lib/session/discover.js +3 -3
- package/dist/lib/session/fork.js +1 -1
- package/dist/lib/session/live-metadata.js +1 -1
- package/dist/lib/session/origin-machine.d.ts +1 -18
- package/dist/lib/session/origin-machine.js +4 -34
- package/dist/lib/session/parse.js +24 -42
- package/dist/lib/session/recovery.js +1 -1
- package/dist/lib/session/relative-time.d.ts +1 -44
- package/dist/lib/session/relative-time.js +4 -120
- package/dist/lib/session/remote-list.js +1 -1
- package/dist/lib/session/remote.js +2 -2
- package/dist/lib/session/short-id.d.ts +1 -17
- package/dist/lib/session/short-id.js +4 -20
- package/dist/lib/session/width.d.ts +1 -29
- package/dist/lib/session/width.js +4 -101
- package/dist/lib/snapshot.d.ts +2 -2
- package/dist/lib/snapshot.js +1 -1
- package/dist/lib/staleness/prune.d.ts +1 -1
- package/dist/lib/staleness/prune.js +1 -1
- package/dist/lib/staleness/writers/hooks.js +1 -1
- package/dist/lib/startup/command-registry.d.ts +4 -1
- package/dist/lib/startup/command-registry.js +12 -5
- package/dist/lib/teams/agents.js +2 -19
- package/dist/lib/teams/parsers.js +20 -26
- package/dist/lib/teams/placement-probe.js +1 -1
- package/dist/lib/teams/registry.js +2 -21
- package/dist/lib/teams/scheduler.js +1 -1
- package/dist/lib/text/relative-time.d.ts +44 -0
- package/dist/lib/text/relative-time.js +120 -0
- package/dist/lib/text/short-id.d.ts +17 -0
- package/dist/lib/text/short-id.js +20 -0
- package/dist/lib/text/width.d.ts +29 -0
- package/dist/lib/text/width.js +101 -0
- package/dist/lib/triggers/handlers.d.ts +7 -0
- package/dist/lib/triggers/handlers.js +9 -1
- package/dist/lib/triggers/webhook.d.ts +1 -0
- package/dist/lib/triggers/webhook.js +3 -2
- package/dist/lib/uninstall.js +1 -1
- package/dist/lib/version.d.ts +9 -2
- package/dist/lib/version.js +11 -9
- package/dist/lib/view-types.d.ts +4 -0
- package/package.json +1 -1
- package/dist/commands/tickets.d.ts +0 -2
- package/dist/commands/tickets.js +0 -43
- package/dist/lib/observe-aliases.d.ts +0 -30
- package/dist/lib/observe-aliases.js +0 -38
- package/dist/lib/tickets/list.d.ts +0 -53
- package/dist/lib/tickets/list.js +0 -153
- /package/dist/lib/{computer-rpc.d.ts → computer/computer-rpc.d.ts} +0 -0
|
@@ -7,36 +7,16 @@
|
|
|
7
7
|
* Reuses the same `itemPicker` + `buildPreview` primitives as the ordinary
|
|
8
8
|
* session picker (`sessions-picker.ts`) — same search/filter/quit help, and the
|
|
9
9
|
* preview pane for a linked task IS the canonical session digest, not a
|
|
10
|
-
* second renderer.
|
|
10
|
+
* second renderer. Interactive routing and the browse loop live in
|
|
11
|
+
* `sessions-picker-factory.ts` (shared with the computer twin).
|
|
11
12
|
*/
|
|
12
13
|
import chalk from 'chalk';
|
|
13
14
|
import { itemPicker } from '../lib/picker.js';
|
|
14
|
-
import {
|
|
15
|
+
import { isPromptCancelled } from './utils.js';
|
|
15
16
|
import { buildPreview } from './sessions-picker.js';
|
|
17
|
+
import { createSessionsPickerCommand } from './sessions-picker-factory.js';
|
|
16
18
|
import { runBrowserSessions, buildBrowserSessionRows, matchesBrowserSessionRow, openArtifact, formatBytes, } from '../lib/browser/sessions-list.js';
|
|
17
19
|
import { formatRelativeTime } from '../lib/session/relative-time.js';
|
|
18
|
-
/** True when the interactive picker should open instead of the printed table:
|
|
19
|
-
* a real TTY, no `--json`/`--open`, and `--no-interactive` not set. */
|
|
20
|
-
export function shouldOpenInteractiveBrowserSessions(opts, isTTY) {
|
|
21
|
-
return opts.interactive !== false && !opts.json && opts.open === undefined && isTTY;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Shared entry point for `agents browser sessions` and `agents sessions
|
|
25
|
-
* --browser`. Replaces direct calls to `runBrowserSessions` at both call
|
|
26
|
-
* sites so the interactive routing decision lives in one place.
|
|
27
|
-
*/
|
|
28
|
-
export async function runBrowserSessionsCommand(opts) {
|
|
29
|
-
if (!shouldOpenInteractiveBrowserSessions(opts, isInteractiveTerminal())) {
|
|
30
|
-
runBrowserSessions({ profile: opts.profile, open: opts.open, json: opts.json });
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
const rows = buildBrowserSessionRows(opts.profile);
|
|
34
|
-
if (rows.length === 0) {
|
|
35
|
-
console.log(`No browser captures found${opts.profile ? ` for profile "${opts.profile}"` : ''}.`);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
await browseAndOpen(rows);
|
|
39
|
-
}
|
|
40
20
|
const KIND_LABEL = {
|
|
41
21
|
screenshot: 'shots',
|
|
42
22
|
pdf: 'pdf',
|
|
@@ -116,44 +96,6 @@ function openAndReport(a) {
|
|
|
116
96
|
if (!openArtifact(a.path))
|
|
117
97
|
console.error(`Could not open ${a.path}`);
|
|
118
98
|
}
|
|
119
|
-
/** Task-level picker with a captures preview, then an artifact drill-down when
|
|
120
|
-
* a task holds more than one capture. Loops until the user quits (esc) so a
|
|
121
|
-
* capture-heavy task can be browsed and opened repeatedly in one session. */
|
|
122
|
-
async function browseAndOpen(rows) {
|
|
123
|
-
for (;;) {
|
|
124
|
-
let picked;
|
|
125
|
-
try {
|
|
126
|
-
picked = await itemPicker({
|
|
127
|
-
message: 'Browser sessions:',
|
|
128
|
-
items: rows,
|
|
129
|
-
filter: (query) => (query.trim() ? rows.filter((r) => matchesBrowserSessionRow(r, query)) : rows),
|
|
130
|
-
labelFor: (row) => formatRowLabel(row),
|
|
131
|
-
buildPreview: (row) => buildRowPreview(row),
|
|
132
|
-
emptyMessage: 'No browser sessions match.',
|
|
133
|
-
enterHint: 'open capture',
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
catch (err) {
|
|
137
|
-
if (isPromptCancelled(err))
|
|
138
|
-
return;
|
|
139
|
-
throw err;
|
|
140
|
-
}
|
|
141
|
-
if (!picked)
|
|
142
|
-
return;
|
|
143
|
-
const row = picked.item;
|
|
144
|
-
if (row.artifacts.length === 0) {
|
|
145
|
-
console.log('No captures in this task yet.');
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
if (row.artifacts.length === 1) {
|
|
149
|
-
openAndReport(row.artifacts[0]);
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
const artifact = await pickArtifact(row);
|
|
153
|
-
if (artifact)
|
|
154
|
-
openAndReport(artifact);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
99
|
/** Second-level picker over one row's captures, newest first. Enter opens the
|
|
158
100
|
* highlighted capture; esc returns to the task list. */
|
|
159
101
|
async function pickArtifact(row) {
|
|
@@ -177,3 +119,41 @@ async function pickArtifact(row) {
|
|
|
177
119
|
throw err;
|
|
178
120
|
}
|
|
179
121
|
}
|
|
122
|
+
const browserSessionsPicker = createSessionsPickerCommand({
|
|
123
|
+
requireOpenUndefined: true,
|
|
124
|
+
runFlat: (opts) => runBrowserSessions({ profile: opts.profile, open: opts.open, json: opts.json }),
|
|
125
|
+
buildRows: (opts) => buildBrowserSessionRows(opts.profile),
|
|
126
|
+
emptyMessage: (opts) => `No browser captures found${opts.profile ? ` for profile "${opts.profile}"` : ''}.`,
|
|
127
|
+
message: 'Browser sessions:',
|
|
128
|
+
matches: matchesBrowserSessionRow,
|
|
129
|
+
labelFor: formatRowLabel,
|
|
130
|
+
buildPreview: buildRowPreview,
|
|
131
|
+
emptyFilterMessage: 'No browser sessions match.',
|
|
132
|
+
enterHint: 'open capture',
|
|
133
|
+
onOpen: async (row) => {
|
|
134
|
+
if (row.artifacts.length === 0) {
|
|
135
|
+
console.log('No captures in this task yet.');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (row.artifacts.length === 1) {
|
|
139
|
+
openAndReport(row.artifacts[0]);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const artifact = await pickArtifact(row);
|
|
143
|
+
if (artifact)
|
|
144
|
+
openAndReport(artifact);
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
/** True when the interactive picker should open instead of the printed table:
|
|
148
|
+
* a real TTY, no `--json`/`--open`, and `--no-interactive` not set. */
|
|
149
|
+
export function shouldOpenInteractiveBrowserSessions(opts, isTTY) {
|
|
150
|
+
return browserSessionsPicker.shouldOpen(opts, isTTY);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Shared entry point for `agents browser sessions` and `agents sessions
|
|
154
|
+
* --browser`. Replaces direct calls to `runBrowserSessions` at both call
|
|
155
|
+
* sites so the interactive routing decision lives in one place.
|
|
156
|
+
*/
|
|
157
|
+
export async function runBrowserSessionsCommand(opts) {
|
|
158
|
+
await browserSessionsPicker.run(opts);
|
|
159
|
+
}
|
package/dist/commands/browser.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
-
import { listProfiles, getProfile, createProfile, deleteProfile,
|
|
4
|
+
import { listProfiles, getProfile, createProfile, deleteProfile, getConfiguredDefaultProfileName, resolveProfileRef, resolveProfileRefForStart, getProfileRuntimeDir, extractConfiguredPort, findFreeProfilePort, getEndpointPresets, listProfilesWithScope, formatProfilesTable, } from '../lib/browser/profiles.js';
|
|
5
5
|
import { resolveActor } from '../lib/actor.js';
|
|
6
6
|
import { loginsForProfile, profilesLoggedInto, serviceForUrl, loginsWithAccountsForProfile, accountsForProfile, credKeysForService, AUTH_SIGNATURES, } from '../lib/browser/login-detection.js';
|
|
7
7
|
import { parseSecretRef } from '../lib/browser/secret-ref.js';
|
|
@@ -576,12 +576,12 @@ function registerProfilesCommands(browser) {
|
|
|
576
576
|
other machine — pass --fleet only when the profile really is fleet config.
|
|
577
577
|
|
|
578
578
|
In \`list\`, the \`*\` marker means "this machine's configured default"
|
|
579
|
-
(\`agents browser start\` with no --profile).
|
|
580
|
-
|
|
581
|
-
|
|
579
|
+
(\`agents browser start\` with no --profile). The auto-detected profile is
|
|
580
|
+
named \`auto-chrome\`; \`default\` is only an ALIAS for whichever profile
|
|
581
|
+
this machine is configured to use, resolved the same way by every command.
|
|
582
582
|
|
|
583
583
|
\`prune\` never removes a profile that is in use, the configured default, the
|
|
584
|
-
auto \`
|
|
584
|
+
auto-detected \`auto-chrome\`, or (without --fleet) a fleet-synced one.
|
|
585
585
|
`,
|
|
586
586
|
});
|
|
587
587
|
profiles
|
|
@@ -846,33 +846,20 @@ function registerTaskCommands(browser) {
|
|
|
846
846
|
console.error(err instanceof Error ? err.message : String(err));
|
|
847
847
|
process.exit(1);
|
|
848
848
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
849
|
+
// One resolution order for every command (RUSH-2709): `--profile default`
|
|
850
|
+
// means the same profile here as it does in stop / status / navigate.
|
|
851
|
+
// `start` is the one command that LAUNCHES, so its implicit path goes
|
|
852
|
+
// through ensureDefaultBrowserProfile, which additionally verifies the
|
|
853
|
+
// resolved default can launch on THIS machine and regenerates it when it
|
|
854
|
+
// can't (the "Custom binary not found" repair) — a filter-only command
|
|
855
|
+
// must not warn or rewrite a profile, so that check lives only here.
|
|
856
|
+
let profileName;
|
|
857
|
+
try {
|
|
858
|
+
profileName = await resolveProfileRefForStart(opts.profile);
|
|
859
859
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
// user's chosen profile (e.g. their logged-in Comet) rather than a
|
|
864
|
-
// literal `default` (which auto-detects Chrome). Narrowly scoped: only
|
|
865
|
-
// the reserved name, only here in `start`.
|
|
866
|
-
const configured = getConfiguredDefaultProfileName();
|
|
867
|
-
if (configured && configured !== DEFAULT_BROWSER_PROFILE_NAME) {
|
|
868
|
-
const target = await getProfile(configured);
|
|
869
|
-
if (target) {
|
|
870
|
-
profileName = target.name;
|
|
871
|
-
}
|
|
872
|
-
else {
|
|
873
|
-
console.error(`warning: configured default profile "${configured}" not found; using "${DEFAULT_BROWSER_PROFILE_NAME}".`);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
860
|
+
catch (err) {
|
|
861
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
862
|
+
process.exit(1);
|
|
876
863
|
}
|
|
877
864
|
// Pre-check the profile locally so we fail fast with a helpful error
|
|
878
865
|
// instead of round-tripping a generic "Profile not found" through the daemon.
|
|
@@ -1001,15 +988,16 @@ function registerTaskCommands(browser) {
|
|
|
1001
988
|
.option('-p, --profile <name>', 'Detach the whole profile (incl. composite "name@endpoint") instead of stopping a single task')
|
|
1002
989
|
.action(async (opts) => {
|
|
1003
990
|
if (opts.profile) {
|
|
991
|
+
const profile = (await resolveProfileRef(opts.profile)) ?? opts.profile;
|
|
1004
992
|
const response = await sendIPCRequest({
|
|
1005
993
|
action: 'stop',
|
|
1006
|
-
profile
|
|
994
|
+
profile,
|
|
1007
995
|
});
|
|
1008
996
|
if (!response.ok) {
|
|
1009
997
|
console.error(response.error);
|
|
1010
998
|
process.exit(1);
|
|
1011
999
|
}
|
|
1012
|
-
console.log(`Stopped profile: ${
|
|
1000
|
+
console.log(`Stopped profile: ${profile}`);
|
|
1013
1001
|
return;
|
|
1014
1002
|
}
|
|
1015
1003
|
const task = resolveTaskName(opts);
|
|
@@ -1083,7 +1071,7 @@ function registerTaskCommands(browser) {
|
|
|
1083
1071
|
action: 'navigate',
|
|
1084
1072
|
task,
|
|
1085
1073
|
url,
|
|
1086
|
-
profile: opts.profile,
|
|
1074
|
+
profile: opts.profile ? await resolveProfileRef(opts.profile) : undefined,
|
|
1087
1075
|
});
|
|
1088
1076
|
if (!response.ok) {
|
|
1089
1077
|
console.error(response.error);
|
|
@@ -1108,7 +1096,7 @@ function registerTaskCommands(browser) {
|
|
|
1108
1096
|
action: 'tab-add',
|
|
1109
1097
|
task,
|
|
1110
1098
|
url: opts.url,
|
|
1111
|
-
profile: opts.profile,
|
|
1099
|
+
profile: opts.profile ? await resolveProfileRef(opts.profile) : undefined,
|
|
1112
1100
|
});
|
|
1113
1101
|
if (!response.ok) {
|
|
1114
1102
|
console.error(response.error);
|
|
@@ -1369,7 +1357,7 @@ function registerTaskCommands(browser) {
|
|
|
1369
1357
|
try {
|
|
1370
1358
|
response = await sendIPCRequest({
|
|
1371
1359
|
action: 'status',
|
|
1372
|
-
profile: opts.profile,
|
|
1360
|
+
profile: opts.profile ? await resolveProfileRef(opts.profile) : undefined,
|
|
1373
1361
|
}, { autoStartDaemon: false });
|
|
1374
1362
|
}
|
|
1375
1363
|
catch (err) {
|
|
@@ -1458,7 +1446,11 @@ function registerTaskCommands(browser) {
|
|
|
1458
1446
|
// pid 0 means the daemon attached to a browser we didn't launch — no
|
|
1459
1447
|
// tracked pid. Render it as "attached" rather than the literal 0.
|
|
1460
1448
|
const pidLabel = profile.pid ? `pid ${profile.pid}` : 'attached';
|
|
1461
|
-
|
|
1449
|
+
// `profile.name` is the BARE profile; the endpoint is its own field,
|
|
1450
|
+
// so the row reads `comet-local (endpoint: endpoint-0, port …)`
|
|
1451
|
+
// instead of the raw `comet-local@endpoint-0` key (RUSH-2709).
|
|
1452
|
+
const endpointLabel = profile.endpoint ? `endpoint: ${profile.endpoint}, ` : '';
|
|
1453
|
+
console.log(`\n${profile.name} (${endpointLabel}${portLabel}, ${pidLabel})`);
|
|
1462
1454
|
if (profile.tasks.length === 0) {
|
|
1463
1455
|
console.log(' No active tasks');
|
|
1464
1456
|
}
|
|
@@ -1493,7 +1485,7 @@ function registerTaskCommands(browser) {
|
|
|
1493
1485
|
.action(async (opts) => {
|
|
1494
1486
|
const response = await sendIPCRequest({
|
|
1495
1487
|
action: 'status',
|
|
1496
|
-
profile: opts.profile,
|
|
1488
|
+
profile: opts.profile ? await resolveProfileRef(opts.profile) : undefined,
|
|
1497
1489
|
});
|
|
1498
1490
|
if (!response.ok) {
|
|
1499
1491
|
if (opts.json) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { type ComputerClient, type RPCResponse } from '../lib/computer-rpc.js';
|
|
2
|
+
import { type ComputerClient, type RPCResponse } from '../lib/computer/computer-rpc.js';
|
|
3
3
|
export { emitComputerAction, pickTarget, resolveTargetPidDecision, type AppInfo } from '../lib/computer/actions.js';
|
|
4
4
|
export declare function parseXY(s: string, flag: string): {
|
|
5
5
|
x: number;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { execFileSync } from 'child_process';
|
|
10
10
|
import * as fs from 'fs';
|
|
11
11
|
import * as path from 'path';
|
|
12
|
-
import { openComputerClient, describeTransport, } from '../lib/computer-rpc.js';
|
|
12
|
+
import { openComputerClient, describeTransport, } from '../lib/computer/computer-rpc.js';
|
|
13
13
|
import { emitComputerAction, resolveTargetPidDecision } from '../lib/computer/actions.js';
|
|
14
14
|
export { emitComputerAction, pickTarget, resolveTargetPidDecision } from '../lib/computer/actions.js';
|
|
15
15
|
// Pure target picker — exercised by unit tests. Precedence: explicit --pid,
|
|
@@ -13,39 +13,14 @@
|
|
|
13
13
|
* computer run has no on-disk artifact of its own to open (see
|
|
14
14
|
* `lib/computer/sessions-list.ts`'s module docblock), so `enter` prints the
|
|
15
15
|
* run's full action list rather than opening a file, and the picker keeps
|
|
16
|
-
* browsing afterward instead of exiting.
|
|
16
|
+
* browsing afterward instead of exiting. Interactive routing and the browse
|
|
17
|
+
* loop live in `sessions-picker-factory.ts` (shared with the browser twin).
|
|
17
18
|
*/
|
|
18
19
|
import chalk from 'chalk';
|
|
19
|
-
import { itemPicker } from '../lib/picker.js';
|
|
20
|
-
import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
21
20
|
import { buildPreview } from './sessions-picker.js';
|
|
21
|
+
import { createSessionsPickerCommand } from './sessions-picker-factory.js';
|
|
22
22
|
import { runComputerSessions, printComputerSessionRows, buildComputerSessionRows, matchesComputerSessionRow, formatRowActions, } from '../lib/computer/sessions-list.js';
|
|
23
23
|
import { formatRelativeTime } from '../lib/session/relative-time.js';
|
|
24
|
-
/** True when the interactive picker should open instead of the printed table:
|
|
25
|
-
* a real TTY, no `--json`, and `--no-interactive` not set. */
|
|
26
|
-
export function shouldOpenInteractiveComputerSessions(opts, isTTY) {
|
|
27
|
-
return opts.interactive !== false && !opts.json && isTTY;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Shared entry point for `agents computer sessions` and `agents sessions
|
|
31
|
-
* --computer`. Mirrors `runBrowserSessionsCommand`'s interactive-routing
|
|
32
|
-
* split so both call sites stay in lockstep.
|
|
33
|
-
*/
|
|
34
|
-
export async function runComputerSessionsCommand(opts) {
|
|
35
|
-
if (!shouldOpenInteractiveComputerSessions(opts, isInteractiveTerminal())) {
|
|
36
|
-
if (opts.rows)
|
|
37
|
-
printComputerSessionRows(opts.rows, { limit: opts.limit, json: opts.json });
|
|
38
|
-
else
|
|
39
|
-
runComputerSessions({ machine: opts.machine, limit: opts.limit, json: opts.json });
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const rows = opts.rows ?? buildComputerSessionRows({ machine: opts.machine });
|
|
43
|
-
if (rows.length === 0) {
|
|
44
|
-
console.log(`No computer actions recorded${opts.machine ? ` for machine "${opts.machine}"` : ''}.`);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
await browseComputerSessions(rows);
|
|
48
|
-
}
|
|
49
24
|
function rowLinkSummary(row) {
|
|
50
25
|
if (row.linkStatus === 'linked' && row.linkedSession) {
|
|
51
26
|
const s = row.linkedSession;
|
|
@@ -111,31 +86,33 @@ function printRunDetail(row) {
|
|
|
111
86
|
console.log('(no driving actions recorded)');
|
|
112
87
|
console.log('');
|
|
113
88
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
89
|
+
const computerSessionsPicker = createSessionsPickerCommand({
|
|
90
|
+
runFlat: (opts) => {
|
|
91
|
+
if (opts.rows)
|
|
92
|
+
printComputerSessionRows(opts.rows, { limit: opts.limit, json: opts.json });
|
|
93
|
+
else
|
|
94
|
+
runComputerSessions({ machine: opts.machine, limit: opts.limit, json: opts.json });
|
|
95
|
+
},
|
|
96
|
+
buildRows: (opts) => opts.rows ?? buildComputerSessionRows({ machine: opts.machine }),
|
|
97
|
+
emptyMessage: (opts) => `No computer actions recorded${opts.machine ? ` for machine "${opts.machine}"` : ''}.`,
|
|
98
|
+
message: 'Computer sessions:',
|
|
99
|
+
matches: matchesComputerSessionRow,
|
|
100
|
+
labelFor: formatRowLabel,
|
|
101
|
+
buildPreview: buildRowPreview,
|
|
102
|
+
emptyFilterMessage: 'No computer sessions match.',
|
|
103
|
+
enterHint: 'view actions',
|
|
104
|
+
onOpen: printRunDetail,
|
|
105
|
+
});
|
|
106
|
+
/** True when the interactive picker should open instead of the printed table:
|
|
107
|
+
* a real TTY, no `--json`, and `--no-interactive` not set. */
|
|
108
|
+
export function shouldOpenInteractiveComputerSessions(opts, isTTY) {
|
|
109
|
+
return computerSessionsPicker.shouldOpen(opts, isTTY);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Shared entry point for `agents computer sessions` and `agents sessions
|
|
113
|
+
* --computer`. Mirrors `runBrowserSessionsCommand`'s interactive-routing
|
|
114
|
+
* split so both call sites stay in lockstep.
|
|
115
|
+
*/
|
|
116
|
+
export async function runComputerSessionsCommand(opts) {
|
|
117
|
+
await computerSessionsPicker.run(opts);
|
|
141
118
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { resolveHelperExec, resolveSocketPath } from '../lib/computer-rpc.js';
|
|
2
|
+
import { resolveHelperExec, resolveSocketPath } from '../lib/computer/computer-rpc.js';
|
|
3
3
|
/**
|
|
4
4
|
* Pure platform gate. The computer subsystem is macOS-only for LOCAL driving
|
|
5
5
|
* (Accessibility / launchctl). It is NOT blocked off macOS when a remote daemon
|
|
@@ -3,8 +3,8 @@ import * as fs from 'fs';
|
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { registerCommandGroups } from '../lib/help.js';
|
|
6
|
-
import { openComputerClient, resolveHelperApp, resolveHelperExec, resolveSocketPath, resolveLogPath, resolvePolicyPath, resolvePeersPath, resolveTcpEndpoint, loadComputerAllowList, loadDefaultPeers, writeComputerPolicy, writeComputerPeers, } from '../lib/computer-rpc.js';
|
|
7
|
-
import { setupRemoteHelper, startRemoteTunnel, stopRemoteHelper, hydrateRemoteEnvFromState, readRemoteState, resolveRemoteDevice, REMOTE_TASK_NAME, WIN_HELPER_EXE, } from '../lib/ssh-tunnel.js';
|
|
6
|
+
import { openComputerClient, resolveHelperApp, resolveHelperExec, resolveSocketPath, resolveLogPath, resolvePolicyPath, resolvePeersPath, resolveTcpEndpoint, loadComputerAllowList, loadDefaultPeers, writeComputerPolicy, writeComputerPeers, } from '../lib/computer/computer-rpc.js';
|
|
7
|
+
import { setupRemoteHelper, startRemoteTunnel, stopRemoteHelper, hydrateRemoteEnvFromState, readRemoteState, resolveRemoteDevice, REMOTE_TASK_NAME, WIN_HELPER_EXE, } from '../lib/computer/ssh-tunnel.js';
|
|
8
8
|
import { sshExec } from '../lib/ssh-exec.js';
|
|
9
9
|
import { encodePowershell } from '../lib/hosts/remote-cmd.js';
|
|
10
10
|
import { registerActionCommands, withClient, unwrap, pickTarget, emitComputerAction } from './computer-actions.js';
|
|
@@ -14,7 +14,7 @@ import { makeClaudeResponder, resolveApiKey, DEFAULT_CLAUDE_MODEL, DEFAULT_CLAUD
|
|
|
14
14
|
import { TASK_PREVIEW_MAX_CHARS } from '../lib/computer/sessions-list.js';
|
|
15
15
|
import { runComputerSessionsCommand } from './computer-sessions-picker.js';
|
|
16
16
|
import { truncate } from '../lib/feed/events.js';
|
|
17
|
-
import { namespacedServiceLabel, serviceManifestHomeEnv } from '../lib/service-manifest.js';
|
|
17
|
+
import { namespacedServiceLabel, serviceManifestHomeEnv, serviceManagerRegistrationAllowed } from '../lib/service-manifest.js';
|
|
18
18
|
// Help groups — mirror `agents browser` so the mental model carries over.
|
|
19
19
|
const COMPUTER_HELP_GROUPS = [
|
|
20
20
|
{ title: 'Installation', names: ['setup'] },
|
|
@@ -564,6 +564,10 @@ export async function activateComputerHelperMacLocal() {
|
|
|
564
564
|
const uid = process.getuid?.();
|
|
565
565
|
if (typeof uid !== 'number')
|
|
566
566
|
throw new Error('cannot resolve uid');
|
|
567
|
+
const reg = serviceManagerRegistrationAllowed();
|
|
568
|
+
if (!reg.allowed) {
|
|
569
|
+
throw new Error(reg.reason);
|
|
570
|
+
}
|
|
567
571
|
const domain = `gui/${uid}`;
|
|
568
572
|
// Render the policy file BEFORE bootstrap so the daemon reads a fresh allow
|
|
569
573
|
// list at startup (fail-safe: missing/unparseable → everything denied).
|
|
@@ -843,11 +847,21 @@ function registerStopCommand(program) {
|
|
|
843
847
|
process.exit(1);
|
|
844
848
|
}
|
|
845
849
|
const domain = `gui/${uid}`;
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
850
|
+
// Same invariant as the start path: a redirected-HOME process must never
|
|
851
|
+
// talk to the real launchd (RUSH-2968). Stop has a local fallback — the
|
|
852
|
+
// plist/socket cleanup below — so skip the bootout with the reason
|
|
853
|
+
// rather than throwing like start does.
|
|
854
|
+
const reg = serviceManagerRegistrationAllowed();
|
|
855
|
+
if (!reg.allowed) {
|
|
856
|
+
console.warn(`skipping launchctl bootout: ${reg.reason}`);
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
try {
|
|
860
|
+
execFileSync('/bin/launchctl', ['bootout', domain, plistPath], { stdio: 'pipe' });
|
|
861
|
+
}
|
|
862
|
+
catch {
|
|
863
|
+
// already gone — fine
|
|
864
|
+
}
|
|
851
865
|
}
|
|
852
866
|
// launchd unlinks the socket when the daemon exits; helper also has an
|
|
853
867
|
// atexit unlink. Best-effort cleanup if either path didn't fire.
|
package/dist/commands/daemon.js
CHANGED
|
@@ -761,7 +761,7 @@ function runWebhooksList(json) {
|
|
|
761
761
|
const port = hostedReceiverPort(r);
|
|
762
762
|
const funnel = r.funnel ? chalk.cyan(` public :${r.funnel.publicPort}`) : chalk.gray(' localhost only');
|
|
763
763
|
console.log(` 127.0.0.1:${String(port).padEnd(6)} ${chalk.gray(`bundle ${r.bundle}`)}${funnel}`);
|
|
764
|
-
console.log(chalk.gray(` endpoints: /hooks/github, /hooks/linear · ${r.rateLimit ?? DEFAULT_WEBHOOK_RATE_LIMIT}/min per source`));
|
|
764
|
+
console.log(chalk.gray(` endpoints: /hooks/github, /hooks/linear, /hooks/slack · ${r.rateLimit ?? DEFAULT_WEBHOOK_RATE_LIMIT}/min per source`));
|
|
765
765
|
}
|
|
766
766
|
console.log(chalk.gray(`\nConfig: ${getDaemonWebhooksConfigPath()}`));
|
|
767
767
|
console.log(chalk.gray('Changes take effect on the next daemon restart.'));
|
|
@@ -25,7 +25,7 @@ import type { Command } from 'commander';
|
|
|
25
25
|
import { type FleetInventory } from '../lib/devices/fleet-divergence.js';
|
|
26
26
|
import { type DoctorFinding } from '../lib/devices/doctor-findings.js';
|
|
27
27
|
import { type VersionResourceReport } from '../lib/doctor-diff.js';
|
|
28
|
-
import { type DuplicateVersionHook } from '../lib/hooks.js';
|
|
28
|
+
import { type DuplicateVersionHook } from '../lib/hooks/install.js';
|
|
29
29
|
import { type SyncStatusRow, type OrphanRow } from '../lib/drift.js';
|
|
30
30
|
import { type FetchStatusMarker } from '../lib/auto-pull.js';
|
|
31
31
|
export declare function wrapLine(prefix: string, text: string, width?: number): string[];
|
|
@@ -78,9 +78,11 @@ export type IssueSeverity = 'critical' | 'warning' | 'info';
|
|
|
78
78
|
*
|
|
79
79
|
* Severity model (agent-agnostic — applies to every agent doctor inspects):
|
|
80
80
|
* - critical (silent breakage): an unwired hook, a missing/unparseable
|
|
81
|
-
* settings.json, a MISSING
|
|
81
|
+
* settings.json, a MISSING hook or plugin.
|
|
82
82
|
* - warning (stale / drift): a source layer behind origin, a DIVERGENT resource,
|
|
83
|
-
* a stale / never-synced version
|
|
83
|
+
* a stale / never-synced version, a MISSING resource of any other kind
|
|
84
|
+
* (see `missingResourceSeverity`, which reads this split from
|
|
85
|
+
* `FINDING_SEVERITY` — RUSH-2947).
|
|
84
86
|
* - info (orphan): an EXTRA resource → `agents prune cleanup`.
|
|
85
87
|
*/
|
|
86
88
|
export interface VerdictIssue {
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IsolationBoundaryError } from '../lib/shims.js';
|
|
1
|
+
import { IsolationBoundaryError } from '../lib/installations/shims.js';
|
|
2
2
|
import { explainIsolationBoundary } from '../lib/isolation-boundary-report.js';
|
|
3
3
|
import { addHostOption } from '../lib/hosts/option.js';
|
|
4
4
|
import { buildRemoteAgentsInvocation } from '../lib/hosts/remote-cmd.js';
|
|
@@ -23,7 +23,7 @@ import { getVersionHomePath, listInstalledVersions, } from '../lib/installations
|
|
|
23
23
|
import { resolveAgentTargets, AgentSpecError } from '../lib/agent-spec/index.js';
|
|
24
24
|
import { loadManifest, isStale } from '../lib/staleness/index.js';
|
|
25
25
|
import { diffVersionResources, DOCTOR_ALL_KINDS, } from '../lib/doctor-diff.js';
|
|
26
|
-
import { checkVersionHookWiring, inspectDuplicateVersionHooks, registerHooksToSettings, repairManagedHookRuntimeArtifacts } from '../lib/hooks.js';
|
|
26
|
+
import { checkVersionHookWiring, inspectDuplicateVersionHooks, registerHooksToSettings, repairManagedHookRuntimeArtifacts } from '../lib/hooks/install.js';
|
|
27
27
|
import { isVersionIsolated } from '../lib/installations/versions.js';
|
|
28
28
|
import { computeDrift, checkSyncStatus, countOrphans, computeSourceBehind } from '../lib/drift.js';
|
|
29
29
|
import { readAuthHealthCache, summarizeHostAuth } from '../lib/auth-health.js';
|
|
@@ -669,6 +669,19 @@ const AUTO_FIXABLE_CATEGORIES = new Set([
|
|
|
669
669
|
export function verdictIsAutoFixable(v) {
|
|
670
670
|
return v.issues.some((i) => AUTO_FIXABLE_CATEGORIES.has(i.category));
|
|
671
671
|
}
|
|
672
|
+
/**
|
|
673
|
+
* Missing-resource severity for one `DoctorKind`, read from `FINDING_SEVERITY`
|
|
674
|
+
* (the fleet-mode rubric) so target mode agrees with it kind by kind instead of
|
|
675
|
+
* re-hardcoding its own. Hooks and plugins map to their dedicated critical
|
|
676
|
+
* finding kinds; every other kind maps to the generic 'missing-resource' warning.
|
|
677
|
+
*/
|
|
678
|
+
function missingResourceSeverity(kind) {
|
|
679
|
+
if (kind === 'hooks')
|
|
680
|
+
return FINDING_SEVERITY['missing-hook'];
|
|
681
|
+
if (kind === 'plugins')
|
|
682
|
+
return FINDING_SEVERITY['missing-plugin'];
|
|
683
|
+
return FINDING_SEVERITY['missing-resource'];
|
|
684
|
+
}
|
|
672
685
|
/**
|
|
673
686
|
* Fold a version report's divergences into a triaged verdict — one severity-tagged
|
|
674
687
|
* finding per unwired hook, missing/divergent/extra resource, and behind-origin
|
|
@@ -718,16 +731,18 @@ export function computeVerdict(report) {
|
|
|
718
731
|
});
|
|
719
732
|
}
|
|
720
733
|
}
|
|
721
|
-
// ──
|
|
734
|
+
// ── missing resources (declared in sources, absent from home) — severity
|
|
735
|
+
// follows FINDING_SEVERITY: hooks/plugins are critical, everything else warns ──
|
|
722
736
|
for (const kind of DOCTOR_ALL_KINDS) {
|
|
723
737
|
for (const r of report.kinds[kind]) {
|
|
724
738
|
if (r.status !== 'missing')
|
|
725
739
|
continue;
|
|
740
|
+
const severity = missingResourceSeverity(kind);
|
|
726
741
|
issues.push({
|
|
727
|
-
severity
|
|
742
|
+
severity, category: 'missing', subject: r.name,
|
|
728
743
|
impact: `declared in sources but absent from the version home (${kind})`,
|
|
729
744
|
fix: fixCmd,
|
|
730
|
-
text: `${r.name} missing`, color: 'red',
|
|
745
|
+
text: `${r.name} missing`, color: severity === 'critical' ? 'red' : 'yellow',
|
|
731
746
|
});
|
|
732
747
|
}
|
|
733
748
|
}
|
|
@@ -1523,7 +1538,7 @@ export function registerDoctorCommand(program) {
|
|
|
1523
1538
|
console.error(chalk.red('--adopt and --release are mutually exclusive; pass only one.'));
|
|
1524
1539
|
process.exit(1);
|
|
1525
1540
|
}
|
|
1526
|
-
const { adoptShadowingLauncher, releaseAdoptedLauncher } = await import('../lib/shims.js');
|
|
1541
|
+
const { adoptShadowingLauncher, releaseAdoptedLauncher } = await import('../lib/installations/shims.js');
|
|
1527
1542
|
const raw = (opts.adopt || opts.release);
|
|
1528
1543
|
const agent = resolveAgentName(raw);
|
|
1529
1544
|
if (!agent) {
|
|
@@ -1739,10 +1754,10 @@ export function registerDoctorCommand(program) {
|
|
|
1739
1754
|
console.log(line);
|
|
1740
1755
|
}
|
|
1741
1756
|
// Point at the interactive reconcile when anything is out of sync — each
|
|
1742
|
-
// finding carries its own fix, but `agents status` is the one place that
|
|
1757
|
+
// finding carries its own fix, but `agents sync status` is the one place that
|
|
1743
1758
|
// reviews and applies them together (opt-in, never auto-fires here).
|
|
1744
1759
|
if (syncRows.some((r) => r.status !== 'fresh' || (r.unwiredHooks ?? 0) > 0) || repoBehindMarkers.some((m) => m.behind > 0)) {
|
|
1745
|
-
console.log(chalk.gray('\nRun `agents status` to review and sync what has drifted.'));
|
|
1760
|
+
console.log(chalk.gray('\nRun `agents sync status` to review and sync what has drifted.'));
|
|
1746
1761
|
}
|
|
1747
1762
|
// A routine runs on exactly one device. Each of these named several and
|
|
1748
1763
|
// used to fire once per device — duplicate agent runs on every schedule.
|
package/dist/commands/exec.js
CHANGED
|
@@ -3015,8 +3015,9 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
|
|
|
3015
3015
|
let exitCode;
|
|
3016
3016
|
let ranAgent = agent;
|
|
3017
3017
|
let ranVersion = defaultVersion;
|
|
3018
|
-
if (fallback.length > 0) {
|
|
3019
|
-
//
|
|
3018
|
+
if (fallback.length > 0 || (rotationResult !== null && prompt !== undefined && !options.interactive)) {
|
|
3019
|
+
// Fallback and balanced runs need captured output so a clean-exit
|
|
3020
|
+
// session-limit refusal can update account availability.
|
|
3020
3021
|
// The sink reports which chain entry actually executed (may differ from
|
|
3021
3022
|
// the primary after a rate-limit handoff) so the audit record is honest.
|
|
3022
3023
|
const sink = {};
|
package/dist/commands/feed.js
CHANGED
|
@@ -312,7 +312,7 @@ export async function loadSessionMetasForFeedEnrichment(load) {
|
|
|
312
312
|
export function registerFeedCommand(program) {
|
|
313
313
|
const feed = program
|
|
314
314
|
.command('feed')
|
|
315
|
-
.description('Operator inbox + agent status posts
|
|
315
|
+
.description('Operator inbox + agent status posts. Default is needs-you; agent progress = --filter updates')
|
|
316
316
|
.option('--json', 'Output as JSON (each block stamped with its outcome + ask class)')
|
|
317
317
|
.option('--filter <view>', 'What to show: needs (default) · updates · all', 'needs')
|
|
318
318
|
.option('--flat', 'List one block per agent instead of grouping by outcome')
|
|
@@ -449,7 +449,7 @@ export function registerFeedCommand(program) {
|
|
|
449
449
|
setupWarnings.push(activityInstall.error);
|
|
450
450
|
if (!hookInstall.error || !activityInstall.error) {
|
|
451
451
|
const [{ iterHooksCapableVersions, parseHookManifest, registerHooksToSettings }, { getVersionHomePath }] = await Promise.all([
|
|
452
|
-
import('../lib/hooks.js'),
|
|
452
|
+
import('../lib/hooks/install.js'),
|
|
453
453
|
import('../lib/installations/versions.js'),
|
|
454
454
|
]);
|
|
455
455
|
const manifest = parseHookManifest({ warn: false });
|
|
@@ -642,35 +642,6 @@ export function registerFeedCommand(program) {
|
|
|
642
642
|
renderOutcomeGroup(g, self);
|
|
643
643
|
await renderTrailingActivity();
|
|
644
644
|
});
|
|
645
|
-
// Observe-umbrella aliases (Phase 3): intentional second names, not deprecations.
|
|
646
|
-
// Re-parse into `feed` so flags/help stay single-sourced. See lib/observe-aliases.ts.
|
|
647
|
-
registerFeedObserveAliases(program);
|
|
648
|
-
}
|
|
649
|
-
/**
|
|
650
|
-
* `inbox` → feed. Loaded with the feed module so the lazy COMMAND_LOADERS entry
|
|
651
|
-
* for `inbox` also gets the real `feed` command registered for re-parse.
|
|
652
|
-
*/
|
|
653
|
-
function registerFeedObserveAliases(program) {
|
|
654
|
-
const reparse = async (alias) => {
|
|
655
|
-
const { expandObserveAlias } = await import('../lib/observe-aliases.js');
|
|
656
|
-
const rest = process.argv.slice(3);
|
|
657
|
-
const expanded = expandObserveAlias(alias, rest);
|
|
658
|
-
if (!expanded) {
|
|
659
|
-
console.error(chalk.red(`Unknown observe alias: ${alias}`));
|
|
660
|
-
process.exit(1);
|
|
661
|
-
}
|
|
662
|
-
if (process.stderr.isTTY)
|
|
663
|
-
process.stderr.write(chalk.gray(`${expanded.note}\n`));
|
|
664
|
-
await program.parseAsync(['node', 'agents', ...expanded.argv]);
|
|
665
|
-
};
|
|
666
|
-
program
|
|
667
|
-
.command('inbox')
|
|
668
|
-
.description('Needs-you inbox (alias of `agents feed`). Open blocks waiting on you.')
|
|
669
|
-
.allowUnknownOption()
|
|
670
|
-
.allowExcessArguments()
|
|
671
|
-
.action(async () => {
|
|
672
|
-
await reparse('inbox');
|
|
673
|
-
});
|
|
674
645
|
}
|
|
675
646
|
/**
|
|
676
647
|
* Mirror a written post to the configured sinks (`feed.broadcast` in
|