@phnx-labs/agents-cli 1.20.4 → 1.20.6
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 +19 -0
- package/README.md +49 -18
- package/dist/commands/browser.js +31 -4
- package/dist/commands/cli.js +1 -1
- package/dist/commands/cloud.js +1 -1
- package/dist/commands/commands.js +2 -0
- package/dist/commands/computer.js +10 -2
- package/dist/commands/defaults.d.ts +7 -0
- package/dist/commands/defaults.js +89 -0
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/exec.js +73 -19
- package/dist/commands/hooks.js +6 -6
- package/dist/commands/inspect.d.ts +26 -0
- package/dist/commands/inspect.js +590 -0
- package/dist/commands/mcp.js +17 -16
- package/dist/commands/models.js +1 -1
- package/dist/commands/packages.js +6 -4
- package/dist/commands/permissions.js +13 -12
- package/dist/commands/plugins.d.ts +13 -0
- package/dist/commands/plugins.js +100 -11
- package/dist/commands/prune.js +3 -2
- package/dist/commands/pull.d.ts +12 -5
- package/dist/commands/pull.js +26 -422
- package/dist/commands/push.d.ts +14 -0
- package/dist/commands/push.js +30 -0
- package/dist/commands/repo.d.ts +1 -1
- package/dist/commands/repo.js +155 -112
- package/dist/commands/resource-view.d.ts +2 -0
- package/dist/commands/resource-view.js +12 -3
- package/dist/commands/routines.js +32 -7
- package/dist/commands/rules.js +4 -4
- package/dist/commands/secrets.js +46 -9
- package/dist/commands/sessions.js +1 -0
- package/dist/commands/setup.d.ts +3 -3
- package/dist/commands/setup.js +17 -17
- package/dist/commands/skills.js +6 -5
- package/dist/commands/subagents.js +5 -4
- package/dist/commands/sync.d.ts +18 -5
- package/dist/commands/sync.js +251 -65
- package/dist/commands/teams.js +109 -11
- package/dist/commands/tmux.d.ts +25 -0
- package/dist/commands/tmux.js +415 -0
- package/dist/commands/trash.d.ts +2 -2
- package/dist/commands/trash.js +1 -1
- package/dist/commands/versions.js +2 -2
- package/dist/commands/view.d.ts +12 -1
- package/dist/commands/view.js +128 -40
- package/dist/commands/workflows.js +4 -3
- package/dist/commands/worktree.d.ts +4 -5
- package/dist/commands/worktree.js +4 -4
- package/dist/index.js +106 -41
- package/dist/lib/agents.d.ts +23 -10
- package/dist/lib/agents.js +88 -25
- package/dist/lib/auto-pull-worker.d.ts +1 -1
- package/dist/lib/auto-pull-worker.js +2 -2
- package/dist/lib/auto-pull.d.ts +1 -1
- package/dist/lib/auto-pull.js +1 -1
- package/dist/lib/beta.d.ts +1 -1
- package/dist/lib/beta.js +1 -1
- package/dist/lib/browser/chrome.d.ts +10 -0
- package/dist/lib/browser/chrome.js +84 -3
- package/dist/lib/capabilities.js +2 -0
- package/dist/lib/commands.d.ts +28 -1
- package/dist/lib/commands.js +125 -20
- package/dist/lib/doctor-diff.js +2 -2
- package/dist/lib/exec.d.ts +14 -0
- package/dist/lib/exec.js +59 -5
- package/dist/lib/fuzzy.d.ts +12 -2
- package/dist/lib/fuzzy.js +29 -4
- package/dist/lib/git.js +8 -1
- package/dist/lib/hooks.d.ts +2 -2
- package/dist/lib/hooks.js +97 -10
- package/dist/lib/mcp.js +32 -2
- package/dist/lib/migrate.d.ts +51 -0
- package/dist/lib/migrate.js +233 -5
- package/dist/lib/models.js +62 -15
- package/dist/lib/permissions.d.ts +59 -2
- package/dist/lib/permissions.js +299 -7
- package/dist/lib/plugin-marketplace.d.ts +98 -40
- package/dist/lib/plugin-marketplace.js +196 -93
- package/dist/lib/plugins.d.ts +21 -4
- package/dist/lib/plugins.js +130 -49
- package/dist/lib/profiles-presets.js +12 -12
- package/dist/lib/project-launch.d.ts +70 -0
- package/dist/lib/project-launch.js +404 -0
- package/dist/lib/pty-client.js +1 -1
- package/dist/lib/pty-server.d.ts +1 -1
- package/dist/lib/pty-server.js +8 -5
- package/dist/lib/refresh.d.ts +26 -0
- package/dist/lib/refresh.js +315 -0
- package/dist/lib/resource-patterns.d.ts +1 -1
- package/dist/lib/resource-patterns.js +1 -1
- package/dist/lib/resources/commands.js +2 -2
- package/dist/lib/resources/hooks.d.ts +1 -1
- package/dist/lib/resources/hooks.js +1 -1
- package/dist/lib/resources/mcp.d.ts +1 -1
- package/dist/lib/resources/mcp.js +5 -6
- package/dist/lib/resources/permissions.js +5 -2
- package/dist/lib/resources/rules.js +3 -2
- package/dist/lib/resources/skills.js +3 -2
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +2 -0
- package/dist/lib/resources.js +4 -3
- package/dist/lib/rotate.d.ts +1 -1
- package/dist/lib/rotate.js +7 -19
- package/dist/lib/routines.d.ts +16 -4
- package/dist/lib/routines.js +67 -17
- package/dist/lib/rules/compile.js +22 -10
- package/dist/lib/rules/rules.js +3 -3
- package/dist/lib/run-config.d.ts +9 -0
- package/dist/lib/run-config.js +35 -0
- package/dist/lib/run-defaults.d.ts +42 -0
- package/dist/lib/run-defaults.js +180 -0
- package/dist/lib/runner.js +16 -3
- package/dist/lib/scheduler.js +15 -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/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +9 -1
- package/dist/lib/secrets/Agents CLI.app/Contents/embedded.provisionprofile +0 -0
- package/dist/lib/secrets/install-helper.d.ts +11 -3
- package/dist/lib/secrets/install-helper.js +48 -6
- package/dist/lib/secrets/linux.d.ts +56 -9
- package/dist/lib/secrets/linux.js +327 -59
- package/dist/lib/session/db.js +15 -2
- package/dist/lib/session/discover.js +118 -3
- package/dist/lib/session/parse.js +3 -0
- package/dist/lib/session/types.d.ts +1 -1
- package/dist/lib/session/types.js +1 -1
- package/dist/lib/shims.d.ts +18 -9
- package/dist/lib/shims.js +133 -50
- package/dist/lib/skills.d.ts +1 -1
- package/dist/lib/skills.js +10 -9
- package/dist/lib/staleness/detectors/commands.d.ts +3 -0
- package/dist/lib/staleness/detectors/commands.js +46 -0
- package/dist/lib/staleness/detectors/hooks.d.ts +3 -0
- package/dist/lib/staleness/detectors/hooks.js +44 -0
- package/dist/lib/staleness/detectors/mcp.d.ts +3 -0
- package/dist/lib/staleness/detectors/mcp.js +31 -0
- package/dist/lib/staleness/detectors/permissions.d.ts +3 -0
- package/dist/lib/staleness/detectors/permissions.js +201 -0
- package/dist/lib/staleness/detectors/plugins.d.ts +8 -0
- package/dist/lib/staleness/detectors/plugins.js +23 -0
- package/dist/lib/staleness/detectors/rules.d.ts +3 -0
- package/dist/lib/staleness/detectors/rules.js +34 -0
- package/dist/lib/staleness/detectors/skills.d.ts +3 -0
- package/dist/lib/staleness/detectors/skills.js +71 -0
- package/dist/lib/staleness/detectors/subagents.d.ts +3 -0
- package/dist/lib/staleness/detectors/subagents.js +50 -0
- package/dist/lib/staleness/detectors/types.d.ts +22 -0
- package/dist/lib/staleness/detectors/types.js +1 -0
- package/dist/lib/staleness/detectors/workflows.d.ts +3 -0
- package/dist/lib/staleness/detectors/workflows.js +28 -0
- package/dist/lib/staleness/registry.d.ts +26 -0
- package/dist/lib/staleness/registry.js +123 -0
- package/dist/lib/staleness/writers/commands.d.ts +3 -0
- package/dist/lib/staleness/writers/commands.js +111 -0
- package/dist/lib/staleness/writers/hooks.d.ts +3 -0
- package/dist/lib/staleness/writers/hooks.js +47 -0
- package/dist/lib/staleness/writers/kinds.d.ts +10 -0
- package/dist/lib/staleness/writers/kinds.js +15 -0
- package/dist/lib/staleness/writers/lazy-map.d.ts +13 -0
- package/dist/lib/staleness/writers/lazy-map.js +19 -0
- package/dist/lib/staleness/writers/mcp.d.ts +10 -0
- package/dist/lib/staleness/writers/mcp.js +19 -0
- package/dist/lib/staleness/writers/permissions.d.ts +13 -0
- package/dist/lib/staleness/writers/permissions.js +26 -0
- package/dist/lib/staleness/writers/plugins.d.ts +7 -0
- package/dist/lib/staleness/writers/plugins.js +31 -0
- package/dist/lib/staleness/writers/rules.d.ts +7 -0
- package/dist/lib/staleness/writers/rules.js +55 -0
- package/dist/lib/staleness/writers/skills.d.ts +3 -0
- package/dist/lib/staleness/writers/skills.js +81 -0
- package/dist/lib/staleness/writers/sources.d.ts +16 -0
- package/dist/lib/staleness/writers/sources.js +72 -0
- package/dist/lib/staleness/writers/subagents.d.ts +3 -0
- package/dist/lib/staleness/writers/subagents.js +53 -0
- package/dist/lib/staleness/writers/types.d.ts +36 -0
- package/dist/lib/staleness/writers/types.js +1 -0
- package/dist/lib/staleness/writers/workflows.d.ts +7 -0
- package/dist/lib/staleness/writers/workflows.js +31 -0
- package/dist/lib/state.d.ts +34 -11
- package/dist/lib/state.js +58 -13
- package/dist/lib/subagents.d.ts +0 -2
- package/dist/lib/subagents.js +6 -6
- package/dist/lib/teams/agents.js +1 -1
- package/dist/lib/teams/api.d.ts +67 -0
- package/dist/lib/teams/api.js +78 -0
- package/dist/lib/teams/parsers.d.ts +1 -1
- package/dist/lib/tmux/binary.d.ts +67 -0
- package/dist/lib/tmux/binary.js +141 -0
- package/dist/lib/tmux/index.d.ts +8 -0
- package/dist/lib/tmux/index.js +8 -0
- package/dist/lib/tmux/paths.d.ts +17 -0
- package/dist/lib/tmux/paths.js +30 -0
- package/dist/lib/tmux/session.d.ts +122 -0
- package/dist/lib/tmux/session.js +305 -0
- package/dist/lib/types.d.ts +73 -13
- package/dist/lib/types.js +1 -1
- package/dist/lib/usage.js +1 -1
- package/dist/lib/versions.d.ts +4 -4
- package/dist/lib/versions.js +138 -496
- package/dist/lib/workflows.d.ts +2 -4
- package/dist/lib/workflows.js +3 -4
- package/package.json +6 -3
- package/scripts/postinstall.js +16 -63
- package/dist/commands/status.d.ts +0 -9
- package/dist/commands/status.js +0 -25
package/dist/index.js
CHANGED
|
@@ -56,11 +56,12 @@ if (IS_DEV_BUILD) {
|
|
|
56
56
|
}
|
|
57
57
|
// Import command registrations
|
|
58
58
|
import { registerPullCommand } from './commands/pull.js';
|
|
59
|
+
import { registerPushCommand } from './commands/push.js';
|
|
59
60
|
import { registerRepoCommands } from './commands/repo.js';
|
|
60
61
|
import { registerSetupCommand, runSetup } from './commands/setup.js';
|
|
61
|
-
import { registerStatusCommand } from './commands/status.js';
|
|
62
62
|
import { registerFeedbackCommand } from './commands/feedback.js';
|
|
63
63
|
import { registerViewCommand } from './commands/view.js';
|
|
64
|
+
import { registerInspectCommand } from './commands/inspect.js';
|
|
64
65
|
import { registerCommandsCommands } from './commands/commands.js';
|
|
65
66
|
import { registerHooksCommands } from './commands/hooks.js';
|
|
66
67
|
import { registerSkillsCommands } from './commands/skills.js';
|
|
@@ -75,6 +76,7 @@ import { registerDaemonCommands } from './commands/daemon.js';
|
|
|
75
76
|
import { registerRoutinesCommands } from './commands/routines.js';
|
|
76
77
|
import { registerRunCommand } from './commands/exec.js';
|
|
77
78
|
import { registerModelsCommand } from './commands/models.js';
|
|
79
|
+
import { registerDefaultsCommands } from './commands/defaults.js';
|
|
78
80
|
import { registerPruneCommand } from './commands/prune.js';
|
|
79
81
|
import { registerTrashCommands } from './commands/trash.js';
|
|
80
82
|
import { registerDoctorCommand } from './commands/doctor.js';
|
|
@@ -86,6 +88,7 @@ import { registerSyncCommand } from './commands/sync.js';
|
|
|
86
88
|
import { registerRefreshRulesCommand } from './commands/refresh-rules.js';
|
|
87
89
|
import { registerDriveCommands } from './commands/drive.js';
|
|
88
90
|
import { registerPtyCommands } from './commands/pty.js';
|
|
91
|
+
import { registerTmuxCommands } from './commands/tmux.js';
|
|
89
92
|
import { registerBrowserCommand } from './commands/browser.js';
|
|
90
93
|
import { registerComputerCommand } from './commands/computer.js';
|
|
91
94
|
import { registerProfilesCommands } from './commands/profiles.js';
|
|
@@ -99,7 +102,7 @@ import { applyGlobalHelpConventions } from './lib/help.js';
|
|
|
99
102
|
import { isInteractiveTerminal, isPromptCancelled } from './commands/utils.js';
|
|
100
103
|
import { AGENTS } from './lib/agents.js';
|
|
101
104
|
import { getGlobalDefault, listInstalledVersions } from './lib/versions.js';
|
|
102
|
-
import { addShimsToPath, ensureShimCurrent, ensureVersionedAliasCurrent, getPathShadowingExecutable, getPathSetupInstructions,
|
|
105
|
+
import { addShimsToPath, ensureShimCurrent, ensureVersionedAliasCurrent, getPathShadowingExecutable, getPathSetupInstructions, getShimsDir, isShimsInPath, listAgentsWithInstalledVersions, removeLegacyUserShim, } from './lib/shims.js';
|
|
103
106
|
const program = new Command();
|
|
104
107
|
program
|
|
105
108
|
.name('agents')
|
|
@@ -131,6 +134,7 @@ Agent versions:
|
|
|
131
134
|
prune cleanup [target] Remove orphan resources and older duplicate version installs
|
|
132
135
|
trash Inspect and restore soft-deleted version directories
|
|
133
136
|
view [agent[@version]] List versions, or inspect one in detail
|
|
137
|
+
inspect <agent>[@version] Deep details for one agent+version — paths, capabilities, resources, drill into any kind
|
|
134
138
|
|
|
135
139
|
Agent configuration (synced across versions):
|
|
136
140
|
rules Instructions given to agents (CLAUDE.md, etc.)
|
|
@@ -148,6 +152,7 @@ Packages:
|
|
|
148
152
|
|
|
149
153
|
Run and dispatch:
|
|
150
154
|
run <agent|profile> [prompt] Run an agent. Omit prompt for interactive mode.
|
|
155
|
+
defaults Configure run defaults by agent/version selector
|
|
151
156
|
teams Coordinate multiple agents on shared work
|
|
152
157
|
routines Run agents on a cron schedule (scheduler auto-starts)
|
|
153
158
|
sessions Browse, search, and replay past runs (live-search in TTY; grouped by workspace)
|
|
@@ -164,7 +169,7 @@ Diagnostics:
|
|
|
164
169
|
|
|
165
170
|
Config sync:
|
|
166
171
|
drive Sync session history across machines via rsync
|
|
167
|
-
pull Clone or pull the system repo at ~/.agents
|
|
172
|
+
pull Clone or pull the system repo at ~/.agents/.system/
|
|
168
173
|
repo init --path <dir> Scaffold your own editable repo from a template
|
|
169
174
|
repo add <path|gh:user/repo> Merge an extra repo after the system repo
|
|
170
175
|
|
|
@@ -182,7 +187,7 @@ Options:
|
|
|
182
187
|
-V, --version Show version number
|
|
183
188
|
-h, --help Show help
|
|
184
189
|
|
|
185
|
-
System config lives in ~/.agents
|
|
190
|
+
System config lives in ~/.agents/.system/. Run 'agents <command> --help' for details.
|
|
186
191
|
`;
|
|
187
192
|
}
|
|
188
193
|
return originalHelpInformation();
|
|
@@ -214,9 +219,12 @@ async function showWhatsNew(fromVersion, toVersion) {
|
|
|
214
219
|
const versionMatch = line.match(/^## (\d+\.\d+\.\d+)/);
|
|
215
220
|
if (versionMatch) {
|
|
216
221
|
currentVersion = versionMatch[1];
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
222
|
+
// Only the range the user actually moved through: (fromVersion, toVersion].
|
|
223
|
+
// Bounding the top end matters when upgrading to a specific older
|
|
224
|
+
// version, and guards against a changelog that lists unreleased entries.
|
|
225
|
+
const inRange = compareVersions(currentVersion, fromVersion) > 0 &&
|
|
226
|
+
compareVersions(currentVersion, toVersion) <= 0;
|
|
227
|
+
inRelevantSection = inRange;
|
|
220
228
|
if (inRelevantSection) {
|
|
221
229
|
relevantChanges.push('');
|
|
222
230
|
relevantChanges.push(chalk.bold(`v${currentVersion}`));
|
|
@@ -276,11 +284,14 @@ function saveUpdateCheck(latestVersion) {
|
|
|
276
284
|
}
|
|
277
285
|
}
|
|
278
286
|
/** Fetch the exact latest npm version plus its registry integrity hash. */
|
|
279
|
-
async function
|
|
280
|
-
const response = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE_NAME}
|
|
287
|
+
async function fetchNpmPackageMetadata(versionOrTag = 'latest', timeoutMs = 5000) {
|
|
288
|
+
const response = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE_NAME}/${versionOrTag}`, {
|
|
281
289
|
signal: AbortSignal.timeout(timeoutMs),
|
|
282
290
|
});
|
|
283
291
|
if (!response.ok) {
|
|
292
|
+
if (response.status === 404) {
|
|
293
|
+
throw new Error(`${NPM_PACKAGE_NAME}@${versionOrTag} not found on npm`);
|
|
294
|
+
}
|
|
284
295
|
throw new Error('Could not reach npm registry');
|
|
285
296
|
}
|
|
286
297
|
const data = await response.json();
|
|
@@ -335,7 +346,7 @@ async function promptUpgrade(latestVersion) {
|
|
|
335
346
|
const { spawnSync } = await import('child_process');
|
|
336
347
|
let spinner = ora('Resolving package metadata...').start();
|
|
337
348
|
try {
|
|
338
|
-
const metadata = await
|
|
349
|
+
const metadata = await fetchNpmPackageMetadata();
|
|
339
350
|
spinner.succeed(`Resolved ${NPM_PACKAGE_NAME}@${metadata.version}`);
|
|
340
351
|
printResolvedPackage(metadata);
|
|
341
352
|
const approved = await confirm({
|
|
@@ -409,10 +420,17 @@ async function checkForUpdates() {
|
|
|
409
420
|
}
|
|
410
421
|
}
|
|
411
422
|
}
|
|
412
|
-
async function maybeBootstrapShimIntegration(requestedCommand) {
|
|
423
|
+
async function maybeBootstrapShimIntegration(requestedCommand, helpOrVersionRequested) {
|
|
413
424
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
414
425
|
return;
|
|
415
426
|
}
|
|
427
|
+
// Pure documentation paths must never trigger interactive repair — mirrors
|
|
428
|
+
// the helpOrVersionRequested gate around ensureInitialized below. Covers
|
|
429
|
+
// both bare `agents --version` (requestedCommand === undefined) and
|
|
430
|
+
// `agents <subcommand> --help` (requestedCommand === subcommand name).
|
|
431
|
+
if (helpOrVersionRequested) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
416
434
|
if (requestedCommand === 'sync' || requestedCommand === 'refresh-rules') {
|
|
417
435
|
return;
|
|
418
436
|
}
|
|
@@ -447,11 +465,13 @@ async function maybeBootstrapShimIntegration(requestedCommand) {
|
|
|
447
465
|
const shadowed = defaultAgents
|
|
448
466
|
.map((agent) => ({ agent, shadowedBy: getPathShadowingExecutable(agent) }))
|
|
449
467
|
.filter((item) => Boolean(item.shadowedBy));
|
|
450
|
-
// Also check for shell aliases that shadow the shim
|
|
451
|
-
const aliased = defaultAgents.filter((agent) => hasAliasShadowingShim(agent));
|
|
452
|
-
// If shims are in PATH and nothing is binary-shadowing, we're done.
|
|
453
468
|
// Shell aliases that call the same command with extra flags are intentional
|
|
454
|
-
// customization and don't break shim integration
|
|
469
|
+
// customization and don't break shim integration — `addShimsToPath` cannot
|
|
470
|
+
// touch them, so they don't belong in the repair prompt. We previously
|
|
471
|
+
// computed an `aliased` list here and inserted it into `affected`, which
|
|
472
|
+
// contradicted the comment below and surfaced false positives (e.g. an
|
|
473
|
+
// earlier `alias codex=...` cancelled by a later `unalias codex` was
|
|
474
|
+
// reported because the detector did a static rc-file regex).
|
|
455
475
|
if (shadowed.length === 0 && isShimsInPath()) {
|
|
456
476
|
return;
|
|
457
477
|
}
|
|
@@ -468,14 +488,11 @@ async function maybeBootstrapShimIntegration(requestedCommand) {
|
|
|
468
488
|
for (const { agent, shadowedBy } of shadowed) {
|
|
469
489
|
affected.push(`${AGENTS[agent].cliCommand} -> ${shadowedBy}`);
|
|
470
490
|
}
|
|
471
|
-
for (const agent of aliased) {
|
|
472
|
-
if (!shadowed.some((s) => s.agent === agent)) {
|
|
473
|
-
affected.push(`${AGENTS[agent].cliCommand} (alias)`);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
491
|
if (affected.length === 0) {
|
|
477
|
-
// PATH
|
|
478
|
-
|
|
492
|
+
// Pure PATH-not-loaded case: rc may already have the shim block, but the
|
|
493
|
+
// running shell hasn't sourced it. Don't list agents here — they aren't
|
|
494
|
+
// broken; only the PATH is stale. The prompt + post-message handle it.
|
|
495
|
+
affected.push('PATH entry missing');
|
|
479
496
|
}
|
|
480
497
|
const shouldRepair = await confirm({
|
|
481
498
|
message: `Repair shim integration now? ${affected.join(', ')}`,
|
|
@@ -494,15 +511,38 @@ async function maybeBootstrapShimIntegration(requestedCommand) {
|
|
|
494
511
|
if (!pathResult.success) {
|
|
495
512
|
console.log(chalk.yellow('Could not repair shim PATH setup automatically.'));
|
|
496
513
|
console.log(chalk.gray(pathResult.error || getPathSetupInstructions()));
|
|
514
|
+
// Write the sentinel even on failure — otherwise an unwritable rc file
|
|
515
|
+
// re-prompts every invocation in the same shell. The user opens a new
|
|
516
|
+
// terminal (new PPID) to retry.
|
|
517
|
+
try {
|
|
518
|
+
fs.writeFileSync(sentinelPath, '1');
|
|
519
|
+
}
|
|
520
|
+
catch { /* best-effort */ }
|
|
497
521
|
return;
|
|
498
522
|
}
|
|
523
|
+
// When the rc file already has the canonical shim block, `addShimsToPath`
|
|
524
|
+
// is a no-op — re-emitting produced byte-identical content. In this branch
|
|
525
|
+
// the user clicked "Yes" but nothing changed on disk, AND the underlying
|
|
526
|
+
// cause (a real binary shadow, or a stale shell PATH) is unaffected by
|
|
527
|
+
// this command. Be honest about it and point at the actual action.
|
|
499
528
|
if (pathResult.alreadyPresent) {
|
|
500
|
-
|
|
529
|
+
if (shadowed.length > 0) {
|
|
530
|
+
const targets = shadowed
|
|
531
|
+
.map(({ agent, shadowedBy }) => ` ${AGENTS[agent].cliCommand}: ${shadowedBy}`)
|
|
532
|
+
.join('\n');
|
|
533
|
+
console.log(chalk.yellow('Repair could not change anything — the shim is shadowed by another binary on PATH:'));
|
|
534
|
+
console.log(chalk.gray(targets));
|
|
535
|
+
console.log(chalk.gray(`Fix it by removing or reordering that binary, or making sure ${getShimsDir()} appears earlier in PATH than its parent dir.`));
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
console.log(chalk.yellow(`Shim PATH entry is already in ~/${pathResult.rcFile} — this shell just needs to reload it.`));
|
|
539
|
+
console.log(chalk.gray(`Run: source ~/${pathResult.rcFile} (or open a new terminal)`));
|
|
540
|
+
}
|
|
501
541
|
}
|
|
502
542
|
else {
|
|
503
543
|
console.log(chalk.green(`Repaired shim PATH setup in ~/${pathResult.rcFile}`));
|
|
544
|
+
console.log(chalk.gray(getPathSetupInstructions()));
|
|
504
545
|
}
|
|
505
|
-
console.log(chalk.gray(getPathSetupInstructions()));
|
|
506
546
|
try {
|
|
507
547
|
fs.writeFileSync(sentinelPath, '1');
|
|
508
548
|
}
|
|
@@ -510,7 +550,7 @@ async function maybeBootstrapShimIntegration(requestedCommand) {
|
|
|
510
550
|
}
|
|
511
551
|
// Register all commands
|
|
512
552
|
registerViewCommand(program);
|
|
513
|
-
|
|
553
|
+
registerInspectCommand(program);
|
|
514
554
|
registerFeedbackCommand(program);
|
|
515
555
|
registerCommandsCommands(program);
|
|
516
556
|
registerHooksCommands(program);
|
|
@@ -551,6 +591,7 @@ registerPackagesCommands(program);
|
|
|
551
591
|
registerDaemonCommands(program);
|
|
552
592
|
registerRoutinesCommands(program);
|
|
553
593
|
registerRunCommand(program);
|
|
594
|
+
registerDefaultsCommands(program);
|
|
554
595
|
registerModelsCommand(program);
|
|
555
596
|
registerPruneCommand(program);
|
|
556
597
|
registerTrashCommands(program);
|
|
@@ -577,6 +618,7 @@ registerFactoryCommands(program);
|
|
|
577
618
|
registerUsageCommand(program);
|
|
578
619
|
registerAliasCommand(program);
|
|
579
620
|
registerPtyCommands(program);
|
|
621
|
+
registerTmuxCommands(program);
|
|
580
622
|
registerBrowserCommand(program);
|
|
581
623
|
registerComputerCommand(program);
|
|
582
624
|
// Deprecated 'jobs' and 'cron' aliases for 'routines'
|
|
@@ -594,26 +636,31 @@ for (const alias of ['jobs', 'cron']) {
|
|
|
594
636
|
}
|
|
595
637
|
program
|
|
596
638
|
.command('upgrade')
|
|
597
|
-
.description('Upgrade agents-cli to the latest version')
|
|
639
|
+
.description('Upgrade agents-cli to the latest version (or a specific [version])')
|
|
640
|
+
.argument('[version]', 'Target version or dist-tag to install (default: latest)')
|
|
598
641
|
.option('-y, --yes', 'Install without an interactive confirmation prompt')
|
|
599
|
-
.action(async (options) => {
|
|
600
|
-
|
|
642
|
+
.action(async (version, options) => {
|
|
643
|
+
const target = version ?? 'latest';
|
|
644
|
+
let spinner = ora(version ? `Resolving ${NPM_PACKAGE_NAME}@${target}...` : 'Checking for updates...').start();
|
|
601
645
|
try {
|
|
602
|
-
const metadata = await
|
|
603
|
-
const
|
|
604
|
-
if (
|
|
605
|
-
spinner.succeed(`Already on
|
|
646
|
+
const metadata = await fetchNpmPackageMetadata(target);
|
|
647
|
+
const resolvedVersion = metadata.version;
|
|
648
|
+
if (resolvedVersion === VERSION) {
|
|
649
|
+
spinner.succeed(`Already on ${VERSION}`);
|
|
606
650
|
return;
|
|
607
651
|
}
|
|
608
|
-
|
|
609
|
-
|
|
652
|
+
// For `latest` (no explicit version) skip when already ahead. When a
|
|
653
|
+
// version is named explicitly, honor it even if it's a downgrade.
|
|
654
|
+
if (!version && compareVersions(resolvedVersion, VERSION) <= 0) {
|
|
655
|
+
spinner.succeed(`Already ahead of latest (${VERSION} >= ${resolvedVersion})`);
|
|
610
656
|
return;
|
|
611
657
|
}
|
|
612
|
-
|
|
658
|
+
const direction = compareVersions(resolvedVersion, VERSION) < 0 ? 'Downgrade' : 'Upgrade';
|
|
659
|
+
spinner.succeed(`Resolved ${NPM_PACKAGE_NAME}@${resolvedVersion}`);
|
|
613
660
|
printResolvedPackage(metadata);
|
|
614
661
|
if (isInteractiveTerminal() && !options.yes) {
|
|
615
662
|
const approved = await confirm({
|
|
616
|
-
message: `Install ${NPM_PACKAGE_NAME}@${
|
|
663
|
+
message: `Install ${NPM_PACKAGE_NAME}@${resolvedVersion}?`,
|
|
617
664
|
default: false,
|
|
618
665
|
});
|
|
619
666
|
if (!approved) {
|
|
@@ -621,17 +668,21 @@ program
|
|
|
621
668
|
return;
|
|
622
669
|
}
|
|
623
670
|
}
|
|
624
|
-
spinner = ora(
|
|
671
|
+
spinner = ora(`${direction === 'Downgrade' ? 'Downgrading' : 'Upgrading'} ${VERSION} -> ${resolvedVersion}...`).start();
|
|
625
672
|
await installResolvedPackage(metadata);
|
|
626
|
-
spinner.succeed(
|
|
627
|
-
|
|
673
|
+
spinner.succeed(`${direction}d to ${resolvedVersion}`);
|
|
674
|
+
// Only show the changelog for a genuine upgrade range.
|
|
675
|
+
if (compareVersions(resolvedVersion, VERSION) > 0) {
|
|
676
|
+
await showWhatsNew(VERSION, resolvedVersion);
|
|
677
|
+
}
|
|
628
678
|
}
|
|
629
679
|
catch (err) {
|
|
630
680
|
spinner.fail('Upgrade failed');
|
|
631
|
-
console.log(chalk.gray(
|
|
681
|
+
console.log(chalk.gray(`Run manually: agents upgrade ${version ? version + ' ' : ''}--yes`));
|
|
632
682
|
}
|
|
633
683
|
});
|
|
634
684
|
registerPullCommand(program);
|
|
685
|
+
registerPushCommand(program);
|
|
635
686
|
registerRepoCommands(program);
|
|
636
687
|
registerSetupCommand(program);
|
|
637
688
|
applyGlobalHelpConventions(program);
|
|
@@ -742,6 +793,20 @@ const SETUP_EXEMPT_COMMANDS = new Set(['setup', 'help']);
|
|
|
742
793
|
// Help and version output are pure documentation — they must never gate on
|
|
743
794
|
// setup, otherwise `agents <cmd> --help` becomes useless on a fresh box.
|
|
744
795
|
const helpOrVersionRequested = passedArgs.some((arg) => arg === '--help' || arg === '-h' || arg === '--version' || arg === '-V');
|
|
796
|
+
// Fold legacy ~/.agents-system/ into ~/.agents/.system/ BEFORE ensureInitialized
|
|
797
|
+
// runs. ensureInitialized checks for .git inside the new path; if the user is
|
|
798
|
+
// upgrading from a layout where .git lives under the legacy path, the check
|
|
799
|
+
// would fail and exit before the migrator ever runs. Also runs outside the
|
|
800
|
+
// sentinel guard below because the sentinel was set by pre-fold releases and
|
|
801
|
+
// would otherwise skip this step on every existing install. Idempotent —
|
|
802
|
+
// no-ops when legacy is missing or already a symlink.
|
|
803
|
+
if (process.env.AGENTS_SKIP_MIGRATION !== '1') {
|
|
804
|
+
try {
|
|
805
|
+
const { foldLegacySystemRepo } = await import('./lib/migrate.js');
|
|
806
|
+
foldLegacySystemRepo();
|
|
807
|
+
}
|
|
808
|
+
catch { /* must never block CLI startup */ }
|
|
809
|
+
}
|
|
745
810
|
if (!firstRun &&
|
|
746
811
|
requestedCommand &&
|
|
747
812
|
!SETUP_EXEMPT_COMMANDS.has(requestedCommand) &&
|
|
@@ -783,7 +848,7 @@ if (process.env.AGENTS_SKIP_MIGRATION !== '1') {
|
|
|
783
848
|
catch { /* migration must never block CLI startup */ }
|
|
784
849
|
}
|
|
785
850
|
try {
|
|
786
|
-
await maybeBootstrapShimIntegration(requestedCommand);
|
|
851
|
+
await maybeBootstrapShimIntegration(requestedCommand, helpOrVersionRequested);
|
|
787
852
|
await program.parseAsync();
|
|
788
853
|
}
|
|
789
854
|
catch (err) {
|
package/dist/lib/agents.d.ts
CHANGED
|
@@ -23,16 +23,6 @@ export declare const GEMINI_HOOKS_MIN_VERSION = "0.26.0";
|
|
|
23
23
|
export declare const AGENTS: Record<AgentId, AgentConfig>;
|
|
24
24
|
/** All registered agent IDs derived from the AGENTS registry. */
|
|
25
25
|
export declare const ALL_AGENT_IDS: AgentId[];
|
|
26
|
-
/** Agents that support MCP (Model Context Protocol) server integration. */
|
|
27
|
-
export declare const MCP_CAPABLE_AGENTS: AgentId[];
|
|
28
|
-
/** Agents that support skills (SKILL.md + rules/ bundles). */
|
|
29
|
-
export declare const SKILLS_CAPABLE_AGENTS: AgentId[];
|
|
30
|
-
/** Agents that support file-based slash commands. */
|
|
31
|
-
export declare const COMMANDS_CAPABLE_AGENTS: AgentId[];
|
|
32
|
-
/** Agents that support event hooks (pre/post lifecycle callbacks). */
|
|
33
|
-
export declare const HOOKS_CAPABLE_AGENTS: readonly AgentId[];
|
|
34
|
-
/** Agents that support the plugin system. */
|
|
35
|
-
export declare const PLUGINS_CAPABLE_AGENTS: AgentId[];
|
|
36
26
|
/** Get the chalk color function for an agent. Works for any AgentId or SessionAgentId. */
|
|
37
27
|
export declare function colorAgent(agentId: string): (s: string) => string;
|
|
38
28
|
/** Return the agent's display name, colored. */
|
|
@@ -59,6 +49,13 @@ export interface UnmanagedInstall {
|
|
|
59
49
|
configDir: string;
|
|
60
50
|
version: string | null;
|
|
61
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Agents that `agents setup` probes for pre-existing native installations
|
|
54
|
+
* (i.e., a config dir present before agents-cli took over). Add an agent here
|
|
55
|
+
* once its `cliCommand` reports a usable `--version` and its session dir is
|
|
56
|
+
* wired into `getSessionDir`.
|
|
57
|
+
*/
|
|
58
|
+
export declare const UNMANAGED_DETECTION_CANDIDATES: AgentId[];
|
|
62
59
|
/**
|
|
63
60
|
* Detect existing agent installations that are NOT yet managed by agents-cli.
|
|
64
61
|
* Returns agents whose config dir exists as a real directory (not a symlink).
|
|
@@ -68,6 +65,22 @@ export declare function getUnmanagedAgentInstalls(): Promise<UnmanagedInstall[]>
|
|
|
68
65
|
export declare function ensureCommandsDir(agentId: AgentId): void;
|
|
69
66
|
/** Create the agent's skills directory if it does not exist. */
|
|
70
67
|
export declare function ensureSkillsDir(agentId: AgentId): void;
|
|
68
|
+
/**
|
|
69
|
+
* The agent's config-dir name relative to $HOME — e.g. '.claude',
|
|
70
|
+
* '.gemini/antigravity-cli', '.config/amp', '.kimi-code'.
|
|
71
|
+
*
|
|
72
|
+
* Path segment to join onto a (version) home root when locating an agent's
|
|
73
|
+
* commands/skills/plugins. Do NOT hardcode `.${agentId}`: it is wrong for
|
|
74
|
+
* every agent whose config dir is nested or under ~/.config — antigravity
|
|
75
|
+
* (~/.gemini/antigravity-cli), amp (~/.config/amp), goose (~/.config/goose),
|
|
76
|
+
* kimi (~/.kimi-code). Mirrors the shim configDirName derivation in shims.ts.
|
|
77
|
+
*
|
|
78
|
+
* Relativized against the module-level HOME constant (the same value used to
|
|
79
|
+
* build every `configDir`), NOT a fresh `os.homedir()` — so the result stays a
|
|
80
|
+
* clean relative name even when HOME is overridden after module load (tests,
|
|
81
|
+
* sandboxes). Using `os.homedir()` here would yield `../../real/home/.claude`.
|
|
82
|
+
*/
|
|
83
|
+
export declare function agentConfigDirName(agentId: AgentId): string;
|
|
71
84
|
/** Account identity and billing information extracted from an agent's auth config. */
|
|
72
85
|
export interface AccountInfo {
|
|
73
86
|
accountKey: string | null;
|
package/dist/lib/agents.js
CHANGED
|
@@ -203,7 +203,7 @@ export const AGENTS = {
|
|
|
203
203
|
format: 'markdown',
|
|
204
204
|
variableSyntax: '$ARGUMENTS',
|
|
205
205
|
supportsHooks: true,
|
|
206
|
-
capabilities: { hooks: true, mcp: true, allowlist: true, skills: true, commands: true, plugins: true, modes: ['plan', 'edit', 'auto', 'skip'], rulesImports: true },
|
|
206
|
+
capabilities: { hooks: true, mcp: true, allowlist: true, skills: true, commands: true, plugins: true, subagents: true, rules: { file: 'CLAUDE.md' }, workflows: true, modes: ['plan', 'edit', 'auto', 'skip'], rulesImports: true },
|
|
207
207
|
},
|
|
208
208
|
// codex hooks: gated to >= 0.116.0 (introduced [features] codex_hooks flag).
|
|
209
209
|
codex: {
|
|
@@ -222,7 +222,7 @@ export const AGENTS = {
|
|
|
222
222
|
format: 'markdown',
|
|
223
223
|
variableSyntax: '$ARGUMENTS',
|
|
224
224
|
supportsHooks: true,
|
|
225
|
-
capabilities: { hooks: { since: '0.116.0' }, mcp: true, allowlist: false, skills: true, commands: { until: '0.117.0' }, plugins: { since: '0.128.0' }, modes: ['plan', 'edit', 'skip'] },
|
|
225
|
+
capabilities: { hooks: { since: '0.116.0' }, mcp: true, allowlist: false, skills: true, commands: { until: '0.117.0' }, plugins: { since: '0.128.0' }, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['plan', 'edit', 'skip'] },
|
|
226
226
|
},
|
|
227
227
|
gemini: {
|
|
228
228
|
id: 'gemini',
|
|
@@ -241,7 +241,7 @@ export const AGENTS = {
|
|
|
241
241
|
supportsHooks: true,
|
|
242
242
|
nativeAgentsSkillsDir: true,
|
|
243
243
|
// gemini hooks: shipped in v0.26.0 (Jan 2026); older binaries silently ignore the `hooks` key.
|
|
244
|
-
capabilities: { hooks: { since: '0.26.0' }, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, modes: ['plan', 'edit', 'skip'], rulesImports: true },
|
|
244
|
+
capabilities: { hooks: { since: '0.26.0' }, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: 'GEMINI.md' }, workflows: false, modes: ['plan', 'edit', 'skip'], rulesImports: true },
|
|
245
245
|
},
|
|
246
246
|
cursor: {
|
|
247
247
|
id: 'cursor',
|
|
@@ -259,7 +259,7 @@ export const AGENTS = {
|
|
|
259
259
|
format: 'markdown',
|
|
260
260
|
variableSyntax: '$ARGUMENTS',
|
|
261
261
|
supportsHooks: false,
|
|
262
|
-
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, modes: ['edit', 'skip'] },
|
|
262
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: '.cursorrules' }, workflows: false, modes: ['edit', 'skip'] },
|
|
263
263
|
},
|
|
264
264
|
opencode: {
|
|
265
265
|
id: 'opencode',
|
|
@@ -276,7 +276,7 @@ export const AGENTS = {
|
|
|
276
276
|
format: 'markdown',
|
|
277
277
|
variableSyntax: '$ARGUMENTS',
|
|
278
278
|
supportsHooks: false,
|
|
279
|
-
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, modes: ['plan', 'edit'] },
|
|
279
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['plan', 'edit'] },
|
|
280
280
|
},
|
|
281
281
|
openclaw: {
|
|
282
282
|
id: 'openclaw',
|
|
@@ -293,7 +293,7 @@ export const AGENTS = {
|
|
|
293
293
|
format: 'markdown',
|
|
294
294
|
variableSyntax: '{{ARGUMENTS}}',
|
|
295
295
|
supportsHooks: true,
|
|
296
|
-
capabilities: { hooks: true, mcp: true, allowlist: false, skills: true, commands: false, plugins: true, modes: ['plan', 'edit', 'skip'] },
|
|
296
|
+
capabilities: { hooks: true, mcp: true, allowlist: false, skills: true, commands: false, plugins: true, subagents: true, rules: { file: 'workspace/AGENTS.md' }, workflows: false, modes: ['plan', 'edit', 'skip'] },
|
|
297
297
|
},
|
|
298
298
|
copilot: {
|
|
299
299
|
id: 'copilot',
|
|
@@ -310,7 +310,7 @@ export const AGENTS = {
|
|
|
310
310
|
format: 'markdown',
|
|
311
311
|
variableSyntax: '$ARGUMENTS',
|
|
312
312
|
supportsHooks: false,
|
|
313
|
-
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, modes: ['plan', 'edit', 'auto', 'skip'] },
|
|
313
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['plan', 'edit', 'auto', 'skip'] },
|
|
314
314
|
},
|
|
315
315
|
amp: {
|
|
316
316
|
id: 'amp',
|
|
@@ -327,7 +327,7 @@ export const AGENTS = {
|
|
|
327
327
|
format: 'markdown',
|
|
328
328
|
variableSyntax: '$ARGUMENTS',
|
|
329
329
|
supportsHooks: false,
|
|
330
|
-
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, modes: ['plan', 'edit'] },
|
|
330
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['plan', 'edit'] },
|
|
331
331
|
},
|
|
332
332
|
kiro: {
|
|
333
333
|
id: 'kiro',
|
|
@@ -345,7 +345,7 @@ export const AGENTS = {
|
|
|
345
345
|
format: 'markdown',
|
|
346
346
|
variableSyntax: '$ARGUMENTS',
|
|
347
347
|
supportsHooks: false,
|
|
348
|
-
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, modes: ['edit'] },
|
|
348
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['edit'] },
|
|
349
349
|
},
|
|
350
350
|
goose: {
|
|
351
351
|
id: 'goose',
|
|
@@ -363,7 +363,7 @@ export const AGENTS = {
|
|
|
363
363
|
format: 'markdown',
|
|
364
364
|
variableSyntax: '$ARGUMENTS',
|
|
365
365
|
supportsHooks: false,
|
|
366
|
-
capabilities: { hooks: false, mcp: true, allowlist: false, skills: false, commands: false, plugins: false, modes: ['edit'] },
|
|
366
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: false, commands: false, plugins: false, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['edit'] },
|
|
367
367
|
},
|
|
368
368
|
roo: {
|
|
369
369
|
id: 'roo',
|
|
@@ -381,7 +381,7 @@ export const AGENTS = {
|
|
|
381
381
|
format: 'markdown',
|
|
382
382
|
variableSyntax: '$ARGUMENTS',
|
|
383
383
|
supportsHooks: false,
|
|
384
|
-
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, modes: ['plan', 'edit'] },
|
|
384
|
+
capabilities: { hooks: false, mcp: true, allowlist: false, skills: true, commands: true, plugins: false, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['plan', 'edit'] },
|
|
385
385
|
},
|
|
386
386
|
// Google Antigravity CLI (`agy`) — official replacement for Gemini CLI as of IO 2026.
|
|
387
387
|
// configDir nests inside `~/.gemini/` since agy shares the parent dir with the Gemini
|
|
@@ -408,7 +408,7 @@ export const AGENTS = {
|
|
|
408
408
|
format: 'markdown',
|
|
409
409
|
variableSyntax: '{{args}}',
|
|
410
410
|
supportsHooks: true,
|
|
411
|
-
capabilities: { hooks: true, mcp: true, allowlist: true, skills: true, commands: true, plugins: true, modes: ['edit', 'skip'], rulesImports: false },
|
|
411
|
+
capabilities: { hooks: true, mcp: true, allowlist: true, skills: true, commands: true, plugins: true, subagents: false, rules: { file: 'AGENTS.md' }, workflows: false, modes: ['edit', 'skip'], rulesImports: false },
|
|
412
412
|
},
|
|
413
413
|
// xAI Grok Build CLI (`grok`) — early beta, SuperGrok Heavy. Auth via OAuth on
|
|
414
414
|
// first launch, or XAI_API_KEY env var for headless. MCP servers configured inline
|
|
@@ -439,23 +439,56 @@ export const AGENTS = {
|
|
|
439
439
|
skills: true,
|
|
440
440
|
commands: false, // covered by skills
|
|
441
441
|
plugins: true,
|
|
442
|
+
subagents: false,
|
|
443
|
+
rules: { file: 'AGENTS.md' },
|
|
444
|
+
workflows: false,
|
|
442
445
|
modes: ['plan', 'edit', 'skip'],
|
|
443
446
|
rulesImports: true,
|
|
444
447
|
},
|
|
445
448
|
},
|
|
449
|
+
// Kimi Code CLI (`kimi`) — Moonshot AI coding agent.
|
|
450
|
+
// Install: `curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash`
|
|
451
|
+
// or: `npm install -g @moonshot-ai/kimi-code`
|
|
452
|
+
// Config: `~/.kimi-code/config.toml`, `~/.kimi-code/mcp.json`,
|
|
453
|
+
// `~/.kimi-code/skills/`, `~/.kimi-code/hooks/`
|
|
454
|
+
kimi: {
|
|
455
|
+
id: 'kimi',
|
|
456
|
+
name: 'Kimi',
|
|
457
|
+
color: 'magentaBright',
|
|
458
|
+
cliCommand: 'kimi',
|
|
459
|
+
npmPackage: '@moonshot-ai/kimi-code',
|
|
460
|
+
installScript: 'curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash',
|
|
461
|
+
configDir: path.join(HOME, '.kimi-code'),
|
|
462
|
+
commandsDir: '',
|
|
463
|
+
commandsSubdir: '',
|
|
464
|
+
skillsDir: path.join(HOME, '.kimi-code', 'skills'),
|
|
465
|
+
hooksDir: path.join(HOME, '.kimi-code', 'hooks'),
|
|
466
|
+
instructionsFile: 'AGENTS.md',
|
|
467
|
+
format: 'markdown',
|
|
468
|
+
variableSyntax: '$ARGUMENTS',
|
|
469
|
+
supportsHooks: true,
|
|
470
|
+
capabilities: {
|
|
471
|
+
hooks: true,
|
|
472
|
+
mcp: true,
|
|
473
|
+
allowlist: true,
|
|
474
|
+
skills: true,
|
|
475
|
+
commands: false,
|
|
476
|
+
plugins: true,
|
|
477
|
+
subagents: false,
|
|
478
|
+
rules: { file: 'AGENTS.md' },
|
|
479
|
+
workflows: false,
|
|
480
|
+
modes: ['plan', 'edit', 'auto', 'skip'],
|
|
481
|
+
rulesImports: false,
|
|
482
|
+
},
|
|
483
|
+
},
|
|
446
484
|
};
|
|
447
485
|
/** All registered agent IDs derived from the AGENTS registry. */
|
|
448
486
|
export const ALL_AGENT_IDS = Object.keys(AGENTS);
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
export const COMMANDS_CAPABLE_AGENTS = ALL_AGENT_IDS.filter((id) => AGENTS[id].capabilities.commands);
|
|
455
|
-
/** Agents that support event hooks (pre/post lifecycle callbacks). */
|
|
456
|
-
export const HOOKS_CAPABLE_AGENTS = ALL_AGENT_IDS.filter((id) => AGENTS[id].capabilities.hooks !== false);
|
|
457
|
-
/** Agents that support the plugin system. */
|
|
458
|
-
export const PLUGINS_CAPABLE_AGENTS = ALL_AGENT_IDS.filter((id) => AGENTS[id].capabilities.plugins !== false);
|
|
487
|
+
// Capability-filtered agent lists used to live here as `*_CAPABLE_AGENTS`
|
|
488
|
+
// constants. They were a frequent source of silent-skip bugs (e.g. grok
|
|
489
|
+
// rules sync gated on `COMMANDS_CAPABLE_AGENTS`). Use `capableAgents(cap)`
|
|
490
|
+
// from `./capabilities.js` instead — it consults the AgentConfig matrix
|
|
491
|
+
// directly, so a single source of truth drives every gate.
|
|
459
492
|
/** Get the chalk color function for an agent. Works for any AgentId or SessionAgentId. */
|
|
460
493
|
export function colorAgent(agentId) {
|
|
461
494
|
const agent = AGENTS[agentId];
|
|
@@ -610,14 +643,26 @@ export function isConfigured(agentId) {
|
|
|
610
643
|
const agent = AGENTS[agentId];
|
|
611
644
|
return fs.existsSync(agent.configDir);
|
|
612
645
|
}
|
|
646
|
+
/**
|
|
647
|
+
* Agents that `agents setup` probes for pre-existing native installations
|
|
648
|
+
* (i.e., a config dir present before agents-cli took over). Add an agent here
|
|
649
|
+
* once its `cliCommand` reports a usable `--version` and its session dir is
|
|
650
|
+
* wired into `getSessionDir`.
|
|
651
|
+
*/
|
|
652
|
+
export const UNMANAGED_DETECTION_CANDIDATES = [
|
|
653
|
+
'claude',
|
|
654
|
+
'codex',
|
|
655
|
+
'gemini',
|
|
656
|
+
'grok',
|
|
657
|
+
'copilot',
|
|
658
|
+
];
|
|
613
659
|
/**
|
|
614
660
|
* Detect existing agent installations that are NOT yet managed by agents-cli.
|
|
615
661
|
* Returns agents whose config dir exists as a real directory (not a symlink).
|
|
616
662
|
*/
|
|
617
663
|
export async function getUnmanagedAgentInstalls() {
|
|
618
664
|
const unmanaged = [];
|
|
619
|
-
const
|
|
620
|
-
for (const agentId of candidates) {
|
|
665
|
+
for (const agentId of UNMANAGED_DETECTION_CANDIDATES) {
|
|
621
666
|
const agent = AGENTS[agentId];
|
|
622
667
|
try {
|
|
623
668
|
const stat = fs.lstatSync(agent.configDir);
|
|
@@ -646,6 +691,24 @@ export function ensureSkillsDir(agentId) {
|
|
|
646
691
|
fs.mkdirSync(agent.skillsDir, { recursive: true });
|
|
647
692
|
}
|
|
648
693
|
}
|
|
694
|
+
/**
|
|
695
|
+
* The agent's config-dir name relative to $HOME — e.g. '.claude',
|
|
696
|
+
* '.gemini/antigravity-cli', '.config/amp', '.kimi-code'.
|
|
697
|
+
*
|
|
698
|
+
* Path segment to join onto a (version) home root when locating an agent's
|
|
699
|
+
* commands/skills/plugins. Do NOT hardcode `.${agentId}`: it is wrong for
|
|
700
|
+
* every agent whose config dir is nested or under ~/.config — antigravity
|
|
701
|
+
* (~/.gemini/antigravity-cli), amp (~/.config/amp), goose (~/.config/goose),
|
|
702
|
+
* kimi (~/.kimi-code). Mirrors the shim configDirName derivation in shims.ts.
|
|
703
|
+
*
|
|
704
|
+
* Relativized against the module-level HOME constant (the same value used to
|
|
705
|
+
* build every `configDir`), NOT a fresh `os.homedir()` — so the result stays a
|
|
706
|
+
* clean relative name even when HOME is overridden after module load (tests,
|
|
707
|
+
* sandboxes). Using `os.homedir()` here would yield `../../real/home/.claude`.
|
|
708
|
+
*/
|
|
709
|
+
export function agentConfigDirName(agentId) {
|
|
710
|
+
return path.relative(HOME, AGENTS[agentId].configDir);
|
|
711
|
+
}
|
|
649
712
|
/** Return the email address associated with the agent's auth config, or null. */
|
|
650
713
|
export async function getAccountEmail(agentId, home) {
|
|
651
714
|
const info = await getAccountInfo(agentId, home);
|
|
@@ -1280,7 +1343,7 @@ export function getMcpConfigPathForHome(agentId, home) {
|
|
|
1280
1343
|
case 'grok':
|
|
1281
1344
|
return path.join(home, '.grok', 'config.toml');
|
|
1282
1345
|
default:
|
|
1283
|
-
return path.join(home,
|
|
1346
|
+
return path.join(home, agentConfigDirName(agentId), 'settings.json');
|
|
1284
1347
|
}
|
|
1285
1348
|
}
|
|
1286
1349
|
/**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* For the user repo + enabled extras: `git fetch` + write a status marker the foreground
|
|
6
6
|
* CLI surfaces on its next invocation.
|
|
7
7
|
*
|
|
8
|
-
* Per-repo lock files at ~/.agents
|
|
8
|
+
* Per-repo lock files at ~/.agents/.system/.fetch/<alias>.lock prevent concurrent fetches.
|
|
9
9
|
* Lock mtime under 5 min => skip (another invocation already in flight).
|
|
10
10
|
*/
|
|
11
11
|
export {};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* For the user repo + enabled extras: `git fetch` + write a status marker the foreground
|
|
6
6
|
* CLI surfaces on its next invocation.
|
|
7
7
|
*
|
|
8
|
-
* Per-repo lock files at ~/.agents
|
|
8
|
+
* Per-repo lock files at ~/.agents/.system/.fetch/<alias>.lock prevent concurrent fetches.
|
|
9
9
|
* Lock mtime under 5 min => skip (another invocation already in flight).
|
|
10
10
|
*/
|
|
11
11
|
import * as fs from 'fs';
|
|
@@ -15,7 +15,7 @@ import { getSystemAgentsDir, getUserAgentsDir, getEnabledExtraRepos, getFetchCac
|
|
|
15
15
|
import { lockFilePath, statusFilePath } from './auto-pull.js';
|
|
16
16
|
const LOCK_TTL_MS = 5 * 60 * 1000;
|
|
17
17
|
/**
|
|
18
|
-
* Background auto-pull of ~/.agents
|
|
18
|
+
* Background auto-pull of ~/.agents/.system/ is off by default. When enabled it
|
|
19
19
|
* silently fast-forwards a tracked source tree that the CLI then reads as a
|
|
20
20
|
* source of skills, hooks, install manifests, and commands — anyone with push
|
|
21
21
|
* access to that upstream gets remote code execution on every user the next
|