@braid-cloud/cli 0.1.6 → 0.1.9

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
@@ -60,7 +60,7 @@ import { homedir } from "os";
60
60
  import { dirname, join, parse } from "path";
61
61
  import process2 from "process";
62
62
  import { Data, Effect, pipe } from "effect";
63
- var CONFIG_DIR, CONFIG_FILE, PROJECT_CONFIG_FILENAME, USER_CONFIG_FILENAME, ConfigReadError, ConfigWriteError, findConfigFile, findProjectConfigFile, findUserConfigFile, loadProjectConfig, loadUserConfig, resolveUserConfigWritePath, saveUserConfig, saveProjectConfig, isValidServerUrl, resolveServerUrlFromConfig, applyConfigSource, applyEnvOverrides, createDefaultMergedConfig, loadMergedConfig, loadConfig, saveConfig, getApiKey, setApiKey, getServerUrl, clearApiKey, loadConfigAsync, loadProjectConfigAsync, loadUserConfigAsync, loadMergedConfigAsync, findProjectConfigFileAsync, findUserConfigFileAsync, saveConfigAsync, saveUserConfigAsync, saveProjectConfigAsync, getApiKeyAsync, setApiKeyAsync, getServerUrlAsync, clearApiKeyAsync;
63
+ var CONFIG_DIR, CONFIG_FILE, PROJECT_CONFIG_FILENAME, USER_CONFIG_FILENAME, ConfigReadError, ConfigWriteError, findConfigFile, findProjectConfigFile, findUserConfigFile, loadProjectConfig, loadUserConfig, resolveUserConfigWritePath, resolveProjectConfigWritePath, saveUserConfig, saveProjectConfig, isValidServerUrl, resolveServerUrlFromConfig, applyConfigSource, applyEnvOverrides, createDefaultMergedConfig, loadMergedConfig, loadConfig, saveConfig, getApiKey, setApiKey, getServerUrl, clearApiKey, loadConfigAsync, loadProjectConfigAsync, loadUserConfigAsync, loadMergedConfigAsync, findProjectConfigFileAsync, findUserConfigFileAsync, saveConfigAsync, saveUserConfigAsync, saveProjectConfigAsync, getApiKeyAsync, setApiKeyAsync, getServerUrlAsync, clearApiKeyAsync;
64
64
  var init_config = __esm({
65
65
  "src/lib/config.ts"() {
66
66
  "use strict";
@@ -112,6 +112,7 @@ var init_config = __esm({
112
112
  catch: () => void 0
113
113
  }).pipe(Effect.orElseSucceed(() => void 0));
114
114
  resolveUserConfigWritePath = (startDir = process2.cwd()) => findUserConfigFile(startDir) ?? join(startDir, USER_CONFIG_FILENAME);
115
+ resolveProjectConfigWritePath = (startDir = process2.cwd()) => findProjectConfigFile(startDir) ?? join(startDir, PROJECT_CONFIG_FILENAME);
115
116
  saveUserConfig = (config, startDir = process2.cwd()) => {
116
117
  const targetPath = resolveUserConfigWritePath(startDir);
117
118
  return pipe(
@@ -129,7 +130,7 @@ var init_config = __esm({
129
130
  );
130
131
  };
131
132
  saveProjectConfig = (config, startDir = process2.cwd()) => {
132
- const targetPath = join(startDir, PROJECT_CONFIG_FILENAME);
133
+ const targetPath = resolveProjectConfigWritePath(startDir);
133
134
  return pipe(
134
135
  Effect.tryPromise({
135
136
  try: async () => {
@@ -1085,7 +1086,7 @@ async function scopeCommand(options) {
1085
1086
  const config = await loadMergedConfigAsync();
1086
1087
  const targetFile = await selectTargetFile(options);
1087
1088
  const loadSpinner = spinner();
1088
- loadSpinner.start("Loading scope options from Braid...");
1089
+ loadSpinner.start("Loading scope options from braid...");
1089
1090
  try {
1090
1091
  const serverUrl = options.server ?? config.serverUrl;
1091
1092
  const apiKey = options.apiKey ?? config.token;
@@ -1191,7 +1192,7 @@ async function authCommand(options) {
1191
1192
  }
1192
1193
  }
1193
1194
  const apiKey = await password({
1194
- message: "Enter your Braid API key:",
1195
+ message: "Enter your braid API key:",
1195
1196
  validate: (value) => {
1196
1197
  if (!value) {
1197
1198
  return "API key is required";
@@ -1311,24 +1312,83 @@ import { join as join2 } from "path";
1311
1312
  import process6 from "process";
1312
1313
  import { Effect as Effect3, pipe as pipe3 } from "effect";
1313
1314
  var home = homedir2();
1315
+ var vscodeExtSettingsPath = (extensionId, filename) => {
1316
+ if (process6.platform === "darwin") {
1317
+ return join2(
1318
+ home,
1319
+ "Library",
1320
+ "Application Support",
1321
+ "Code",
1322
+ "User",
1323
+ "globalStorage",
1324
+ extensionId,
1325
+ "settings",
1326
+ filename
1327
+ );
1328
+ }
1329
+ if (process6.platform === "win32") {
1330
+ const appData = process6.env.APPDATA ?? join2(home, "AppData", "Roaming");
1331
+ return join2(
1332
+ appData,
1333
+ "Code",
1334
+ "User",
1335
+ "globalStorage",
1336
+ extensionId,
1337
+ "settings",
1338
+ filename
1339
+ );
1340
+ }
1341
+ return join2(
1342
+ home,
1343
+ ".config",
1344
+ "Code",
1345
+ "User",
1346
+ "globalStorage",
1347
+ extensionId,
1348
+ "settings",
1349
+ filename
1350
+ );
1351
+ };
1352
+ var claudeDesktopConfigPath = () => {
1353
+ if (process6.platform === "darwin") {
1354
+ return join2(
1355
+ home,
1356
+ "Library",
1357
+ "Application Support",
1358
+ "Claude",
1359
+ "claude_desktop_config.json"
1360
+ );
1361
+ }
1362
+ if (process6.platform === "win32") {
1363
+ const appData = process6.env.APPDATA ?? join2(home, "AppData", "Roaming");
1364
+ return join2(appData, "Claude", "claude_desktop_config.json");
1365
+ }
1366
+ return join2(home, ".config", "Claude", "claude_desktop_config.json");
1367
+ };
1314
1368
  var AGENTS = [
1315
1369
  {
1316
1370
  id: "amp",
1317
- name: "Amp, Kimi Code CLI",
1371
+ name: "Amp",
1318
1372
  projectPath: ".agents/skills",
1319
- globalPath: join2(home, ".config", "agents", "skills")
1373
+ globalPath: join2(home, ".config", "agents", "skills"),
1374
+ mcpProjectConfigPath: ".amp/mcp.json",
1375
+ mcpGlobalConfigPath: join2(home, ".amp", "mcp.json")
1320
1376
  },
1321
1377
  {
1322
1378
  id: "kimi-cli",
1323
1379
  name: "Kimi Code CLI",
1324
1380
  projectPath: ".agents/skills",
1325
- globalPath: join2(home, ".config", "agents", "skills")
1381
+ globalPath: join2(home, ".config", "agents", "skills"),
1382
+ mcpProjectConfigPath: ".agents/mcp.json",
1383
+ mcpGlobalConfigPath: join2(home, ".config", "agents", "mcp.json")
1326
1384
  },
1327
1385
  {
1328
1386
  id: "antigravity",
1329
1387
  name: "Antigravity",
1330
1388
  projectPath: ".agent/skills",
1331
- globalPath: join2(home, ".gemini", "antigravity", "global_skills")
1389
+ globalPath: join2(home, ".gemini", "antigravity", "global_skills"),
1390
+ mcpProjectConfigPath: ".agent/mcp.json",
1391
+ mcpGlobalConfigPath: join2(home, ".gemini", "antigravity", "mcp.json")
1332
1392
  },
1333
1393
  {
1334
1394
  id: "claude-code",
@@ -1339,13 +1399,24 @@ var AGENTS = [
1339
1399
  globalMarkerPath: join2(home, ".claude"),
1340
1400
  rulesProjectPath: ".claude/rules",
1341
1401
  rulesGlobalPath: join2(home, ".claude", "rules"),
1342
- ruleFormat: "markdown-dir"
1402
+ ruleFormat: "markdown-dir",
1403
+ mcpProjectConfigPath: ".mcp.json",
1404
+ mcpEntryStyle: "typed-stdio"
1405
+ },
1406
+ {
1407
+ id: "claude-desktop",
1408
+ name: "Claude Desktop",
1409
+ projectPath: "",
1410
+ globalPath: "",
1411
+ mcpGlobalConfigPath: claudeDesktopConfigPath()
1343
1412
  },
1344
1413
  {
1345
1414
  id: "moltbot",
1346
1415
  name: "Moltbot",
1347
1416
  projectPath: "skills",
1348
- globalPath: join2(home, ".moltbot", "skills")
1417
+ globalPath: join2(home, ".moltbot", "skills"),
1418
+ mcpProjectConfigPath: "mcp.json",
1419
+ mcpGlobalConfigPath: join2(home, ".moltbot", "mcp.json")
1349
1420
  },
1350
1421
  {
1351
1422
  id: "cline",
@@ -1353,37 +1424,52 @@ var AGENTS = [
1353
1424
  projectPath: ".cline/skills",
1354
1425
  globalPath: join2(home, ".cline", "skills"),
1355
1426
  rulesProjectPath: ".clinerules",
1356
- ruleFormat: "append-single"
1427
+ ruleFormat: "append-single",
1428
+ mcpGlobalConfigPath: vscodeExtSettingsPath(
1429
+ "saoudrizwan.claude-dev",
1430
+ "cline_mcp_settings.json"
1431
+ ),
1432
+ mcpEntryStyle: "cline"
1357
1433
  },
1358
1434
  {
1359
1435
  id: "codebuddy",
1360
1436
  name: "CodeBuddy",
1361
1437
  projectPath: ".codebuddy/skills",
1362
- globalPath: join2(home, ".codebuddy", "skills")
1438
+ globalPath: join2(home, ".codebuddy", "skills"),
1439
+ mcpProjectConfigPath: ".codebuddy/mcp.json",
1440
+ mcpGlobalConfigPath: join2(home, ".codebuddy", "mcp.json")
1363
1441
  },
1364
1442
  {
1365
1443
  id: "codex",
1366
1444
  name: "Codex",
1367
1445
  projectPath: ".codex/skills",
1368
- globalPath: join2(home, ".codex", "skills")
1446
+ globalPath: join2(home, ".codex", "skills"),
1447
+ mcpProjectConfigPath: ".codex/mcp.json",
1448
+ mcpGlobalConfigPath: join2(home, ".codex", "mcp.json")
1369
1449
  },
1370
1450
  {
1371
1451
  id: "command-code",
1372
1452
  name: "Command Code",
1373
1453
  projectPath: ".commandcode/skills",
1374
- globalPath: join2(home, ".commandcode", "skills")
1454
+ globalPath: join2(home, ".commandcode", "skills"),
1455
+ mcpProjectConfigPath: ".commandcode/mcp.json",
1456
+ mcpGlobalConfigPath: join2(home, ".commandcode", "mcp.json")
1375
1457
  },
1376
1458
  {
1377
1459
  id: "continue",
1378
1460
  name: "Continue",
1379
1461
  projectPath: ".continue/skills",
1380
- globalPath: join2(home, ".continue", "skills")
1462
+ globalPath: join2(home, ".continue", "skills"),
1463
+ mcpProjectConfigPath: ".continue/mcp.json",
1464
+ mcpGlobalConfigPath: join2(home, ".continue", "mcp.json")
1381
1465
  },
1382
1466
  {
1383
1467
  id: "crush",
1384
1468
  name: "Crush",
1385
1469
  projectPath: ".crush/skills",
1386
- globalPath: join2(home, ".config", "crush", "skills")
1470
+ globalPath: join2(home, ".config", "crush", "skills"),
1471
+ mcpProjectConfigPath: ".crush/mcp.json",
1472
+ mcpGlobalConfigPath: join2(home, ".config", "crush", "mcp.json")
1387
1473
  },
1388
1474
  {
1389
1475
  id: "cursor",
@@ -1391,19 +1477,25 @@ var AGENTS = [
1391
1477
  projectPath: ".cursor/skills",
1392
1478
  globalPath: join2(home, ".cursor", "skills"),
1393
1479
  rulesProjectPath: ".cursor/rules",
1394
- ruleFormat: "mdc"
1480
+ ruleFormat: "mdc",
1481
+ mcpProjectConfigPath: ".cursor/mcp.json",
1482
+ mcpGlobalConfigPath: join2(home, ".cursor", "mcp.json")
1395
1483
  },
1396
1484
  {
1397
1485
  id: "droid",
1398
1486
  name: "Droid",
1399
1487
  projectPath: ".factory/skills",
1400
- globalPath: join2(home, ".factory", "skills")
1488
+ globalPath: join2(home, ".factory", "skills"),
1489
+ mcpProjectConfigPath: ".factory/mcp.json",
1490
+ mcpGlobalConfigPath: join2(home, ".factory", "mcp.json")
1401
1491
  },
1402
1492
  {
1403
1493
  id: "gemini-cli",
1404
1494
  name: "Gemini CLI",
1405
1495
  projectPath: ".gemini/skills",
1406
- globalPath: join2(home, ".gemini", "skills")
1496
+ globalPath: join2(home, ".gemini", "skills"),
1497
+ mcpProjectConfigPath: ".gemini/mcp.json",
1498
+ mcpGlobalConfigPath: join2(home, ".gemini", "mcp.json")
1407
1499
  },
1408
1500
  {
1409
1501
  id: "github-copilot",
@@ -1411,79 +1503,108 @@ var AGENTS = [
1411
1503
  projectPath: ".github/skills",
1412
1504
  globalPath: join2(home, ".copilot", "skills"),
1413
1505
  rulesProjectPath: ".github/copilot-instructions.md",
1414
- ruleFormat: "append-single"
1506
+ ruleFormat: "append-single",
1507
+ mcpProjectConfigPath: ".vscode/mcp.json",
1508
+ mcpRootKey: "servers",
1509
+ mcpEntryStyle: "typed-stdio"
1415
1510
  },
1416
1511
  {
1417
1512
  id: "goose",
1418
1513
  name: "Goose",
1419
1514
  projectPath: ".goose/skills",
1420
- globalPath: join2(home, ".config", "goose", "skills")
1515
+ globalPath: join2(home, ".config", "goose", "skills"),
1516
+ mcpGlobalConfigPath: join2(home, ".config", "goose", "mcp.json")
1421
1517
  },
1422
1518
  {
1423
1519
  id: "junie",
1424
1520
  name: "Junie",
1425
1521
  projectPath: ".junie/skills",
1426
- globalPath: join2(home, ".junie", "skills")
1522
+ globalPath: join2(home, ".junie", "skills"),
1523
+ mcpProjectConfigPath: ".junie/mcp.json",
1524
+ mcpGlobalConfigPath: join2(home, ".junie", "mcp.json")
1427
1525
  },
1428
1526
  {
1429
1527
  id: "kilo",
1430
1528
  name: "Kilo Code",
1431
1529
  projectPath: ".kilocode/skills",
1432
- globalPath: join2(home, ".kilocode", "skills")
1530
+ globalPath: join2(home, ".kilocode", "skills"),
1531
+ mcpGlobalConfigPath: vscodeExtSettingsPath(
1532
+ "kilocode.kilo-code",
1533
+ "mcp_settings.json"
1534
+ ),
1535
+ mcpEntryStyle: "cline"
1433
1536
  },
1434
1537
  {
1435
1538
  id: "kiro-cli",
1436
1539
  name: "Kiro CLI",
1437
1540
  projectPath: ".kiro/skills",
1438
- globalPath: join2(home, ".kiro", "skills")
1541
+ globalPath: join2(home, ".kiro", "skills"),
1542
+ mcpProjectConfigPath: ".kiro/mcp.json",
1543
+ mcpGlobalConfigPath: join2(home, ".kiro", "mcp.json")
1439
1544
  },
1440
1545
  {
1441
1546
  id: "kode",
1442
1547
  name: "Kode",
1443
1548
  projectPath: ".kode/skills",
1444
- globalPath: join2(home, ".kode", "skills")
1549
+ globalPath: join2(home, ".kode", "skills"),
1550
+ mcpProjectConfigPath: ".kode/mcp.json",
1551
+ mcpGlobalConfigPath: join2(home, ".kode", "mcp.json")
1445
1552
  },
1446
1553
  {
1447
1554
  id: "mcpjam",
1448
1555
  name: "MCPJam",
1449
1556
  projectPath: ".mcpjam/skills",
1450
- globalPath: join2(home, ".mcpjam", "skills")
1557
+ globalPath: join2(home, ".mcpjam", "skills"),
1558
+ mcpProjectConfigPath: ".mcpjam/mcp.json",
1559
+ mcpGlobalConfigPath: join2(home, ".mcpjam", "mcp.json")
1451
1560
  },
1452
1561
  {
1453
1562
  id: "mux",
1454
1563
  name: "Mux",
1455
1564
  projectPath: ".mux/skills",
1456
- globalPath: join2(home, ".mux", "skills")
1565
+ globalPath: join2(home, ".mux", "skills"),
1566
+ mcpProjectConfigPath: ".mux/mcp.json",
1567
+ mcpGlobalConfigPath: join2(home, ".mux", "mcp.json")
1457
1568
  },
1458
1569
  {
1459
1570
  id: "opencode",
1460
1571
  name: "OpenCode",
1461
1572
  projectPath: ".opencode/skills",
1462
- globalPath: join2(home, ".config", "opencode", "skills")
1573
+ globalPath: join2(home, ".config", "opencode", "skills"),
1574
+ mcpProjectConfigPath: ".opencode/mcp.json",
1575
+ mcpGlobalConfigPath: join2(home, ".config", "opencode", "mcp.json")
1463
1576
  },
1464
1577
  {
1465
1578
  id: "openhands",
1466
1579
  name: "OpenHands",
1467
1580
  projectPath: ".openhands/skills",
1468
- globalPath: join2(home, ".openhands", "skills")
1581
+ globalPath: join2(home, ".openhands", "skills"),
1582
+ mcpProjectConfigPath: ".openhands/mcp.json",
1583
+ mcpGlobalConfigPath: join2(home, ".openhands", "mcp.json")
1469
1584
  },
1470
1585
  {
1471
1586
  id: "pi",
1472
1587
  name: "Pi",
1473
1588
  projectPath: ".pi/skills",
1474
- globalPath: join2(home, ".pi", "agent", "skills")
1589
+ globalPath: join2(home, ".pi", "agent", "skills"),
1590
+ mcpProjectConfigPath: ".pi/mcp.json",
1591
+ mcpGlobalConfigPath: join2(home, ".pi", "agent", "mcp.json")
1475
1592
  },
1476
1593
  {
1477
1594
  id: "qoder",
1478
1595
  name: "Qoder",
1479
1596
  projectPath: ".qoder/skills",
1480
- globalPath: join2(home, ".qoder", "skills")
1597
+ globalPath: join2(home, ".qoder", "skills"),
1598
+ mcpProjectConfigPath: ".qoder/mcp.json",
1599
+ mcpGlobalConfigPath: join2(home, ".qoder", "mcp.json")
1481
1600
  },
1482
1601
  {
1483
1602
  id: "qwen-code",
1484
1603
  name: "Qwen Code",
1485
1604
  projectPath: ".qwen/skills",
1486
- globalPath: join2(home, ".qwen", "skills")
1605
+ globalPath: join2(home, ".qwen", "skills"),
1606
+ mcpProjectConfigPath: ".qwen/mcp.json",
1607
+ mcpGlobalConfigPath: join2(home, ".qwen", "mcp.json")
1487
1608
  },
1488
1609
  {
1489
1610
  id: "roo",
@@ -1492,13 +1613,20 @@ var AGENTS = [
1492
1613
  globalPath: join2(home, ".roo", "skills"),
1493
1614
  rulesProjectPath: ".roo/rules",
1494
1615
  rulesGlobalPath: join2(home, ".roo", "rules"),
1495
- ruleFormat: "markdown-dir"
1616
+ ruleFormat: "markdown-dir",
1617
+ mcpGlobalConfigPath: vscodeExtSettingsPath(
1618
+ "rooveterinaryinc.roo-cline",
1619
+ "mcp_settings.json"
1620
+ ),
1621
+ mcpEntryStyle: "cline"
1496
1622
  },
1497
1623
  {
1498
1624
  id: "trae",
1499
1625
  name: "Trae",
1500
1626
  projectPath: ".trae/skills",
1501
- globalPath: join2(home, ".trae", "skills")
1627
+ globalPath: join2(home, ".trae", "skills"),
1628
+ mcpProjectConfigPath: ".trae/mcp.json",
1629
+ mcpGlobalConfigPath: join2(home, ".trae", "mcp.json")
1502
1630
  },
1503
1631
  {
1504
1632
  id: "windsurf",
@@ -1506,25 +1634,32 @@ var AGENTS = [
1506
1634
  projectPath: ".windsurf/skills",
1507
1635
  globalPath: join2(home, ".codeium", "windsurf", "skills"),
1508
1636
  rulesProjectPath: ".windsurfrules",
1509
- ruleFormat: "append-single"
1637
+ ruleFormat: "append-single",
1638
+ mcpGlobalConfigPath: join2(home, ".codeium", "windsurf", "mcp_config.json")
1510
1639
  },
1511
1640
  {
1512
1641
  id: "zencoder",
1513
1642
  name: "Zencoder",
1514
1643
  projectPath: ".zencoder/skills",
1515
- globalPath: join2(home, ".zencoder", "skills")
1644
+ globalPath: join2(home, ".zencoder", "skills"),
1645
+ mcpProjectConfigPath: ".zencoder/mcp.json",
1646
+ mcpGlobalConfigPath: join2(home, ".zencoder", "mcp.json")
1516
1647
  },
1517
1648
  {
1518
1649
  id: "neovate",
1519
1650
  name: "Neovate",
1520
1651
  projectPath: ".neovate/skills",
1521
- globalPath: join2(home, ".neovate", "skills")
1652
+ globalPath: join2(home, ".neovate", "skills"),
1653
+ mcpProjectConfigPath: ".neovate/mcp.json",
1654
+ mcpGlobalConfigPath: join2(home, ".neovate", "mcp.json")
1522
1655
  },
1523
1656
  {
1524
1657
  id: "pochi",
1525
1658
  name: "Pochi",
1526
1659
  projectPath: ".pochi/skills",
1527
- globalPath: join2(home, ".pochi", "skills")
1660
+ globalPath: join2(home, ".pochi", "skills"),
1661
+ mcpProjectConfigPath: ".pochi/mcp.json",
1662
+ mcpGlobalConfigPath: join2(home, ".pochi", "mcp.json")
1528
1663
  },
1529
1664
  {
1530
1665
  id: "zed",
@@ -1535,7 +1670,10 @@ var AGENTS = [
1535
1670
  globalMarkerPath: join2(home, ".config", "zed"),
1536
1671
  rulesProjectPath: ".zed/rules",
1537
1672
  rulesGlobalPath: join2(home, ".config", "zed", "rules"),
1538
- ruleFormat: "markdown-dir"
1673
+ ruleFormat: "markdown-dir",
1674
+ mcpGlobalConfigPath: join2(home, ".config", "zed", "settings.json"),
1675
+ mcpRootKey: "context_servers",
1676
+ mcpEntryStyle: "zed"
1539
1677
  }
1540
1678
  ];
1541
1679
  var directoryExists = (path2) => pipe3(
@@ -1605,6 +1743,40 @@ var resolveRulesInstallPath = (agent, options) => {
1605
1743
  const cwd = options.projectRoot ?? process6.cwd();
1606
1744
  return join2(cwd, agent.rulesProjectPath);
1607
1745
  };
1746
+ var hasMcpConfig = (agent) => Boolean(agent.mcpProjectConfigPath) || Boolean(agent.mcpGlobalConfigPath);
1747
+ var resolveMcpConfigPath = (agent, options) => {
1748
+ if (options.global) {
1749
+ return agent.mcpGlobalConfigPath;
1750
+ }
1751
+ if (agent.mcpProjectConfigPath) {
1752
+ const cwd = options.projectRoot ?? process6.cwd();
1753
+ return join2(cwd, agent.mcpProjectConfigPath);
1754
+ }
1755
+ return agent.mcpGlobalConfigPath;
1756
+ };
1757
+ var buildMcpEntry = (style, env) => {
1758
+ const command = "npx";
1759
+ const args = ["-y", "@braid-cloud/mcp"];
1760
+ const envObj = Object.keys(env).length > 0 ? env : void 0;
1761
+ switch (style) {
1762
+ case "standard":
1763
+ return envObj ? { command, args, env: envObj } : { command, args };
1764
+ case "typed-stdio":
1765
+ return envObj ? { type: "stdio", command, args, env: envObj } : { type: "stdio", command, args };
1766
+ case "zed":
1767
+ return envObj ? { command: { path: command, args, env: envObj } } : { command: { path: command, args } };
1768
+ case "cline":
1769
+ return envObj ? { command, args, env: envObj, disabled: false } : { command, args, disabled: false };
1770
+ default:
1771
+ return envObj ? { command, args, env: envObj } : { command, args };
1772
+ }
1773
+ };
1774
+ var detectMcpAgents = (projectRoot) => Effect3.runPromise(
1775
+ pipe3(
1776
+ detectAgents(projectRoot),
1777
+ Effect3.map((detected) => detected.filter(hasMcpConfig))
1778
+ )
1779
+ );
1608
1780
 
1609
1781
  // src/commands/install.ts
1610
1782
  init_api();
@@ -2219,7 +2391,7 @@ async function installCommand(options) {
2219
2391
  const sourceDesc = buildSourceDescription(resolved);
2220
2392
  intro(`Installing from ${sourceDesc}`);
2221
2393
  const installSpinner = spinner();
2222
- installSpinner.start("Fetching from Braid...");
2394
+ installSpinner.start("Fetching from braid...");
2223
2395
  try {
2224
2396
  const fetchOptions = buildFetchOptions(resolved);
2225
2397
  const response = await fetchSkillsAsync(fetchOptions);
@@ -2371,11 +2543,357 @@ async function listCommand(options) {
2371
2543
  }
2372
2544
  }
2373
2545
 
2546
+ // src/commands/mcp.ts
2547
+ init_esm_shims();
2548
+ import process7 from "process";
2549
+ init_config();
2550
+
2551
+ // src/lib/mcp-config.ts
2552
+ init_esm_shims();
2553
+ import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
2554
+ import { dirname as dirname4 } from "path";
2555
+ import { Data as Data6, Effect as Effect7, pipe as pipe7 } from "effect";
2556
+ var McpConfigReadError = class extends Data6.TaggedError("McpConfigReadError") {
2557
+ };
2558
+ var McpConfigWriteError = class extends Data6.TaggedError("McpConfigWriteError") {
2559
+ };
2560
+ var readMcpConfig = (path2) => pipe7(
2561
+ Effect7.tryPromise({
2562
+ try: () => readFile4(path2, "utf-8"),
2563
+ catch: (e) => new McpConfigReadError({ path: path2, cause: e })
2564
+ }),
2565
+ Effect7.flatMap(
2566
+ (content) => Effect7.try({
2567
+ try: () => JSON.parse(content),
2568
+ catch: () => ({})
2569
+ })
2570
+ ),
2571
+ Effect7.orElseSucceed(() => ({}))
2572
+ );
2573
+ var writeMcpConfig = (path2, config) => Effect7.tryPromise({
2574
+ try: async () => {
2575
+ await mkdir4(dirname4(path2), { recursive: true });
2576
+ await writeFile5(path2, `${JSON.stringify(config, null, 2)}
2577
+ `, "utf-8");
2578
+ },
2579
+ catch: (e) => new McpConfigWriteError({ path: path2, cause: e })
2580
+ });
2581
+ var mergebraidEntry = (config, rootKey, entryName, entry) => {
2582
+ const servers = config[rootKey] ?? {};
2583
+ return {
2584
+ ...config,
2585
+ [rootKey]: {
2586
+ ...servers,
2587
+ [entryName]: entry
2588
+ }
2589
+ };
2590
+ };
2591
+ var removebraidEntry = (config, rootKey, entryName) => {
2592
+ const servers = { ...config[rootKey] ?? {} };
2593
+ delete servers[entryName];
2594
+ return {
2595
+ ...config,
2596
+ [rootKey]: servers
2597
+ };
2598
+ };
2599
+ var hasbraidEntry = (config, rootKey, entryName) => {
2600
+ const servers = config[rootKey];
2601
+ return servers !== void 0 && entryName in servers;
2602
+ };
2603
+ var readMcpConfigAsync = (path2) => Effect7.runPromise(readMcpConfig(path2));
2604
+ var writeMcpConfigAsync = (path2, config) => Effect7.runPromise(writeMcpConfig(path2, config));
2605
+
2606
+ // src/commands/mcp.ts
2607
+ init_tui();
2608
+ var BRAID_ENTRY_NAME = "braid";
2609
+ function maskToken(token) {
2610
+ if (token.length <= 10) {
2611
+ return token;
2612
+ }
2613
+ return `${token.slice(0, 7)}...${token.slice(-4)}`;
2614
+ }
2615
+ function getMcpAgents() {
2616
+ return AGENTS.filter(hasMcpConfig);
2617
+ }
2618
+ function resolveScope(agent, options) {
2619
+ if (options.global) {
2620
+ return "global";
2621
+ }
2622
+ if (agent.mcpProjectConfigPath) {
2623
+ return "project";
2624
+ }
2625
+ return "global";
2626
+ }
2627
+ async function selectTool(mcpAgents, toolFlag) {
2628
+ if (toolFlag) {
2629
+ const agent = mcpAgents.find((a) => a.id === toolFlag);
2630
+ if (!agent) {
2631
+ log.error(`Unknown or unsupported tool: ${toolFlag}`);
2632
+ log.info(`Supported tools: ${mcpAgents.map((a) => a.id).join(", ")}`);
2633
+ process7.exit(1);
2634
+ }
2635
+ return agent;
2636
+ }
2637
+ const detected = await detectMcpAgents();
2638
+ const detectedIds = new Set(detected.map((a) => a.id));
2639
+ const toolChoice = await select({
2640
+ message: "Select tool to configure:",
2641
+ options: mcpAgents.map((agent) => ({
2642
+ value: agent.id,
2643
+ label: agent.name,
2644
+ hint: [
2645
+ agent.mcpProjectConfigPath ?? agent.mcpGlobalConfigPath,
2646
+ detectedIds.has(agent.id) ? "detected" : void 0
2647
+ ].filter(Boolean).join(" \u2014 ")
2648
+ }))
2649
+ });
2650
+ if (isCancel(toolChoice)) {
2651
+ cancel("MCP setup cancelled.");
2652
+ process7.exit(0);
2653
+ }
2654
+ const found = mcpAgents.find((a) => a.id === toolChoice);
2655
+ if (!found) {
2656
+ log.error("Agent not found.");
2657
+ process7.exit(1);
2658
+ }
2659
+ return found;
2660
+ }
2661
+ async function selectScope(agent, options) {
2662
+ const initial = resolveScope(agent, options);
2663
+ if (options.global || options.yes || !agent.mcpProjectConfigPath || !agent.mcpGlobalConfigPath) {
2664
+ return initial;
2665
+ }
2666
+ const scopeChoice = await select({
2667
+ message: "Where should this be configured?",
2668
+ options: [
2669
+ {
2670
+ value: "project",
2671
+ label: "Project",
2672
+ hint: agent.mcpProjectConfigPath
2673
+ },
2674
+ {
2675
+ value: "global",
2676
+ label: "Global",
2677
+ hint: agent.mcpGlobalConfigPath
2678
+ }
2679
+ ]
2680
+ });
2681
+ if (isCancel(scopeChoice)) {
2682
+ cancel("MCP setup cancelled.");
2683
+ process7.exit(0);
2684
+ }
2685
+ return scopeChoice;
2686
+ }
2687
+ async function resolveToken(options, existingToken) {
2688
+ if (options.auth === false) {
2689
+ return void 0;
2690
+ }
2691
+ if (options.token) {
2692
+ return options.token;
2693
+ }
2694
+ if (existingToken && options.yes) {
2695
+ return existingToken;
2696
+ }
2697
+ if (existingToken) {
2698
+ const authChoice = await select({
2699
+ message: "Authentication:",
2700
+ options: [
2701
+ {
2702
+ value: "existing",
2703
+ label: `Use existing token (${maskToken(existingToken)})`
2704
+ },
2705
+ { value: "new", label: "Enter a new token" },
2706
+ {
2707
+ value: "skip",
2708
+ label: "Skip \u2014 set BRAID_TOKEN env var later"
2709
+ }
2710
+ ]
2711
+ });
2712
+ if (isCancel(authChoice)) {
2713
+ cancel("MCP setup cancelled.");
2714
+ process7.exit(0);
2715
+ }
2716
+ if (authChoice === "existing") {
2717
+ return existingToken;
2718
+ }
2719
+ if (authChoice === "skip") {
2720
+ return void 0;
2721
+ }
2722
+ }
2723
+ const token = await password({
2724
+ message: "Enter your braid API token:",
2725
+ validate: (value) => {
2726
+ if (!value) {
2727
+ return "Token is required";
2728
+ }
2729
+ if (!value.startsWith("br_")) {
2730
+ return "Token should start with 'br_'";
2731
+ }
2732
+ return void 0;
2733
+ }
2734
+ });
2735
+ if (isCancel(token)) {
2736
+ cancel("MCP setup cancelled.");
2737
+ process7.exit(0);
2738
+ }
2739
+ return token;
2740
+ }
2741
+ function buildEnvVars(token, server) {
2742
+ const env = {};
2743
+ if (token) {
2744
+ env.BRAID_TOKEN = token;
2745
+ }
2746
+ if (server) {
2747
+ env.BRAID_MCP_URL = server;
2748
+ }
2749
+ return env;
2750
+ }
2751
+ async function writeEntry(agent, configPath, env) {
2752
+ const entry = buildMcpEntry(agent.mcpEntryStyle ?? "standard", env);
2753
+ const rootKey = agent.mcpRootKey ?? "mcpServers";
2754
+ const existingConfig = await readMcpConfigAsync(configPath);
2755
+ const updatedConfig = mergebraidEntry(
2756
+ existingConfig,
2757
+ rootKey,
2758
+ BRAID_ENTRY_NAME,
2759
+ entry
2760
+ );
2761
+ await writeMcpConfigAsync(configPath, updatedConfig);
2762
+ }
2763
+ async function addFlow(options) {
2764
+ const config = await loadMergedConfigAsync();
2765
+ const mcpAgents = getMcpAgents();
2766
+ if (mcpAgents.length === 0) {
2767
+ log.error("No agents with MCP configuration support found.");
2768
+ process7.exit(1);
2769
+ }
2770
+ const selectedAgent = await selectTool(mcpAgents, options.tool);
2771
+ const scope = await selectScope(selectedAgent, options);
2772
+ const configPath = resolveMcpConfigPath(selectedAgent, {
2773
+ global: scope === "global"
2774
+ });
2775
+ if (!configPath) {
2776
+ log.error(`No ${scope} config path available for ${selectedAgent.name}.`);
2777
+ process7.exit(1);
2778
+ }
2779
+ const token = await resolveToken(options, config.token);
2780
+ const env = buildEnvVars(token, options.server);
2781
+ if (options.scope) {
2782
+ const { scopeCommand: scopeCommand2 } = await Promise.resolve().then(() => (init_scope(), scope_exports));
2783
+ await scopeCommand2({
2784
+ server: options.server ?? config.serverUrl,
2785
+ ...config.token ? { apiKey: config.token } : {}
2786
+ });
2787
+ }
2788
+ const mcpSpinner = spinner();
2789
+ mcpSpinner.start(`Configuring ${selectedAgent.name}...`);
2790
+ try {
2791
+ await writeEntry(selectedAgent, configPath, env);
2792
+ mcpSpinner.stop(`Configured ${selectedAgent.name}`);
2793
+ log.info(`Config written to ${configPath}`);
2794
+ if (!token) {
2795
+ log.info("Set BRAID_TOKEN environment variable before using.");
2796
+ }
2797
+ outro(`Done! Restart ${selectedAgent.name} to activate.`);
2798
+ } catch (error) {
2799
+ mcpSpinner.stop("Configuration failed");
2800
+ const message = error instanceof Error ? error.message : String(error);
2801
+ log.error(`Failed to write config: ${message}`);
2802
+ process7.exit(1);
2803
+ }
2804
+ }
2805
+ async function removeFlow(options) {
2806
+ const mcpAgents = getMcpAgents();
2807
+ const selectedAgent = await selectTool(mcpAgents, options.tool);
2808
+ const scope = resolveScope(selectedAgent, options);
2809
+ const configPath = resolveMcpConfigPath(selectedAgent, {
2810
+ global: scope === "global"
2811
+ });
2812
+ if (!configPath) {
2813
+ log.error(`No ${scope} config path available for ${selectedAgent.name}.`);
2814
+ process7.exit(1);
2815
+ }
2816
+ const removeSpinner = spinner();
2817
+ removeSpinner.start(`Removing braid from ${selectedAgent.name}...`);
2818
+ try {
2819
+ const rootKey = selectedAgent.mcpRootKey ?? "mcpServers";
2820
+ const existingConfig = await readMcpConfigAsync(configPath);
2821
+ if (!hasbraidEntry(existingConfig, rootKey, BRAID_ENTRY_NAME)) {
2822
+ removeSpinner.stop("No braid MCP entry found");
2823
+ log.info(
2824
+ `${selectedAgent.name} doesn't have a braid MCP entry at ${configPath}`
2825
+ );
2826
+ return;
2827
+ }
2828
+ const updatedConfig = removebraidEntry(
2829
+ existingConfig,
2830
+ rootKey,
2831
+ BRAID_ENTRY_NAME
2832
+ );
2833
+ await writeMcpConfigAsync(configPath, updatedConfig);
2834
+ removeSpinner.stop(`Removed braid from ${selectedAgent.name}`);
2835
+ outro(`braid MCP removed from ${configPath}`);
2836
+ } catch (error) {
2837
+ removeSpinner.stop("Removal failed");
2838
+ const message = error instanceof Error ? error.message : String(error);
2839
+ log.error(`Failed to remove config: ${message}`);
2840
+ process7.exit(1);
2841
+ }
2842
+ }
2843
+ async function statusFlow() {
2844
+ const mcpAgents = getMcpAgents();
2845
+ const statusSpinner = spinner();
2846
+ statusSpinner.start("Checking MCP configuration status...");
2847
+ const results = [];
2848
+ for (const agent of mcpAgents) {
2849
+ const rootKey = agent.mcpRootKey ?? "mcpServers";
2850
+ for (const scope of ["project", "global"]) {
2851
+ const configPath = resolveMcpConfigPath(agent, {
2852
+ global: scope === "global"
2853
+ });
2854
+ if (!configPath) {
2855
+ continue;
2856
+ }
2857
+ const config = await readMcpConfigAsync(configPath);
2858
+ if (hasbraidEntry(config, rootKey, BRAID_ENTRY_NAME)) {
2859
+ results.push({
2860
+ name: agent.name,
2861
+ path: configPath,
2862
+ scope
2863
+ });
2864
+ }
2865
+ }
2866
+ }
2867
+ statusSpinner.stop(`Found ${results.length} configured tool(s)`);
2868
+ if (results.length === 0) {
2869
+ log.info("No tools have braid MCP configured.");
2870
+ log.info("Run 'braid mcp' to set up MCP for your AI tools.");
2871
+ return;
2872
+ }
2873
+ for (const result of results) {
2874
+ log.info(` ${result.name} (${result.scope}) \u2192 ${result.path}`);
2875
+ }
2876
+ }
2877
+ async function mcpCommand(options) {
2878
+ if (options.status) {
2879
+ intro("braid mcp status");
2880
+ await statusFlow();
2881
+ return;
2882
+ }
2883
+ if (options.remove) {
2884
+ intro("braid mcp remove");
2885
+ await removeFlow(options);
2886
+ return;
2887
+ }
2888
+ intro("braid mcp");
2889
+ await addFlow(options);
2890
+ }
2891
+
2374
2892
  // src/commands/remove.ts
2375
2893
  init_esm_shims();
2376
2894
  import { rm } from "fs/promises";
2377
2895
  import { join as join4, resolve as resolve3 } from "path";
2378
- import process7 from "process";
2896
+ import process8 from "process";
2379
2897
  init_tui();
2380
2898
  async function collectInstalledSkills(detectedAgents, options) {
2381
2899
  const skillsToRemove = [];
@@ -2408,7 +2926,7 @@ async function selectSkillsToRemove(skillsToRemove, options) {
2408
2926
  if (selected.length === 0) {
2409
2927
  log.error(`Skill '${options.skill}' not found.`);
2410
2928
  log.info("Run 'braid list' to see installed skills.");
2411
- process7.exit(1);
2929
+ process8.exit(1);
2412
2930
  }
2413
2931
  return selected;
2414
2932
  }
@@ -2427,7 +2945,7 @@ async function selectSkillsToRemove(skillsToRemove, options) {
2427
2945
  });
2428
2946
  if (isCancel(result)) {
2429
2947
  cancel("Remove cancelled.");
2430
- process7.exit(0);
2948
+ process8.exit(0);
2431
2949
  }
2432
2950
  return result;
2433
2951
  }
@@ -2441,7 +2959,7 @@ async function confirmRemoval(selectedCount, options) {
2441
2959
  });
2442
2960
  if (isCancel(confirmed) || !confirmed) {
2443
2961
  cancel("Remove cancelled.");
2444
- process7.exit(0);
2962
+ process8.exit(0);
2445
2963
  }
2446
2964
  }
2447
2965
  async function removeSkill(skill, removeSpinner) {
@@ -2505,7 +3023,7 @@ async function removeCommand(options) {
2505
3023
  removeSpinner.stop("Remove failed");
2506
3024
  const message = error instanceof Error ? error.message : String(error);
2507
3025
  log.error(message);
2508
- process7.exit(1);
3026
+ process8.exit(1);
2509
3027
  }
2510
3028
  }
2511
3029
 
@@ -2522,11 +3040,11 @@ import {
2522
3040
  outro as outro2,
2523
3041
  spinner as spinner3
2524
3042
  } from "@clack/prompts";
2525
- import { Data as Data6, Effect as Effect7, pipe as pipe7 } from "effect";
3043
+ import { Data as Data7, Effect as Effect8, pipe as pipe8 } from "effect";
2526
3044
  init_api();
2527
- var UpdateError = class extends Data6.TaggedError("UpdateError") {
3045
+ var UpdateError = class extends Data7.TaggedError("UpdateError") {
2528
3046
  };
2529
- var UserCancelledError = class extends Data6.TaggedError("UserCancelledError") {
3047
+ var UserCancelledError = class extends Data7.TaggedError("UserCancelledError") {
2530
3048
  };
2531
3049
  async function resolveValidInstallPath(agent, options) {
2532
3050
  const installPath = resolveInstallPath(agent, {
@@ -2538,7 +3056,7 @@ async function resolveValidInstallPath(agent, options) {
2538
3056
  const exists = await directoryExistsAsync(installPath);
2539
3057
  return exists ? installPath : null;
2540
3058
  }
2541
- var collectSourcesFromAgent = (agent, options, sourcesToUpdate) => Effect7.tryPromise({
3059
+ var collectSourcesFromAgent = (agent, options, sourcesToUpdate) => Effect8.tryPromise({
2542
3060
  try: async () => {
2543
3061
  const installPath = await resolveValidInstallPath(agent, options);
2544
3062
  if (!installPath) {
@@ -2569,10 +3087,10 @@ var collectSourcesFromAgent = (agent, options, sourcesToUpdate) => Effect7.tryPr
2569
3087
  },
2570
3088
  catch: () => new UpdateError({ message: "Failed to collect sources" })
2571
3089
  });
2572
- var collectSources = (detectedAgents, options) => pipe7(
2573
- Effect7.succeed(/* @__PURE__ */ new Map()),
2574
- Effect7.tap(
2575
- (sourcesToUpdate) => Effect7.forEach(
3090
+ var collectSources = (detectedAgents, options) => pipe8(
3091
+ Effect8.succeed(/* @__PURE__ */ new Map()),
3092
+ Effect8.tap(
3093
+ (sourcesToUpdate) => Effect8.forEach(
2576
3094
  detectedAgents,
2577
3095
  (agent) => collectSourcesFromAgent(agent, options, sourcesToUpdate),
2578
3096
  { concurrency: 1 }
@@ -2581,9 +3099,9 @@ var collectSources = (detectedAgents, options) => pipe7(
2581
3099
  );
2582
3100
  var selectSources = (sourcesToUpdate, options) => {
2583
3101
  if (options.yes) {
2584
- return Effect7.succeed(sourcesToUpdate);
3102
+ return Effect8.succeed(sourcesToUpdate);
2585
3103
  }
2586
- return Effect7.tryPromise({
3104
+ return Effect8.tryPromise({
2587
3105
  try: async () => {
2588
3106
  const sources = Array.from(sourcesToUpdate.entries()).map(
2589
3107
  ([key, source]) => ({
@@ -2634,7 +3152,7 @@ var buildFetchOptionsForSource = (source, options) => {
2634
3152
  }
2635
3153
  return fetchOptions;
2636
3154
  };
2637
- var updateAgentSkills = (agentId, agentName, installPath, response, serverUrl, updateSpinner) => Effect7.tryPromise({
3155
+ var updateAgentSkills = (agentId, agentName, installPath, response, serverUrl, updateSpinner) => Effect8.tryPromise({
2638
3156
  try: async () => {
2639
3157
  updateSpinner.start(`Updating ${agentName}...`);
2640
3158
  const result = await writeSkillsAsync(
@@ -2672,15 +3190,15 @@ var updateSource = (source, options, updateSpinner) => {
2672
3190
  const serverUrl = options.server ?? source.serverUrl;
2673
3191
  const fetchOptions = buildFetchOptionsForSource(source, options);
2674
3192
  if (fetchOptions === null) {
2675
- return Effect7.fail(
3193
+ return Effect8.fail(
2676
3194
  new UpdateError({
2677
3195
  message: "Skills installed with legacy metadata format. Please reinstall using 'braid install --profile <name>' or 'braid install --projects <names>'.",
2678
3196
  source: sourceDesc
2679
3197
  })
2680
3198
  );
2681
3199
  }
2682
- return pipe7(
2683
- Effect7.tryPromise({
3200
+ return pipe8(
3201
+ Effect8.tryPromise({
2684
3202
  try: async () => {
2685
3203
  updateSpinner.start(`Fetching latest skills from ${sourceDesc}...`);
2686
3204
  const response = await fetchSkillsAsync(fetchOptions);
@@ -2694,9 +3212,9 @@ var updateSource = (source, options, updateSpinner) => {
2694
3212
  source: sourceDesc
2695
3213
  })
2696
3214
  }),
2697
- Effect7.flatMap(
2698
- (response) => pipe7(
2699
- Effect7.forEach(
3215
+ Effect8.flatMap(
3216
+ (response) => pipe8(
3217
+ Effect8.forEach(
2700
3218
  source.agents,
2701
3219
  ({ agentId, agentName, installPath }) => updateAgentSkills(
2702
3220
  agentId,
@@ -2708,7 +3226,7 @@ var updateSource = (source, options, updateSpinner) => {
2708
3226
  ),
2709
3227
  { concurrency: 1 }
2710
3228
  ),
2711
- Effect7.map((results) => ({
3229
+ Effect8.map((results) => ({
2712
3230
  updated: results.reduce((sum, r) => sum + r.updated, 0),
2713
3231
  errors: results.reduce((sum, r) => sum + r.errors, 0)
2714
3232
  }))
@@ -2716,22 +3234,22 @@ var updateSource = (source, options, updateSpinner) => {
2716
3234
  )
2717
3235
  );
2718
3236
  };
2719
- var updateAllSources = (sources, options, updateSpinner) => pipe7(
2720
- Effect7.forEach(
3237
+ var updateAllSources = (sources, options, updateSpinner) => pipe8(
3238
+ Effect8.forEach(
2721
3239
  Array.from(sources.values()),
2722
- (source) => pipe7(
3240
+ (source) => pipe8(
2723
3241
  updateSource(source, options, updateSpinner),
2724
- Effect7.catchAll((error) => {
3242
+ Effect8.catchAll((error) => {
2725
3243
  updateSpinner.stop(
2726
3244
  `Failed to update from ${getSourceDesc(source)}`
2727
3245
  );
2728
3246
  log3.error(` ${error.message}`);
2729
- return Effect7.succeed({ updated: 0, errors: 1 });
3247
+ return Effect8.succeed({ updated: 0, errors: 1 });
2730
3248
  })
2731
3249
  ),
2732
3250
  { concurrency: 1 }
2733
3251
  ),
2734
- Effect7.map((results) => ({
3252
+ Effect8.map((results) => ({
2735
3253
  totalUpdated: results.reduce((sum, r) => sum + r.updated, 0),
2736
3254
  totalErrors: results.reduce((sum, r) => sum + r.errors, 0)
2737
3255
  }))
@@ -2770,28 +3288,28 @@ var handleProgramExit = (result, updateSpinner) => {
2770
3288
  async function updateCommand(options) {
2771
3289
  const updateSpinner = spinner3();
2772
3290
  updateSpinner.start("Scanning for installed skills...");
2773
- const program2 = pipe7(
2774
- Effect7.tryPromise({
3291
+ const program2 = pipe8(
3292
+ Effect8.tryPromise({
2775
3293
  try: () => detectAgentsAsync(),
2776
3294
  catch: () => new UpdateError({ message: "Failed to detect agents" })
2777
3295
  }),
2778
- Effect7.filterOrFail(
3296
+ Effect8.filterOrFail(
2779
3297
  (agents) => agents.length > 0,
2780
3298
  () => new UpdateError({ message: "No AI coding agents detected." })
2781
3299
  ),
2782
- Effect7.flatMap((detectedAgents) => collectSources(detectedAgents, options)),
2783
- Effect7.tap((sources) => {
3300
+ Effect8.flatMap((detectedAgents) => collectSources(detectedAgents, options)),
3301
+ Effect8.tap((sources) => {
2784
3302
  updateSpinner.stop(`Found ${sources.size} source(s) to update`);
2785
3303
  }),
2786
- Effect7.filterOrFail(
3304
+ Effect8.filterOrFail(
2787
3305
  (sources) => sources.size > 0,
2788
3306
  () => new UpdateError({ message: "No skills installed via braid." })
2789
3307
  ),
2790
- Effect7.flatMap((sources) => selectSources(sources, options)),
2791
- Effect7.flatMap(
3308
+ Effect8.flatMap((sources) => selectSources(sources, options)),
3309
+ Effect8.flatMap(
2792
3310
  (selectedSources) => updateAllSources(selectedSources, options, updateSpinner)
2793
3311
  ),
2794
- Effect7.tap(({ totalUpdated, totalErrors }) => {
3312
+ Effect8.tap(({ totalUpdated, totalErrors }) => {
2795
3313
  if (totalErrors > 0) {
2796
3314
  outro2(`Updated ${totalUpdated} skills with ${totalErrors} errors.`);
2797
3315
  } else {
@@ -2799,7 +3317,7 @@ async function updateCommand(options) {
2799
3317
  }
2800
3318
  })
2801
3319
  );
2802
- const result = await Effect7.runPromiseExit(program2);
3320
+ const result = await Effect8.runPromiseExit(program2);
2803
3321
  handleProgramExit(result, updateSpinner);
2804
3322
  }
2805
3323
 
@@ -2808,10 +3326,10 @@ var require2 = createRequire(import.meta.url);
2808
3326
  var { version: PACKAGE_VERSION } = require2("../package.json");
2809
3327
  var program = new Command();
2810
3328
  program.name("braid").description(
2811
- "Install Braid prompts as agent skills to your local development environment"
3329
+ "Install braid prompts as agent skills to your local development environment"
2812
3330
  ).version(PACKAGE_VERSION);
2813
- var auth = program.command("auth").description("Configure API key for Braid authentication");
2814
- auth.command("login", { isDefault: true }).description("Configure API key").option("-s, --server <url>", "Braid server URL (for review apps, local dev)").action(authCommand);
3331
+ var auth = program.command("auth").description("Configure API key for braid authentication");
3332
+ auth.command("login", { isDefault: true }).description("Configure API key").option("-s, --server <url>", "braid server URL (for review apps, local dev)").action(authCommand);
2815
3333
  auth.command("status").description("Show current authentication status").action(authStatusCommand);
2816
3334
  auth.command("logout").description("Remove stored API key").action(authLogoutCommand);
2817
3335
  program.command("install").alias("add").description("Install skills from a profile or project").option("-p, --profile <name>", "Profile name to install from").option(
@@ -2829,7 +3347,7 @@ program.command("install").alias("add").description("Install skills from a profi
2829
3347
  ).option("--no-include-org-globals", "Exclude organization's global prompts").option(
2830
3348
  "-a, --agents <list>",
2831
3349
  "Comma-separated list of agents (e.g., claude-code,opencode)"
2832
- ).option("-g, --global", "Install to global agent directories").option("-y, --yes", "Skip confirmation prompts").option("-l, --list", "Preview skills without installing").option("-s, --server <url>", "Braid server URL (for review apps, local dev)").action(installCommand);
3350
+ ).option("-g, --global", "Install to global agent directories").option("-y, --yes", "Skip confirmation prompts").option("-l, --list", "Preview skills without installing").option("-s, --server <url>", "braid server URL (for review apps, local dev)").action(installCommand);
2833
3351
  program.command("scope").description("Interactively configure braid.json or braid.user.json scope").option("--file <target>", "Config file target: user or project").option(
2834
3352
  "--organization <type>",
2835
3353
  "Scope organization for non-interactive mode: personal or organization"
@@ -2851,9 +3369,10 @@ program.command("scope").description("Interactively configure braid.json or brai
2851
3369
  ).option(
2852
3370
  "--include-org-global",
2853
3371
  "Include org global rules in non-interactive mode"
2854
- ).option("-s, --server <url>", "Braid server URL (for review apps, local dev)").action(scopeCommand);
3372
+ ).option("-s, --server <url>", "braid server URL (for review apps, local dev)").action(scopeCommand);
2855
3373
  program.command("list").alias("ls").description("List installed skills").option("-g, --global", "List skills in global directories only").action(listCommand);
2856
- program.command("update").alias("up").description("Update installed skills to the latest version").option("-g, --global", "Update skills in global directories only").option("-y, --yes", "Skip confirmation prompts").option("-s, --server <url>", "Braid server URL (for review apps, local dev)").action(updateCommand);
3374
+ program.command("update").alias("up").description("Update installed skills to the latest version").option("-g, --global", "Update skills in global directories only").option("-y, --yes", "Skip confirmation prompts").option("-s, --server <url>", "braid server URL (for review apps, local dev)").action(updateCommand);
2857
3375
  program.command("remove").alias("rm").description("Remove installed skills").option("-a, --all", "Remove all installed skills").option("-g, --global", "Remove skills from global directories only").option("-y, --yes", "Skip confirmation prompts").option("--skill <name>", "Remove a specific skill by name").action(removeCommand);
3376
+ program.command("mcp").description("Configure braid MCP in your AI coding tools").option("-t, --tool <name>", "Tool to configure").option("-g, --global", "Use global config instead of project").option("--token <token>", "API token to embed").option("--no-auth", "Skip authentication setup").option("--scope", "Run interactive scope configuration").option("--remove", "Remove braid MCP from a tool").option("--status", "Show which tools have braid MCP configured").option("-y, --yes", "Skip confirmation prompts").option("-s, --server <url>", "Custom MCP server URL").action(mcpCommand);
2858
3377
  program.parse();
2859
3378
  //# sourceMappingURL=index.js.map