@phnx-labs/agents-cli 1.15.0 → 1.17.0

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.
Files changed (111) hide show
  1. package/CHANGELOG.md +143 -39
  2. package/README.md +6 -6
  3. package/dist/commands/alias.js +2 -2
  4. package/dist/commands/browser-picker.d.ts +21 -0
  5. package/dist/commands/browser-picker.js +114 -0
  6. package/dist/commands/browser.js +793 -83
  7. package/dist/commands/cloud.js +8 -0
  8. package/dist/commands/commands.js +72 -22
  9. package/dist/commands/daemon.js +2 -2
  10. package/dist/commands/exec.js +70 -1
  11. package/dist/commands/hooks.js +71 -26
  12. package/dist/commands/mcp.js +81 -39
  13. package/dist/commands/plugins.js +224 -17
  14. package/dist/commands/prune.js +29 -1
  15. package/dist/commands/pull.js +3 -3
  16. package/dist/commands/repo.js +1 -1
  17. package/dist/commands/routines.js +2 -2
  18. package/dist/commands/secrets.js +154 -20
  19. package/dist/commands/sessions.js +62 -19
  20. package/dist/commands/{init.d.ts → setup.d.ts} +7 -6
  21. package/dist/commands/{init.js → setup.js} +22 -21
  22. package/dist/commands/skills.js +60 -19
  23. package/dist/commands/subagents.js +41 -13
  24. package/dist/commands/utils.d.ts +16 -0
  25. package/dist/commands/utils.js +32 -0
  26. package/dist/commands/view.js +78 -20
  27. package/dist/commands/workflows.d.ts +10 -0
  28. package/dist/commands/workflows.js +457 -0
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.js +48 -36
  31. package/dist/lib/agents.js +2 -2
  32. package/dist/lib/auto-pull-worker.js +2 -3
  33. package/dist/lib/auto-pull.js +2 -2
  34. package/dist/lib/browser/cdp.d.ts +7 -1
  35. package/dist/lib/browser/cdp.js +32 -1
  36. package/dist/lib/browser/chrome.d.ts +10 -0
  37. package/dist/lib/browser/chrome.js +41 -3
  38. package/dist/lib/browser/devices.d.ts +4 -0
  39. package/dist/lib/browser/devices.js +27 -0
  40. package/dist/lib/browser/drivers/local.js +22 -6
  41. package/dist/lib/browser/drivers/ssh.js +9 -2
  42. package/dist/lib/browser/input.d.ts +1 -0
  43. package/dist/lib/browser/input.js +3 -0
  44. package/dist/lib/browser/ipc.js +158 -23
  45. package/dist/lib/browser/profiles.d.ts +10 -2
  46. package/dist/lib/browser/profiles.js +122 -37
  47. package/dist/lib/browser/service.d.ts +91 -13
  48. package/dist/lib/browser/service.js +767 -132
  49. package/dist/lib/browser/types.d.ts +91 -3
  50. package/dist/lib/browser/types.js +16 -0
  51. package/dist/lib/cloud/rush.d.ts +28 -1
  52. package/dist/lib/cloud/rush.js +69 -14
  53. package/dist/lib/cloud/store.js +2 -2
  54. package/dist/lib/commands.d.ts +1 -15
  55. package/dist/lib/commands.js +11 -7
  56. package/dist/lib/daemon.js +2 -3
  57. package/dist/lib/doctor-diff.js +4 -4
  58. package/dist/lib/events.js +2 -2
  59. package/dist/lib/hooks.d.ts +11 -7
  60. package/dist/lib/hooks.js +138 -49
  61. package/dist/lib/migrate.d.ts +1 -1
  62. package/dist/lib/migrate.js +1237 -22
  63. package/dist/lib/models.js +2 -2
  64. package/dist/lib/permissions.d.ts +8 -66
  65. package/dist/lib/permissions.js +18 -18
  66. package/dist/lib/plugins.d.ts +94 -24
  67. package/dist/lib/plugins.js +702 -123
  68. package/dist/lib/pty-server.js +9 -10
  69. package/dist/lib/resource-patterns.d.ts +41 -0
  70. package/dist/lib/resource-patterns.js +82 -0
  71. package/dist/lib/resources/hooks.d.ts +5 -1
  72. package/dist/lib/resources/hooks.js +21 -4
  73. package/dist/lib/resources/index.d.ts +17 -0
  74. package/dist/lib/resources/index.js +7 -0
  75. package/dist/lib/resources/types.d.ts +1 -1
  76. package/dist/lib/resources/workflows.d.ts +24 -0
  77. package/dist/lib/resources/workflows.js +110 -0
  78. package/dist/lib/resources.d.ts +6 -1
  79. package/dist/lib/resources.js +12 -2
  80. package/dist/lib/rotate.js +3 -4
  81. package/dist/lib/session/active.d.ts +3 -0
  82. package/dist/lib/session/active.js +92 -6
  83. package/dist/lib/session/cloud.js +2 -2
  84. package/dist/lib/session/db.d.ts +18 -0
  85. package/dist/lib/session/db.js +109 -5
  86. package/dist/lib/session/discover.d.ts +6 -0
  87. package/dist/lib/session/discover.js +55 -29
  88. package/dist/lib/session/team-filter.js +2 -2
  89. package/dist/lib/shims.d.ts +4 -52
  90. package/dist/lib/shims.js +23 -15
  91. package/dist/lib/skills.js +6 -2
  92. package/dist/lib/sqlite.js +10 -4
  93. package/dist/lib/state.d.ts +101 -16
  94. package/dist/lib/state.js +179 -31
  95. package/dist/lib/subagents.d.ts +28 -0
  96. package/dist/lib/subagents.js +98 -1
  97. package/dist/lib/sync-manifest.d.ts +1 -1
  98. package/dist/lib/sync-manifest.js +3 -3
  99. package/dist/lib/teams/persistence.js +15 -5
  100. package/dist/lib/teams/registry.js +2 -2
  101. package/dist/lib/types.d.ts +75 -17
  102. package/dist/lib/types.js +3 -3
  103. package/dist/lib/usage.js +2 -2
  104. package/dist/lib/versions.d.ts +3 -0
  105. package/dist/lib/versions.js +158 -47
  106. package/dist/lib/workflows.d.ts +79 -0
  107. package/dist/lib/workflows.js +233 -0
  108. package/package.json +1 -5
  109. package/scripts/postinstall.js +60 -59
  110. package/dist/commands/fork.d.ts +0 -10
  111. package/dist/commands/fork.js +0 -146
