@swarmify/agents-cli 1.5.15 → 1.5.17

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/dist/index.js CHANGED
@@ -18,9 +18,9 @@ function isPromptCancelled(err) {
18
18
  }
19
19
  import { AGENTS, ALL_AGENT_IDS, MCP_CAPABLE_AGENTS, SKILLS_CAPABLE_AGENTS, HOOKS_CAPABLE_AGENTS, getAllCliStates, getCliVersion, isMcpRegistered, registerMcp, unregisterMcp, listInstalledMcpsWithScope, promoteMcpToUser, } from './lib/agents.js';
20
20
  import { readManifest, writeManifest, createDefaultManifest, MANIFEST_FILENAME, } from './lib/manifest.js';
21
- import { readState, ensureAgentsDir, getRepoLocalPath, getScope, setScope, removeScope, getScopesByPriority, getScopePriority, } from './lib/state.js';
21
+ import { readState, getRepoLocalPath, getScope, setScope, removeScope, getScopesByPriority, getScopePriority, } from './lib/state.js';
22
22
  import { SCOPE_PRIORITIES, DEFAULT_SYSTEM_REPO } from './lib/types.js';
23
- import { cloneRepo, parseSource } from './lib/git.js';
23
+ import { cloneRepo, parseSource, getGitHubUsername, getRemoteUrl, setRemoteUrl, checkGitHubRepoExists, commitAndPush, hasUncommittedChanges, } from './lib/git.js';
24
24
  import { discoverCommands, resolveCommandSource, installCommand, uninstallCommand, listInstalledCommandsWithScope, promoteCommandToUser, commandExists, commandContentMatches, } from './lib/commands.js';
25
25
  import { discoverHooksFromRepo, installHooks, listInstalledHooksWithScope, promoteHookToUser, removeHook, hookExists, hookContentMatches, getSourceHookEntry, } from './lib/hooks.js';
26
26
  import { discoverSkillsFromRepo, installSkill, uninstallSkill, listInstalledSkillsWithScope, promoteSkillToUser, getSkillInfo, getSkillRules, skillExists, skillContentMatches, } from './lib/skills.js';
@@ -400,7 +400,7 @@ program
400
400
  console.log(chalk.gray(`\nFiltering for ${AGENTS[agentFilter].name} only\n`));
401
401
  }
402
402
  else if (options.yes || options.force) {
403
- selectedAgents = (manifest?.defaults?.agents || ['claude', 'codex', 'gemini']);
403
+ selectedAgents = (manifest?.defaults?.agents || ALL_AGENT_IDS);
404
404
  }
405
405
  else {
406
406
  const installedAgents = ALL_AGENT_IDS.filter((id) => cliStates[id]?.installed || id === 'cursor');
@@ -409,7 +409,7 @@ program
409
409
  choices: installedAgents.map((id) => ({
410
410
  name: AGENTS[id].name,
411
411
  value: id,
412
- checked: (manifest?.defaults?.agents || ['claude', 'codex', 'gemini']).includes(id),
412
+ checked: (manifest?.defaults?.agents || ALL_AGENT_IDS).includes(id),
413
413
  })),
414
414
  });
415
415
  }
@@ -1041,88 +1041,147 @@ program
1041
1041
  // =============================================================================
1042
1042
  program
1043
1043
  .command('push')
1044
- .description('Export local configuration to .agents repo for manual commit')
1044
+ .description('Push local configuration to your .agents repo on GitHub')
1045
1045
  .option('-s, --scope <scope>', 'Target scope (default: user)', 'user')
