swarm-code 0.1.0 → 0.1.1

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/cli.js CHANGED
@@ -21,10 +21,10 @@ const { runRlmLoop } = await import("./core/rlm.js");
21
21
  // ── Arg parsing ─────────────────────────────────────────────────────────────
22
22
  function usage() {
23
23
  console.error(`
24
- swarm run — Recursive Language Model CLI (arXiv:2512.24601)
24
+ swarm run — Text processing mode (RLM)
25
25
 
26
26
  USAGE
27
- rlm run [OPTIONS] "<query>"
27
+ swarm run [OPTIONS] "<query>"
28
28
 
29
29
  OPTIONS
30
30
  --model <id> Model ID (default: RLM_MODEL from .env)
@@ -34,9 +34,9 @@ OPTIONS
34
34
  --verbose Show iteration progress
35
35
 
36
36
  EXAMPLES
37
- rlm run --file big.txt "List all classes"
38
- curl -s https://example.com/large.py | rlm run --stdin "Summarize"
39
- rlm run --url https://raw.githubusercontent.com/.../typing.py "Count public classes"
37
+ swarm run --file big.txt "List all classes"
38
+ curl -s https://example.com/large.py | swarm run --stdin "Summarize"
39
+ swarm run --url https://raw.githubusercontent.com/.../typing.py "Count public classes"
40
40
  `.trim());
41
41
  process.exit(1);
42
42
  }