@@ -11,8 +11,8 @@ import * as fs from 'fs';
11
11
  import * as path from 'path';
12
12
  import { execFileSync } from 'child_process';
13
13
  import { getVersionDir } from './versions.js';
14
- import { getAgentsDir } from './state.js';
15
- const CACHE_PATH = path.join(getAgentsDir(), '.models-cache.json');
14
+ import { getModelsCachePath } from './state.js';
15
+ const CACHE_PATH = getModelsCachePath();
16
16
  /**
17
17
  * Bump when the extractor logic changes shape in an incompatible way so cached
18
18
  * catalogs from older agents-cli builds are re-extracted.
@@ -8,10 +8,6 @@ export declare const CODEX_RULES_FILENAME = "agents-deny.rules";
8
8
  * E.g. "Bash(git reset:*)" -> prefix_rule(pattern=["git", "reset"], decision="forbidden")
9
9
  */
10
10
  export declare function convertDenyToCodexRules(deny: string[]): string | null;
11
- /**
12
- * Ensure central permissions directory exists.
13
- */
14
- export declare function ensurePermissionsDir(): void;
15
11
  /**
16
12
  * Parse a permission set from a YAML file.
17
13
  */
@@ -42,26 +38,26 @@ export declare function discoverPermissionGroups(): PermissionGroupInfo[];
42
38
  */
43
39
  export declare function getTotalPermissionRuleCount(): number;
44
40
  /**
45
- * A permission set recipe — names a set and lists which groups it composes.
46
- * Lives at ~/.agents/permissions/sets/<name>.yaml.
41
+ * A permission preset recipe — names a preset and lists which groups it composes.
42
+ * Lives at ~/.agents/permissions/presets/<name>.yaml.
47
43
  */