1046
- .option('--export-only', 'Only export, do not update manifest')
1046
+ .option('--export-only', 'Only export to local repo, do not push to GitHub')
1047
+ .option('-m, --message <msg>', 'Commit message', 'Update agent configuration')
1047
1048
  .action(async (options) => {
1048
- const scopeName = options.scope;
1049
- const scope = getScope(scopeName);
1050
- if (!scope) {
1051
- console.log(chalk.red(`Scope '${scopeName}' not configured.`));
1052
- const scopeHint = scopeName === 'user' ? '' : ` --scope ${scopeName}`;
1053
- console.log(chalk.gray(` Run: agents repo add <source>${scopeHint}`));
1054
- process.exit(1);
1055
- }
1056
- if (scope.readonly) {
1057
- console.log(chalk.red(`Scope '${scopeName}' is readonly. Cannot push.`));
1058
- process.exit(1);
1059
- }
1060
- const localPath = getRepoLocalPath(scope.source);
1061
- const manifest = readManifest(localPath) || createDefaultManifest();
1062
- console.log(chalk.bold('\nExporting local configuration...\n'));
1063
- const cliStates = await getAllCliStates();
1064
- let exported = 0;
1065
- for (const agentId of ALL_AGENT_IDS) {
1066
- const agent = AGENTS[agentId];
1067
- const cli = cliStates[agentId];
1068
- if (cli?.installed && cli.version) {
1069
- manifest.clis = manifest.clis || {};
1070
- manifest.clis[agentId] = {
1071
- package: agent.npmPackage,
1072
- version: cli.version,
1073
- };
1074
- console.log(` ${chalk.green('+')} ${agent.name} @ ${cli.version}`);
1075
- exported++;
1049
+ try {
1050
+ const scopeName = options.scope;
1051
+ const scope = getScope(scopeName);
1052
+ if (!scope) {
1053
+ console.log(chalk.red(`Scope '${scopeName}' not configured.`));
1054
+ console.log(chalk.gray(' Run: agents pull'));
1055
+ process.exit(1);
1076
1056
  }
1077
- }
1078
- // Export MCP servers from installed agents
1079
- console.log();
1080
- let mcpExported = 0;
1081
- const mcpByName = new Map();
1082
- for (const agentId of MCP_CAPABLE_AGENTS) {
1083
- if (!cliStates[agentId]?.installed)
1084
- continue;
1085
- const mcps = listInstalledMcpsWithScope(agentId);
1086
- for (const mcp of mcps) {
1087
- if (mcp.scope !== 'user')
1088
- continue; // Only export user-scoped MCPs
1089
- const existing = mcpByName.get(mcp.name);
1090
- if (existing) {
1091
- if (!existing.agents.includes(agentId)) {
1092
- existing.agents.push(agentId);
1057
+ if (scope.readonly) {
1058
+ console.log(chalk.red(`Scope '${scopeName}' is readonly. Cannot push.`));
1059
+ process.exit(1);
1060
+ }
1061
+ const localPath = getRepoLocalPath(scope.source);
1062
+ const manifest = readManifest(localPath) || createDefaultManifest();
1063
+ console.log(chalk.bold('\nExporting local configuration...\n'));
1064
+ const cliStates = await getAllCliStates();
1065
+ let exported = 0;
1066
+ for (const agentId of ALL_AGENT_IDS) {
1067
+ const agent = AGENTS[agentId];
1068
+ const cli = cliStates[agentId];
1069
+ if (cli?.installed && cli.version) {
1070
+ manifest.clis = manifest.clis || {};
1071
+ manifest.clis[agentId] = {
1072
+ package: agent.npmPackage,
1073
+ version: cli.version,
1074
+ };
1075
+ console.log(` ${chalk.green('+')} ${agent.name} @ ${cli.version}`);
1076
+ exported++;
1077
+ }
1078
+ }
1079
+ // Export MCP servers from installed agents
1080
+ console.log();
1081
+ let mcpExported = 0;
1082
+ const mcpByName = new Map();
1083
+ for (const agentId of MCP_CAPABLE_AGENTS) {
1084
+ if (!cliStates[agentId]?.installed)
1085
+ continue;
1086
+ const mcps = listInstalledMcpsWithScope(agentId);
1087
+ for (const mcp of mcps) {
1088
+ if (mcp.scope !== 'user')
1089
+ continue; // Only export user-scoped MCPs
1090
+ const existing = mcpByName.get(mcp.name);
1091
+ if (existing) {
1092
+ if (!existing.agents.includes(agentId)) {
1093
+ existing.agents.push(agentId);
1094
+ }
1095
+ }
1096
+ else {
1097
+ mcpByName.set(mcp.name, {
1098
+ command: mcp.command || '',
1099
+ agents: [agentId],
1100
+ });
1093
1101
  }
1094
- }
1095
- else {
1096
- mcpByName.set(mcp.name, {
1097
- command: mcp.command || '',
1098
- agents: [agentId],
1099
- });
1100
1102
  }
1101
1103
  }
1102
- }
1103
- if (mcpByName.size > 0) {
1104
- manifest.mcp = manifest.mcp || {};
1105
- for (const [name, config] of mcpByName) {
1106
- manifest.mcp[name] = {
1107
- command: config.command,
1108
- transport: 'stdio',
1109
- agents: config.agents,
1110
- scope: 'user',
1111
- };
1112
- console.log(` ${chalk.green('+')} MCP: ${name} (${config.agents.map(id => AGENTS[id].name).join(', ')})`);
1113
- mcpExported++;
1104
+ if (mcpByName.size > 0) {
1105
+ manifest.mcp = manifest.mcp || {};
1106
+ for (const [name, config] of mcpByName) {
1107
+ manifest.mcp[name] = {
1108
+ command: config.command,
1109
+ transport: 'stdio',
1110
+ agents: config.agents,
1111
+ scope: 'user',
1112
+ };
1113
+ console.log(` ${chalk.green('+')} MCP: ${name} (${config.agents.map((id) => AGENTS[id].name).join(', ')})`);
1114
+ mcpExported++;
1115
+ }
1114
1116
  }
1115
- }
1116
- if (!options.exportOnly) {
1117
1117
  writeManifest(localPath, manifest);
1118
1118
  console.log(chalk.bold(`\nUpdated ${MANIFEST_FILENAME}`));
1119
+ if (options.exportOnly) {
1120
+ console.log(chalk.bold('\nExport complete. Changes saved locally.'));
1121
+ console.log(chalk.gray(` Path: ${localPath}`));
1122
+ return;
1123
+ }
1124
+ // Check if there are changes to push
1125
+ const hasChanges = await hasUncommittedChanges(localPath);
1126
+ if (!hasChanges) {
1127
+ console.log(chalk.green('\nNo changes to push.'));
1128
+ return;
1129
+ }
1130
+ // Get GitHub username
1131
+ const spinner = ora('Checking GitHub authentication...').start();
1132
+ const username = await getGitHubUsername();
1133
+ if (!username) {
1134
+ spinner.fail('GitHub CLI not authenticated');
1135
+ console.log(chalk.yellow('\nTo push changes, authenticate with GitHub:'));
1136
+ console.log(chalk.gray(' gh auth login'));
1137
+ console.log(chalk.gray('\nOr push manually:'));
1138
+ console.log(chalk.gray(` cd ${localPath}`));
1139
+ console.log(chalk.gray(' git add -A && git commit -m "Update" && git push'));
1140
+ return;
1141
+ }
1142
+ spinner.text = 'Checking remote configuration...';
1143
+ // Check if remote is set to user's repo
1144
+ const currentRemote = await getRemoteUrl(localPath);
1145
+ const userRepoUrl = `https://github.com/${username}/.agents.git`;
1146
+ const isUserRepo = currentRemote?.includes(`${username}/.agents`);
1147
+ if (!isUserRepo) {
1148
+ // Check if user's repo exists on GitHub
1149
+ spinner.text = `Checking if ${username}/.agents exists...`;
1150
+ const repoExists = await checkGitHubRepoExists(username, '.agents');
1151
+ if (!repoExists) {
1152
+ spinner.fail(`Repository ${username}/.agents does not exist`);
1153
+ console.log(chalk.yellow('\nCreate your .agents repo on GitHub:'));
1154
+ console.log(chalk.cyan(` gh repo create .agents --public --description "My agent configurations"`));
1155
+ console.log(chalk.gray('\nThen run: agents push'));
1156
+ return;
1157
+ }
1158
+ // Update remote to user's repo
1159
+ spinner.text = `Switching remote to ${username}/.agents...`;
1160
+ await setRemoteUrl(localPath, userRepoUrl);
1161
+ }
1162
+ // Commit and push
1163
+ spinner.text = 'Pushing changes...';
1164
+ const result = await commitAndPush(localPath, options.message);
1165
+ if (result.success) {
1166
+ spinner.succeed(`Pushed to ${username}/.agents`);
1167
+ console.log(chalk.green(`\nView: https://github.com/${username}/.agents`));
1168
+ }
1169
+ else {
1170
+ spinner.fail('Failed to push');
1171
+ console.log(chalk.red(result.error || 'Unknown error'));
1172
+ if (result.error?.includes('rejected')) {
1173
+ console.log(chalk.yellow('\nTry pulling first: agents pull'));
1174
+ }
1175
+ }
1176
+ }
1177
+ catch (err) {
1178
+ if (isPromptCancelled(err)) {
1179
+ console.log(chalk.yellow('\nCancelled'));
1180
+ process.exit(0);
1181
+ }
1182
+ console.error(chalk.red(err.message));
1183
+ process.exit(1);
1119
1184
  }
1120
- console.log(chalk.bold('\nNext steps:'));
1121
- console.log(chalk.gray(` cd ${localPath}`));
1122
- console.log(chalk.gray(' git add -A'));
1123
- console.log(chalk.gray(' git commit -m "Update agent configuration"'));
1124
- console.log(chalk.gray(' git push'));
1125
- console.log();
1126
1185
  });
1127
1186
  // =============================================================================
1128
1187
  // SYNC COMMAND
@@ -1204,7 +1263,7 @@ commandsCmd
1204
1263
  spinner.succeed(`Found ${commands.length} commands`);
1205
1264
  const agents = options.agents
1206
1265
  ? options.agents.split(',')
1207
- : ['claude', 'codex', 'gemini'];
1266
+ : ALL_AGENT_IDS;
1208
1267
  const cliStates = await getAllCliStates();
1209
1268
  for (const command of commands) {
1210
1269
  console.log(`\n ${chalk.cyan(command.name)}: ${command.description}`);
@@ -1533,7 +1592,7 @@ skillsCmd
1533
1592
  choices: SKILLS_CAPABLE_AGENTS.filter((id) => cliStates[id]?.installed || id === 'cursor').map((id) => ({
1534
1593
  name: AGENTS[id].name,
1535
1594
  value: id,
1536
- checked: ['claude', 'codex', 'gemini'].includes(id),
1595
+ checked: true,
1537
1596
  })),
1538
1597
  });
1539
1598
  if (agents.length === 0) {
@@ -2340,26 +2399,6 @@ program
2340
2399
  }
2341
2400
  }
2342
2401
  });
2343
- // Legacy alias for backwards compatibility
2344
- program
2345
- .command('cli')
2346
- .description('(deprecated) Use: agents add, agents remove, agents list')
2347
- .action(() => {
2348
- console.log(chalk.yellow('The "cli" subcommand is deprecated.'));
2349
- console.log();
2350
- console.log('New commands:');
2351
- console.log(' agents add <agent>@<version> Install agent CLI');
2352
- console.log(' agents remove <agent>[@version] Remove agent CLI');
2353
- console.log(' agents use <agent>@<version> Set default version');
2354
- console.log(' agents list List installed versions');
2355
- console.log(' agents upgrade [agent] Upgrade to latest');
2356
- console.log();
2357
- console.log('Examples:');
2358
- console.log(' agents add claude@1.5.0');
2359
- console.log(' agents add claude@1.5.0 -p Pin to project');
2360
- console.log(' agents use claude@1.4.0');
2361
- console.log(' agents remove claude@1.4.0');
2362
- });
2363
2402
  // =============================================================================
2364
2403
  // REPO COMMANDS
2365
2404
  // =============================================================================
@@ -2500,31 +2539,6 @@ repoCmd
2500
2539
  console.log(chalk.green('\nSync complete.'));
2501
2540
  });
