@phnx-labs/agents-cli 1.22.41 → 1.22.42
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 +14 -0
- package/README.md +9 -3
- package/dist/bin/agents +0 -0
- package/dist/cli/command-registry.d.ts +2 -0
- package/dist/cli/command-registry.js +4 -0
- package/dist/commands/accounts.d.ts +29 -0
- package/dist/commands/accounts.js +220 -29
- package/dist/commands/alias.js +1 -1
- package/dist/commands/auth.d.ts +9 -0
- package/dist/commands/auth.js +104 -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 +2 -2
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.js +3 -3
- package/dist/commands/feed.js +1 -1
- 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/org.d.ts +6 -0
- package/dist/commands/org.js +174 -0
- package/dist/commands/packages.js +1 -1
- package/dist/commands/prune.js +1 -1
- package/dist/commands/routines.js +1 -1
- 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/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 +5 -3
- package/dist/commands/sync.js +1 -1
- package/dist/commands/versions.js +1 -1
- package/dist/commands/view.js +1 -1
- package/dist/lib/account-capabilities.d.ts +10 -0
- package/dist/lib/account-capabilities.js +34 -0
- 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/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/daemon/daemon.js +1 -1
- package/dist/lib/{runner.d.ts → daemon/runner.d.ts} +10 -10
- package/dist/lib/{runner.js → daemon/runner.js} +40 -114
- package/dist/lib/devices/doctor-findings.d.ts +1 -1
- package/dist/lib/devices/doctor-findings.js +3 -3
- package/dist/lib/devices/fleet-inventory.js +1 -1
- package/dist/lib/devices/harness-inventory.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.js +1 -1
- package/dist/lib/entitlement.d.ts +31 -0
- package/dist/lib/entitlement.js +137 -0
- package/dist/lib/exec.js +39 -202
- package/dist/lib/feed/feed.js +2 -8
- package/dist/lib/fs-atomic.d.ts +7 -0
- package/dist/lib/fs-atomic.js +9 -0
- package/dist/lib/harness/adapter.d.ts +160 -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/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} +12 -114
- package/dist/lib/installations/store.d.ts +141 -3
- package/dist/lib/installations/store.js +475 -5
- package/dist/lib/installations/versions.d.ts +1 -126
- package/dist/lib/installations/versions.js +5 -465
- 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/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/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/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/scheduling/routines.js +1 -1
- 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/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/session/discover.d.ts +39 -0
- package/dist/lib/session/discover.js +3 -3
- package/dist/lib/session/parse.js +24 -42
- package/dist/lib/session/recovery.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.js +1 -1
- package/dist/lib/teams/agents.js +2 -19
- package/dist/lib/teams/parsers.js +20 -26
- package/dist/lib/teams/registry.js +2 -21
- package/dist/lib/triggers/handlers.js +1 -1
- package/dist/lib/triggers/webhook.js +1 -1
- package/dist/lib/uninstall.js +1 -1
- package/dist/lib/version.d.ts +9 -2
- package/dist/lib/version.js +11 -9
- package/package.json +1 -1
- /package/dist/lib/{computer-rpc.d.ts → computer/computer-rpc.d.ts} +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { setHelpSections } from '../lib/help.js';
|
|
3
|
+
import { clearPrixSession, fetchWhoAmI, pollDeviceToken, PrixApiError, readPrixSession, resolvePrixToken, startDeviceAuthorization, writePrixSession, } from '../lib/prix-account.js';
|
|
4
|
+
function sleep(ms) {
|
|
5
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* `agents auth login` — RFC 8628 device-code flow against the already-shipped
|
|
9
|
+
* `/api/v1/auth/device/*` routes. If the live API rejects the request shape
|
|
10
|
+
* (a route this spec missed, or the endpoint moved), this fails loud with the
|
|
11
|
+
* `rush login` fallback rather than silently stubbing a fake session.
|
|
12
|
+
*/
|
|
13
|
+
export async function runAuthLogin() {
|
|
14
|
+
let authorization;
|
|
15
|
+
try {
|
|
16
|
+
authorization = await startDeviceAuthorization();
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
20
|
+
const existing = resolvePrixToken();
|
|
21
|
+
if (existing?.source === 'rush') {
|
|
22
|
+
console.log(chalk.yellow(`Device login is unavailable right now (${message}), but you're already signed in via 'rush login'.`));
|
|
23
|
+
console.log("Run 'agents auth whoami' to confirm.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
throw new Error(`Device login is unavailable right now (${message}). Run 'rush login' instead, then 'agents auth whoami' to confirm.`);
|
|
27
|
+
}
|
|
28
|
+
console.log(`To sign in, open:\n\n ${chalk.cyan(authorization.verification_uri_complete)}\n`);
|
|
29
|
+
console.log(chalk.gray(`(code: ${authorization.user_code})`));
|
|
30
|
+
const deadline = Date.now() + authorization.expires_in * 1000;
|
|
31
|
+
let interval = Math.max(authorization.interval, 1) * 1000;
|
|
32
|
+
while (Date.now() < deadline) {
|
|
33
|
+
await sleep(interval);
|
|
34
|
+
const poll = await pollDeviceToken(authorization.device_code);
|
|
35
|
+
if (poll.status === 'pending')
|
|
36
|
+
continue;
|
|
37
|
+
if (poll.status === 'slow_down') {
|
|
38
|
+
interval += 1000;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (poll.status === 'expired')
|
|
42
|
+
throw new Error('Login code expired. Run `agents auth login` again.');
|
|
43
|
+
if (poll.status === 'denied')
|
|
44
|
+
throw new Error('Login was denied.');
|
|
45
|
+
writePrixSession({
|
|
46
|
+
access_token: poll.access_token,
|
|
47
|
+
refresh_token: poll.refresh_token,
|
|
48
|
+
expires_at: poll.expires_in ? Date.now() + poll.expires_in * 1000 : undefined,
|
|
49
|
+
email: poll.user.email,
|
|
50
|
+
userId: poll.user.id,
|
|
51
|
+
});
|
|
52
|
+
console.log(chalk.green(`Signed in as ${poll.user.email}.`));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
throw new Error('Login code expired. Run `agents auth login` again.');
|
|
56
|
+
}
|
|
57
|
+
async function runAuthWhoami(json) {
|
|
58
|
+
const resolved = resolvePrixToken();
|
|
59
|
+
if (!resolved)
|
|
60
|
+
throw new Error("Not signed in. Run 'agents auth login' first.");
|
|
61
|
+
let who;
|
|
62
|
+
try {
|
|
63
|
+
who = await fetchWhoAmI(resolved.token);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (err instanceof PrixApiError && err.status === 401) {
|
|
67
|
+
throw new Error(`Signed-in token is no longer valid (${resolved.source === 'agents' ? "run 'agents auth login'" : "run 'rush login'"} again).`);
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
if (json) {
|
|
72
|
+
console.log(JSON.stringify({ ...who, source: resolved.source }, null, 2));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
console.log(`${chalk.bold(who.email)} ${chalk.gray(who.userId)}`);
|
|
76
|
+
console.log(chalk.gray(`signed in via ${resolved.source === 'agents' ? "'agents auth login'" : "'rush login' (shared session)"}`));
|
|
77
|
+
}
|
|
78
|
+
function runAuthLogout() {
|
|
79
|
+
const cleared = clearPrixSession();
|
|
80
|
+
const rushRemains = resolvePrixToken()?.source === 'rush';
|
|
81
|
+
if (!cleared && !readPrixSession()) {
|
|
82
|
+
console.log(chalk.gray('Not signed in via `agents auth login` — nothing to clear.'));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.log(chalk.green('Signed out.'));
|
|
86
|
+
}
|
|
87
|
+
if (rushRemains) {
|
|
88
|
+
console.log(chalk.gray("You're still signed in via `rush login` — `agents auth whoami` will use that session. Run `rush logout` to clear it too."));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export function registerAuthCommand(program) {
|
|
92
|
+
const auth = program.command('auth').description('Sign in to your Rush account (shared by `agents org` and paid tiers)');
|
|
93
|
+
auth.command('login').description('Sign in via the device-code flow').action(async () => runAuthLogin());
|
|
94
|
+
auth.command('whoami').description('Show the signed-in account').option('--json', 'Machine-readable output')
|
|
95
|
+
.action((o, command) => runAuthWhoami(!!(o.json || command.optsWithGlobals().json)));
|
|
96
|
+
auth.command('logout').description('Clear the local `agents auth login` session').action(() => runAuthLogout());
|
|
97
|
+
setHelpSections(auth, {
|
|
98
|
+
examples: `agents auth login
|
|
99
|
+
agents auth whoami
|
|
100
|
+
agents auth whoami --json
|
|
101
|
+
agents auth logout`,
|
|
102
|
+
notes: "`agents auth login` writes its own session, separate from \`rush login\`'s \`~/.rush/user.yaml\` — \`agents auth logout\` never signs you out of \`rush\`. If you're already signed in via \`rush login\`, \`agents auth whoami\`/\`agents org\` use that session automatically; no separate login is required.",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
@@ -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';
|
|
@@ -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[];
|
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';
|
|
@@ -1523,7 +1523,7 @@ export function registerDoctorCommand(program) {
|
|
|
1523
1523
|
console.error(chalk.red('--adopt and --release are mutually exclusive; pass only one.'));
|
|
1524
1524
|
process.exit(1);
|
|
1525
1525
|
}
|
|
1526
|
-
const { adoptShadowingLauncher, releaseAdoptedLauncher } = await import('../lib/shims.js');
|
|
1526
|
+
const { adoptShadowingLauncher, releaseAdoptedLauncher } = await import('../lib/installations/shims.js');
|
|
1527
1527
|
const raw = (opts.adopt || opts.release);
|
|
1528
1528
|
const agent = resolveAgentName(raw);
|
|
1529
1529
|
if (!agent) {
|
package/dist/commands/feed.js
CHANGED
|
@@ -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 });
|
package/dist/commands/hooks.js
CHANGED
|
@@ -7,7 +7,7 @@ import { checkbox } from '@inquirer/prompts';
|
|
|
7
7
|
import { AGENTS, resolveAgentName, formatAgentError, agentLabel, } from '../lib/agents.js';
|
|
8
8
|
import { supports, capableAgents } from '../lib/capabilities.js';
|
|
9
9
|
import { cloneRepo } from '../lib/git.js';
|
|
10
|
-
import { discoverHooksFromRepo, installHooksCentrally, listCentralHooks, listInstalledHooksWithScope, getHookInfo, parseHookManifest, iterHooksCapableVersions, removeHookFromVersion, } from '../lib/hooks.js';
|
|
10
|
+
import { discoverHooksFromRepo, installHooksCentrally, listCentralHooks, listInstalledHooksWithScope, getHookInfo, parseHookManifest, iterHooksCapableVersions, removeHookFromVersion, } from '../lib/hooks/install.js';
|
|
11
11
|
import { listInstalledVersions, getGlobalDefault, syncResourcesToVersion, promptAgentVersionSelection, getVersionHomePath, resolveInstalledAgentTargets, } from '../lib/installations/versions.js';
|
|
12
12
|
import { recordVersionResources } from '../lib/state.js';
|
|
13
13
|
import { isPromptCancelled, isInteractiveTerminal, parseCommaSeparatedList, printWithPager, requireInteractiveSelection, promptRemovalTargets, resolveAgentTargetsAutoInstalling, resolveListFilterOrExit, } from './utils.js';
|
package/dist/commands/import.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* management — same behavior as the first-run `agents setup` import flow.
|
|
22
22
|
*/
|
|
23
23
|
import { withIsolationBoundary } from '../lib/isolation-boundary-report.js';
|
|
24
|
-
import { assertIsolationBoundary, createVersionedAlias } from '../lib/shims.js';
|
|
24
|
+
import { assertIsolationBoundary, createVersionedAlias } from '../lib/installations/shims.js';
|
|
25
25
|
import { markVersionIsolated } from '../lib/installations/versions.js';
|
|
26
26
|
import chalk from 'chalk';
|
|
27
27
|
import ora from 'ora';
|