squads-cli 0.4.10 → 0.4.11

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
@@ -43,8 +43,8 @@ import {
43
43
 
44
44
  // src/cli.ts
45
45
  import { config } from "dotenv";
46
- import { existsSync as existsSync18 } from "fs";
47
- import { join as join20 } from "path";
46
+ import { existsSync as existsSync20 } from "fs";
47
+ import { join as join22 } from "path";
48
48
  import { homedir as homedir4 } from "os";
49
49
  import { Command } from "commander";
50
50
  import chalk4 from "chalk";
@@ -534,9 +534,18 @@ var Events = {
534
534
  CLI_FEEDBACK_ADD: "cli.feedback.add",
535
535
  CLI_FEEDBACK_SHOW: "cli.feedback.show",
536
536
  CLI_FEEDBACK_STATS: "cli.feedback.stats",
537
+ // Learnings
538
+ CLI_LEARN: "cli.learn",
539
+ CLI_LEARN_SHOW: "cli.learn.show",
540
+ CLI_LEARN_SEARCH: "cli.learn.search",
537
541
  // Auth
538
542
  CLI_LOGIN: "cli.login",
539
- CLI_LOGOUT: "cli.logout"
543
+ CLI_LOGOUT: "cli.logout",
544
+ // Context Condenser
545
+ CONDENSER_COMPRESS: "condenser.compress",
546
+ CONDENSER_DEDUPE: "condenser.dedupe",
547
+ CONDENSER_PRUNE: "condenser.prune",
548
+ CONDENSER_SUMMARIZE: "condenser.summarize"
540
549
  };
541
550
  var exitHandlerRegistered = false;
542
551
  function registerExitHandler() {
@@ -884,10 +893,13 @@ async function initCommand(options) {
884
893
  ".agents/squads/demo",
885
894
  ".agents/memory",
886
895
  ".agents/memory/getting-started",
896
+ ".agents/memory/general/shared",
897
+ // For cross-squad learnings
887
898
  ".agents/outputs",
888
899
  ".claude",
889
900
  ".claude/skills",
890
- ".claude/skills/squads-workflow"
901
+ ".claude/skills/squads-workflow",
902
+ ".claude/skills/squads-learn"
891
903
  ];
892
904
  for (const dir of dirs) {
893
905
  await fs.mkdir(path.join(cwd, dir), { recursive: true });
@@ -1063,6 +1075,56 @@ When a task could be automated:
1063
1075
  path.join(cwd, ".claude/skills/squads-workflow/instruction.md"),
1064
1076
  squadsWorkflowSkill
1065
1077
  );
1078
+ const squadsLearnSkill = `---
1079
+ name: squads-learn
1080
+ description: Capture learnings after completing work. Use when finishing a task, fixing a bug, discovering a pattern, or learning something worth remembering for future sessions.
1081
+ ---
1082
+
1083
+ # Capture Learnings
1084
+
1085
+ After completing work, capture what you learned so future sessions can benefit.
1086
+
1087
+ ## When to Use
1088
+
1089
+ - After fixing a bug - What was the root cause?
1090
+ - After completing a feature - What approach worked?
1091
+ - After research - What's the key insight?
1092
+ - When you notice a pattern - Something that works consistently
1093
+
1094
+ ## Quick Commands
1095
+
1096
+ \`\`\`bash
1097
+ # Capture a learning
1098
+ squads learn "The auth token needs refresh after 1 hour, not on 401"
1099
+
1100
+ # With squad and category
1101
+ squads learn "Always check memory first" --squad engineering --category pattern
1102
+
1103
+ # View learnings
1104
+ squads learnings show engineering
1105
+ squads learnings search "auth"
1106
+ \`\`\`
1107
+
1108
+ ## Categories
1109
+
1110
+ - \`success\` - Something that worked well
1111
+ - \`failure\` - Something that didn't work (learn from mistakes)
1112
+ - \`pattern\` - A reusable approach
1113
+ - \`tip\` - General advice
1114
+
1115
+ ## End of Task Checklist
1116
+
1117
+ Before marking done, ask:
1118
+ 1. What worked that I should remember?
1119
+ 2. What didn't work that I should avoid?
1120
+ 3. Is there a pattern worth capturing?
1121
+
1122
+ If yes \u2192 \`squads learn "<insight>"\`
1123
+ `;
1124
+ await fs.writeFile(
1125
+ path.join(cwd, ".claude/skills/squads-learn/SKILL.md"),
1126
+ squadsLearnSkill
1127
+ );
1066
1128
  const seedMemory = `# Getting Started with Squads
1067
1129
 
1068
1130
  ## What You've Set Up
@@ -1139,7 +1201,7 @@ When a task could be automated:
1139
1201
  hooks: [
1140
1202
  {
1141
1203
  type: "command",
1142
- command: "squads memory sync",
1204
+ command: 'squads memory sync && echo "\\n\u{1F4A1} Capture learnings: squads learn \\"<what you learned>\\"\\n"',
1143
1205
  timeout: 15
1144
1206
  }
1145
1207
  ]
@@ -1303,9 +1365,9 @@ squads goal list # View goals
1303
1365
  console.log(chalk.dim(" Created:"));
1304
1366
  console.log(chalk.dim(" \u2022 .agents/squads/demo/ - Demo squad with 2 agents"));
1305
1367
  console.log(chalk.dim(" \u2022 .agents/BUSINESS_BRIEF - Business context template"));
1306
- console.log(chalk.dim(" \u2022 .agents/memory/ - Seed memory"));
1368
+ console.log(chalk.dim(" \u2022 .agents/memory/ - Seed memory + learnings"));
1307
1369
  console.log(chalk.dim(" \u2022 .claude/settings.json - Claude Code hooks"));
1308
- console.log(chalk.dim(" \u2022 .claude/skills/ - Squads workflow skill"));
1370
+ console.log(chalk.dim(" \u2022 .claude/skills/ - Workflow + learn skills"));
1309
1371
  console.log(chalk.dim(" \u2022 CLAUDE.md - Agent instructions"));
1310
1372
  console.log();
1311
1373
  const email = await promptEmail();
@@ -1331,21 +1393,185 @@ squads goal list # View goals
1331
1393
  // src/commands/run.ts
1332
1394
  import ora2 from "ora";
1333
1395
  import { spawn as spawn2 } from "child_process";
1334
- import { join as join4, dirname } from "path";
1335
- import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2 } from "fs";
1396
+ import { join as join5, dirname as dirname2 } from "path";
1397
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
1336
1398
 
1337
1399
  // src/lib/squad-parser.ts
1338
- import { readFileSync as readFileSync2, existsSync as existsSync3, readdirSync, writeFileSync as writeFileSync2 } from "fs";
1339
- import { join as join3, basename } from "path";
1400
+ import { readFileSync as readFileSync3, existsSync as existsSync4, readdirSync, writeFileSync as writeFileSync3 } from "fs";
1401
+ import { join as join4, basename } from "path";
1340
1402
  import matter from "gray-matter";
1403
+
1404
+ // src/lib/mcp-config.ts
1405
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync2 } from "fs";
1406
+ import { join as join3, dirname } from "path";
1407
+ var SERVER_REGISTRY = {
1408
+ // Browser/Web tools
1409
+ "chrome-devtools": {
1410
+ type: "stdio",
1411
+ command: "npx",
1412
+ args: ["chrome-devtools-mcp", "--isolated", "--headless"],
1413
+ env: {}
1414
+ },
1415
+ "nano-banana": {
1416
+ type: "stdio",
1417
+ command: "npx",
1418
+ args: ["nano-banana-mcp"],
1419
+ env: {}
1420
+ },
1421
+ "firecrawl": {
1422
+ type: "stdio",
1423
+ command: "npx",
1424
+ args: ["firecrawl-mcp"],
1425
+ env: {
1426
+ FIRECRAWL_API_KEY: "${FIRECRAWL_API_KEY}"
1427
+ }
1428
+ },
1429
+ // Data tools
1430
+ "supabase": {
1431
+ type: "stdio",
1432
+ command: "npx",
1433
+ args: ["-y", "@supabase/mcp-server-supabase@latest", "--read-only"],
1434
+ env: {
1435
+ SUPABASE_ACCESS_TOKEN: "${SUPABASE_ACCESS_TOKEN}"
1436
+ }
1437
+ },
1438
+ "grafana": {
1439
+ type: "stdio",
1440
+ command: "npx",
1441
+ args: ["-y", "@leval/mcp-grafana"],
1442
+ env: {
1443
+ GRAFANA_URL: "${GRAFANA_URL}",
1444
+ GRAFANA_SERVICE_ACCOUNT_TOKEN: "${GRAFANA_SERVICE_ACCOUNT_TOKEN}"
1445
+ }
1446
+ },
1447
+ // AI/ML tools
1448
+ "huggingface": {
1449
+ type: "stdio",
1450
+ command: "npx",
1451
+ args: ["huggingface-mcp"],
1452
+ env: {
1453
+ HF_TOKEN: "${HF_TOKEN}"
1454
+ }
1455
+ },
1456
+ "context7": {
1457
+ type: "stdio",
1458
+ command: "npx",
1459
+ args: ["context7-mcp"],
1460
+ env: {}
1461
+ },
1462
+ // Social/Research tools
1463
+ "x-mcp": {
1464
+ type: "stdio",
1465
+ command: "python3",
1466
+ args: ["~/.claude/mcps/x-mcp/server.py"],
1467
+ env: {
1468
+ X_BEARER_TOKEN: "${X_BEARER_TOKEN}"
1469
+ }
1470
+ },
1471
+ // Telemetry
1472
+ "langfuse-telemetry": {
1473
+ type: "stdio",
1474
+ command: "python3",
1475
+ args: ["~/.claude/mcps/langfuse-telemetry/server.py"],
1476
+ env: {
1477
+ LANGFUSE_HOST: "${LANGFUSE_HOST}",
1478
+ LANGFUSE_PUBLIC_KEY: "${LANGFUSE_PUBLIC_KEY}",
1479
+ LANGFUSE_SECRET_KEY: "${LANGFUSE_SECRET_KEY}"
1480
+ }
1481
+ },
1482
+ // Analytics
1483
+ "ga4-admin": {
1484
+ type: "stdio",
1485
+ command: "python3",
1486
+ args: ["-m", "mcp_ga4.server"],
1487
+ env: {}
1488
+ }
1489
+ };
1490
+ function getHome() {
1491
+ return process.env.HOME || process.env.USERPROFILE || "";
1492
+ }
1493
+ function getContextsDir() {
1494
+ return join3(getHome(), ".claude", "contexts");
1495
+ }
1496
+ function getMcpConfigsDir() {
1497
+ return join3(getHome(), ".claude", "mcp-configs");
1498
+ }
1499
+ function generateMcpConfig(mcpServers) {
1500
+ const config2 = { mcpServers: {} };
1501
+ for (const server of mcpServers) {
1502
+ const def = SERVER_REGISTRY[server];
1503
+ if (def) {
1504
+ config2.mcpServers[server] = def;
1505
+ }
1506
+ }
1507
+ return config2;
1508
+ }
1509
+ function writeMcpConfig(config2, path3) {
1510
+ const dir = dirname(path3);
1511
+ if (!existsSync3(dir)) {
1512
+ mkdirSync2(dir, { recursive: true });
1513
+ }
1514
+ writeFileSync2(path3, JSON.stringify(config2, null, 2));
1515
+ }
1516
+ function readMcpConfig(path3) {
1517
+ if (!existsSync3(path3)) return null;
1518
+ try {
1519
+ const content = readFileSync2(path3, "utf-8");
1520
+ return JSON.parse(content);
1521
+ } catch {
1522
+ return null;
1523
+ }
1524
+ }
1525
+ function resolveMcpConfig(squadName, mcpServers, forceRegenerate = false) {
1526
+ const home = getHome();
1527
+ const userOverride = join3(getMcpConfigsDir(), `${squadName}.json`);
1528
+ if (existsSync3(userOverride)) {
1529
+ const config2 = readMcpConfig(userOverride);
1530
+ return {
1531
+ path: userOverride,
1532
+ source: "user-override",
1533
+ servers: config2 ? Object.keys(config2.mcpServers) : void 0
1534
+ };
1535
+ }
1536
+ if (mcpServers && mcpServers.length > 0) {
1537
+ const generatedPath = join3(getContextsDir(), `${squadName}.mcp.json`);
1538
+ const shouldGenerate = forceRegenerate || !existsSync3(generatedPath);
1539
+ if (shouldGenerate) {
1540
+ const config3 = generateMcpConfig(mcpServers);
1541
+ writeMcpConfig(config3, generatedPath);
1542
+ return {
1543
+ path: generatedPath,
1544
+ source: "generated",
1545
+ servers: Object.keys(config3.mcpServers),
1546
+ generated: true
1547
+ };
1548
+ }
1549
+ const config2 = readMcpConfig(generatedPath);
1550
+ return {
1551
+ path: generatedPath,
1552
+ source: "generated",
1553
+ servers: config2 ? Object.keys(config2.mcpServers) : mcpServers,
1554
+ generated: false
1555
+ };
1556
+ }
1557
+ return {
1558
+ path: join3(home, ".claude.json"),
1559
+ source: "fallback"
1560
+ };
1561
+ }
1562
+ function resolveMcpConfigPath(squadName, mcpServers) {
1563
+ return resolveMcpConfig(squadName, mcpServers).path;
1564
+ }
1565
+
1566
+ // src/lib/squad-parser.ts
1341
1567
  function findSquadsDir() {
1342
1568
  let dir = process.cwd();
1343
1569
  for (let i = 0; i < 5; i++) {
1344
- const squadsPath = join3(dir, ".agents", "squads");
1345
- if (existsSync3(squadsPath)) {
1570
+ const squadsPath = join4(dir, ".agents", "squads");
1571
+ if (existsSync4(squadsPath)) {
1346
1572
  return squadsPath;
1347
1573
  }
1348
- const parent = join3(dir, "..");
1574
+ const parent = join4(dir, "..");
1349
1575
  if (parent === dir) break;
1350
1576
  dir = parent;
1351
1577
  }
@@ -1354,14 +1580,14 @@ function findSquadsDir() {
1354
1580
  function findProjectRoot() {
1355
1581
  const squadsDir = findSquadsDir();
1356
1582
  if (!squadsDir) return null;
1357
- return join3(squadsDir, "..", "..");
1583
+ return join4(squadsDir, "..", "..");
1358
1584
  }
1359
1585
  function hasLocalInfraConfig() {
1360
1586
  const projectRoot = findProjectRoot();
1361
1587
  if (!projectRoot) return false;
1362
- const envPath = join3(projectRoot, ".env");
1363
- if (!existsSync3(envPath)) return false;
1364
- const content = readFileSync2(envPath, "utf-8");
1588
+ const envPath = join4(projectRoot, ".env");
1589
+ if (!existsSync4(envPath)) return false;
1590
+ const content = readFileSync3(envPath, "utf-8");
1365
1591
  const infraKeys = ["LANGFUSE_", "SQUADS_BRIDGE", "SQUADS_POSTGRES", "SQUADS_REDIS"];
1366
1592
  return infraKeys.some((key) => content.includes(key));
1367
1593
  }
@@ -1370,8 +1596,8 @@ function listSquads(squadsDir) {
1370
1596
  const entries = readdirSync(squadsDir, { withFileTypes: true });
1371
1597
  for (const entry of entries) {
1372
1598
  if (entry.isDirectory() && !entry.name.startsWith("_")) {
1373
- const squadFile = join3(squadsDir, entry.name, "SQUAD.md");
1374
- if (existsSync3(squadFile)) {
1599
+ const squadFile = join4(squadsDir, entry.name, "SQUAD.md");
1600
+ if (existsSync4(squadFile)) {
1375
1601
  squads.push(entry.name);
1376
1602
  }
1377
1603
  }
@@ -1382,8 +1608,8 @@ function listAgents(squadsDir, squadName) {
1382
1608
  const agents = [];
1383
1609
  const dirs = squadName ? [squadName] : readdirSync(squadsDir, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith("_")).map((e) => e.name);
1384
1610
  for (const dir of dirs) {
1385
- const squadPath = join3(squadsDir, dir);
1386
- if (!existsSync3(squadPath)) continue;
1611
+ const squadPath = join4(squadsDir, dir);
1612
+ if (!existsSync4(squadPath)) continue;
1387
1613
  const files = readdirSync(squadPath);
1388
1614
  for (const file of files) {
1389
1615
  if (file.endsWith(".md") && file !== "SQUAD.md") {
@@ -1392,7 +1618,7 @@ function listAgents(squadsDir, squadName) {
1392
1618
  name: agentName,
1393
1619
  role: `Agent in ${dir}`,
1394
1620
  trigger: "manual",
1395
- filePath: join3(squadPath, file)
1621
+ filePath: join4(squadPath, file)
1396
1622
  });
1397
1623
  }
1398
1624
  }
@@ -1400,7 +1626,7 @@ function listAgents(squadsDir, squadName) {
1400
1626
  return agents;
1401
1627
  }
1402
1628
  function parseSquadFile(filePath) {
1403
- const rawContent = readFileSync2(filePath, "utf-8");
1629
+ const rawContent = readFileSync3(filePath, "utf-8");
1404
1630
  const { data: frontmatter, content: bodyContent } = matter(rawContent);
1405
1631
  const fm = frontmatter;
1406
1632
  const lines = bodyContent.split("\n");
@@ -1521,20 +1747,20 @@ function parseSquadFile(filePath) {
1521
1747
  function loadSquad(squadName) {
1522
1748
  const squadsDir = findSquadsDir();
1523
1749
  if (!squadsDir) return null;
1524
- const squadFile = join3(squadsDir, squadName, "SQUAD.md");
1525
- if (!existsSync3(squadFile)) return null;
1750
+ const squadFile = join4(squadsDir, squadName, "SQUAD.md");
1751
+ if (!existsSync4(squadFile)) return null;
1526
1752
  return parseSquadFile(squadFile);
1527
1753
  }
1528
1754
  function loadAgentDefinition(agentPath) {
1529
- if (!existsSync3(agentPath)) return "";
1530
- return readFileSync2(agentPath, "utf-8");
1755
+ if (!existsSync4(agentPath)) return "";
1756
+ return readFileSync3(agentPath, "utf-8");
1531
1757
  }
1532
1758
  function addGoalToSquad(squadName, goal2) {
1533
1759
  const squadsDir = findSquadsDir();
1534
1760
  if (!squadsDir) return false;
1535
- const squadFile = join3(squadsDir, squadName, "SQUAD.md");
1536
- if (!existsSync3(squadFile)) return false;
1537
- let content = readFileSync2(squadFile, "utf-8");
1761
+ const squadFile = join4(squadsDir, squadName, "SQUAD.md");
1762
+ if (!existsSync4(squadFile)) return false;
1763
+ let content = readFileSync3(squadFile, "utf-8");
1538
1764
  if (!content.includes("## Goals")) {
1539
1765
  const insertPoint = content.indexOf("## Dependencies");
1540
1766
  if (insertPoint > 0) {
@@ -1569,15 +1795,15 @@ function addGoalToSquad(squadName, goal2) {
1569
1795
  - [ ] ${goal2}` + content.slice(headerEnd);
1570
1796
  }
1571
1797
  }