2502
2541
  // =============================================================================
2503
- // INIT COMMAND
2504
- // =============================================================================
2505
- program
2506
- .command('init')
2507
- .description('Initialize a new .agents repo')
2508
- .action(() => {
2509
- ensureAgentsDir();
2510
- const manifest = createDefaultManifest();
2511
- console.log(chalk.bold('\nDefault agents.yaml:\n'));
2512
- console.log(chalk.gray('clis:'));
2513
- console.log(chalk.gray(' claude:'));
2514
- console.log(chalk.gray(' package: "@anthropic-ai/claude-code"'));
2515
- console.log(chalk.gray(' version: "latest"'));
2516
- console.log(chalk.gray(' codex:'));
2517
- console.log(chalk.gray(' package: "@openai/codex"'));
2518
- console.log(chalk.gray(' version: "latest"'));
2519
- console.log();
2520
- console.log(chalk.green('Create a new repo with this structure:'));
2521
- console.log(chalk.gray(' .agents/'));
2522
- console.log(chalk.gray(' agents.yaml'));
2523
- console.log(chalk.gray(' shared/commands/'));
2524
- console.log(chalk.gray(' claude/hooks/'));
2525
- console.log();
2526
- });
2527
- // =============================================================================
2528
2542
  // REGISTRY COMMANDS
2529
2543
  // =============================================================================
2530
2544
  const registryCmd = program
@@ -2812,7 +2826,7 @@ program
2812
2826
  console.log(` ${hooks.shared.length + Object.values(hooks.agentSpecific).flat().length} hooks`);
2813
2827
  const agents = options.agents
2814
2828
  ? options.agents.split(',')
2815
- : ['claude', 'codex', 'gemini'];
2829
+ : ALL_AGENT_IDS;
2816
2830
  const gitCliStates = await getAllCliStates();
2817
2831
  // Install commands
2818
2832
  if (hasCommands) {