48
- export interface PermissionSetRecipe {
44
+ export interface PermissionPresetRecipe {
49
45
  name: string;
50
46
  description?: string;
51
47
  includes: string[];
52
48
  }
53
49
  /** Env var that selects which set recipe to apply at sync time. */
54
- export declare const PERMISSION_SET_ENV_VAR = "AGENTS_PERMISSION_SET";
50
+ export declare const PERMISSION_PRESET_ENV_VAR = "AGENTS_PERMISSION_PRESET";
55
51
  /**
56
- * Read a permission set recipe by name from ~/.agents/permissions/sets/.
52
+ * Read a permission preset recipe by name from ~/.agents/permissions/presets/.
57
53
  * Returns null if the recipe file is missing or malformed.
58
54
  */
59
- export declare function readPermissionSetRecipe(name: string): PermissionSetRecipe | null;
55
+ export declare function readPermissionPresetRecipe(name: string): PermissionPresetRecipe | null;
60
56
  /**
61
- * Return the active permission set name from AGENTS_PERMISSION_SET env var,
57
+ * Return the active permission preset name from AGENTS_PERMISSION_PRESET env var,
62
58
  * or null if unset. Caller decides the default behavior when null.
63
59
  */
64
- export declare function getActivePermissionSetName(): string | null;
60
+ export declare function getActivePermissionPresetName(): string | null;
65
61
  /**
66
62
  * Build a PermissionSet from selected groups.
67
63
  * Concatenates allow/deny rules from each group.
@@ -76,10 +72,6 @@ export declare function buildPermissionsFromGroups(groupNames: string[]): Permis
76
72
  * same-named override.
77
73
  */
78
74
  export declare function listInstalledPermissions(): InstalledPermission[];
79
- /**
80
- * Get a specific permission set by name. Searches user dir first, then system.
81
- */
82
- export declare function getPermissionSet(name: string): InstalledPermission | null;
83
75
  /**
84
76
  * Install a permission set to user-level central storage.
85
77
  */
@@ -110,24 +102,6 @@ export declare function convertToOpenCodeFormat(set: PermissionSet): OpenCodePer
110
102
  * Codex uses coarse-grained modes, so we infer the best fit.
111
103
  */
112
104
  export declare function convertToCodexFormat(set: PermissionSet, cwd?: string): CodexPermissions;
113
- /**
114
- * Read Claude's current permissions from settings.json.
115
- */
116
- export declare function readClaudePermissions(scope?: 'user' | 'project', cwd?: string, options?: {
117
- home?: string;
118
- }): ClaudePermissions | null;
119
- /**
120
- * Read OpenCode's current permissions from opencode.jsonc.
121
- */
122
- export declare function readOpenCodePermissions(scope?: 'user' | 'project', cwd?: string, options?: {
123
- home?: string;
124
- }): OpenCodePermissions | null;
125
- /**
126
- * Read Codex's current permissions from config.toml.
127
- */
128
- export declare function readCodexPermissions(scope?: 'user' | 'project', cwd?: string, options?: {
129
- home?: string;
130
- }): CodexPermissions | null;
131
105
  /**
132
106
  * Read agent permissions based on agent ID.
133
107
  */
@@ -141,27 +115,6 @@ export declare function applyClaudePermissions(set: PermissionSet, scope?: 'user
141
115
  success: boolean;
142
116
  error?: string;
143
117
  };
144
- /**
145
- * Apply a permission set to OpenCode's opencode.jsonc.
146
- */
147
- export declare function applyOpenCodePermissions(set: PermissionSet, scope?: 'user' | 'project', cwd?: string, merge?: boolean): {
148
- success: boolean;
149
- error?: string;
150
- };
151
- /**
152
- * Apply a permission set to Codex's config.toml.
153
- */
154
- export declare function applyCodexPermissions(set: PermissionSet, scope?: 'user' | 'project', cwd?: string, merge?: boolean): {
155
- success: boolean;
156
- error?: string;
157
- };
158
- /**
159
- * Apply a permission set to an agent (global config).
160
- */
161
- export declare function applyPermissionsToAgent(agentId: AgentId, set: PermissionSet, scope?: 'user' | 'project', cwd?: string, merge?: boolean): {
162
- success: boolean;
163
- error?: string;
164
- };
165
118
  /**
166
119
  * Apply a permission set to a specific version's home directory.
167
120
  * This writes to {versionHome}/.{agent}/settings.json (or equivalent).
@@ -182,22 +135,11 @@ export declare function openCodeToCanonical(perms: OpenCodePermissions): Permiss
182
135
  * Convert Codex permissions back to canonical format (approximation).
183
136
  */
184
137
  export declare function codexToCanonical(perms: CodexPermissions): PermissionSet;
185
- /**
186
- * Export agent's current permissions to canonical format.
187
- */
188
- export declare function exportAgentPermissions(agentId: AgentId, scope?: 'user' | 'project', cwd?: string): PermissionSet | null;
189
138
  /**
190
139
  * Export permissions from a specific config file path to canonical format.
191
140
  * Auto-detects agent type from file path/name.
192
141
  */
193
142
  export declare function exportPermissionsFromPath(filePath: string): PermissionSet | null;
194
- /**
195
- * Save a permission set to central storage.
196
- */
197
- export declare function savePermissionSet(set: PermissionSet): {
198
- success: boolean;
199
- error?: string;
200
- };
201
143
  /**
202
144
  * Get the default permission set from central storage.
203
145
  */
@@ -44,7 +44,7 @@ export function convertDenyToCodexRules(deny) {
44
44
  /**
45
45
  * Ensure central permissions directory exists.
46
46
  */
47
- export function ensurePermissionsDir() {
47
+ function ensurePermissionsDir() {
48
48
  const dir = getUserPermissionsDir();
49
49
  if (!fs.existsSync(dir)) {
50
50
  fs.mkdirSync(dir, { recursive: true });
@@ -159,15 +159,15 @@ export function getTotalPermissionRuleCount() {
159
159
  return groups.reduce((sum, g) => sum + g.ruleCount, 0);
160
160
  }
161
161
  /** Env var that selects which set recipe to apply at sync time. */
162
- export const PERMISSION_SET_ENV_VAR = 'AGENTS_PERMISSION_SET';
162
+ export const PERMISSION_PRESET_ENV_VAR = 'AGENTS_PERMISSION_PRESET';
163
163
  /**
164
- * Read a permission set recipe by name from ~/.agents/permissions/sets/.
164
+ * Read a permission preset recipe by name from ~/.agents/permissions/presets/.
165
165
  * Returns null if the recipe file is missing or malformed.
166
166
  */
167
- export function readPermissionSetRecipe(name) {
168
- const setsDir = path.join(getPermissionsDir(), 'sets');
167
+ export function readPermissionPresetRecipe(name) {
168
+ const presetsDir = path.join(getPermissionsDir(), 'presets');
169
169
  for (const ext of ['.yaml', '.yml']) {
170
- const filePath = safeJoin(setsDir, name + ext);
170
+ const filePath = safeJoin(presetsDir, name + ext);
171
171
  if (!fs.existsSync(filePath))
172
172
  continue;
173
173
  try {
@@ -190,11 +190,11 @@ export function readPermissionSetRecipe(name) {
190
190
  return null;
191
191
  }
192
192
  /**
193
- * Return the active permission set name from AGENTS_PERMISSION_SET env var,
193
+ * Return the active permission preset name from AGENTS_PERMISSION_PRESET env var,
194
194
  * or null if unset. Caller decides the default behavior when null.
195
195
  */
196
- export function getActivePermissionSetName() {
197
- const v = process.env[PERMISSION_SET_ENV_VAR];
196
+ export function getActivePermissionPresetName() {
197
+ const v = process.env[PERMISSION_PRESET_ENV_VAR];
198
198
  return v && v.trim() ? v.trim() : null;
199
199
  }
200
200
  /**
@@ -295,7 +295,7 @@ export function listInstalledPermissions() {
295
295
  /**
296
296
  * Get a specific permission set by name. Searches user dir first, then system.
297
297
  */
298
- export function getPermissionSet(name) {
298
+ function getPermissionSet(name) {
299
299
  for (const dir of [getUserPermissionsDir(), getPermissionsDir()]) {
300
300
  for (const ext of ['.yml', '.yaml']) {
301
301
  const filePath = safeJoin(dir, name + ext);
@@ -504,7 +504,7 @@ function stripJsonComments(content) {
504
504
  /**
505
505
  * Read Claude's current permissions from settings.json.
506
506
  */
507
- export function readClaudePermissions(scope = 'user', cwd, options) {
507
+ function readClaudePermissions(scope = 'user', cwd, options) {
508
508
  const home = options?.home || HOME;
509
509
  const configPath = scope === 'user'
510
510
  ? path.join(home, '.claude', 'settings.json')
@@ -532,7 +532,7 @@ export function readClaudePermissions(scope = 'user', cwd, options) {
532
532
  /**
533
533
  * Read OpenCode's current permissions from opencode.jsonc.
534
534
  */
535
- export function readOpenCodePermissions(scope = 'user', cwd, options) {
535
+ function readOpenCodePermissions(scope = 'user', cwd, options) {
536
536
  const home = options?.home || HOME;
537
537
  const configPath = scope === 'user'
538
538
  ? path.join(home, '.opencode', 'opencode.jsonc')
@@ -559,7 +559,7 @@ export function readOpenCodePermissions(scope = 'user', cwd, options) {
559
559
  /**
560
560
  * Read Codex's current permissions from config.toml.
561
561
  */
562
- export function readCodexPermissions(scope = 'user', cwd, options) {
562
+ function readCodexPermissions(scope = 'user', cwd, options) {
563
563
  const home = options?.home || HOME;
564
564
  const configPath = scope === 'user'
565
565
  ? path.join(home, '.codex', 'config.toml')
@@ -649,7 +649,7 @@ export function applyClaudePermissions(set, scope = 'user', cwd, merge = true) {
649
649
  /**
650
650
  * Apply a permission set to OpenCode's opencode.jsonc.
651
651
  */
652
- export function applyOpenCodePermissions(set, scope = 'user', cwd, merge = true) {
652
+ function applyOpenCodePermissions(set, scope = 'user', cwd, merge = true) {
653
653
  const configDir = scope === 'user'
654
654
  ? path.join(HOME, '.opencode')
655
655
  : path.join(cwd || process.cwd(), '.opencode');
@@ -690,7 +690,7 @@ export function applyOpenCodePermissions(set, scope = 'user', cwd, merge = true)
690
690
  /**
691
691
  * Apply a permission set to Codex's config.toml.
692
692
  */
693
- export function applyCodexPermissions(set, scope = 'user', cwd, merge = true) {
693
+ function applyCodexPermissions(set, scope = 'user', cwd, merge = true) {
694
694
  const configDir = scope === 'user'
695
695
  ? path.join(HOME, '.codex')
696
696
  : path.join(cwd || process.cwd(), '.codex');
@@ -739,7 +739,7 @@ export function applyCodexPermissions(set, scope = 'user', cwd, merge = true) {
739
739
  /**
740
740
  * Apply a permission set to an agent (global config).
741
741
  */
742
- export function applyPermissionsToAgent(agentId, set, scope = 'user', cwd, merge = true) {
742
+ function applyPermissionsToAgent(agentId, set, scope = 'user', cwd, merge = true) {
743
743
  switch (agentId) {
744
744
  case 'claude':
745
745
  return applyClaudePermissions(set, scope, cwd, merge);
@@ -912,7 +912,7 @@ export function codexToCanonical(perms) {
912
912
  /**
913
913
  * Export agent's current permissions to canonical format.
914
914
  */
915
- export function exportAgentPermissions(agentId, scope = 'user', cwd) {
915
+ function exportAgentPermissions(agentId, scope = 'user', cwd) {
916
916
  const perms = readAgentPermissions(agentId, scope, cwd);
917
917
  if (!perms)
918
918
  return null;
@@ -1017,7 +1017,7 @@ export function exportPermissionsFromPath(filePath) {
1017
1017
  /**
1018
1018
  * Save a permission set to central storage.
1019
1019
  */
1020
- export function savePermissionSet(set) {
1020
+ function savePermissionSet(set) {
1021
1021
  ensurePermissionsDir();
1022
1022
  const filePath = safeJoin(getUserPermissionsDir(), set.name + '.yml');
1023
1023
  try {
@@ -1,16 +1,18 @@
1
1
  /**
2
2
  * Plugin discovery, validation, and syncing.
3
3
  *
4
- * Plugins are bundles in ~/.agents/plugins/ that package skills, hooks, and
5
- * scripts under a single manifest (plugin.yaml). This module discovers plugins,
6
- * validates their manifests, and syncs their contents into agent version homes.
4
+ * Plugins are bundles in ~/.agents/.cache/plugins/ that package skills, hooks,
5
+ * commands, agents, bin scripts, MCP servers, and settings under a single
6
+ * manifest (plugin.json). This module discovers plugins, validates their
7
+ * manifests, and syncs their contents into agent version homes.
7
8
  */
8
9
  import type { AgentId, DiscoveredPlugin, PluginManifest } from './types.js';
9
10
  /**
10
- * Discover all plugins in ~/.agents/plugins/.
11
+ * Discover all plugins in ~/.agents/.cache/plugins/.
11
12
  * A valid plugin has a .claude-plugin/plugin.json manifest.
12
13
  */
13
14
  export declare function discoverPlugins(): DiscoveredPlugin[];
15
+ export declare function buildDiscoveredPlugin(pluginRoot: string, manifest: PluginManifest): DiscoveredPlugin;
14
16
  /**
15
17
  * Load a plugin manifest from a plugin directory.
16
18
  */
@@ -25,55 +27,123 @@ export declare function getPlugin(name: string): DiscoveredPlugin | null;
25
27
  * Otherwise defaults to all plugin-capable agents.
26
28
  */
27
29
  export declare function pluginSupportsAgent(plugin: DiscoveredPlugin, agent: AgentId): boolean;
30
+ /** Discover command .md files inside a plugin's commands/ directory. */
31
+ export declare function discoverPluginCommands(pluginRoot: string): string[];
32
+ /** Discover agent definition .md files inside a plugin's agents/ directory. */
33
+ export declare function discoverPluginAgentDefs(pluginRoot: string): string[];
34
+ /** Discover executable files in a plugin's bin/ directory. */
35
+ export declare function discoverPluginBin(pluginRoot: string): string[];
28
36
  /**
29
37
  * Expand plugin variables in a string.
30
38
  *
31
39
  * Variables:
32
- * ${CLAUDE_PLUGIN_ROOT} -> absolute path to plugin directory
33
- * ${CLAUDE_PLUGIN_DATA} -> per-version data directory for this plugin
40
+ * ${CLAUDE_PLUGIN_ROOT} -> absolute path to plugin directory
41
+ * ${CLAUDE_PLUGIN_DATA} -> per-version data directory for this plugin
42
+ * ${user_config.<key>} -> value from plugin's .user-config.json
34
43
  */
35
- export declare function expandPluginVars(str: string, pluginRoot: string, pluginName: string, agentId: AgentId, versionHome: string): string;
44
+ export declare function expandPluginVars(str: string, pluginRoot: string, pluginName: string, agentId: AgentId, versionHome: string, userConfig?: Record<string, string>): string;
45
+ /**
46
+ * Load persisted user config for a plugin from .user-config.json.
47
+ */
48
+ export declare function loadUserConfig(pluginName: string): Record<string, string>;
49
+ /**
50
+ * Persist user config for a plugin to .user-config.json.
51
+ */
52
+ export declare function saveUserConfig(pluginName: string, config: Record<string, string>): void;
53
+ /**
54
+ * Check plugin dependencies against installed plugins.
55
+ * Returns names of missing dependencies (warning only — not a hard error).
56
+ */
57
+ export declare function checkPluginDependencies(manifest: PluginManifest): string[];
36
58
  /**
37
59
  * Sync a plugin to a specific agent version's home directory.
38
60
  *
39
61
  * For Claude:
40
- * 1. Copy plugin skills into version's skills dir (prefixed: pluginName:skillName)
41
- * 2. Read hooks/hooks.json, expand vars, merge into settings.json hooks
42
- * 3. Read settings.json, expand vars, merge permissions into settings.json
43
- *
44
- * For OpenClaw:
45
- * 1. Copy plugin skills into version's skills dir
62
+ * 1. Copy plugin skills into version's skills dir (prefixed: pluginName--skillName)
63
+ * 2. Copy plugin commands into version's commands dir (prefixed: pluginName--cmdName.md)
64
+ * 3. Copy plugin agent defs into version's agents dir (prefixed: pluginName--agentName.md)
65
+ * 4. Copy plugin bin/ into version home plugin-bin/<pluginName>/, note path in settings
66
+ * 5. Read hooks/hooks.json, expand vars, merge into settings.json hooks
67
+ * 6. Read .mcp.json, expand vars, merge mcpServers into settings.json
68
+ * 7. Read settings.json, merge non-permission keys non-destructively into settings.json
69
+ * 8. Read settings.json permissions, expand vars, merge into settings.json
46
70
  */
47
71
  export declare function syncPluginToVersion(plugin: DiscoveredPlugin, agent: AgentId, versionHome: string): {
48
72
  success: boolean;
49
73
  skills: string[];
74
+ commands: string[];
75
+ agentDefs: string[];
76
+ bin: string[];
50
77
  hooks: string[];
51
78
  permissions: boolean;
79
+ mcp: boolean;
80
+ settings: boolean;
52
81
  };
53
82
  /**
54
83
  * Check if a plugin is synced to a version by inspecting the version home.
55
- * Checks multiple signals: skills directories, hook commands in settings.json,
56
- * and plugin permissions in settings.json.
84
+ * Checks skills, commands, agent defs, bin, hook commands, and permissions.
57
85
  */
58
86
  export declare function isPluginSynced(plugin: DiscoveredPlugin, agent: AgentId, versionHome: string): boolean;
59
87
  /**
60
88
  * Remove a plugin from a specific agent version's home directory.
61
- * Inverse of syncPluginToVersion:
62
- * 1. Delete synced skill directories (pluginName--*)
63
- * 2. Strip hook entries whose commands reference the plugin root
64
- * 3. Strip permission rules that reference the plugin root
89
+ * Inverse of syncPluginToVersion.
65
90
  *
66
- * Works whether or not the plugin source still exists on disk, because it
67
- * matches by the plugin's name and root path rather than re-reading manifests.
91
+ * Works whether or not the plugin source still exists on disk.
68
92
  */
69
93
  export declare function removePluginFromVersion(pluginName: string, pluginRoot: string, agent: AgentId, versionHome: string): {
70
94
  skills: string[];
95
+ commands: string[];
96
+ agentDefs: string[];
97
+ bin: string[];
71
98
  hooks: string[];
72
99
  permissions: number;
100
+ mcp: number;
73
101
  };
74
102
  /**
75
103
  * Remove orphaned plugin skill directories from a version home.
76
- * An orphan is a skill dir with the plugin prefix pattern (name--skill)
77
- * where the plugin no longer exists in ~/.agents/plugins/.
104
+ * Soft-deletes to ~/.agents/.trash/plugins/.
78
105
  */
79
- export declare function cleanOrphanedPluginSkills(agent: AgentId, versionHome: string, activePluginNames: Set<string>): string[];
106
+ export declare function cleanOrphanedPluginSkills(agent: AgentId, versionHome: string, activePluginNames: Set<string>, version?: string): string[];
107
+ export interface VersionPluginDiff {
108
+ agent: AgentId;
109
+ version: string;
110
+ orphans: string[];
111
+ }
112
+ export declare function diffVersionPlugins(agent: AgentId, version: string): VersionPluginDiff;
113
+ export declare function iterPluginsCapableVersions(filter?: {
114
+ agent?: AgentId;
115
+ version?: string;
116
+ }): Array<{
117
+ agent: AgentId;
118
+ version: string;
119
+ }>;
120
+ export declare function removePluginSkillFromVersion(agent: AgentId, version: string, skillName: string): {
121
+ success: boolean;
122
+ error?: string;
123
+ };
124
+ /**
125
+ * Parse an install spec of the form `name@source` or just `source`.
126
+ * Source can be a git URL or an absolute/relative local path.
127
+ */
128
+ export declare function parseInstallSpec(spec: string): {
129
+ name: string | null;
130
+ source: string;
131
+ };
132
+ /**
133
+ * Install a plugin from a git URL or local path.
134
+ * Clones/copies to ~/.agents/.cache/plugins/<name>/.
135
+ * Returns the installed plugin name and root path.
136
+ */
137
+ export declare function installPlugin(spec: string): Promise<{
138
+ name: string;
139
+ root: string;
140
+ isNew: boolean;
141
+ }>;
142
+ /**
143
+ * Update an installed plugin by re-pulling from its original source.
144
+ * Returns true if the update succeeded.
145
+ */
146
+ export declare function updatePlugin(name: string): Promise<{
147
+ success: boolean;
148
+ error?: string;
149
+ }>;