1572
- writeFileSync2(squadFile, content);
1798
+ writeFileSync3(squadFile, content);
1573
1799
  return true;
1574
1800
  }
1575
1801
  function updateGoalInSquad(squadName, goalIndex, updates) {
1576
1802
  const squadsDir = findSquadsDir();
1577
1803
  if (!squadsDir) return false;
1578
- const squadFile = join3(squadsDir, squadName, "SQUAD.md");
1579
- if (!existsSync3(squadFile)) return false;
1580
- const content = readFileSync2(squadFile, "utf-8");
1804
+ const squadFile = join4(squadsDir, squadName, "SQUAD.md");
1805
+ if (!existsSync4(squadFile)) return false;
1806
+ const content = readFileSync3(squadFile, "utf-8");
1581
1807
  const lines = content.split("\n");
1582
1808
  let currentSection = "";
1583
1809
  let goalCount = 0;
@@ -1599,7 +1825,7 @@ function updateGoalInSquad(squadName, goalIndex, updates) {
1599
1825
  }
1600
1826
  }
1601
1827
  lines[i] = newLine;
1602
- writeFileSync2(squadFile, lines.join("\n"));
1828
+ writeFileSync3(squadFile, lines.join("\n"));
1603
1829
  return true;
1604
1830
  }
1605
1831
  goalCount++;
@@ -1608,6 +1834,84 @@ function updateGoalInSquad(squadName, goalIndex, updates) {
1608
1834
  }
1609
1835
  return false;
1610
1836
  }
1837
+ function findSkillsDir() {
1838
+ const projectRoot = findProjectRoot();
1839
+ if (!projectRoot) return null;
1840
+ const skillsDir = join4(projectRoot, ".claude", "skills");
1841
+ return existsSync4(skillsDir) ? skillsDir : null;
1842
+ }
1843
+ function findMemoryDir2() {
1844
+ const projectRoot = findProjectRoot();
1845
+ if (!projectRoot) return null;
1846
+ const memoryDir = join4(projectRoot, ".agents", "memory");
1847
+ return existsSync4(memoryDir) ? memoryDir : null;
1848
+ }
1849
+ function resolveSkillPath(skillName) {
1850
+ const skillsDir = findSkillsDir();
1851
+ if (!skillsDir) return null;
1852
+ const skillPath = join4(skillsDir, skillName);
1853
+ return existsSync4(skillPath) ? skillPath : null;
1854
+ }
1855
+ function resolveMemoryPaths(patterns) {
1856
+ const memoryDir = findMemoryDir2();
1857
+ if (!memoryDir) return [];
1858
+ const resolved = [];
1859
+ for (const pattern of patterns) {
1860
+ if (pattern.endsWith("/*")) {
1861
+ const subdir = pattern.slice(0, -2);
1862
+ const subdirPath = join4(memoryDir, subdir);
1863
+ if (existsSync4(subdirPath)) {
1864
+ try {
1865
+ const files = readdirSync(subdirPath);
1866
+ for (const file of files) {
1867
+ if (file.endsWith(".md")) {
1868
+ resolved.push(join4(subdirPath, file));
1869
+ }
1870
+ }
1871
+ } catch {
1872
+ }
1873
+ }
1874
+ } else {
1875
+ const fullPath = join4(memoryDir, pattern);
1876
+ if (existsSync4(fullPath)) {
1877
+ resolved.push(fullPath);
1878
+ }
1879
+ }
1880
+ }
1881
+ return resolved;
1882
+ }
1883
+ function resolveExecutionContext(squad, forceRegenerate = false) {
1884
+ const ctx = squad.context || {};
1885
+ const mcpResolution = resolveMcpConfig(
1886
+ squad.name,
1887
+ ctx.mcp,
1888
+ forceRegenerate
1889
+ );
1890
+ const skillPaths = [];
1891
+ if (ctx.skills) {
1892
+ for (const skill of ctx.skills) {
1893
+ const path3 = resolveSkillPath(skill);
1894
+ if (path3) {
1895
+ skillPaths.push(path3);
1896
+ }
1897
+ }
1898
+ }
1899
+ const memoryPaths = ctx.memory?.load ? resolveMemoryPaths(ctx.memory.load) : [];
1900
+ return {
1901
+ // Copy all SquadContext fields
1902
+ ...ctx,
1903
+ // Add squad name
1904
+ squadName: squad.name,
1905
+ // Add resolved paths
1906
+ resolved: {
1907
+ mcpConfigPath: mcpResolution.path,
1908
+ mcpSource: mcpResolution.source,
1909
+ mcpServers: mcpResolution.servers || [],
1910
+ skillPaths,
1911
+ memoryPaths
1912
+ }
1913
+ };
1914
+ }
1611
1915
 
1612
1916
  // src/lib/permissions.ts
1613
1917
  import { minimatch } from "minimatch";
@@ -1846,9 +2150,12 @@ function generateExecutionId() {
1846
2150
  const random = Math.random().toString(36).substring(2, 8);
1847
2151
  return `exec_${timestamp}_${random}`;
1848
2152
  }