@@ -309,14 +309,14 @@ function handleMultiLineAsContext(input) {
309
309
  function printBanner() {
310
310
  console.log(`
311
311
  ${c.cyan}${c.bold}
312
- ██████╗ ██╗ ███╗ ███╗
313
- ██╔══██╗██║ ████╗ ████║
314
- ██████╔╝██║ ██╔████╔██║
315
- ██╔══██╗██║ ██║╚██╔╝██║
316
- ██║ ██║███████╗██║ ╚═╝ ██║
317
- ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
312
+ ███████╗██╗ ██╗ █████╗ ██████╗ ███╗ ███╗
313
+ ██╔════╝██║ ██║██╔══██╗██╔══██╗████╗ ████║
314
+ ███████╗██║ █╗ ██║███████║██████╔╝██╔████╔██║
315
+ ╚════██║██║███╗██║██╔══██║██╔══██╗██║╚██╔╝██║
316
+ ███████║╚███╔███╔╝██║ ██║██║ ██║██║ ╚═╝ ██║
317
+ ╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝
318
318
  ${c.reset}
319
- ${c.dim} Recursive Language Models — arXiv:2512.24601${c.reset}
319
+ ${c.dim} Swarm-native coding agent orchestrator${c.reset}
320
320
  `);
321
321
  }
322
322
  // ── Status line ─────────────────────────────────────────────────────────────
@@ -1285,45 +1285,124 @@ async function interactive() {
1285
1285
  if (!hasAnyApiKey()) {
1286
1286
  printBanner();
1287
1287
  console.log(` ${c.bold}Welcome! Let's get you set up.${c.reset}\n`);
1288
+ // Agent definitions — each lists which API keys it needs (if any)
1289
+ const AGENT_CHOICES = [
1290
+ {
1291
+ name: "OpenCode",
1292
+ id: "opencode",
1293
+ desc: "Multi-provider + open-source (Ollama, DeepSeek, Kimi, GLM, ...)",
1294
+ keys: SETUP_PROVIDERS, // optionally accepts any provider
1295
+ requiresKey: false, // can run with local/open-source models, no API key needed
1296
+ },
1297
+ {
1298
+ name: "Claude Code",
1299
+ id: "claude-code",
1300
+ desc: "Anthropic",
1301
+ keys: SETUP_PROVIDERS.filter((p) => p.piProvider === "anthropic"),
1302
+ requiresKey: true,
1303
+ },
1304
+ {
1305
+ name: "Codex",
1306
+ id: "codex",
1307
+ desc: "OpenAI",
1308
+ keys: SETUP_PROVIDERS.filter((p) => p.piProvider === "openai"),
1309
+ requiresKey: true,
1310
+ },
1311
+ {
1312
+ name: "Aider",
1313
+ id: "aider",
1314
+ desc: "Git-aware AI pair programmer (Anthropic, OpenAI)",
1315
+ keys: SETUP_PROVIDERS.filter((p) => p.piProvider === "anthropic" || p.piProvider === "openai"),
1316
+ requiresKey: true,
1317
+ },
1318
+ {
1319
+ name: "Direct LLM",
1320
+ id: "direct-llm",
1321
+ desc: "Bare API calls, no coding agent",
1322
+ keys: SETUP_PROVIDERS,
1323
+ requiresKey: true,
1324
+ },
1325
+ ];
1288
1326
  const setupRl = readline.createInterface({ input: stdin, output: stdout, terminal: true });
1289
1327
  let setupDone = false;
1290
1328
  while (!setupDone) {
1291
- console.log(` ${c.bold}Select your provider:${c.reset}\n`);
1292
- for (let i = 0; i < SETUP_PROVIDERS.length; i++) {
1293
- console.log(` ${c.dim}${i + 1}${c.reset} ${SETUP_PROVIDERS[i].name} ${c.dim}(${SETUP_PROVIDERS[i].label})${c.reset}`);
1329
+ console.log(` ${c.bold}Select your coding agent:${c.reset}\n`);
1330
+ for (let i = 0; i < AGENT_CHOICES.length; i++) {
1331
+ const a = AGENT_CHOICES[i];
1332
+ console.log(` ${c.dim}${i + 1}${c.reset} ${a.name} ${c.dim}${a.desc}${c.reset}`);
1294
1333
  }
1295
1334
  console.log();
1296
- const choice = await questionWithEsc(setupRl, ` ${c.cyan}Provider [1-${SETUP_PROVIDERS.length}]:${c.reset} `);
1335
+ const choice = await questionWithEsc(setupRl, ` ${c.cyan}Agent [1-${AGENT_CHOICES.length}]:${c.reset} `);
1297
1336
  if (choice === null) {
1298
- // ESC at provider selection → exit
1299
1337
  console.log(`\n ${c.dim}Exiting.${c.reset}\n`);
1300
1338
  setupRl.close();
1301
1339
  process.exit(0);
1302
1340
  }
1303
1341
  const idx = parseInt(choice, 10) - 1;
1304
- if (Number.isNaN(idx) || idx < 0 || idx >= SETUP_PROVIDERS.length) {
1342
+ if (Number.isNaN(idx) || idx < 0 || idx >= AGENT_CHOICES.length) {
1305
1343
  console.log(`\n ${c.dim}Invalid choice.${c.reset}\n`);
1306
1344
  continue;
1307
1345
  }
1308
- const provider = SETUP_PROVIDERS[idx];
1309
- const gotKey = await promptForProviderKey(setupRl, provider);
1310
- if (gotKey === null) {
1311
- // ESC at key entry → back to provider selection
1346
+ const agent = AGENT_CHOICES[idx];
1347
+ console.log(`\n ${c.green}✓${c.reset} Agent: ${c.bold}${agent.name}${c.reset}\n`);
1348
+ // Prompt for API key(s) one by one based on the selected agent
1349
+ let gotAnyKey = false;
1350
+ if (agent.requiresKey) {
1351
+ // Agent requires at least one key — prompt until we get one
1352
+ console.log(` ${c.dim}${agent.name} requires an API key. Configure one now:${c.reset}\n`);
1353
+ for (const provider of agent.keys) {
1354
+ const gotKey = await promptForProviderKey(setupRl, provider);
1355
+ if (gotKey === null)
1356
+ break; // ESC — skip remaining
1357
+ if (gotKey) {
1358
+ gotAnyKey = true;
1359
+ break; // Got one — that's enough
1360
+ }
1361
+ }
1362
+ if (!gotAnyKey) {
1363
+ console.log(`\n ${c.dim}No key provided. Try another agent or set keys in .env${c.reset}\n`);
1364
+ continue;
1365
+ }
1366
+ }
1367
+ else {
1368
+ // Agent works without keys (e.g. OpenCode with open-source models)
1369
+ // Offer to configure a provider key optionally
1370
+ console.log(` ${c.dim}${agent.name} works with open-source models (no API key needed).${c.reset}`);
1371
+ console.log(` ${c.dim}Optionally configure a provider for cloud models:${c.reset}\n`);
1372
+ for (const provider of agent.keys) {
1373
+ console.log(` ${c.dim}-${c.reset} ${provider.name} ${c.dim}(${provider.env})${c.reset}`);
1374
+ }
1312
1375
  console.log();
1313
- continue;
1376
+ const addKey = await questionWithEsc(setupRl, ` ${c.cyan}Add an API key? [y/N]:${c.reset} `);
1377
+ if (addKey !== null && (addKey.toLowerCase() === "y" || addKey.toLowerCase() === "yes")) {
1378
+ for (const provider of agent.keys) {
1379
+ const gotKey = await promptForProviderKey(setupRl, provider);
1380
+ if (gotKey === null)
1381
+ break;
1382
+ if (gotKey) {
1383
+ gotAnyKey = true;
1384
+ break;
1385
+ }
1386
+ }
1387
+ }
1314
1388
  }
1315
- if (!gotKey) {
1316
- console.log(`\n ${c.dim}No key provided. Exiting.${c.reset}\n`);
1317
- setupRl.close();
1318
- process.exit(0);
1389
+ // Set default model
1390
+ const activeProvider = Object.keys(PROVIDER_KEYS).find((p) => process.env[providerEnvKey(p)]);
1391
+ if (activeProvider) {
1392
+ // Has an API key — use that provider's default model
1393
+ currentProviderName = activeProvider;
1394
+ const defaultModel = getDefaultModelForProvider(activeProvider);
1395
+ if (defaultModel) {
1396
+ currentModelId = defaultModel;
1397
+ saveModelPreference(currentModelId);
1398
+ console.log(` ${c.green}✓${c.reset} Default model: ${c.bold}${currentModelId}${c.reset}`);
1399
+ }
1319
1400
  }
1320
- // Auto-select default model for chosen provider
1321
- currentProviderName = provider.piProvider;
1322
- const defaultModel = getDefaultModelForProvider(provider.piProvider);
1323
- if (defaultModel) {
1324
- currentModelId = defaultModel;
1401
+ else {
1402
+ // No API key — default to open-source model via OpenCode
1403
+ currentModelId = "ollama/deepseek-coder-v2";
1325
1404
  saveModelPreference(currentModelId);
1326
- console.log(` ${c.green}✓${c.reset} Default model: ${c.bold}${currentModelId}${c.reset}`);
1405
+ console.log(` ${c.green}✓${c.reset} Default model: ${c.bold}${currentModelId}${c.reset} ${c.dim}(open-source, requires Ollama)${c.reset}`);
1327
1406
  }
1328
1407
  console.log();
1329
1408
  setupDone = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swarm-code",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Open-source swarm-native coding agent orchestrator — spawns parallel coding agents in isolated git worktrees, built on RLM (arXiv:2512.24601)",
5
5
  "type": "module",
6
6
  "bin": {