@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
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as os from 'os';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { getHistoryDir } from '../../state.js';
|
|
4
|
+
import { resolveCodexHome, codexHomeShimBash } from '../../codex-home.js';
|
|
5
|
+
import { codexEditWritableRoots, codexPolicyArgs } from '../../codex-policy.js';
|
|
6
|
+
import { stripForeignConfigDir } from '../adapter.js';
|
|
7
|
+
/**
|
|
8
|
+
* Shim-script single-quoting — identical to the local `shellQuote` in shims.ts
|
|
9
|
+
* (always wraps in single quotes), NOT ssh-exec's variant (which leaves
|
|
10
|
+
* shell-safe strings unquoted). The generated shim's codex launch args must stay
|
|
11
|
+
* byte-for-byte what shims.ts produced, so the quoting moves with the logic.
|
|
12
|
+
*/
|
|
13
|
+
function shimShellQuote(value) {
|
|
14
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
15
|
+
}
|
|
16
|
+
export const codexAdapter = {
|
|
17
|
+
id: 'codex',
|
|
18
|
+
applyExecConfigEnv(result, ctx) {
|
|
19
|
+
if (ctx.version && ctx.versionHome) {
|
|
20
|
+
// On macOS the deep versioned home overflows the Unix-socket SUN_LEN
|
|
21
|
+
// limit for codex's app-server control socket; resolve to a short,
|
|
22
|
+
// SUN_LEN-safe home (migrating once if needed). See codex-home.ts.
|
|
23
|
+
const versionedHome = path.join(ctx.versionHome, '.codex');
|
|
24
|
+
const agentsUserDir = path.dirname(getHistoryDir());
|
|
25
|
+
result.CODEX_HOME = resolveCodexHome(versionedHome, agentsUserDir, ctx.version);
|
|
26
|
+
}
|
|
27
|
+
stripForeignConfigDir(result, ['CODEX_HOME']);
|
|
28
|
+
},
|
|
29
|
+
shimConfigEnvBash(ctx) {
|
|
30
|
+
return codexHomeShimBash(`$VERSION_DIR/home/${ctx.configDirName}`, `$AGENTS_USER_DIR/.codex-homes/$VERSION`);
|
|
31
|
+
},
|
|
32
|
+
shimLaunchArgs() {
|
|
33
|
+
return ` ${[
|
|
34
|
+
'-c',
|
|
35
|
+
'check_for_update_on_startup=false',
|
|
36
|
+
...codexPolicyArgs('edit'),
|
|
37
|
+
].map(shimShellQuote).join(' ')}`;
|
|
38
|
+
},
|
|
39
|
+
shimExecTail(launchArgs) {
|
|
40
|
+
// Codex is special: its `workspace-write` sandbox hardcodes any `.agents/`
|
|
41
|
+
// (and `.codex/`) directory read-only, but agents-cli keeps every worktree at
|
|
42
|
+
// `<repo>/.agents/worktrees/<slug>`, so an in-repo build under a static shim
|
|
43
|
+
// would hit `EROFS`. The shim resolves the repo's `.agents` from `$PWD` at RUN
|
|
44
|
+
// time — worktree-aware, mirroring repoAgentsDirForCwd — and passes it via
|
|
45
|
+
// Codex's own `--add-dir`. `--add-dir` is added only when the resolved
|
|
46
|
+
// `.agents` exists.
|
|
47
|
+
return `_repo_agents=""
|
|
48
|
+
case "$PWD" in
|
|
49
|
+
*/.agents/worktrees/*) _repo_agents="\${PWD%%/.agents/worktrees/*}/.agents" ;;
|
|
50
|
+
*)
|
|
51
|
+
_d="$PWD"
|
|
52
|
+
# Stop before $HOME so a dotfiles repo at $HOME is not treated as the project
|
|
53
|
+
# root (mirrors repoRootForCwd's home exclusion in project-key.ts).
|
|
54
|
+
while [ -n "$_d" ] && [ "$_d" != "/" ] && [ "$_d" != "$HOME" ]; do
|
|
55
|
+
if [ -e "$_d/.git" ]; then _repo_agents="$_d/.agents"; break; fi
|
|
56
|
+
_d=$(dirname "$_d")
|
|
57
|
+
done
|
|
58
|
+
;;
|
|
59
|
+
esac
|
|
60
|
+
if [ -n "$_repo_agents" ] && [ -d "$_repo_agents" ]; then
|
|
61
|
+
exec "$BINARY"${launchArgs} --add-dir "$_repo_agents" "$@"
|
|
62
|
+
fi
|
|
63
|
+
exec "$BINARY"${launchArgs} "$@"`;
|
|
64
|
+
},
|
|
65
|
+
execModeArgs(ctx) {
|
|
66
|
+
const policyMode = ctx.resolvedMode === 'plan' || ctx.resolvedMode === 'skip' ? ctx.resolvedMode : 'edit';
|
|
67
|
+
const writableRoots = [
|
|
68
|
+
...codexEditWritableRoots(ctx.cwd),
|
|
69
|
+
...ctx.addDirs,
|
|
70
|
+
];
|
|
71
|
+
return codexPolicyArgs(policyMode, writableRoots);
|
|
72
|
+
},
|
|
73
|
+
routineModeArgs(cmd, ctx) {
|
|
74
|
+
const policyMode = ctx.mode === 'plan' || ctx.mode === 'skip' ? ctx.mode : 'edit';
|
|
75
|
+
const routineRoots = (ctx.config.allow?.dirs ?? []).map((dir) => {
|
|
76
|
+
if (dir.startsWith('-')) {
|
|
77
|
+
throw new Error(`allow.dirs entries must not start with '-': ${JSON.stringify(dir)}`);
|
|
78
|
+
}
|
|
79
|
+
return dir.replace(/^~/, os.homedir());
|
|
80
|
+
});
|
|
81
|
+
cmd.push(...codexPolicyArgs(policyMode, [...codexEditWritableRoots(), ...routineRoots]));
|
|
82
|
+
},
|
|
83
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { stripForeignConfigDir } from '../adapter.js';
|
|
3
|
+
export const copilotAdapter = {
|
|
4
|
+
id: 'copilot',
|
|
5
|
+
// Copilot honors COPILOT_HOME (relocates ~/.copilot, including settings,
|
|
6
|
+
// mcp-config.json, sessions, logs). Pin it at the per-version home so
|
|
7
|
+
// version switches isolate MCP servers, auth, and session history.
|
|
8
|
+
applyExecConfigEnv(result, ctx) {
|
|
9
|
+
if (ctx.versionHome) {
|
|
10
|
+
result.COPILOT_HOME = path.join(ctx.versionHome, '.copilot');
|
|
11
|
+
}
|
|
12
|
+
stripForeignConfigDir(result, ['COPILOT_HOME']);
|
|
13
|
+
},
|
|
14
|
+
shimConfigEnvBash(ctx) {
|
|
15
|
+
return `
|
|
16
|
+
# GitHub Copilot CLI honors COPILOT_HOME to relocate its config and state
|
|
17
|
+
# (settings.json, mcp-config.json, session-state/, logs/, plugins/). Point
|
|
18
|
+
# it at the versioned home so MCP servers, custom agents, and session
|
|
19
|
+
# history are isolated per copilot version.
|
|
20
|
+
export COPILOT_HOME="$VERSION_DIR/home/${ctx.configDirName}"
|
|
21
|
+
`;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { stripForeignConfigDir } from '../adapter.js';
|
|
3
|
+
export const cursorAdapter = {
|
|
4
|
+
id: 'cursor',
|
|
5
|
+
// Cursor has no config-dir env var (only CURSOR_API_KEY / CURSOR_API_ENDPOINT).
|
|
6
|
+
// Its OAuth token — the login gate — lives at $XDG_CONFIG_HOME/cursor/auth.json
|
|
7
|
+
// (verified empirically: relocating XDG_CONFIG_HOME relocates the login;
|
|
8
|
+
// ~/.cursor/cli-config.json holds only account metadata, not the token). Pin
|
|
9
|
+
// XDG_CONFIG_HOME into the version home so each installed Cursor account
|
|
10
|
+
// authenticates from its own token, isolated per run — no global ~/.cursor
|
|
11
|
+
// symlink swap, so concurrent runs on different accounts never clobber one
|
|
12
|
+
// another. cli-config.json (HOME-relative) has no override and stays on the
|
|
13
|
+
// shared home; only the token is per-account, which is what gates the login.
|
|
14
|
+
applyExecConfigEnv(result, ctx) {
|
|
15
|
+
if (ctx.versionHome) {
|
|
16
|
+
result.XDG_CONFIG_HOME = path.join(ctx.versionHome, '.config');
|
|
17
|
+
}
|
|
18
|
+
stripForeignConfigDir(result);
|
|
19
|
+
},
|
|
20
|
+
execPreModeArgs(ctx) {
|
|
21
|
+
// A configured headless run is the workspace trust decision. Keep this
|
|
22
|
+
// narrower than --yolo/-f, which also bypasses permission checks.
|
|
23
|
+
return ctx.resolvedMode === 'edit' && !ctx.interactive ? ['--trust'] : undefined;
|
|
24
|
+
},
|
|
25
|
+
routineModeArgs(cmd, ctx) {
|
|
26
|
+
if (ctx.mode === 'plan') {
|
|
27
|
+
cmd.push('--plan');
|
|
28
|
+
}
|
|
29
|
+
else if (ctx.mode === 'skip') {
|
|
30
|
+
cmd.push('-f');
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// The configured cwd is the user's workspace trust decision. --trust is
|
|
34
|
+
// narrower than --yolo/-f because it does not bypass tool permissions.
|
|
35
|
+
cmd.push('--trust');
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Droid has no config-dir env pin (exec strips the foreign keys via the registry
|
|
2
|
+
// fallback) and no shim config env. Its only harness quirk is routine autonomy.
|
|
3
|
+
export const droidAdapter = {
|
|
4
|
+
id: 'droid',
|
|
5
|
+
// droid exec defaults to read-only (plan). Escalate autonomy per mode.
|
|
6
|
+
routineModeArgs(cmd, ctx) {
|
|
7
|
+
if (ctx.mode === 'edit') {
|
|
8
|
+
cmd.push('--auto', 'low');
|
|
9
|
+
}
|
|
10
|
+
else if (ctx.mode === 'auto') {
|
|
11
|
+
cmd.push('--auto', 'high');
|
|
12
|
+
}
|
|
13
|
+
else if (ctx.mode === 'skip') {
|
|
14
|
+
cmd.push('--skip-permissions-unsafe');
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Grok has no exec-time config-dir env pin (buildExecEnv's `else` strips the
|
|
2
|
+
// foreign keys — the registry fallback preserves that). It DOES relocate its
|
|
3
|
+
// whole config tree via GROK_HOME in the generated shim.
|
|
4
|
+
export const grokAdapter = {
|
|
5
|
+
id: 'grok',
|
|
6
|
+
shimConfigEnvBash() {
|
|
7
|
+
return `
|
|
8
|
+
# Grok Build uses GROK_HOME to isolate its entire configuration tree
|
|
9
|
+
# (skills, hooks, plugins, agents, memory, sessions, config.toml, MCP, etc.).
|
|
10
|
+
# This gives agents-cli full versioned isolation + resource sync for grok.
|
|
11
|
+
export GROK_HOME="$VERSION_DIR/home/.grok"
|
|
12
|
+
`;
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { stripForeignConfigDir } from '../adapter.js';
|
|
3
|
+
export const kimiAdapter = {
|
|
4
|
+
id: 'kimi',
|
|
5
|
+
// Kimi honors KIMI_CODE_HOME (relocates ~/.kimi-code, including config,
|
|
6
|
+
// skills, hooks, sessions). Pin it at the per-version home.
|
|
7
|
+
applyExecConfigEnv(result, ctx) {
|
|
8
|
+
if (ctx.versionHome) {
|
|
9
|
+
result.KIMI_CODE_HOME = path.join(ctx.versionHome, '.kimi-code');
|
|
10
|
+
}
|
|
11
|
+
stripForeignConfigDir(result, ['KIMI_CODE_HOME']);
|
|
12
|
+
},
|
|
13
|
+
shimConfigEnvBash(ctx) {
|
|
14
|
+
return `
|
|
15
|
+
# Kimi Code CLI honors KIMI_CODE_HOME to relocate ~/.kimi-code (config.toml,
|
|
16
|
+
# mcp.json, sessions, skills, hooks). Point it at the versioned home.
|
|
17
|
+
export KIMI_CODE_HOME="$VERSION_DIR/home/${ctx.configDirName}"
|
|
18
|
+
`;
|
|
19
|
+
},
|
|
20
|
+
execModeArgs(ctx) {
|
|
21
|
+
// kimi's headless prompt mode (`-p`/`--prompt`) is self-contained and REFUSES
|
|
22
|
+
// to be combined with any startup-mode flag: `--plan`, `--auto`, and `--yolo`
|
|
23
|
+
// all abort with "Cannot combine --prompt with --X" (verified against the live
|
|
24
|
+
// kimi CLI). The write-capable modes (edit/auto/skip) all collapse to kimi's
|
|
25
|
+
// default `-p` behavior, which already auto-approves tool calls, so we emit no
|
|
26
|
+
// mode flag. An interactive kimi run defers to the generic modeFlags path.
|
|
27
|
+
if (ctx.interactive)
|
|
28
|
+
return undefined;
|
|
29
|
+
// Plan can't reach here headless — resolveHeadlessMode already downgraded it to
|
|
30
|
+
// auto (kimi's headlessPlan:false); this asserts that invariant so a plan-mode
|
|
31
|
+
// run can never silently mutate the workspace.
|
|
32
|
+
if (ctx.resolvedMode === 'plan') {
|
|
33
|
+
throw new Error(`Internal error: kimi reached headless command build with resolved mode 'plan'; ` +
|
|
34
|
+
`resolveHeadlessMode should have downgraded it to auto (capabilities.headlessPlan is false).`);
|
|
35
|
+
}
|
|
36
|
+
// edit/auto/skip: emit no mode flag — `kimi -p` auto-runs.
|
|
37
|
+
return [];
|
|
38
|
+
},
|
|
39
|
+
routineModeArgs(_cmd, ctx) {
|
|
40
|
+
// kimi daemon jobs always run headless via `--prompt`, which cannot be
|
|
41
|
+
// combined with any startup-mode flag (--plan/--auto/--yolo all abort with
|
|
42
|
+
// "Cannot combine --prompt with --X"). edit/auto/skip reduce to kimi's default
|
|
43
|
+
// headless auto-run, so emit no flag. plan has no headless read-only
|
|
44
|
+
// equivalent, so resolveHeadlessMode downgrades a plan request to auto with a
|
|
45
|
+
// stderr warning (kimi's headlessPlan is false) — routines run headless, so
|
|
46
|
+
// interactive is always false here. The returned mode carries no flag either.
|
|
47
|
+
ctx.resolveHeadlessMode('kimi', ctx.mode, false);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { stripForeignConfigDir } from '../adapter.js';
|
|
3
|
+
export const museAdapter = {
|
|
4
|
+
id: 'muse',
|
|
5
|
+
// Muse has no MUSE_CONFIG_DIR. Config is XDG-based:
|
|
6
|
+
// $XDG_CONFIG_HOME/muse (settings, skills, hooks, auth)
|
|
7
|
+
// $XDG_DATA_HOME/muse (sessions, plugins)
|
|
8
|
+
// Pin both into the version home so multi-version isolation matches
|
|
9
|
+
// Claude's CLAUDE_CONFIG_DIR / Codex's CODEX_HOME, and so Muse never
|
|
10
|
+
// resolves through the adopt-time ~/.config/muse symlink (SymlinkOrReparse).
|
|
11
|
+
applyExecConfigEnv(result, ctx) {
|
|
12
|
+
if (ctx.versionHome) {
|
|
13
|
+
result.XDG_CONFIG_HOME = path.join(ctx.versionHome, '.config');
|
|
14
|
+
result.XDG_DATA_HOME = path.join(ctx.versionHome, '.local', 'share');
|
|
15
|
+
}
|
|
16
|
+
stripForeignConfigDir(result);
|
|
17
|
+
},
|
|
18
|
+
shimConfigEnvBash() {
|
|
19
|
+
return `
|
|
20
|
+
# Muse Code has no MUSE_CONFIG_DIR. It resolves config via XDG:
|
|
21
|
+
# $XDG_CONFIG_HOME/muse (settings, skills, hooks, auth)
|
|
22
|
+
# $XDG_DATA_HOME/muse (sessions, plugins)
|
|
23
|
+
# Pin XDG into the version home so managed runs never walk the adopt-time
|
|
24
|
+
# ~/.config/muse -> version-home symlink — Muse refuses agent-definition
|
|
25
|
+
# sources that are SymlinkOrReparse (exit 1). Same idea as CLAUDE_CONFIG_DIR.
|
|
26
|
+
export XDG_CONFIG_HOME="$VERSION_DIR/home/.config"
|
|
27
|
+
export XDG_DATA_HOME="$VERSION_DIR/home/.local/share"
|
|
28
|
+
`;
|
|
29
|
+
},
|
|
30
|
+
// muse exec: plan ≈ no non-shell writes; auto skips approval prompts but
|
|
31
|
+
// keeps the OS sandbox; skip is --yolo (no approval, no sandbox, trust).
|
|
32
|
+
routineModeArgs(cmd, ctx) {
|
|
33
|
+
if (ctx.mode === 'plan') {
|
|
34
|
+
cmd.push('--disable-write');
|
|
35
|
+
}
|
|
36
|
+
else if (ctx.mode === 'auto') {
|
|
37
|
+
cmd.push('--disable-approval');
|
|
38
|
+
}
|
|
39
|
+
else if (ctx.mode === 'skip') {
|
|
40
|
+
cmd.push('--yolo');
|
|
41
|
+
}
|
|
42
|
+
// edit: default on-request approval + sandbox
|
|
43
|
+
},
|
|
44
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// OpenCode has no exec-time config-dir env pin (buildExecEnv's `else` strips the
|
|
2
|
+
// foreign keys — the registry fallback preserves that). It reads config-directory
|
|
3
|
+
// resources from OPENCODE_CONFIG_DIR, pinned in the generated shim.
|
|
4
|
+
export const opencodeAdapter = {
|
|
5
|
+
id: 'opencode',
|
|
6
|
+
shimConfigEnvBash() {
|
|
7
|
+
return `
|
|
8
|
+
# OpenCode reads plugins, agents, commands, and other config-directory
|
|
9
|
+
# resources from OPENCODE_CONFIG_DIR. Point it at the versioned global config
|
|
10
|
+
# tree where agents-cli syncs OpenCode resources.
|
|
11
|
+
export OPENCODE_CONFIG_DIR="$VERSION_DIR/home/.config/opencode"
|
|
12
|
+
`;
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentId } from '../types.js';
|
|
2
|
+
export interface ResolvedConfigVersion {
|
|
3
|
+
/** The version to pin, or null when unresolved / not installed. */
|
|
4
|
+
version: string | null;
|
|
5
|
+
/** The version home for that version, or null. */
|
|
6
|
+
versionHome: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveConfigVersion(agent: AgentId, cwd: string, optionsVersion?: string): ResolvedConfigVersion;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared version resolution for the exec-time config-dir env pin. Every
|
|
3
|
+
* config-dir harness branch in the old buildExecEnv computed this identically:
|
|
4
|
+
* an explicit `--version` is used unconditionally; an auto-resolved version is
|
|
5
|
+
* only pinned when it is actually installed on disk.
|
|
6
|
+
*
|
|
7
|
+
* The caller (buildExecEnv) invokes this and passes the result into the adapter
|
|
8
|
+
* via ExecConfigEnvCtx — the adapters MUST NOT import installations/versions
|
|
9
|
+
* themselves, because that module imports shims.ts and shims.ts imports the
|
|
10
|
+
* harness barrel, which would close an import cycle (versions → shims → harness →
|
|
11
|
+
* adapter → versions). That cycle forced esbuild/tsx to emit CJS for part of the
|
|
12
|
+
* graph and broke sqlite.ts's top-level await in subprocess-spawning tests.
|
|
13
|
+
*/
|
|
14
|
+
import { getVersionHomePath, isVersionInstalled, resolveVersion } from '../installations/versions.js';
|
|
15
|
+
export function resolveConfigVersion(agent, cwd, optionsVersion) {
|
|
16
|
+
const resolvedVersion = optionsVersion ?? resolveVersion(agent, cwd);
|
|
17
|
+
const version = optionsVersion
|
|
18
|
+
? resolvedVersion
|
|
19
|
+
: (resolvedVersion && isVersionInstalled(agent, resolvedVersion) ? resolvedVersion : null);
|
|
20
|
+
const versionHome = version ? getVersionHomePath(agent, version) : null;
|
|
21
|
+
return { version: version ?? null, versionHome };
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { type HarnessAdapter, type ExecConfigEnvCtx, type ShimConfigEnvCtx, type ExecLaunchArgsCtx, type RoutineLaunchCtx, CONFIG_DIR_ENV_KEYS, stripForeignConfigDir, registerHarnessAdapter, resolveHarnessAdapter, listHarnessAdapters, } from './adapter.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness adapter barrel — importing this registers every built-in adapter, the
|
|
3
|
+
* same pattern as lib/channels/providers/index.ts. Consumers import
|
|
4
|
+
* `resolveHarnessAdapter` from here (not from ./adapter.js directly) so the
|
|
5
|
+
* registration side-effect has run before the first resolve.
|
|
6
|
+
*
|
|
7
|
+
* A harness with no config-env / launch quirks needs no adapter file: every
|
|
8
|
+
* `AgentId` still resolves (to the id-only default), so call sites never
|
|
9
|
+
* name-check a harness.
|
|
10
|
+
*/
|
|
11
|
+
import { registerHarnessAdapter } from './adapter.js';
|
|
12
|
+
import { claudeAdapter } from './adapters/claude.js';
|
|
13
|
+
import { codexAdapter } from './adapters/codex.js';
|
|
14
|
+
import { copilotAdapter } from './adapters/copilot.js';
|
|
15
|
+
import { kimiAdapter } from './adapters/kimi.js';
|
|
16
|
+
import { museAdapter } from './adapters/muse.js';
|
|
17
|
+
import { cursorAdapter } from './adapters/cursor.js';
|
|
18
|
+
import { grokAdapter } from './adapters/grok.js';
|
|
19
|
+
import { opencodeAdapter } from './adapters/opencode.js';
|
|
20
|
+
import { droidAdapter } from './adapters/droid.js';
|
|
21
|
+
for (const adapter of [
|
|
22
|
+
claudeAdapter,
|
|
23
|
+
codexAdapter,
|
|
24
|
+
copilotAdapter,
|
|
25
|
+
kimiAdapter,
|
|
26
|
+
museAdapter,
|
|
27
|
+
cursorAdapter,
|
|
28
|
+
grokAdapter,
|
|
29
|
+
opencodeAdapter,
|
|
30
|
+
droidAdapter,
|
|
31
|
+
]) {
|
|
32
|
+
registerHarnessAdapter(adapter);
|
|
33
|
+
}
|
|
34
|
+
export { CONFIG_DIR_ENV_KEYS, stripForeignConfigDir, registerHarnessAdapter, resolveHarnessAdapter, listHarnessAdapters, } from './adapter.js';
|
|
@@ -28,7 +28,7 @@ export declare function toPortableCommand(absPath: string, home?: string, sep?:
|
|
|
28
28
|
* outside version homes are user-owned and remain untouched.
|
|
29
29
|
*/
|
|
30
30
|
export declare function deduplicateVersionHookCommands(commands: string[], activeVersionHome: string): string[];
|
|
31
|
-
import type { AgentId, HookCacheConfig, HookMatches, InstalledHook, ManifestHook } from '
|
|
31
|
+
import type { AgentId, HookCacheConfig, HookMatches, InstalledHook, ManifestHook } from '../types.js';
|
|
32
32
|
export type HookEntry = {
|
|
33
33
|
name: string;
|
|
34
34
|
scriptPath: string;
|
|
@@ -16,10 +16,10 @@ import * as TOML from 'smol-toml';
|
|
|
16
16
|
import { execFile, execFileSync } from 'child_process';
|
|
17
17
|
import { promisify } from 'util';
|
|
18
18
|
import { fileURLToPath } from 'url';
|
|
19
|
-
import { AGENTS, agentConfigDirName, isAgentHardDeprecated } from '
|
|
20
|
-
import { supports, explainSkip, capableAgents } from '
|
|
21
|
-
import { getHooksDir as getSystemHooksDir, getUserHooksDir, getUserAgentsDir, getSystemAgentsDir, getProjectAgentsDir, getTrashHooksDir, getEnabledExtraRepos, getResolvedRulesDir, getUserRulesDir, getPerfDir } from '
|
|
22
|
-
import { collectSubruleHooksFromState } from '
|
|
19
|
+
import { AGENTS, agentConfigDirName, isAgentHardDeprecated } from '../agents.js';
|
|
20
|
+
import { supports, explainSkip, capableAgents } from '../capabilities.js';
|
|
21
|
+
import { getHooksDir as getSystemHooksDir, getUserHooksDir, getUserAgentsDir, getSystemAgentsDir, getProjectAgentsDir, getTrashHooksDir, getEnabledExtraRepos, getResolvedRulesDir, getUserRulesDir, getPerfDir } from '../state.js';
|
|
22
|
+
import { collectSubruleHooksFromState } from '../rules/compose.js';
|
|
23
23
|
function getCentralHooksDir() { return getUserHooksDir(); }
|
|
24
24
|
/**
|
|
25
25
|
* Resolve a hook script's absolute path. Checks user dir first, then enabled
|
|
@@ -267,9 +267,9 @@ function collapseVersionHookEntries(entries, activeVersionHome) {
|
|
|
267
267
|
return true;
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
|
-
import { getEffectiveHome, getGlobalDefault, getVersionHomePath, isVersionIsolated, listInstalledVersions, resolveVersion, } from '
|
|
271
|
-
import { generateHookShim, getHookShimPath, isValidHookShimName, parseCacheConfig, removeHookShim } from './
|
|
272
|
-
import { getHookShimsDir } from '
|
|
270
|
+
import { getEffectiveHome, getGlobalDefault, getVersionHomePath, isVersionIsolated, listInstalledVersions, resolveVersion, } from '../installations/versions.js';
|
|
271
|
+
import { generateHookShim, getHookShimPath, isValidHookShimName, parseCacheConfig, removeHookShim } from './cache.js';
|
|
272
|
+
import { getHookShimsDir } from '../state.js';
|
|
273
273
|
function hookContentHash(scriptPath) {
|
|
274
274
|
return crypto.createHash('sha256').update(fs.readFileSync(scriptPath)).digest('hex');
|
|
275
275
|
}
|
|
@@ -3250,13 +3250,13 @@ function registerHooksForHermes(versionHome, manifest, resolveScript, managedPre
|
|
|
3250
3250
|
const execFileAsync = promisify(execFile);
|
|
3251
3251
|
function resolveSessionTrackerRoot() {
|
|
3252
3252
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
3253
|
-
// Built/installed layout: dist/lib/ -> dist/session-tracker
|
|
3254
|
-
const built = path.resolve(here, '..', 'session-tracker');
|
|
3253
|
+
// Built/installed layout: dist/lib/hooks/ -> dist/session-tracker
|
|
3254
|
+
const built = path.resolve(here, '..', '..', 'session-tracker');
|
|
3255
3255
|
if (fs.existsSync(path.join(built, 'dist', 'hook.sh'))) {
|
|
3256
3256
|
return built;
|
|
3257
3257
|
}
|
|
3258
|
-
// Source layout: apps/cli/src/lib/ -> repo root -> packages/session-tracker
|
|
3259
|
-
const source = path.resolve(here, '..', '..', '..', '..', 'packages', 'session-tracker');
|
|
3258
|
+
// Source layout: apps/cli/src/lib/hooks/ -> repo root -> packages/session-tracker
|
|
3259
|
+
const source = path.resolve(here, '..', '..', '..', '..', '..', 'packages', 'session-tracker');
|
|
3260
3260
|
if (fs.existsSync(path.join(source, 'src', 'hook.sh'))) {
|
|
3261
3261
|
return source;
|
|
3262
3262
|
}
|
|
@@ -48,6 +48,16 @@ export declare const REMOTE_PASSTHROUGH: Record<string, RemoteSpec>;
|
|
|
48
48
|
* these to {@link REMOTE_PASSTHROUGH}.
|
|
49
49
|
*/
|
|
50
50
|
export declare const OWN_HOST_COMMANDS: Set<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Argv forwarded over SSH for a `--device` passthrough.
|
|
53
|
+
*
|
|
54
|
+
* `sync`'s umbrella spec appends `--yes` when there is no TTY so a remote
|
|
55
|
+
* reconcile does not hang on a picker. `sync status` is inspect-only unless the
|
|
56
|
+
* caller typed `--yes` themselves: `--yes` on that command is reconcile, not
|
|
57
|
+
* "don't prompt". Nesting it under `sync` must not inherit the umbrella flag
|
|
58
|
+
* (RUSH-2864).
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildPassthroughForwardedArgs(command: string, allArgs: string[], interactive: boolean): string[];
|
|
51
61
|
/** Injectable dependencies for {@link runFleetPassthrough} — used by tests. */
|
|
52
62
|
export interface FleetPassthroughOptions {
|
|
53
63
|
/** Override the device registry loader (tests). */
|
|
@@ -52,11 +52,10 @@ export { flagValue, hasHostRoutingFlag } from './routing-flag.js';
|
|
|
52
52
|
* `add`/`use`/`list`, and none) and were removed.
|
|
53
53
|
*/
|
|
54
54
|
export const REMOTE_PASSTHROUGH = {
|
|
55
|
-
//
|
|
55
|
+
// inspect
|
|
56
56
|
view: {},
|
|
57
57
|
inspect: {},
|
|
58
58
|
doctor: {},
|
|
59
|
-
status: {},
|
|
60
59
|
check: {},
|
|
61
60
|
list: {},
|
|
62
61
|
usage: {},
|
|
@@ -81,7 +80,6 @@ export const REMOTE_PASSTHROUGH = {
|
|
|
81
80
|
workflows: {},
|
|
82
81
|
models: {},
|
|
83
82
|
defaults: {},
|
|
84
|
-
alias: {},
|
|
85
83
|
// Installations are per-machine, so updating one on a peer means running it
|
|
86
84
|
// there — the same local/remote shape `add` would need.
|
|
87
85
|
update: {},
|
|
@@ -137,6 +135,32 @@ const STRIP_SPECS = [
|
|
|
137
135
|
{ long: 'hosts', takesValue: true },
|
|
138
136
|
{ long: 'devices', takesValue: true },
|
|
139
137
|
];
|
|
138
|
+
/** First non-flag token after `group` in argv (the subcommand, robust to leading flags). */
|
|
139
|
+
function firstSubcommand(allArgs, group) {
|
|
140
|
+
const idx = allArgs.indexOf(group);
|
|
141
|
+
return idx >= 0 ? allArgs.slice(idx + 1).find((a) => !a.startsWith('-')) : undefined;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Argv forwarded over SSH for a `--device` passthrough.
|
|
145
|
+
*
|
|
146
|
+
* `sync`'s umbrella spec appends `--yes` when there is no TTY so a remote
|
|
147
|
+
* reconcile does not hang on a picker. `sync status` is inspect-only unless the
|
|
148
|
+
* caller typed `--yes` themselves: `--yes` on that command is reconcile, not
|
|
149
|
+
* "don't prompt". Nesting it under `sync` must not inherit the umbrella flag
|
|
150
|
+
* (RUSH-2864).
|
|
151
|
+
*/
|
|
152
|
+
export function buildPassthroughForwardedArgs(command, allArgs, interactive) {
|
|
153
|
+
const spec = REMOTE_PASSTHROUGH[command];
|
|
154
|
+
let forwarded = stripRoutingFlags(allArgs, STRIP_SPECS);
|
|
155
|
+
// Detect the subcommand on the *stripped* argv. On the raw argv,
|
|
156
|
+
// `sync --device peer status` would treat `peer` as the first non-flag
|
|
157
|
+
// token and inherit umbrella `--yes` (RUSH-2864 review).
|
|
158
|
+
const skipInheritedYes = command === 'sync' && firstSubcommand(forwarded, 'sync') === 'status';
|
|
159
|
+
if (!interactive && spec?.nonInteractive && !skipInheritedYes) {
|
|
160
|
+
forwarded = [...forwarded, ...spec.nonInteractive];
|
|
161
|
+
}
|
|
162
|
+
return forwarded;
|
|
163
|
+
}
|
|
140
164
|
/** Synthesize a `Host` for a raw `user@host` / bare-alias target (not enrolled). */
|
|
141
165
|
function syntheticHost(target) {
|
|
142
166
|
const at = target.indexOf('@');
|
|
@@ -531,9 +555,7 @@ export async function maybeRunOnHost(command, allArgs, opts) {
|
|
|
531
555
|
// out — otherwise force the command's non-interactive path so no half-drawn
|
|
532
556
|
// picker is piped into a file or another program.
|
|
533
557
|
const interactive = !!process.stdout.isTTY && !allArgs.includes('--no-tty');
|
|
534
|
-
|
|
535
|
-
if (!interactive && spec.nonInteractive)
|
|
536
|
-
forwarded = [...forwarded, ...spec.nonInteractive];
|
|
558
|
+
const forwarded = buildPassthroughForwardedArgs(command, allArgs, interactive);
|
|
537
559
|
// The one long-running case: keep the remote team supervisor alive past a
|
|
538
560
|
// disconnect by dispatching it detached (nohup), still streaming live.
|
|
539
561
|
const isWatchedTeamStart = command === 'teams' && forwarded[1] === 'start' && forwarded.includes('--watch');
|
|
@@ -21,7 +21,7 @@ import { upsertSession } from '../session/db.js';
|
|
|
21
21
|
import { isSessionTrackedAgent } from '../session/types.js';
|
|
22
22
|
import { localLogPath, updateTask } from './tasks.js';
|
|
23
23
|
import { parseSessionIdMarker } from './session-marker.js';
|
|
24
|
-
import { deriveShortId } from '../
|
|
24
|
+
import { deriveShortId } from '../text/short-id.js';
|
|
25
25
|
import { normalizeHost } from '../machine-id.js';
|
|
26
26
|
/**
|
|
27
27
|
* Build the SessionMeta for a host-dispatched run. Returns null when the run has
|
package/dist/lib/import.js
CHANGED
|
@@ -22,7 +22,7 @@ import * as path from 'path';
|
|
|
22
22
|
import { AGENTS, resolveNativeBinaryPath } from './agents.js';
|
|
23
23
|
import { getUserAgentsDir, getVersionsDir } from './state.js';
|
|
24
24
|
import { setGlobalDefault } from './installations/versions.js';
|
|
25
|
-
import { createShim, createVersionedAlias, ensureShimCurrent, switchHomeFileSymlinks, assertIsolationBoundary } from './shims.js';
|
|
25
|
+
import { createShim, createVersionedAlias, ensureShimCurrent, switchHomeFileSymlinks, assertIsolationBoundary } from './installations/shims.js';
|
|
26
26
|
const IMPORT_VERSION_RE = /^(?:latest|[A-Za-z0-9._+-]{1,64})$/;
|
|
27
27
|
export function isValidImportVersion(version) {
|
|
28
28
|
return IMPORT_VERSION_RE.test(version);
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* it, so the internal split can change without breaking callers (the Cursor
|
|
8
8
|
* per-installation isolation track consumes exactly this).
|
|
9
9
|
*/
|
|
10
|
-
export {
|
|
11
|
-
export { createInstallation,
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
10
|
+
export { type Installation, type InstallationRelease, type UpdateOutcome, type UpdateStrategyId, } from './types.js';
|
|
11
|
+
export { createInstallation, listInstallations, recordRelease, } from './store.js';
|
|
12
|
+
export { describeInstallation, resolveInstallation, type ResolveInstallationOptions, } from './resolve.js';
|
|
13
|
+
export { selectUpdateStrategy, supportsPinnedUpdate, type UpdateStrategy, } from './strategies.js';
|
|
14
14
|
export { updateInstallation, type UpdateInstallationOptions } from './update.js';
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
* it, so the internal split can change without breaking callers (the Cursor
|
|
8
8
|
* per-installation isolation track consumes exactly this).
|
|
9
9
|
*/
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
export { assertValidRelease, selectUpdateStrategy, supportsPinnedUpdate, } from './strategies.js';
|
|
10
|
+
export { createInstallation, listInstallations, recordRelease, } from './store.js';
|
|
11
|
+
export { describeInstallation, resolveInstallation, } from './resolve.js';
|
|
12
|
+
export { selectUpdateStrategy, supportsPinnedUpdate, } from './strategies.js';
|
|
14
13
|
export { updateInstallation } from './update.js';
|
|
@@ -23,7 +23,7 @@ import { evaluateActivationReadiness } from '../routine-readiness.js';
|
|
|
23
23
|
import { migrateDeviceConfigStores } from '../devices/config-migration.js';
|
|
24
24
|
// Two constants only, never the read/write API — migrations still operate on raw
|
|
25
25
|
// YAML so they never take the meta lock or prime the meta cache mid-migration.
|
|
26
|
-
import {
|
|
26
|
+
import { LEGACY_DEFAULT_BROWSER_PROFILE_NAME } from '../browser/profiles.js';
|
|
27
27
|
import { META_HEADER as DEVICE_META_HEADER } from '../state.js';
|
|
28
28
|
import { COMPILED_HEADER_PROJECT } from '../rules/compile.js';
|
|
29
29
|
const HOME = process.env.HOME ?? os.homedir();
|
|
@@ -1763,7 +1763,7 @@ export function migrateMachineLocalBrowserProfileOutOfCentral(userDir = USER_DIR
|
|
|
1763
1763
|
const browser = central.browser;
|
|
1764
1764
|
if (!browser || typeof browser !== 'object' || Array.isArray(browser))
|
|
1765
1765
|
return;
|
|
1766
|
-
const entry = browser[
|
|
1766
|
+
const entry = browser[LEGACY_DEFAULT_BROWSER_PROFILE_NAME];
|
|
1767
1767
|
if (entry === undefined)
|
|
1768
1768
|
return;
|
|
1769
1769
|
// Device file first — a crash before central is rewritten leaves a harmless
|
|
@@ -1777,15 +1777,15 @@ export function migrateMachineLocalBrowserProfileOutOfCentral(userDir = USER_DIR
|
|
|
1777
1777
|
const deviceBrowser = (deviceDoc.browser && typeof deviceDoc.browser === 'object' && !Array.isArray(deviceDoc.browser))
|
|
1778
1778
|
? deviceDoc.browser
|
|
1779
1779
|
: {};
|
|
1780
|
-
if (deviceBrowser[
|
|
1781
|
-
deviceBrowser[
|
|
1780
|
+
if (deviceBrowser[LEGACY_DEFAULT_BROWSER_PROFILE_NAME] === undefined) {
|
|
1781
|
+
deviceBrowser[LEGACY_DEFAULT_BROWSER_PROFILE_NAME] = entry;
|
|
1782
1782
|
deviceDoc.browser = deviceBrowser;
|
|
1783
1783
|
fs.mkdirSync(path.dirname(devicePath), { recursive: true });
|
|
1784
1784
|
atomicWriteFileSync(devicePath, DEVICE_META_HEADER + yaml.stringify(deviceDoc));
|
|
1785
1785
|
}
|
|
1786
1786
|
// Then strip it from the synced file, dropping `browser:` entirely when the
|
|
1787
1787
|
// machine-local entry was its only member.
|
|
1788
|
-
doc.deleteIn(['browser',
|
|
1788
|
+
doc.deleteIn(['browser', LEGACY_DEFAULT_BROWSER_PROFILE_NAME]);
|
|
1789
1789
|
if (Object.keys(browser).length === 1) {
|
|
1790
1790
|
const itemsOf = () => (doc.contents?.items) ?? [];
|
|
1791
1791
|
const idx = itemsOf().findIndex((pair) => pair.key?.value === 'browser');
|
|
@@ -1806,7 +1806,7 @@ export function migrateMachineLocalBrowserProfileOutOfCentral(userDir = USER_DIR
|
|
|
1806
1806
|
// the identical case (state.ts, `isEmpty ? META_HEADER : stringifyDoc(doc)`).
|
|
1807
1807
|
const remaining = Object.keys(doc.toJSON() ?? {}).length;
|
|
1808
1808
|
atomicWriteFileSync(metaFile, remaining === 0 ? DEVICE_META_HEADER : stringifyDoc(doc));
|
|
1809
|
-
console.error(`Migrated agents.yaml: browser '${
|
|
1809
|
+
console.error(`Migrated agents.yaml: browser '${LEGACY_DEFAULT_BROWSER_PROFILE_NAME}' profile -> devices/${machine}/agents.yaml`);
|
|
1810
1810
|
}
|
|
1811
1811
|
/**
|
|
1812
1812
|
* Rename the legacy `extras-extras/` plugin-marketplace dir to `agents-extras/`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AgentId } from '
|
|
2
|
-
import { getShimsDir } from '
|
|
1
|
+
import type { AgentId } from '../types.js';
|
|
2
|
+
import { getShimsDir } from '../state.js';
|
|
3
3
|
export { getShimsDir };
|
|
4
4
|
/**
|
|
5
5
|
* Strategy for handling file conflicts during config migration.
|