1849
- function selectMcpConfig(squadName) {
2153
+ function selectMcpConfig(squadName, squad) {
2154
+ if (squad?.context?.mcp && squad.context.mcp.length > 0) {
2155
+ return resolveMcpConfigPath(squadName, squad.context.mcp);
2156
+ }
1850
2157
  const home = process.env.HOME || "";
1851
- const configsDir = join4(home, ".claude", "mcp-configs");
2158
+ const configsDir = join5(home, ".claude", "mcp-configs");
1852
2159
  const squadConfigs = {
1853
2160
  website: "website.json",
1854
2161
  // chrome-devtools, nano-banana
@@ -1863,12 +2170,12 @@ function selectMcpConfig(squadName) {
1863
2170
  };
1864
2171
  const configFile = squadConfigs[squadName.toLowerCase()];
1865
2172
  if (configFile) {
1866
- const configPath = join4(configsDir, configFile);
1867
- if (existsSync4(configPath)) {
2173
+ const configPath = join5(configsDir, configFile);
2174
+ if (existsSync5(configPath)) {
1868
2175
  return configPath;
1869
2176
  }
1870
2177
  }
1871
- return join4(home, ".claude.json");
2178
+ return join5(home, ".claude.json");
1872
2179
  }
1873
2180
  function detectTaskType(agentName) {
1874
2181
  const name = agentName.toLowerCase();
@@ -1884,12 +2191,12 @@ function detectTaskType(agentName) {
1884
2191
  return "execution";
1885
2192
  }
1886
2193
  function ensureProjectTrusted(projectPath) {
1887
- const configPath = join4(process.env.HOME || "", ".claude.json");
1888
- if (!existsSync4(configPath)) {
2194
+ const configPath = join5(process.env.HOME || "", ".claude.json");
2195
+ if (!existsSync5(configPath)) {
1889
2196
  return;
1890
2197
  }
1891
2198
  try {
1892
- const config2 = JSON.parse(readFileSync3(configPath, "utf-8"));
2199
+ const config2 = JSON.parse(readFileSync4(configPath, "utf-8"));
1893
2200
  if (!config2.projects) {
1894
2201
  config2.projects = {};
1895
2202
  }
@@ -1898,7 +2205,7 @@ function ensureProjectTrusted(projectPath) {
1898
2205
  }
1899
2206
  if (!config2.projects[projectPath].hasTrustDialogAccepted) {
1900
2207
  config2.projects[projectPath].hasTrustDialogAccepted = true;
1901
- writeFileSync3(configPath, JSON.stringify(config2, null, 2));
2208
+ writeFileSync4(configPath, JSON.stringify(config2, null, 2));
1902
2209
  }
1903
2210
  } catch {
1904
2211
  }
@@ -1906,25 +2213,25 @@ function ensureProjectTrusted(projectPath) {
1906
2213
  function getProjectRoot() {
1907
2214
  const squadsDir = findSquadsDir();
1908
2215
  if (squadsDir) {
1909
- return dirname(dirname(squadsDir));
2216
+ return dirname2(dirname2(squadsDir));
1910
2217
  }
1911
2218
  return process.cwd();
1912
2219
  }
1913
2220
  function getExecutionLogPath(squadName, agentName) {
1914
2221
  const memoryDir = findMemoryDir();
1915
2222
  if (!memoryDir) return null;
1916
- return join4(memoryDir, squadName, agentName, "executions.md");
2223
+ return join5(memoryDir, squadName, agentName, "executions.md");
1917
2224
  }
1918
2225
  function logExecution(record) {
1919
2226
  const logPath = getExecutionLogPath(record.squadName, record.agentName);
1920
2227
  if (!logPath) return;
1921
- const dir = dirname(logPath);
1922
- if (!existsSync4(dir)) {
1923
- mkdirSync2(dir, { recursive: true });
2228
+ const dir = dirname2(logPath);
2229
+ if (!existsSync5(dir)) {
2230
+ mkdirSync3(dir, { recursive: true });
1924
2231
  }
1925
2232
  let content = "";
1926
- if (existsSync4(logPath)) {
1927
- content = readFileSync3(logPath, "utf-8").trimEnd();
2233
+ if (existsSync5(logPath)) {
2234
+ content = readFileSync4(logPath, "utf-8").trimEnd();
1928
2235
  } else {
1929
2236
  content = `# ${record.squadName}/${record.agentName} - Execution Log`;
1930
2237
  }
@@ -1937,12 +2244,12 @@ function logExecution(record) {
1937
2244
  - Trigger: ${record.trigger || "manual"}
1938
2245
  - Task Type: ${record.taskType || "execution"}
1939
2246
  `;
1940
- writeFileSync3(logPath, content + entry);
2247
+ writeFileSync4(logPath, content + entry);
1941
2248
  }
1942
2249
  function updateExecutionStatus(squadName, agentName, executionId, status, details) {
1943
2250
  const logPath = getExecutionLogPath(squadName, agentName);
1944
- if (!logPath || !existsSync4(logPath)) return;
1945
- let content = readFileSync3(logPath, "utf-8");
2251
+ if (!logPath || !existsSync5(logPath)) return;
2252
+ let content = readFileSync4(logPath, "utf-8");
1946
2253
  const endTime = (/* @__PURE__ */ new Date()).toISOString();
1947
2254
  const execMarker = `<!-- exec:${executionId} -->`;
1948
2255
  const markerIndex = content.indexOf(execMarker);
@@ -1963,7 +2270,7 @@ function updateExecutionStatus(squadName, agentName, executionId, status, detail
1963
2270
  - Error: ${details.error}`;
1964
2271
  }
1965
2272
  content = content.slice(0, entryStart) + updatedEntry + content.slice(entryEnd);
1966
- writeFileSync3(logPath, content);
2273
+ writeFileSync4(logPath, content);
1967
2274
  }
1968
2275
  function extractMcpServersFromDefinition(definition) {
1969
2276
  const servers = /* @__PURE__ */ new Set();
@@ -2042,8 +2349,8 @@ async function runSquad(squad, squadsDir, options) {
2042
2349
  if (options.parallel) {
2043
2350
  const agentFiles = squad.agents.map((a) => ({
2044
2351
  name: a.name,
2045
- path: join4(squadsDir, squad.name, `${a.name}.md`)
2046
- })).filter((a) => existsSync4(a.path));
2352
+ path: join5(squadsDir, squad.name, `${a.name}.md`)
2353
+ })).filter((a) => existsSync5(a.path));
2047
2354
  if (agentFiles.length === 0) {
2048
2355
  writeLine(` ${icons.error} ${colors.red}No agent files found${RESET}`);
2049
2356
  return;
@@ -2079,8 +2386,8 @@ async function runSquad(squad, squadsDir, options) {
2079
2386
  writeLine();
2080
2387
  for (let i = 0; i < pipeline.agents.length; i++) {
2081
2388
  const agentName = pipeline.agents[i];
2082
- const agentPath = join4(squadsDir, squad.name, `${agentName}.md`);
2083
- if (existsSync4(agentPath)) {
2389
+ const agentPath = join5(squadsDir, squad.name, `${agentName}.md`);
2390
+ if (existsSync5(agentPath)) {
2084
2391
  writeLine(` ${colors.dim}[${i + 1}/${pipeline.agents.length}]${RESET}`);
2085
2392
  await runAgent(agentName, agentPath, squad.name, options);
2086
2393
  writeLine();
@@ -2090,8 +2397,8 @@ async function runSquad(squad, squadsDir, options) {
2090
2397
  }
2091
2398
  } else {
2092
2399
  if (options.agent) {
2093
- const agentPath = join4(squadsDir, squad.name, `${options.agent}.md`);
2094
- if (existsSync4(agentPath)) {
2400
+ const agentPath = join5(squadsDir, squad.name, `${options.agent}.md`);
2401
+ if (existsSync5(agentPath)) {
2095
2402
  await runAgent(options.agent, agentPath, squad.name, options);
2096
2403
  } else {
2097
2404
  writeLine(` ${icons.error} ${colors.red}Agent ${options.agent} not found${RESET}`);
@@ -2102,8 +2409,8 @@ async function runSquad(squad, squadsDir, options) {
2102
2409
  (a) => a.name.includes("lead") || a.trigger === "Manual"
2103
2410
  );
2104
2411
  if (orchestrator) {
2105
- const agentPath = join4(squadsDir, squad.name, `${orchestrator.name}.md`);
2106
- if (existsSync4(agentPath)) {
2412
+ const agentPath = join5(squadsDir, squad.name, `${orchestrator.name}.md`);
2413
+ if (existsSync5(agentPath)) {
2107
2414
  await runAgent(orchestrator.name, agentPath, squad.name, options);
2108
2415
  }
2109
2416
  } else {
@@ -2129,9 +2436,9 @@ async function runLeadMode(squad, squadsDir, options) {
2129
2436
  if (!squad) return;
2130
2437
  const agentFiles = squad.agents.map((a) => ({
2131
2438
  name: a.name,
2132
- path: join4(squadsDir, squad.name, `${a.name}.md`),
2439
+ path: join5(squadsDir, squad.name, `${a.name}.md`),
2133
2440
  role: a.role || ""
2134
- })).filter((a) => existsSync4(a.path));
2441
+ })).filter((a) => existsSync5(a.path));
2135
2442
  if (agentFiles.length === 0) {
2136
2443
  writeLine(` ${icons.error} ${colors.red}No agent files found${RESET}`);
2137
2444
  return;
@@ -2250,9 +2557,9 @@ async function runAgent(agentName, agentPath, squadName, options) {
2250
2557
  }
2251
2558
  const squadsDir = findSquadsDir();
2252
2559
  if (squadsDir) {
2253
- const squadFilePath = join4(squadsDir, squadName, "SQUAD.md");
2254
- if (existsSync4(squadFilePath)) {
2255
- const squadContent = readFileSync3(squadFilePath, "utf-8");
2560
+ const squadFilePath = join5(squadsDir, squadName, "SQUAD.md");
2561
+ if (existsSync5(squadFilePath)) {
2562
+ const squadContent = readFileSync4(squadFilePath, "utf-8");
2256
2563
  const permContext = buildContextFromSquad(squadName, squadContent, agentName);
2257
2564
  const mcpServers = extractMcpServersFromDefinition(definition);
2258
2565
  const execRequest = {
@@ -2361,7 +2668,8 @@ async function executeWithClaude(prompt2, verbose, _timeoutMinutes = 30, foregro
2361
2668
  const agentMatch = prompt2.match(/(\w+) agent/);
2362
2669
  const squadName = process.env.SQUADS_SQUAD || squadMatch?.[1] || "unknown";
2363
2670
  const agentName = process.env.SQUADS_AGENT || agentMatch?.[1] || "unknown";
2364
- const mcpConfigPath = selectMcpConfig(squadName);
2671
+ const squad = squadName !== "unknown" ? loadSquad(squadName) : null;
2672
+ const mcpConfigPath = selectMcpConfig(squadName, squad);
2365
2673
  const execContext = {
2366
2674
  squad: squadName,
2367
2675
  agent: agentName,
@@ -2532,8 +2840,8 @@ async function listCommand(options) {
2532
2840
  }
2533
2841
 
2534
2842
  // src/commands/status.ts
2535
- import { existsSync as existsSync5, statSync } from "fs";
2536
- import { join as join5 } from "path";
2843
+ import { existsSync as existsSync6, statSync } from "fs";
2844
+ import { join as join6 } from "path";
2537
2845
  async function statusCommand(squadName, options = {}) {
2538
2846
  await track(Events.CLI_STATUS, { squad: squadName || "all", verbose: options.verbose });
2539
2847
  const squadsDir = findSquadsDir();
@@ -2586,8 +2894,8 @@ async function showOverallStatus(squadsDir, _options) {
2586
2894
  let lastActivity = `${colors.dim}\u2014${RESET}`;
2587
2895
  let activityColor = colors.dim;
2588
2896
  if (memoryDir) {
2589
- const squadMemoryPath = join5(memoryDir, squadName);
2590
- if (existsSync5(squadMemoryPath)) {
2897
+ const squadMemoryPath = join6(memoryDir, squadName);
2898
+ if (existsSync6(squadMemoryPath)) {
2591
2899
  const states = getSquadState(squadName);
2592
2900
  memoryStatus = `${colors.green}${states.length} ${states.length === 1 ? "entry" : "entries"}${RESET}`;
2593
2901
  let mostRecent = 0;
@@ -2689,14 +2997,14 @@ async function showSquadStatus(squadName, squadsDir, options) {
2689
2997
  }
2690
2998
 
2691
2999
  // src/commands/stack.ts
2692
- import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, copyFileSync } from "fs";
2693
- import { join as join6, dirname as dirname2 } from "path";
3000
+ import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, copyFileSync } from "fs";
3001
+ import { join as join7, dirname as dirname3 } from "path";
2694
3002
  import { homedir as homedir2 } from "os";
2695
3003
  import { execSync as execSync3, spawn as spawn3 } from "child_process";
2696
3004
  import { createInterface as createInterface2 } from "readline";
2697
3005
  import { fileURLToPath } from "url";
2698
3006
  var __filename2 = fileURLToPath(import.meta.url);
2699
- var __dirname2 = dirname2(__filename2);
3007
+ var __dirname2 = dirname3(__filename2);
2700
3008
  var DEFAULT_CONFIG = {
2701
3009
  SQUADS_DATABASE_URL: "postgresql://squads:squads@localhost:5433/squads",
2702
3010
  SQUADS_BRIDGE_URL: "http://localhost:8088",
@@ -2705,8 +3013,8 @@ var DEFAULT_CONFIG = {
2705
3013
  LANGFUSE_SECRET_KEY: "",
2706
3014
  REDIS_URL: "redis://localhost:6379"
2707
3015
  };
2708
- var CONFIG_PATH2 = join6(homedir2(), ".squadsrc");
2709
- var SQUADS_DATA_DIR = join6(homedir2(), ".squads");
3016
+ var CONFIG_PATH2 = join7(homedir2(), ".squadsrc");
3017
+ var SQUADS_DATA_DIR = join7(homedir2(), ".squads");
2710
3018
  var SERVICES = {
2711
3019
  bridge: {
2712
3020
  name: "Bridge API",
@@ -2840,25 +3148,25 @@ async function confirm2(question, defaultYes = true) {
2840
3148
  function findPackageDockerDir() {
2841
3149
  const candidates = [
2842
3150
  // From npm package (relative to dist/commands/stack.js)
2843
- join6(__dirname2, "..", "..", "docker"),
3151
+ join7(__dirname2, "..", "..", "docker"),
2844
3152
  // Local development
2845
- join6(process.cwd(), "docker"),
2846
- join6(process.cwd(), "..", "squads-cli", "docker"),
2847
- join6(homedir2(), "agents-squads", "squads-cli", "docker")
3153
+ join7(process.cwd(), "docker"),
3154
+ join7(process.cwd(), "..", "squads-cli", "docker"),
3155
+ join7(homedir2(), "agents-squads", "squads-cli", "docker")
2848
3156
  ];
2849
3157
  for (const dir of candidates) {
2850
- if (existsSync6(join6(dir, "docker-compose.yml"))) {
3158
+ if (existsSync7(join7(dir, "docker-compose.yml"))) {
2851
3159
  return dir;
2852
3160
  }
2853
3161
  }
2854
3162
  return null;
2855
3163
  }
2856
3164
  function loadStackConfig() {
2857
- if (!existsSync6(CONFIG_PATH2)) {
3165
+ if (!existsSync7(CONFIG_PATH2)) {
2858
3166
  return null;
2859
3167
  }
2860
3168
  try {
2861
- const content = readFileSync4(CONFIG_PATH2, "utf-8");
3169
+ const content = readFileSync5(CONFIG_PATH2, "utf-8");
2862
3170
  const config2 = {};
2863
3171
  for (const line of content.split("\n")) {
2864
3172
  const trimmed = line.trim();
@@ -2899,7 +3207,7 @@ function saveStackConfig(config2) {
2899
3207
  "# To activate: source ~/.squadsrc",
2900
3208
  ""
2901
3209
  ];
2902
- writeFileSync4(CONFIG_PATH2, lines.join("\n"));
3210
+ writeFileSync5(CONFIG_PATH2, lines.join("\n"));
2903
3211
  }
2904
3212
  function applyStackConfig() {
2905
3213
  const config2 = loadStackConfig();
@@ -2971,13 +3279,13 @@ async function checkService(url, timeout = 2e3) {
2971
3279
  }
2972
3280
  function getLangfuseKeysFromDockerEnv() {
2973
3281
  const envPaths2 = [
2974
- join6(process.cwd(), "docker", ".env"),
2975
- join6(process.cwd(), "..", "squads-cli", "docker", ".env"),
2976
- join6(homedir2(), "agents-squads", "squads-cli", "docker", ".env")
3282
+ join7(process.cwd(), "docker", ".env"),
3283
+ join7(process.cwd(), "..", "squads-cli", "docker", ".env"),
3284
+ join7(homedir2(), "agents-squads", "squads-cli", "docker", ".env")
2977
3285
  ];
2978
3286
  for (const envPath of envPaths2) {
2979
- if (existsSync6(envPath)) {
2980
- const content = readFileSync4(envPath, "utf-8");
3287
+ if (existsSync7(envPath)) {
3288
+ const content = readFileSync5(envPath, "utf-8");
2981
3289
  const publicMatch = content.match(/LANGFUSE_PUBLIC_KEY=(\S+)/);
2982
3290
  const secretMatch = content.match(/LANGFUSE_SECRET_KEY=(\S+)/);
2983
3291
  if (publicMatch && secretMatch) {
@@ -2992,12 +3300,12 @@ function getLangfuseKeysFromDockerEnv() {
2992
3300
  }
2993
3301
  function findDockerComposeDir() {
2994
3302
  const candidates = [
2995
- join6(process.cwd(), "docker"),
2996
- join6(process.cwd(), "..", "squads-cli", "docker"),
2997
- join6(homedir2(), "agents-squads", "squads-cli", "docker")
3303
+ join7(process.cwd(), "docker"),
3304
+ join7(process.cwd(), "..", "squads-cli", "docker"),
3305
+ join7(homedir2(), "agents-squads", "squads-cli", "docker")
2998
3306
  ];
2999
3307
  for (const dir of candidates) {
3000
- if (existsSync6(join6(dir, "docker-compose.yml"))) {
3308
+ if (existsSync7(join7(dir, "docker-compose.yml"))) {
3001
3309
  return dir;
3002
3310
  }
3003
3311
  }
@@ -3023,7 +3331,7 @@ async function stackInitCommand() {
3023
3331
  writeLine();
3024
3332
  writeLine(` ${bold}Step 2: Docker Compose Files${RESET}`);
3025
3333
  let composeDir = findPackageDockerDir();
3026
- const targetDir = join6(SQUADS_DATA_DIR, "docker");
3334
+ const targetDir = join7(SQUADS_DATA_DIR, "docker");
3027
3335
  if (!composeDir) {
3028
3336
  writeLine(` ${colors.red}${icons.error}${RESET} Docker compose files not found`);
3029
3337
  writeLine(` ${colors.dim}This shouldn't happen if you installed via npm.${RESET}`);
@@ -3031,20 +3339,20 @@ async function stackInitCommand() {
3031
3339
  writeLine();
3032
3340
  return;
3033
3341
  }
3034
- if (composeDir !== targetDir && !existsSync6(targetDir)) {
3342
+ if (composeDir !== targetDir && !existsSync7(targetDir)) {
3035
3343
  writeLine(` ${colors.cyan}${icons.progress}${RESET} Copying docker files to ${colors.dim}~/.squads/docker${RESET}`);
3036
3344
  try {
3037
- mkdirSync3(SQUADS_DATA_DIR, { recursive: true });
3038
- mkdirSync3(targetDir, { recursive: true });
3345
+ mkdirSync4(SQUADS_DATA_DIR, { recursive: true });
3346
+ mkdirSync4(targetDir, { recursive: true });
3039
3347
  const filesToCopy = [
3040
3348
  "docker-compose.yml",
3041
3349
  "docker-compose.engram.yml",
3042
3350
  ".env.example"
3043
3351
  ];
3044
3352
  for (const file of filesToCopy) {
3045
- const src = join6(composeDir, file);
3046
- const dst = join6(targetDir, file);
3047
- if (existsSync6(src)) {
3353
+ const src = join7(composeDir, file);
3354
+ const dst = join7(targetDir, file);
3355
+ if (existsSync7(src)) {
3048
3356
  copyFileSync(src, dst);
3049
3357
  }
3050
3358
  }
@@ -3053,7 +3361,7 @@ async function stackInitCommand() {
3053
3361
  } catch {
3054
3362
  writeLine(` ${colors.yellow}${icons.warning}${RESET} Could not copy files, using source location`);
3055
3363
  }
3056
- } else if (existsSync6(targetDir)) {
3364
+ } else if (existsSync7(targetDir)) {
3057
3365
  composeDir = targetDir;
3058
3366
  writeLine(` ${colors.green}${icons.success}${RESET} Using ${colors.dim}~/.squads/docker${RESET}`);
3059
3367
  } else {
@@ -3061,10 +3369,10 @@ async function stackInitCommand() {
3061
3369
  }
3062
3370
  writeLine();
3063
3371
  writeLine(` ${bold}Step 3: Environment Configuration${RESET}`);
3064
- const envPath = join6(composeDir, ".env");
3065
- const envExamplePath = join6(composeDir, ".env.example");
3066
- if (!existsSync6(envPath)) {
3067
- if (existsSync6(envExamplePath)) {
3372
+ const envPath = join7(composeDir, ".env");
3373
+ const envExamplePath = join7(composeDir, ".env.example");
3374
+ if (!existsSync7(envPath)) {
3375
+ if (existsSync7(envExamplePath)) {
3068
3376
  copyFileSync(envExamplePath, envPath);
3069
3377
  writeLine(` ${colors.cyan}${icons.progress}${RESET} Created .env from template`);
3070
3378
  } else {
@@ -3093,13 +3401,13 @@ LANGFUSE_PORT=3100
3093
3401
  OTEL_PORT=4318
3094
3402
  BRIDGE_PORT=8088
3095
3403
  `;
3096
- writeFileSync4(envPath, minimalEnv);
3404
+ writeFileSync5(envPath, minimalEnv);
3097
3405
  writeLine(` ${colors.cyan}${icons.progress}${RESET} Created default .env`);
3098
3406
  }
3099
3407
  } else {
3100
3408
  writeLine(` ${colors.green}${icons.success}${RESET} .env exists`);
3101
3409
  }
3102
- const envContent = readFileSync4(envPath, "utf-8");
3410
+ const envContent = readFileSync5(envPath, "utf-8");
3103
3411
  const missingSecrets = [];
3104
3412
  const llmProvider = envContent.match(/LLM_PROVIDER=(\w+)/)?.[1] || "ollama";
3105
3413
  if (llmProvider === "openai") {
@@ -3779,8 +4087,8 @@ async function memoryExtractCommand(options = {}) {
3779
4087
 
3780
4088
  // src/commands/sync.ts
3781
4089
  import { execSync as execSync4 } from "child_process";
3782
- import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, readdirSync as readdirSync2 } from "fs";
3783
- import { join as join7 } from "path";
4090
+ import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, readdirSync as readdirSync2 } from "fs";
4091
+ import { join as join8 } from "path";
3784
4092
  var PATH_TO_SQUAD = {
3785
4093
  "squads-cli": "product",
3786
4094
  "agents-squads-web": "website",
@@ -3808,15 +4116,15 @@ var MESSAGE_TO_SQUAD = {
3808
4116
  "infra": "engineering"
3809
4117
  };
3810
4118
  function getLastSyncTime(memoryDir) {
3811
- const syncFile = join7(memoryDir, ".last-sync");
3812
- if (existsSync7(syncFile)) {
3813
- return readFileSync5(syncFile, "utf-8").trim();
4119
+ const syncFile = join8(memoryDir, ".last-sync");
4120
+ if (existsSync8(syncFile)) {
4121
+ return readFileSync6(syncFile, "utf-8").trim();
3814
4122
  }
3815
4123
  return null;
3816
4124
  }
3817
4125
  function updateLastSyncTime(memoryDir) {
3818
- const syncFile = join7(memoryDir, ".last-sync");
3819
- writeFileSync5(syncFile, (/* @__PURE__ */ new Date()).toISOString());
4126
+ const syncFile = join8(memoryDir, ".last-sync");
4127
+ writeFileSync6(syncFile, (/* @__PURE__ */ new Date()).toISOString());
3820
4128
  }
3821
4129
  function getRecentCommits(since) {
3822
4130
  const commits = [];
@@ -3888,22 +4196,22 @@ ${messages}
3888
4196
  `;
3889
4197
  }
3890
4198
  function appendToSquadMemory(memoryDir, squad, summary) {
3891
- const squadMemoryDir = join7(memoryDir, squad);
3892
- if (!existsSync7(squadMemoryDir)) {
3893
- mkdirSync4(squadMemoryDir, { recursive: true });
4199
+ const squadMemoryDir = join8(memoryDir, squad);
4200
+ if (!existsSync8(squadMemoryDir)) {
4201
+ mkdirSync5(squadMemoryDir, { recursive: true });
3894
4202
  }
3895
4203
  let agentDir;
3896
- const existingDirs = existsSync7(squadMemoryDir) ? readdirSync2(squadMemoryDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name) : [];
4204
+ const existingDirs = existsSync8(squadMemoryDir) ? readdirSync2(squadMemoryDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name) : [];
3897
4205
  if (existingDirs.length > 0) {
3898
- agentDir = join7(squadMemoryDir, existingDirs[0]);
4206
+ agentDir = join8(squadMemoryDir, existingDirs[0]);
3899
4207
  } else {
3900
- agentDir = join7(squadMemoryDir, `${squad}-lead`);
3901
- mkdirSync4(agentDir, { recursive: true });
4208
+ agentDir = join8(squadMemoryDir, `${squad}-lead`);
4209
+ mkdirSync5(agentDir, { recursive: true });
3902
4210
  }
3903
- const statePath = join7(agentDir, "state.md");
4211
+ const statePath = join8(agentDir, "state.md");
3904
4212
  let content = "";
3905
- if (existsSync7(statePath)) {
3906
- content = readFileSync5(statePath, "utf-8");
4213
+ if (existsSync8(statePath)) {
4214
+ content = readFileSync6(statePath, "utf-8");
3907
4215
  } else {
3908
4216
  content = `# ${squad} Squad - State
3909
4217
 
@@ -3915,7 +4223,7 @@ Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
3915
4223
  `Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`
3916
4224
  );
3917
4225
  content += summary;
3918
- writeFileSync5(statePath, content);
4226
+ writeFileSync6(statePath, content);
3919
4227
  return true;
3920
4228
  }
3921
4229
  function gitPullMemory() {
@@ -4192,28 +4500,28 @@ async function goalProgressCommand(squadName, goalIndex, progress2) {
4192
4500
  }
4193
4501
 
4194
4502
  // src/commands/feedback.ts
4195
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync3 } from "fs";
4196
- import { join as join8, dirname as dirname3 } from "path";
4503
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync7, existsSync as existsSync9, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
4504
+ import { join as join9, dirname as dirname4 } from "path";
4197
4505
  function getFeedbackPath(squadName) {
4198
4506
  const memoryDir = findMemoryDir();
4199
4507
  if (!memoryDir) return null;
4200
4508
  const squad = loadSquad(squadName);
4201
4509
  const agentName = squad?.agents[0]?.name || `${squadName}-lead`;
4202
- return join8(memoryDir, squadName, agentName, "feedback.md");
4510
+ return join9(memoryDir, squadName, agentName, "feedback.md");
4203
4511
  }
4204
4512
  function getOutputPath(squadName) {
4205
4513
  const memoryDir = findMemoryDir();
4206
4514
  if (!memoryDir) return null;
4207
4515
  const squad = loadSquad(squadName);
4208
4516
  const agentName = squad?.agents[0]?.name || `${squadName}-lead`;
4209
- return join8(memoryDir, squadName, agentName, "output.md");
4517
+ return join9(memoryDir, squadName, agentName, "output.md");
4210
4518
  }
4211
4519
  function getLastExecution(squadName) {
4212
4520
  const outputPath = getOutputPath(squadName);
4213
- if (!outputPath || !existsSync8(outputPath)) {
4521
+ if (!outputPath || !existsSync9(outputPath)) {
4214
4522
  return null;
4215
4523
  }
4216
- const content = readFileSync6(outputPath, "utf-8");
4524
+ const content = readFileSync7(outputPath, "utf-8");
4217
4525
  const lines = content.split("\n");
4218
4526
  let date = "unknown";
4219
4527
  let summary = lines.slice(0, 5).join("\n");
@@ -4265,9 +4573,9 @@ async function feedbackAddCommand(squadName, rating, feedback2, options) {
4265
4573
  return;
4266
4574
  }
4267
4575
  const lastExec = getLastExecution(squadName);
4268
- const dir = dirname3(feedbackPath);
4269
- if (!existsSync8(dir)) {
4270
- mkdirSync5(dir, { recursive: true });
4576
+ const dir = dirname4(feedbackPath);
4577
+ if (!existsSync9(dir)) {
4578
+ mkdirSync6(dir, { recursive: true });
4271
4579
  }
4272
4580
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
4273
4581
  let entry = `
@@ -4295,15 +4603,15 @@ _Date: ${date}_
4295
4603
  }
4296
4604
  }
4297
4605
  let existing = "";
4298
- if (existsSync8(feedbackPath)) {
4299
- existing = readFileSync6(feedbackPath, "utf-8");
4606
+ if (existsSync9(feedbackPath)) {
4607
+ existing = readFileSync7(feedbackPath, "utf-8");
4300
4608
  } else {
4301
4609
  existing = `# ${squadName} - Feedback Log
4302
4610
 
4303
4611
  > Execution feedback and learnings
4304
4612
  `;
4305
4613
  }
4306
- writeFileSync6(feedbackPath, existing + entry);
4614
+ writeFileSync7(feedbackPath, existing + entry);
4307
4615
  const stars = `${colors.yellow}${"\u2605".repeat(ratingNum)}${"\u2606".repeat(5 - ratingNum)}${RESET}`;
4308
4616
  writeLine();
4309
4617
  writeLine(` ${icons.success} Feedback recorded for ${colors.cyan}${squadName}${RESET}`);
@@ -4317,11 +4625,11 @@ _Date: ${date}_
4317
4625
  async function feedbackShowCommand(squadName, options) {
4318
4626
  await track(Events.CLI_FEEDBACK_SHOW, { squad: squadName });
4319
4627
  const feedbackPath = getFeedbackPath(squadName);
4320
- if (!feedbackPath || !existsSync8(feedbackPath)) {
4628
+ if (!feedbackPath || !existsSync9(feedbackPath)) {
4321
4629
  writeLine(` ${colors.yellow}No feedback recorded for ${squadName}${RESET}`);
4322
4630
  return;
4323
4631
  }
4324
- const content = readFileSync6(feedbackPath, "utf-8");
4632
+ const content = readFileSync7(feedbackPath, "utf-8");
4325
4633
  const entries = parseFeedbackHistory(content);
4326
4634
  const limit = options.limit ? parseInt(options.limit) : 5;
4327
4635
  const recent = entries.slice(-limit).reverse();
@@ -4366,10 +4674,10 @@ async function feedbackStatsCommand() {
4366
4674
  writeLine(` ${colors.purple}${box.teeRight}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.teeLeft}${RESET}`);
4367
4675
  for (const squad of squads) {
4368
4676
  const feedbackPath = getFeedbackPath(squad);
4369
- if (!feedbackPath || !existsSync8(feedbackPath)) {
4677
+ if (!feedbackPath || !existsSync9(feedbackPath)) {
4370
4678
  continue;
4371
4679
  }
4372
- const content = readFileSync6(feedbackPath, "utf-8");
4680
+ const content = readFileSync7(feedbackPath, "utf-8");
4373
4681
  const entries = parseFeedbackHistory(content);
4374
4682
  if (entries.length === 0) continue;
4375
4683
  const avgRating = entries.reduce((sum, e) => sum + e.rating, 0) / entries.length;
@@ -4391,9 +4699,252 @@ async function feedbackStatsCommand() {
4391
4699
  writeLine();
4392
4700
  }
4393
4701
 
4702
+ // src/commands/learn.ts
4703
+ import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "fs";
4704
+ import { join as join10, dirname as dirname5 } from "path";
4705
+ function parseLearnings(content) {
4706
+ const learnings = [];
4707
+ const sections = content.split(/\n---\n/).filter((s) => s.trim());
4708
+ for (const section of sections) {
4709
+ if (section.startsWith("#")) continue;
4710
+ const dateMatch = section.match(/_(\d{4}-\d{2}-\d{2})_/);
4711
+ const categoryMatch = section.match(/\*\*(\w+)\*\*:/);
4712
+ const tagsMatch = section.match(/Tags: `([^`]+)`/);
4713
+ const lines = section.split("\n").filter((l) => l.trim() && !l.startsWith("_") && !l.includes("Tags:"));
4714
+ const insight = lines.map((l) => l.replace(/^\*\*\w+\*\*:\s*/, "")).join(" ").trim();
4715
+ if (dateMatch && insight) {
4716
+ learnings.push({
4717
+ date: dateMatch[1],
4718
+ insight,
4719
+ category: categoryMatch?.[1]?.toLowerCase() || "tip",
4720
+ tags: tagsMatch?.[1]?.split(",").map((t) => t.trim()) || []
4721
+ });
4722
+ }
4723
+ }
4724
+ return learnings;
4725
+ }
4726
+ function formatLearning(learning) {
4727
+ const categoryEmoji = {
4728
+ success: "\u25CF",
4729
+ failure: "\u2717",
4730
+ pattern: "\u25C6",
4731
+ tip: "\u2192"
4732
+ };
4733
+ let entry = `
4734
+ ---
4735
+ _${learning.date}_
4736
+
4737
+ `;
4738
+ entry += `${categoryEmoji[learning.category]} **${learning.category.charAt(0).toUpperCase() + learning.category.slice(1)}**: ${learning.insight}
4739
+ `;
4740
+ if (learning.tags.length > 0) {
4741
+ entry += `Tags: \`${learning.tags.join(", ")}\`
4742
+ `;
4743
+ }
4744
+ if (learning.context) {
4745
+ entry += `
4746
+ _Context: ${learning.context}_
4747
+ `;
4748
+ }
4749
+ return entry;
4750
+ }
4751
+ async function learnCommand(insight, options) {
4752
+ let squadName = options.squad || "general";
4753
+ if (options.squad) {
4754
+ const squadsDir = findSquadsDir();
4755
+ if (squadsDir) {
4756
+ const squads = listSquads(squadsDir);
4757
+ if (!squads.includes(options.squad)) {
4758
+ writeLine();
4759
+ writeLine(` ${colors.yellow}${icons.warning} Squad '${options.squad}' not found${RESET}`);
4760
+ writeLine(` ${colors.dim}Available: ${squads.join(", ")}${RESET}`);
4761
+ writeLine(` ${colors.dim}Using 'general' instead${RESET}`);
4762
+ squadName = "general";
4763
+ }
4764
+ }
4765
+ }
4766
+ const tags = options.tags ? options.tags.split(",").map((t) => t.trim().toLowerCase()) : [];
4767
+ if (tags.length === 0) {
4768
+ const autoTags = extractTags(insight);
4769
+ tags.push(...autoTags);
4770
+ }
4771
+ const category = options.category || inferCategory(insight);
4772
+ const learning = {
4773
+ date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
4774
+ insight,
4775
+ category,
4776
+ tags,
4777
+ squad: squadName,
4778
+ context: options.context
4779
+ };
4780
+ const memoryDir = findMemoryDir();
4781
+ if (!memoryDir) {
4782
+ writeLine(` ${colors.red}No .agents/memory directory found${RESET}`);
4783
+ writeLine(` ${colors.dim}Run 'squads init' first${RESET}`);
4784
+ return;
4785
+ }
4786
+ const learningsPath = join10(memoryDir, squadName, "shared", "learnings.md");
4787
+ const dir = dirname5(learningsPath);
4788
+ if (!existsSync10(dir)) {
4789
+ mkdirSync7(dir, { recursive: true });
4790
+ }
4791
+ let content = "";
4792
+ if (existsSync10(learningsPath)) {
4793
+ content = readFileSync8(learningsPath, "utf-8");
4794
+ } else {
4795
+ content = `# ${squadName} - Learnings
4796
+
4797
+ > Accumulated knowledge from sessions
4798
+ `;
4799
+ }
4800
+ content += formatLearning(learning);
4801
+ writeFileSync8(learningsPath, content);
4802
+ await track(Events.CLI_LEARN, {
4803
+ squad: squadName,
4804
+ category,
4805
+ tagCount: tags.length
4806
+ });
4807
+ writeLine();
4808
+ writeLine(` ${icons.success} Learning captured for ${colors.cyan}${squadName}${RESET}`);
4809
+ writeLine();
4810
+ writeLine(` ${colors.dim}Category:${RESET} ${category}`);
4811
+ if (tags.length > 0) {
4812
+ writeLine(` ${colors.dim}Tags:${RESET} ${tags.map((t) => `#${t}`).join(" ")}`);
4813
+ }
4814
+ writeLine();
4815
+ writeLine(` ${colors.green}${insight}${RESET}`);
4816
+ writeLine();
4817
+ }
4818
+ async function learnShowCommand(squadName, options) {
4819
+ const memoryDir = findMemoryDir();
4820
+ if (!memoryDir) {
4821
+ writeLine(` ${colors.red}No memory directory found${RESET}`);
4822
+ return;
4823
+ }
4824
+ const learningsPath = join10(memoryDir, squadName, "shared", "learnings.md");
4825
+ if (!existsSync10(learningsPath)) {
4826
+ writeLine(` ${colors.yellow}No learnings recorded for ${squadName}${RESET}`);
4827
+ writeLine(` ${colors.dim}Add one: squads learn "insight" --squad ${squadName}${RESET}`);
4828
+ return;
4829
+ }
4830
+ const content = readFileSync8(learningsPath, "utf-8");
4831
+ const learnings = parseLearnings(content);
4832
+ let filtered = learnings;
4833
+ if (options.category) {
4834
+ filtered = filtered.filter((l) => l.category === options.category);
4835
+ }
4836
+ if (options.tag) {
4837
+ const tag = options.tag.toLowerCase();
4838
+ filtered = filtered.filter((l) => l.tags.includes(tag));
4839
+ }
4840
+ const limit = options.limit ? parseInt(options.limit) : 10;
4841
+ const recent = filtered.slice(-limit).reverse();
4842
+ await track(Events.CLI_LEARN_SHOW, { squad: squadName });
4843
+ writeLine();
4844
+ writeLine(` ${gradient("squads")} ${colors.dim}learnings${RESET} ${colors.cyan}${squadName}${RESET}`);
4845
+ writeLine();
4846
+ if (recent.length === 0) {
4847
+ writeLine(` ${colors.dim}No learnings found${RESET}`);
4848
+ return;
4849
+ }
4850
+ writeLine(` ${colors.dim}Showing ${recent.length} of ${filtered.length} learnings${RESET}`);
4851
+ writeLine();
4852
+ const categoryIcon = {
4853
+ success: `${colors.green}${icons.success}${RESET}`,
4854
+ failure: `${colors.red}\u2717${RESET}`,
4855
+ pattern: `${colors.purple}\u25C6${RESET}`,
4856
+ tip: `${colors.cyan}\u2192${RESET}`
4857
+ };
4858
+ for (const learning of recent) {
4859
+ writeLine(` ${colors.dim}${learning.date}${RESET} ${categoryIcon[learning.category]} ${learning.insight}`);
4860
+ if (learning.tags.length > 0) {
4861
+ writeLine(` ${colors.dim}${learning.tags.map((t) => `#${t}`).join(" ")}${RESET}`);
4862
+ }
4863
+ }
4864
+ writeLine();
4865
+ }
4866
+ async function learnSearchCommand(query, options) {
4867
+ const memoryDir = findMemoryDir();
4868
+ if (!memoryDir) {
4869
+ writeLine(` ${colors.red}No memory directory found${RESET}`);
4870
+ return;
4871
+ }
4872
+ const squadsDir = findSquadsDir();
4873
+ const squads = squadsDir ? listSquads(squadsDir) : [];
4874
+ squads.push("general");
4875
+ const allLearnings = [];
4876
+ for (const squad of squads) {
4877
+ const learningsPath = join10(memoryDir, squad, "shared", "learnings.md");
4878
+ if (existsSync10(learningsPath)) {
4879
+ const content = readFileSync8(learningsPath, "utf-8");
4880
+ const learnings = parseLearnings(content);
4881
+ allLearnings.push(...learnings.map((l) => ({ ...l, squad })));
4882
+ }
4883
+ }
4884
+ const queryLower = query.toLowerCase();
4885
+ const matches = allLearnings.filter(
4886
+ (l) => l.insight.toLowerCase().includes(queryLower) || l.tags.some((t) => t.includes(queryLower))
4887
+ );
4888
+ await track(Events.CLI_LEARN_SEARCH, { query, matches: matches.length });
4889
+ writeLine();
4890
+ writeLine(` ${gradient("squads")} ${colors.dim}search learnings${RESET} "${query}"`);
4891
+ writeLine();
4892
+ const limit = options.limit ? parseInt(options.limit) : 10;
4893
+ const limited = matches.slice(0, limit);
4894
+ if (limited.length === 0) {
4895
+ writeLine(` ${colors.dim}No learnings found matching "${query}"${RESET}`);
4896
+ return;
4897
+ }
4898
+ writeLine(` ${colors.dim}Found ${matches.length} matches${RESET}`);
4899
+ writeLine();
4900
+ const categoryIcon = {
4901
+ success: `${colors.green}${icons.success}${RESET}`,
4902
+ failure: `${colors.red}\u2717${RESET}`,
4903
+ pattern: `${colors.purple}\u25C6${RESET}`,
4904
+ tip: `${colors.cyan}\u2192${RESET}`
4905
+ };
4906
+ for (const learning of limited) {
4907
+ writeLine(` ${colors.cyan}${learning.squad}${RESET} ${categoryIcon[learning.category]} ${learning.insight}`);
4908
+ }
4909
+ writeLine();
4910
+ }
4911
+ function extractTags(insight) {
4912
+ const tags = [];
4913
+ const lowerInsight = insight.toLowerCase();
4914
+ const patterns = {
4915
+ "auth": ["auth", "login", "token", "session", "password"],
4916
+ "api": ["api", "endpoint", "request", "response", "rest"],
4917
+ "bug": ["bug", "fix", "error", "issue", "crash"],
4918
+ "perf": ["performance", "slow", "fast", "optimize", "cache"],
4919
+ "ux": ["user", "ui", "interface", "design", "experience"],
4920
+ "test": ["test", "spec", "coverage", "assert"],
4921
+ "db": ["database", "query", "sql", "postgres", "redis"],
4922
+ "deploy": ["deploy", "release", "production", "staging"]
4923
+ };
4924
+ for (const [tag, keywords] of Object.entries(patterns)) {
4925
+ if (keywords.some((kw) => lowerInsight.includes(kw))) {
4926
+ tags.push(tag);
4927
+ }
4928
+ }
4929
+ return tags.slice(0, 3);
4930
+ }
4931
+ function inferCategory(insight) {
4932
+ const lower = insight.toLowerCase();
4933
+ if (lower.includes("worked") || lower.includes("success") || lower.includes("fixed")) {
4934
+ return "success";
4935
+ }
4936
+ if (lower.includes("failed") || lower.includes("error") || lower.includes("didn't work")) {
4937
+ return "failure";
4938
+ }
4939
+ if (lower.includes("pattern") || lower.includes("always") || lower.includes("whenever")) {
4940
+ return "pattern";
4941
+ }
4942
+ return "tip";
4943
+ }
4944
+
4394
4945
  // src/commands/dashboard.ts
4395
- import { readdirSync as readdirSync4, existsSync as existsSync9, statSync as statSync2 } from "fs";
4396
- import { join as join9 } from "path";
4946
+ import { readdirSync as readdirSync4, existsSync as existsSync11, statSync as statSync2 } from "fs";
4947
+ import { join as join11 } from "path";
4397
4948
 
4398
4949
  // src/lib/providers.ts
4399
4950
  var PROVIDERS = {
@@ -5252,16 +5803,16 @@ async function closeDatabase() {
5252
5803
  function getLastActivityDate(squadName) {
5253
5804
  const memoryDir = findMemoryDir();
5254
5805
  if (!memoryDir) return "unknown";
5255
- const squadMemory = join9(memoryDir, squadName);
5256
- if (!existsSync9(squadMemory)) return "\u2014";
5806
+ const squadMemory = join11(memoryDir, squadName);
5807
+ if (!existsSync11(squadMemory)) return "\u2014";
5257
5808
  let latestTime = 0;
5258
5809
  try {
5259
5810
  const agents = readdirSync4(squadMemory, { withFileTypes: true }).filter((e) => e.isDirectory());
5260
5811
  for (const agent of agents) {
5261
- const agentPath = join9(squadMemory, agent.name);
5812
+ const agentPath = join11(squadMemory, agent.name);
5262
5813
  const files = readdirSync4(agentPath).filter((f) => f.endsWith(".md"));
5263
5814
  for (const file of files) {
5264
- const filePath = join9(agentPath, file);
5815
+ const filePath = join11(agentPath, file);
5265
5816
  const stats = statSync2(filePath);
5266
5817
  if (stats.mtimeMs > latestTime) {
5267
5818
  latestTime = stats.mtimeMs;
@@ -5508,11 +6059,11 @@ async function dashboardCommand(options = {}) {
5508
6059
  await closeDatabase();
5509
6060
  }
5510
6061
  function findAgentsSquadsDir() {
5511
- const parentDir = join9(process.cwd(), "..");
5512
- if (existsSync9(join9(parentDir, "hq"))) {
6062
+ const parentDir = join11(process.cwd(), "..");
6063
+ if (existsSync11(join11(parentDir, "hq"))) {
5513
6064
  return parentDir;
5514
6065
  }
5515
- if (existsSync9(join9(process.cwd(), ".git"))) {
6066
+ if (existsSync11(join11(process.cwd(), ".git"))) {
5516
6067
  return process.cwd();
5517
6068
  }
5518
6069
  return null;
@@ -6151,7 +6702,7 @@ function executeClaudePrompt(prompt2) {
6151
6702
  // src/commands/open-issues.ts
6152
6703
  import { execSync as execSync7, spawn as spawn5 } from "child_process";
6153
6704
  import { readdirSync as readdirSync5 } from "fs";
6154
- import { join as join10 } from "path";
6705
+ import { join as join12 } from "path";
6155
6706
  import ora4 from "ora";
6156
6707
  var ISSUE_FINDER_PATTERNS = [
6157
6708
  "*-eval.md",
@@ -6209,7 +6760,7 @@ function findEvalAgents(squadsDir, filterSquad) {
6209
6760
  const agents = [];
6210
6761
  const squads = readdirSync5(squadsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).filter((d) => !filterSquad || d.name === filterSquad).map((d) => d.name);
6211
6762
  for (const squad of squads) {
6212
- const squadPath = join10(squadsDir, squad);
6763
+ const squadPath = join12(squadsDir, squad);
6213
6764
  const files = readdirSync5(squadPath).filter((f) => f.endsWith(".md"));
6214
6765
  for (const file of files) {
6215
6766
  const isEval = ISSUE_FINDER_PATTERNS.some((pattern) => {
@@ -6220,7 +6771,7 @@ function findEvalAgents(squadsDir, filterSquad) {
6220
6771
  agents.push({
6221
6772
  name: file,
6222
6773
  squad,
6223
- path: join10(squadPath, file)
6774
+ path: join12(squadPath, file)
6224
6775
  });
6225
6776
  }
6226
6777
  }
@@ -6330,8 +6881,8 @@ import open from "open";
6330
6881
 
6331
6882
  // src/lib/auth.ts
6332
6883
  import { createClient } from "@supabase/supabase-js";
6333
- import { existsSync as existsSync10, readFileSync as readFileSync7, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6 } from "fs";
6334
- import { join as join11 } from "path";
6884
+ import { existsSync as existsSync12, readFileSync as readFileSync9, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8 } from "fs";
6885
+ import { join as join13 } from "path";
6335
6886
  import { homedir as homedir3 } from "os";
6336
6887
  import "open";
6337
6888
  import http from "http";
@@ -6361,8 +6912,8 @@ var PERSONAL_DOMAINS = [
6361
6912
  "tutanota.com",
6362
6913
  "hey.com"
6363
6914
  ];
6364
- var AUTH_DIR = join11(homedir3(), ".squads-cli");
6365
- var AUTH_PATH = join11(AUTH_DIR, "auth.json");
6915
+ var AUTH_DIR = join13(homedir3(), ".squads-cli");
6916
+ var AUTH_PATH = join13(AUTH_DIR, "auth.json");
6366
6917
  function isPersonalEmail(email) {
6367
6918
  const domain = email.split("@")[1]?.toLowerCase();
6368
6919
  return PERSONAL_DOMAINS.includes(domain);
@@ -6371,22 +6922,22 @@ function getEmailDomain(email) {
6371
6922
  return email.split("@")[1]?.toLowerCase() || "";
6372
6923
  }
6373
6924
  function saveSession(session2) {
6374
- if (!existsSync10(AUTH_DIR)) {
6375
- mkdirSync6(AUTH_DIR, { recursive: true });
6925
+ if (!existsSync12(AUTH_DIR)) {
6926
+ mkdirSync8(AUTH_DIR, { recursive: true });
6376
6927
  }
6377
- writeFileSync7(AUTH_PATH, JSON.stringify(session2, null, 2));
6928
+ writeFileSync9(AUTH_PATH, JSON.stringify(session2, null, 2));
6378
6929
  }
6379
6930
  function loadSession() {
6380
- if (!existsSync10(AUTH_PATH)) return null;
6931
+ if (!existsSync12(AUTH_PATH)) return null;
6381
6932
  try {
6382
- return JSON.parse(readFileSync7(AUTH_PATH, "utf-8"));
6933
+ return JSON.parse(readFileSync9(AUTH_PATH, "utf-8"));
6383
6934
  } catch {
6384
6935
  return null;
6385
6936
  }
6386
6937
  }
6387
6938
  function clearSession() {
6388
- if (existsSync10(AUTH_PATH)) {
6389
- writeFileSync7(AUTH_PATH, "");
6939
+ if (existsSync12(AUTH_PATH)) {
6940
+ writeFileSync9(AUTH_PATH, "");
6390
6941
  }
6391
6942
  }
6392
6943
  function startAuthCallbackServer(port = 54321) {
@@ -6609,25 +7160,25 @@ async function updateCommand(options = {}) {
6609
7160
 
6610
7161
  // src/commands/progress.ts
6611
7162
  import { execSync as execSync8 } from "child_process";
6612
- import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7 } from "fs";
6613
- import { join as join12 } from "path";
7163
+ import { existsSync as existsSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9 } from "fs";
7164
+ import { join as join14 } from "path";
6614
7165
  function getTasksFilePath() {
6615
7166
  const memoryDir = findMemoryDir();
6616
7167
  if (!memoryDir) {
6617
7168
  const cwd = process.cwd();
6618
- const agentsDir = join12(cwd, ".agents");
6619
- if (!existsSync11(agentsDir)) {
6620
- mkdirSync7(agentsDir, { recursive: true });
7169
+ const agentsDir = join14(cwd, ".agents");
7170
+ if (!existsSync13(agentsDir)) {
7171
+ mkdirSync9(agentsDir, { recursive: true });
6621
7172
  }
6622
- return join12(agentsDir, "tasks.json");
7173
+ return join14(agentsDir, "tasks.json");
6623
7174
  }
6624
- return join12(memoryDir, "..", "tasks.json");
7175
+ return join14(memoryDir, "..", "tasks.json");
6625
7176
  }
6626
7177
  function loadTasks() {
6627
7178
  const tasksPath = getTasksFilePath();
6628
- if (existsSync11(tasksPath)) {
7179
+ if (existsSync13(tasksPath)) {
6629
7180
  try {
6630
- return JSON.parse(readFileSync8(tasksPath, "utf-8"));
7181
+ return JSON.parse(readFileSync10(tasksPath, "utf-8"));
6631
7182
  } catch {
6632
7183
  return { tasks: [], lastUpdated: (/* @__PURE__ */ new Date()).toISOString() };
6633
7184
  }
@@ -6637,7 +7188,7 @@ function loadTasks() {
6637
7188
  function saveTasks(data) {
6638
7189
  const tasksPath = getTasksFilePath();
6639
7190
  data.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
6640
- writeFileSync8(tasksPath, JSON.stringify(data, null, 2));
7191
+ writeFileSync10(tasksPath, JSON.stringify(data, null, 2));
6641
7192
  }
6642
7193
  function getRecentActivity() {
6643
7194
  const activity = [];
@@ -6989,8 +7540,8 @@ async function resultsCommand(options = {}) {
6989
7540
  }
6990
7541
 
6991
7542
  // src/commands/history.ts
6992
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
6993
- import { join as join13 } from "path";
7543
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
7544
+ import { join as join15 } from "path";
6994
7545
  var BRIDGE_URL2 = process.env.SQUADS_BRIDGE_URL || "http://localhost:8088";
6995
7546
  var FETCH_TIMEOUT_MS2 = 3e3;
6996
7547
  async function fetchWithTimeout2(url, timeoutMs = FETCH_TIMEOUT_MS2) {
@@ -7035,12 +7586,12 @@ async function fetchFromBridge2(days, squad) {
7035
7586
  function fetchFromLocal(days, squad) {
7036
7587
  const executions = [];
7037
7588
  const historyPaths = [
7038
- join13(process.cwd(), ".agents/sessions/history.jsonl"),
7039
- join13(process.env.HOME || "", "agents-squads/hq/.agents/sessions/history.jsonl")
7589
+ join15(process.cwd(), ".agents/sessions/history.jsonl"),
7590
+ join15(process.env.HOME || "", "agents-squads/hq/.agents/sessions/history.jsonl")
7040
7591
  ];
7041
7592
  let historyPath;
7042
7593
  for (const path3 of historyPaths) {
7043
- if (existsSync12(path3)) {
7594
+ if (existsSync14(path3)) {
7044
7595
  historyPath = path3;
7045
7596
  break;
7046
7597
  }
@@ -7049,7 +7600,7 @@ function fetchFromLocal(days, squad) {
7049
7600
  return [];
7050
7601
  }
7051
7602
  try {
7052
- const content = readFileSync9(historyPath, "utf-8");
7603
+ const content = readFileSync11(historyPath, "utf-8");
7053
7604
  const lines = content.trim().split("\n").filter(Boolean);
7054
7605
  const cutoff = Date.now() - days * 24 * 60 * 60 * 1e3;
7055
7606
  for (const line of lines) {
@@ -7386,18 +7937,18 @@ async function healthCommand(options = {}) {
7386
7937
 
7387
7938
  // src/commands/workers.ts
7388
7939
  import { execSync as execSync10 } from "child_process";
7389
- import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
7390
- import { join as join14 } from "path";
7940
+ import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
7941
+ import { join as join16 } from "path";
7391
7942
  function getTasksFilePath2() {
7392
7943
  const memoryDir = findMemoryDir();
7393
7944
  if (!memoryDir) return null;
7394
- return join14(memoryDir, "..", "tasks.json");
7945
+ return join16(memoryDir, "..", "tasks.json");
7395
7946
  }
7396
7947
  function loadActiveTasks() {
7397
7948
  const tasksPath = getTasksFilePath2();
7398
- if (!tasksPath || !existsSync13(tasksPath)) return [];
7949
+ if (!tasksPath || !existsSync15(tasksPath)) return [];
7399
7950
  try {
7400
- const data = JSON.parse(readFileSync10(tasksPath, "utf-8"));
7951
+ const data = JSON.parse(readFileSync12(tasksPath, "utf-8"));
7401
7952
  return data.tasks?.filter((t) => t.status === "active") || [];
7402
7953
  } catch {
7403
7954
  return [];
@@ -7544,8 +8095,8 @@ function getElapsedTime2(startTime) {
7544
8095
  }
7545
8096
 
7546
8097
  // src/commands/context-feed.ts
7547
- import { existsSync as existsSync14, statSync as statSync3, readdirSync as readdirSync6, readFileSync as readFileSync11 } from "fs";
7548
- import { join as join15 } from "path";
8098
+ import { existsSync as existsSync16, statSync as statSync3, readdirSync as readdirSync6, readFileSync as readFileSync13 } from "fs";
8099
+ import { join as join17 } from "path";
7549
8100
  var BRIDGE_URL3 = process.env.SQUADS_BRIDGE_URL || "http://localhost:8088";
7550
8101
  async function syncBriefToBridge(brief, sourcePath) {
7551
8102
  try {
@@ -7574,10 +8125,10 @@ async function syncBriefToBridge(brief, sourcePath) {
7574
8125
  }
7575
8126
  function readBusinessBrief(squadsDir) {
7576
8127
  if (!squadsDir) return void 0;
7577
- const briefPath = join15(squadsDir, "..", "BUSINESS_BRIEF.md");
7578
- if (!existsSync14(briefPath)) return void 0;
8128
+ const briefPath = join17(squadsDir, "..", "BUSINESS_BRIEF.md");
8129
+ if (!existsSync16(briefPath)) return void 0;
7579
8130
  try {
7580
- const content = readFileSync11(briefPath, "utf-8");
8131
+ const content = readFileSync13(briefPath, "utf-8");
7581
8132
  const brief = { raw: content };
7582
8133
  const priorityMatch = content.match(/##\s*#1 Priority\s*\n+\*\*([^*]+)\*\*/);
7583
8134
  if (priorityMatch) {
@@ -7627,7 +8178,7 @@ function readBusinessBrief(squadsDir) {
7627
8178
  async function collectBriefingData(options) {
7628
8179
  const squadsDir = findSquadsDir();
7629
8180
  const memoryDir = findMemoryDir();
7630
- const baseDir = squadsDir ? join15(squadsDir, "..", "..", "..") : null;
8181
+ const baseDir = squadsDir ? join17(squadsDir, "..", "..", "..") : null;
7631
8182
  const allSquads = squadsDir ? listSquads(squadsDir) : [];
7632
8183
  if (options.squad && !allSquads.includes(options.squad)) {
7633
8184
  return {
@@ -7667,14 +8218,14 @@ async function collectBriefingData(options) {
7667
8218
  }
7668
8219
  let lastActivity;
7669
8220
  if (memoryDir) {
7670
- const squadMemoryPath = join15(memoryDir, squadName);
7671
- if (existsSync14(squadMemoryPath)) {
8221
+ const squadMemoryPath = join17(memoryDir, squadName);
8222
+ if (existsSync16(squadMemoryPath)) {
7672
8223
  let mostRecent = 0;
7673
8224
  try {
7674
8225
  const walkDir = (dir) => {
7675
8226
  const entries = readdirSync6(dir, { withFileTypes: true });
7676
8227
  for (const entry of entries) {
7677
- const fullPath = join15(dir, entry.name);
8228
+ const fullPath = join17(dir, entry.name);
7678
8229
  if (entry.isDirectory()) {
7679
8230
  walkDir(fullPath);
7680
8231
  } else if (entry.name.endsWith(".md")) {
@@ -7754,7 +8305,7 @@ async function collectBriefingData(options) {
7754
8305
  }
7755
8306
  const brief = readBusinessBrief(squadsDir);
7756
8307
  if (brief && squadsDir) {
7757
- const briefPath = join15(squadsDir, "..", "BUSINESS_BRIEF.md");
8308
+ const briefPath = join17(squadsDir, "..", "BUSINESS_BRIEF.md");
7758
8309
  syncBriefToBridge(brief, briefPath).catch(() => {
7759
8310
  });
7760
8311
  }
@@ -8306,7 +8857,7 @@ async function detectSquadCommand() {
8306
8857
 
8307
8858
  // src/commands/trigger.ts
8308
8859
  import chalk3 from "chalk";
8309
- import { existsSync as existsSync15 } from "fs";
8860
+ import { existsSync as existsSync17 } from "fs";
8310
8861
  var SCHEDULER_URL = process.env.SCHEDULER_URL || "http://localhost:8090";
8311
8862
  async function fetchScheduler(path3, options) {
8312
8863
  const res = await fetch(`${SCHEDULER_URL}${path3}`, {
@@ -8356,7 +8907,7 @@ async function syncTriggers() {
8356
8907
  const hqPath = process.env.HQ_PATH || `${process.env.HOME}/agents-squads/hq`;
8357
8908
  try {
8358
8909
  const venvPython = `${hqPath}/squads-scheduler/.venv/bin/python`;
8359
- const pythonCmd = existsSync15(venvPython) ? venvPython : "python3";
8910
+ const pythonCmd = existsSync17(venvPython) ? venvPython : "python3";
8360
8911
  const output = execSync14(
8361
8912
  `${pythonCmd} ${hqPath}/squads-scheduler/sync_triggers.py`,
8362
8913
  { encoding: "utf-8", cwd: hqPath }
@@ -8440,13 +8991,13 @@ function registerTriggerCommand(program2) {
8440
8991
 
8441
8992
  // src/commands/skill.ts
8442
8993
  import ora6 from "ora";
8443
- import { existsSync as existsSync16, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readFileSync as readFileSync13 } from "fs";
8444
- import { join as join17, basename as basename2, dirname as dirname4 } from "path";
8994
+ import { existsSync as existsSync18, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, readFileSync as readFileSync15 } from "fs";
8995
+ import { join as join19, basename as basename2, dirname as dirname6 } from "path";
8445
8996
 
8446
8997
  // src/lib/anthropic.ts
8447
8998
  import Anthropic from "@anthropic-ai/sdk";
8448
- import { readFileSync as readFileSync12, readdirSync as readdirSync7 } from "fs";
8449
- import { join as join16 } from "path";
8999
+ import { readFileSync as readFileSync14, readdirSync as readdirSync7 } from "fs";
9000
+ import { join as join18 } from "path";
8450
9001
  var client = null;
8451
9002
  function getClient() {
8452
9003
  if (!client) {
@@ -8475,12 +9026,12 @@ function loadSkillFiles(skillPath) {
8475
9026
  function walkDir(dir, prefix = "") {
8476
9027
  const entries = readdirSync7(dir, { withFileTypes: true });
8477
9028
  for (const entry of entries) {
8478
- const fullPath = join16(dir, entry.name);
9029
+ const fullPath = join18(dir, entry.name);
8479
9030
  const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
8480
9031
  if (entry.isDirectory()) {
8481
9032
  walkDir(fullPath, relativePath);
8482
9033
  } else if (entry.isFile()) {
8483
- const content = readFileSync12(fullPath, "utf-8");
9034
+ const content = readFileSync14(fullPath, "utf-8");
8484
9035
  files.push({
8485
9036
  name: relativePath,
8486
9037
  content
@@ -8644,14 +9195,14 @@ async function skillUploadCommand(skillPath) {
8644
9195
  writeLine();
8645
9196
  return;
8646
9197
  }
8647
- const fullPath = skillPath.startsWith("/") ? skillPath : join17(process.cwd(), skillPath);
8648
- if (!existsSync16(fullPath)) {
9198
+ const fullPath = skillPath.startsWith("/") ? skillPath : join19(process.cwd(), skillPath);
9199
+ if (!existsSync18(fullPath)) {
8649
9200
  writeLine(` ${icons.error} ${colors.red}Directory not found: ${skillPath}${RESET}`);
8650
9201
  writeLine();
8651
9202
  return;
8652
9203
  }
8653
- const skillMdPath = join17(fullPath, "SKILL.md");
8654
- if (!existsSync16(skillMdPath)) {
9204
+ const skillMdPath = join19(fullPath, "SKILL.md");
9205
+ if (!existsSync18(skillMdPath)) {
8655
9206
  writeLine(` ${icons.error} ${colors.red}SKILL.md not found in ${skillPath}${RESET}`);
8656
9207
  writeLine();
8657
9208
  writeLine(` ${colors.dim}Create a SKILL.md file or use:${RESET}`);
@@ -8762,7 +9313,7 @@ async function skillConvertCommand(agentPath, options) {
8762
9313
  const [squad, agent] = agentPath.split("/");
8763
9314
  squadName = squad;
8764
9315
  agentName = agent.replace(".md", "");
8765
- agentFilePath = join17(squadsDir, squad, `${agentName}.md`);
9316
+ agentFilePath = join19(squadsDir, squad, `${agentName}.md`);
8766
9317
  } else {
8767
9318
  agentName = agentPath.replace(".md", "");
8768
9319
  const foundPath = findAgentFile(squadsDir, agentName);
@@ -8773,22 +9324,22 @@ async function skillConvertCommand(agentPath, options) {
8773
9324
  return;
8774
9325
  }
8775
9326
  agentFilePath = foundPath;
8776
- squadName = basename2(dirname4(agentFilePath));
9327
+ squadName = basename2(dirname6(agentFilePath));
8777
9328
  }
8778
- if (!existsSync16(agentFilePath)) {
9329
+ if (!existsSync18(agentFilePath)) {
8779
9330
  writeLine(` ${icons.error} ${colors.red}Agent file not found: ${agentFilePath}${RESET}`);
8780
9331
  writeLine();
8781
9332
  return;
8782
9333
  }
8783
- const agentContent = readFileSync13(agentFilePath, "utf-8");
9334
+ const agentContent = readFileSync15(agentFilePath, "utf-8");
8784
9335
  const skillName = `${squadName}-${agentName}`;
8785
- const outputDir = options.output || join17(dirname4(squadsDir), "skills", skillName);
8786
- if (!existsSync16(outputDir)) {
8787
- mkdirSync8(outputDir, { recursive: true });
9336
+ const outputDir = options.output || join19(dirname6(squadsDir), "skills", skillName);
9337
+ if (!existsSync18(outputDir)) {
9338
+ mkdirSync10(outputDir, { recursive: true });
8788
9339
  }
8789
9340
  const skillMd = convertAgentToSkill(agentContent, squadName, agentName);
8790
- const skillMdPath = join17(outputDir, "SKILL.md");
8791
- writeFileSync9(skillMdPath, skillMd);
9341
+ const skillMdPath = join19(outputDir, "SKILL.md");
9342
+ writeFileSync11(skillMdPath, skillMd);
8792
9343
  writeLine(` ${icons.success} ${colors.green}Converted:${RESET} ${agentPath}`);
8793
9344
  writeLine();
8794
9345
  writeLine(` ${colors.dim}Output:${RESET} ${outputDir}`);
@@ -8805,8 +9356,8 @@ function findAgentFile(squadsDir, agentName) {
8805
9356
  const { readdirSync: readdirSync9 } = __require("fs");
8806
9357
  const squads = readdirSync9(squadsDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("_")).map((d) => d.name);
8807
9358
  for (const squad of squads) {
8808
- const agentPath = join17(squadsDir, squad, `${agentName}.md`);
8809
- if (existsSync16(agentPath)) {
9359
+ const agentPath = join19(squadsDir, squad, `${agentName}.md`);
9360
+ if (existsSync18(agentPath)) {
8810
9361
  return agentPath;
8811
9362
  }
8812
9363
  }
@@ -8847,8 +9398,8 @@ function formatBytes(bytes) {
8847
9398
  }
8848
9399
 
8849
9400
  // src/commands/permissions.ts
8850
- import { readFileSync as readFileSync14 } from "fs";
8851
- import { join as join18 } from "path";
9401
+ import { readFileSync as readFileSync16 } from "fs";
9402
+ import { join as join20 } from "path";
8852
9403
  function registerPermissionsCommand(program2) {
8853
9404
  const permissions = program2.command("permissions").alias("perms").description("Manage and validate squad permissions");
8854
9405
  permissions.command("show <squad>").description("Show permission context for a squad").action(permissionsShowCommand);
@@ -8870,8 +9421,8 @@ async function permissionsShowCommand(squadName) {
8870
9421
  writeLine();
8871
9422
  return;
8872
9423
  }
8873
- const squadFilePath = join18(squadsDir, squadName, "SQUAD.md");
8874
- const squadContent = readFileSync14(squadFilePath, "utf-8");
9424
+ const squadFilePath = join20(squadsDir, squadName, "SQUAD.md");
9425
+ const squadContent = readFileSync16(squadFilePath, "utf-8");
8875
9426
  const context = buildContextFromSquad(squadName, squadContent);
8876
9427
  const defaults = getDefaultContext(squadName);
8877
9428
  const isDefault = JSON.stringify(context.permissions) === JSON.stringify(defaults.permissions);
@@ -8965,8 +9516,8 @@ async function permissionsCheckCommand(squadName, options) {
8965
9516
  writeLine();
8966
9517
  return;
8967
9518
  }
8968
- const squadFilePath = join18(squadsDir, squadName, "SQUAD.md");
8969
- const squadContent = readFileSync14(squadFilePath, "utf-8");
9519
+ const squadFilePath = join20(squadsDir, squadName, "SQUAD.md");
9520
+ const squadContent = readFileSync16(squadFilePath, "utf-8");
8970
9521
  const context = buildContextFromSquad(squadName, squadContent, options.agent);
8971
9522
  const request = {
8972
9523
  mcpServers: options.mcp,
@@ -9153,6 +9704,77 @@ async function contextListCommand(options = {}) {
9153
9704
  writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);
9154
9705
  writeLine();
9155
9706
  }
9707
+ async function contextActivateCommand(squadName, options = {}) {
9708
+ await track(Events.CLI_CONTEXT, { squad: squadName, action: "activate" });
9709
+ const squadsDir = findSquadsDir();
9710
+ if (!squadsDir) {
9711
+ writeLine(`${colors.red}No .agents/squads directory found${RESET}`);
9712
+ process.exit(1);
9713
+ }
9714
+ const squad = loadSquad(squadName);
9715
+ if (!squad) {
9716
+ writeLine(`${colors.red}Squad "${squadName}" not found.${RESET}`);
9717
+ process.exit(1);
9718
+ }
9719
+ const execContext = resolveExecutionContext(squad, options.force);
9720
+ if (options.json) {
9721
+ console.log(JSON.stringify(execContext, null, 2));
9722
+ return;
9723
+ }
9724
+ if (options.dryRun) {
9725
+ writeLine();
9726
+ writeLine(` ${gradient("squads")} ${colors.dim}context activate${RESET} ${colors.cyan}${squadName}${RESET} ${colors.yellow}(dry run)${RESET}`);
9727
+ writeLine();
9728
+ writeLine(` ${colors.dim}Would resolve:${RESET}`);
9729
+ writeLine();
9730
+ writeLine(` ${bold}MCP Config${RESET}`);
9731
+ writeLine(` Path: ${execContext.resolved.mcpConfigPath}`);
9732
+ writeLine(` Source: ${execContext.resolved.mcpSource}`);
9733
+ if (execContext.resolved.mcpServers.length > 0) {
9734
+ writeLine(` Servers: ${execContext.resolved.mcpServers.join(", ")}`);
9735
+ }
9736
+ if (execContext.resolved.skillPaths.length > 0) {
9737
+ writeLine();
9738
+ writeLine(` ${bold}Skills${RESET}`);
9739
+ for (const path3 of execContext.resolved.skillPaths) {
9740
+ writeLine(` ${colors.dim}${path3}${RESET}`);
9741
+ }
9742
+ }
9743
+ if (execContext.resolved.memoryPaths.length > 0) {
9744
+ writeLine();
9745
+ writeLine(` ${bold}Memory${RESET}`);
9746
+ for (const path3 of execContext.resolved.memoryPaths) {
9747
+ writeLine(` ${colors.dim}${path3}${RESET}`);
9748
+ }
9749
+ }
9750
+ writeLine();
9751
+ writeLine(` ${colors.dim}Run without --dry-run to generate config${RESET}`);
9752
+ writeLine();
9753
+ return;
9754
+ }
9755
+ writeLine();
9756
+ writeLine(` ${gradient("squads")} ${colors.dim}context activate${RESET} ${colors.cyan}${squadName}${RESET}`);
9757
+ writeLine();
9758
+ const sourceLabel = execContext.resolved.mcpSource === "generated" ? `${colors.green}generated${RESET}` : execContext.resolved.mcpSource === "user-override" ? `${colors.cyan}user override${RESET}` : `${colors.dim}fallback${RESET}`;
9759
+ writeLine(` ${icons.success} MCP config: ${sourceLabel}`);
9760
+ writeLine(` ${colors.dim}${execContext.resolved.mcpConfigPath}${RESET}`);
9761
+ if (execContext.resolved.mcpServers.length > 0) {
9762
+ writeLine(` ${colors.dim}Servers: ${execContext.resolved.mcpServers.join(", ")}${RESET}`);
9763
+ }
9764
+ if (execContext.resolved.skillPaths.length > 0) {
9765
+ writeLine(` ${icons.success} Skills: ${execContext.resolved.skillPaths.length} resolved`);
9766
+ }
9767
+ if (execContext.resolved.memoryPaths.length > 0) {
9768
+ writeLine(` ${icons.success} Memory: ${execContext.resolved.memoryPaths.length} files`);
9769
+ }
9770
+ writeLine();
9771
+ writeLine(` ${colors.dim}To use this context manually:${RESET}`);
9772
+ writeLine(` ${colors.dim}$${RESET} claude --mcp-config '${execContext.resolved.mcpConfigPath}'`);
9773
+ writeLine();
9774
+ writeLine(` ${colors.dim}Or run with squads:${RESET}`);
9775
+ writeLine(` ${colors.dim}$${RESET} squads run ${colors.cyan}${squadName}${RESET}`);
9776
+ writeLine();
9777
+ }
9156
9778
 
9157
9779
  // src/commands/cost.ts
9158
9780
  function getBudgetStatus(squadName, spent, dailyBudget, weeklyBudget) {
@@ -9399,8 +10021,8 @@ function createBudgetBar(percent, width = 10) {
9399
10021
  }
9400
10022
 
9401
10023
  // src/lib/executions.ts
9402
- import { readFileSync as readFileSync15, existsSync as existsSync17, readdirSync as readdirSync8 } from "fs";
9403
- import { join as join19 } from "path";
10024
+ import { readFileSync as readFileSync17, existsSync as existsSync19, readdirSync as readdirSync8 } from "fs";
10025
+ import { join as join21 } from "path";
9404
10026
  function parseExecutionEntry(content, squad, agent) {
9405
10027
  const idMatch = content.match(/<!-- exec:(\S+) -->/);
9406
10028
  if (!idMatch) return null;
@@ -9438,8 +10060,8 @@ function parseExecutionEntry(content, squad, agent) {
9438
10060
  };
9439
10061
  }
9440
10062
  function parseExecutionLog(filePath, squad, agent) {
9441
- if (!existsSync17(filePath)) return [];
9442
- const content = readFileSync15(filePath, "utf-8");
10063
+ if (!existsSync19(filePath)) return [];
10064
+ const content = readFileSync17(filePath, "utf-8");
9443
10065
  const executions = [];
9444
10066
  const entries = content.split(/\n---\n/);
9445
10067
  for (const entry of entries) {
@@ -9477,11 +10099,11 @@ function listExecutions(options = {}) {
9477
10099
  const squads = readdirSync8(memoryDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
9478
10100
  for (const squad of squads) {
9479
10101
  if (filterSquad && squad !== filterSquad) continue;
9480
- const squadPath = join19(memoryDir, squad);
10102
+ const squadPath = join21(memoryDir, squad);
9481
10103
  const agents = readdirSync8(squadPath, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
9482
10104
  for (const agent of agents) {
9483
10105
  if (filterAgent && agent !== filterAgent) continue;
9484
- const logPath = join19(squadPath, agent, "executions.md");
10106
+ const logPath = join21(squadPath, agent, "executions.md");
9485
10107
  const agentExecutions = parseExecutionLog(logPath, squad, agent);
9486
10108
  executions.push(...agentExecutions);
9487
10109
  }
@@ -9731,12 +10353,12 @@ async function execStatsCommand(options = {}) {
9731
10353
  // src/commands/tonight.ts
9732
10354
  import ora7 from "ora";
9733
10355
  import fs2 from "fs/promises";
9734
- import path2, { dirname as dirname5 } from "path";
10356
+ import path2, { dirname as dirname7 } from "path";
9735
10357
  import { execSync as execSync13, spawn as spawn7 } from "child_process";
9736
10358
  function getProjectRoot2() {
9737
10359
  const squadsDir = findSquadsDir();
9738
10360
  if (squadsDir) {
9739
- return dirname5(dirname5(squadsDir));
10361
+ return dirname7(dirname7(squadsDir));
9740
10362
  }
9741
10363
  return process.cwd();
9742
10364
  }
@@ -10065,12 +10687,12 @@ process.stderr.on("error", (err) => {
10065
10687
  throw err;
10066
10688
  });
10067
10689
  var envPaths = [
10068
- join20(process.cwd(), ".env"),
10069
- join20(process.cwd(), "..", "hq", ".env"),
10070
- join20(homedir4(), "agents-squads", "hq", ".env")
10690
+ join22(process.cwd(), ".env"),
10691
+ join22(process.cwd(), "..", "hq", ".env"),
10692
+ join22(homedir4(), "agents-squads", "hq", ".env")
10071
10693
  ];
10072
10694
  for (const envPath of envPaths) {
10073
- if (existsSync18(envPath)) {
10695
+ if (existsSync20(envPath)) {
10074
10696
  config({ path: envPath, quiet: true });
10075
10697
  break;
10076
10698
  }
@@ -10121,6 +10743,7 @@ program.command("dashboard").alias("dash").description("Show comprehensive goals
10121
10743
  var env = program.command("env").description("View squad execution environment (MCP, skills, model, budget)");
10122
10744
  env.command("show <squad>").description("Show execution environment for a squad").option("--json", "Output as JSON").action(contextShowCommand);
10123
10745
  env.command("list").description("List execution environment for all squads").option("--json", "Output as JSON").action(contextListCommand);
10746
+ env.command("activate <squad>").description("Activate execution context for a squad (generates scoped MCP config)").option("-d, --dry-run", "Show what would be generated without writing files").option("-f, --force", "Force regeneration even if config exists").option("--json", "Output as JSON").action(contextActivateCommand);
10124
10747
  program.command("cost").description("Show cost summary (today, week, by squad)").option("-s, --squad <squad>", "Filter to specific squad").option("--json", "Output as JSON").action(costCommand);
10125
10748
  program.command("budget").description("Check budget status for a squad").argument("<squad>", "Squad to check").option("--json", "Output as JSON").action(budgetCheckCommand);
10126
10749
  var exec2 = program.command("exec").description("View execution history and statistics");
@@ -10181,6 +10804,10 @@ var feedback = program.command("feedback").description("Record and view executio
10181
10804
  feedback.command("add <squad> <rating> <feedback>").description("Add feedback for last execution (rating 1-5)").option("-l, --learning <learnings...>", "Learnings to extract").action(feedbackAddCommand);
10182
10805
  feedback.command("show <squad>").description("Show feedback history").option("-n, --limit <n>", "Number of entries to show", "5").action(feedbackShowCommand);
10183
10806
  feedback.command("stats").description("Show feedback summary across all squads").action(feedbackStatsCommand);
10807
+ program.command("learn <insight>").description("Capture a learning for future sessions").option("-s, --squad <squad>", "Squad to associate learning with").option("-c, --category <category>", "Category: success, failure, pattern, tip").option("-t, --tags <tags>", "Comma-separated tags").option("--context <context>", "Additional context").action(learnCommand);
10808
+ var learn = program.command("learnings").description("View and search learnings");
10809
+ learn.command("show <squad>").description("Show learnings for a squad").option("-n, --limit <n>", "Number to show", "10").option("-c, --category <category>", "Filter by category").option("--tag <tag>", "Filter by tag").action(learnShowCommand);
10810
+ learn.command("search <query>").description("Search learnings across all squads").option("-n, --limit <n>", "Max results", "10").action(learnSearchCommand);
10184
10811
  var sessions = program.command("sessions").description("Show active Claude Code sessions across squads").option("-v, --verbose", "Show session details").option("-j, --json", "Output as JSON").action(sessionsCommand);
10185
10812
  sessions.command("history").description("Show session history and statistics").option("-d, --days <days>", "Days of history to show", "7").option("-s, --squad <squad>", "Filter by squad").option("-j, --json", "Output as JSON").action((options) => sessionsHistoryCommand({
10186
10813
  days: parseInt(options.days, 10),
@@ -10191,8 +10818,8 @@ sessions.command("summary").description("Show pretty session summary (auto-detec
10191
10818
  const { buildCurrentSessionSummary } = await import("./sessions-R4VWIGFR.js");
10192
10819
  let data;
10193
10820
  if (options.file) {
10194
- const { readFileSync: readFileSync16 } = await import("fs");
10195
- data = JSON.parse(readFileSync16(options.file, "utf-8"));
10821
+ const { readFileSync: readFileSync18 } = await import("fs");
10822
+ data = JSON.parse(readFileSync18(options.file, "utf-8"));
10196
10823
  } else if (options.data) {
10197
10824
  data = JSON.parse(options.data);
10198
10825
  } else if (!process.stdin.isTTY) {