squads-cli 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +196 -1152
  2. package/dist/auth-YW3UPFSB.js +23 -0
  3. package/dist/autonomy-BWTVDEAT.js +102 -0
  4. package/dist/autonomy-BWTVDEAT.js.map +1 -0
  5. package/dist/chunk-3KCWNZWW.js +401 -0
  6. package/dist/chunk-3KCWNZWW.js.map +1 -0
  7. package/dist/chunk-67RO2HKR.js +174 -0
  8. package/dist/chunk-67RO2HKR.js.map +1 -0
  9. package/dist/chunk-7JVD7RD4.js +275 -0
  10. package/dist/chunk-7JVD7RD4.js.map +1 -0
  11. package/dist/chunk-BODLDQY7.js +452 -0
  12. package/dist/chunk-BODLDQY7.js.map +1 -0
  13. package/dist/chunk-FFFCFZ6A.js +121 -0
  14. package/dist/chunk-FFFCFZ6A.js.map +1 -0
  15. package/dist/chunk-FIWT2NMM.js +165 -0
  16. package/dist/chunk-FIWT2NMM.js.map +1 -0
  17. package/dist/chunk-L6GQCHDF.js +222 -0
  18. package/dist/chunk-L6GQCHDF.js.map +1 -0
  19. package/dist/{chunk-O7UV3FWI.js → chunk-LDM62TIX.js} +2 -2
  20. package/dist/chunk-LDM62TIX.js.map +1 -0
  21. package/dist/chunk-LOA3KWYJ.js +294 -0
  22. package/dist/chunk-LOA3KWYJ.js.map +1 -0
  23. package/dist/chunk-NA45DFXY.js +616 -0
  24. package/dist/chunk-NA45DFXY.js.map +1 -0
  25. package/dist/{chunk-4CMAEQQY.js → chunk-NQN6JPI7.js} +4 -3
  26. package/dist/chunk-NQN6JPI7.js.map +1 -0
  27. package/dist/chunk-OQJHPULO.js +103 -0
  28. package/dist/chunk-OQJHPULO.js.map +1 -0
  29. package/dist/chunk-QHNUMM4V.js +87 -0
  30. package/dist/chunk-QHNUMM4V.js.map +1 -0
  31. package/dist/chunk-RM6BWILN.js +74 -0
  32. package/dist/chunk-RM6BWILN.js.map +1 -0
  33. package/dist/chunk-WBR5J7EX.js +90 -0
  34. package/dist/chunk-WBR5J7EX.js.map +1 -0
  35. package/dist/chunk-Z2UKDBNL.js +162 -0
  36. package/dist/chunk-Z2UKDBNL.js.map +1 -0
  37. package/dist/cli.js +2136 -12600
  38. package/dist/cli.js.map +1 -1
  39. package/dist/context-M2A2DOFV.js +291 -0
  40. package/dist/context-M2A2DOFV.js.map +1 -0
  41. package/dist/context-feed-JMNW4GAM.js +391 -0
  42. package/dist/context-feed-JMNW4GAM.js.map +1 -0
  43. package/dist/cost-N37I4UTA.js +274 -0
  44. package/dist/cost-N37I4UTA.js.map +1 -0
  45. package/dist/create-554W5HNU.js +286 -0
  46. package/dist/create-554W5HNU.js.map +1 -0
  47. package/dist/daemon-XWPQPPPN.js +546 -0
  48. package/dist/daemon-XWPQPPPN.js.map +1 -0
  49. package/dist/dashboard-L7YKVQEB.js +945 -0
  50. package/dist/dashboard-L7YKVQEB.js.map +1 -0
  51. package/dist/dashboard-MFNRLCEE.js +794 -0
  52. package/dist/dashboard-MFNRLCEE.js.map +1 -0
  53. package/dist/doctor-RG75M5RO.js +346 -0
  54. package/dist/doctor-RG75M5RO.js.map +1 -0
  55. package/dist/env-config-KCLDBKYX.js +21 -0
  56. package/dist/exec-JQKBF7BL.js +197 -0
  57. package/dist/exec-JQKBF7BL.js.map +1 -0
  58. package/dist/feedback-KA2UYBZG.js +229 -0
  59. package/dist/feedback-KA2UYBZG.js.map +1 -0
  60. package/dist/github-UQTM5KMS.js +23 -0
  61. package/dist/goal-EOPC5ZCD.js +168 -0
  62. package/dist/goal-EOPC5ZCD.js.map +1 -0
  63. package/dist/health-3FZDOSR5.js +209 -0
  64. package/dist/health-3FZDOSR5.js.map +1 -0
  65. package/dist/history-TFVXJEDH.js +229 -0
  66. package/dist/history-TFVXJEDH.js.map +1 -0
  67. package/dist/index.js +1 -1
  68. package/dist/index.js.map +1 -1
  69. package/dist/init-UOWTNMIE.js +747 -0
  70. package/dist/init-UOWTNMIE.js.map +1 -0
  71. package/dist/kpi-2SQ2WCVT.js +413 -0
  72. package/dist/kpi-2SQ2WCVT.js.map +1 -0
  73. package/dist/learn-6ERTERAO.js +269 -0
  74. package/dist/learn-6ERTERAO.js.map +1 -0
  75. package/dist/list-KSOMUBMB.js +92 -0
  76. package/dist/list-KSOMUBMB.js.map +1 -0
  77. package/dist/login-ST6PAXYE.js +155 -0
  78. package/dist/login-ST6PAXYE.js.map +1 -0
  79. package/dist/memory-3CSNKXIL.js +562 -0
  80. package/dist/memory-3CSNKXIL.js.map +1 -0
  81. package/dist/progress-FKG4V2VH.js +202 -0
  82. package/dist/progress-FKG4V2VH.js.map +1 -0
  83. package/dist/providers-66PDCORB.js +65 -0
  84. package/dist/providers-66PDCORB.js.map +1 -0
  85. package/dist/results-2MJFLWEO.js +224 -0
  86. package/dist/results-2MJFLWEO.js.map +1 -0
  87. package/dist/run-72OQLH5A.js +2685 -0
  88. package/dist/run-72OQLH5A.js.map +1 -0
  89. package/dist/session-6H67XPAQ.js +64 -0
  90. package/dist/session-6H67XPAQ.js.map +1 -0
  91. package/dist/{chunk-NHGLXN2F.js → sessions-GVQIMN4W.js} +23 -459
  92. package/dist/sessions-GVQIMN4W.js.map +1 -0
  93. package/dist/{squad-parser-4BI3G4RS.js → squad-parser-CM3HOIWM.js} +2 -2
  94. package/dist/squad-parser-CM3HOIWM.js.map +1 -0
  95. package/dist/stats-ONZI557Q.js +335 -0
  96. package/dist/stats-ONZI557Q.js.map +1 -0
  97. package/dist/status-FYH42FTB.js +346 -0
  98. package/dist/status-FYH42FTB.js.map +1 -0
  99. package/dist/sync-HJZJNXHW.js +800 -0
  100. package/dist/sync-HJZJNXHW.js.map +1 -0
  101. package/dist/update-B4WMUOPO.js +83 -0
  102. package/dist/update-B4WMUOPO.js.map +1 -0
  103. package/dist/{update-ALJKFFM7.js → update-L7FGHN6W.js} +2 -2
  104. package/dist/update-L7FGHN6W.js.map +1 -0
  105. package/package.json +18 -10
  106. package/dist/chunk-4CMAEQQY.js.map +0 -1
  107. package/dist/chunk-NHGLXN2F.js.map +0 -1
  108. package/dist/chunk-O7UV3FWI.js.map +0 -1
  109. package/dist/sessions-6PB7ALCE.js +0 -16
  110. /package/dist/{sessions-6PB7ALCE.js.map → auth-YW3UPFSB.js.map} +0 -0
  111. /package/dist/{squad-parser-4BI3G4RS.js.map → env-config-KCLDBKYX.js.map} +0 -0
  112. /package/dist/{update-ALJKFFM7.js.map → github-UQTM5KMS.js.map} +0 -0
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ Events,
4
+ track
5
+ } from "./chunk-L6GQCHDF.js";
6
+ import {
7
+ addGoalToSquad,
8
+ findSquadsDir,
9
+ listSquads,
10
+ loadSquad,
11
+ updateGoalInSquad
12
+ } from "./chunk-LDM62TIX.js";
13
+ import {
14
+ RESET,
15
+ bold,
16
+ colors,
17
+ gradient,
18
+ icons,
19
+ truncate,
20
+ writeLine
21
+ } from "./chunk-N7KDWU4W.js";
22
+ import "./chunk-7OCVIDC7.js";
23
+
24
+ // src/commands/goal.ts
25
+ async function goalSetCommand(squadName, description, options) {
26
+ await track(Events.CLI_GOAL_SET, { squad: squadName });
27
+ const squad = loadSquad(squadName);
28
+ if (!squad) {
29
+ writeLine(` ${colors.red}Squad "${squadName}" not found${RESET}`);
30
+ return;
31
+ }
32
+ let goalText = description;
33
+ if (options.metric && options.metric.length > 0) {
34
+ goalText += ` [metrics: ${options.metric.join(", ")}]`;
35
+ }
36
+ const success = addGoalToSquad(squadName, goalText);
37
+ writeLine();
38
+ if (success) {
39
+ writeLine(` ${icons.success} Goal added to ${colors.cyan}${squadName}${RESET}`);
40
+ writeLine(` ${bold}${description}${RESET}`);
41
+ if (options.metric && options.metric.length > 0) {
42
+ writeLine(` ${colors.dim}Metrics: ${options.metric.join(", ")}${RESET}`);
43
+ }
44
+ } else {
45
+ writeLine(` ${colors.red}Failed to add goal${RESET}`);
46
+ }
47
+ writeLine();
48
+ }
49
+ async function goalListCommand(squadName, options = {}) {
50
+ await track(Events.CLI_GOAL_LIST, { squad: squadName || "all" });
51
+ const squadsDir = findSquadsDir();
52
+ if (!squadsDir) {
53
+ writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);
54
+ writeLine(` ${colors.dim}Run \`squads init\` to create one.${RESET}`);
55
+ return;
56
+ }
57
+ const squadsToCheck = squadName ? [squadName] : listSquads(squadsDir);
58
+ let totalActive = 0;
59
+ let totalCompleted = 0;
60
+ let hasGoals = false;
61
+ writeLine();
62
+ writeLine(` ${gradient("squads")} ${colors.dim}goal list${RESET}`);
63
+ writeLine();
64
+ for (const name of squadsToCheck) {
65
+ const squad = loadSquad(name);
66
+ if (!squad || squad.goals.length === 0) {
67
+ if (squadName) {
68
+ writeLine(` ${colors.yellow}No goals set for ${name}${RESET}`);
69
+ }
70
+ continue;
71
+ }
72
+ hasGoals = true;
73
+ const activeGoals = squad.goals.filter((g) => !g.completed);
74
+ const completedGoals = squad.goals.filter((g) => g.completed);
75
+ totalActive += activeGoals.length;
76
+ totalCompleted += completedGoals.length;
77
+ if (activeGoals.length === 0 && !options.all) continue;
78
+ writeLine(` ${colors.cyan}${name}${RESET}`);
79
+ if (squad.mission) {
80
+ writeLine(` ${colors.dim}${truncate(squad.mission, 60)}${RESET}`);
81
+ }
82
+ writeLine();
83
+ for (const goal of activeGoals) {
84
+ const globalIdx = squad.goals.indexOf(goal) + 1;
85
+ writeLine(` ${icons.active} ${colors.dim}[${globalIdx}]${RESET} ${goal.description}`);
86
+ if (goal.progress) {
87
+ writeLine(` ${colors.dim}\u2514 ${goal.progress}${RESET}`);
88
+ }
89
+ }
90
+ if (options.all && completedGoals.length > 0) {
91
+ for (const goal of completedGoals) {
92
+ const globalIdx = squad.goals.indexOf(goal) + 1;
93
+ writeLine(` ${icons.success} ${colors.dim}[${globalIdx}] ${goal.description}${RESET}`);
94
+ }
95
+ }
96
+ writeLine();
97
+ }
98
+ if (hasGoals) {
99
+ writeLine(` ${colors.green}${totalActive}${RESET} active ${colors.dim}\u2502${RESET} ${colors.dim}${totalCompleted} completed${RESET}`);
100
+ } else if (!squadName) {
101
+ writeLine(` ${colors.yellow}No goals defined yet${RESET}`);
102
+ writeLine();
103
+ writeLine(` ${colors.dim}$${RESET} squads goal set ${colors.cyan}<squad>${RESET} ${colors.cyan}"<goal>"${RESET}`);
104
+ }
105
+ writeLine();
106
+ }
107
+ async function goalCompleteCommand(squadName, goalIndex) {
108
+ await track(Events.CLI_GOAL_COMPLETE, { squad: squadName });
109
+ const squad = loadSquad(squadName);
110
+ if (!squad) {
111
+ writeLine(` ${colors.red}Squad "${squadName}" not found${RESET}`);
112
+ return;
113
+ }
114
+ const idx = parseInt(goalIndex) - 1;
115
+ if (isNaN(idx) || idx < 0 || idx >= squad.goals.length) {
116
+ writeLine(` ${colors.red}Invalid goal index: ${goalIndex}${RESET}`);
117
+ if (squad.goals.length === 0) {
118
+ writeLine(` ${colors.dim}Squad has no goals${RESET}`);
119
+ } else {
120
+ writeLine(` ${colors.dim}Valid indexes: 1-${squad.goals.length}${RESET}`);
121
+ writeLine(` ${colors.dim}Tip: Run 'squads goal list ${squadName}' to see goals with indexes${RESET}`);
122
+ }
123
+ return;
124
+ }
125
+ const success = updateGoalInSquad(squadName, idx, { completed: true });
126
+ writeLine();
127
+ if (success) {
128
+ writeLine(` ${icons.success} Goal completed: ${colors.cyan}${squad.goals[idx].description}${RESET}`);
129
+ } else {
130
+ writeLine(` ${colors.red}Failed to update goal${RESET}`);
131
+ }
132
+ writeLine();
133
+ }
134
+ async function goalProgressCommand(squadName, goalIndex, progress) {
135
+ await track(Events.CLI_GOAL_PROGRESS, { squad: squadName });
136
+ const squad = loadSquad(squadName);
137
+ if (!squad) {
138
+ writeLine(` ${colors.red}Squad "${squadName}" not found${RESET}`);
139
+ return;
140
+ }
141
+ const idx = parseInt(goalIndex) - 1;
142
+ if (isNaN(idx) || idx < 0 || idx >= squad.goals.length) {
143
+ writeLine(` ${colors.red}Invalid goal index: ${goalIndex}${RESET}`);
144
+ if (squad.goals.length === 0) {
145
+ writeLine(` ${colors.dim}Squad has no goals${RESET}`);
146
+ } else {
147
+ writeLine(` ${colors.dim}Valid indexes: 1-${squad.goals.length}${RESET}`);
148
+ writeLine(` ${colors.dim}Tip: Run 'squads goal list ${squadName}' to see goals with indexes${RESET}`);
149
+ }
150
+ return;
151
+ }
152
+ const success = updateGoalInSquad(squadName, idx, { progress });
153
+ writeLine();
154
+ if (success) {
155
+ writeLine(` ${icons.success} Progress updated: ${colors.cyan}${squad.goals[idx].description}${RESET}`);
156
+ writeLine(` ${colors.dim}${progress}${RESET}`);
157
+ } else {
158
+ writeLine(` ${colors.red}Failed to update progress${RESET}`);
159
+ }
160
+ writeLine();
161
+ }
162
+ export {
163
+ goalCompleteCommand,
164
+ goalListCommand,
165
+ goalProgressCommand,
166
+ goalSetCommand
167
+ };
168
+ //# sourceMappingURL=goal-EOPC5ZCD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/goal.ts"],"sourcesContent":["import {\n loadSquad,\n findSquadsDir,\n listSquads,\n addGoalToSquad,\n updateGoalInSquad,\n} from '../lib/squad-parser.js';\nimport {\n colors,\n bold,\n RESET,\n gradient,\n truncate,\n icons,\n writeLine,\n} from '../lib/terminal.js';\nimport { track, Events } from '../lib/telemetry.js';\n\nexport async function goalSetCommand(\n squadName: string,\n description: string,\n options: { metric?: string[] }\n): Promise<void> {\n await track(Events.CLI_GOAL_SET, { squad: squadName });\n const squad = loadSquad(squadName);\n if (!squad) {\n writeLine(` ${colors.red}Squad \"${squadName}\" not found${RESET}`);\n return;\n }\n\n // Add metric annotations if provided\n let goalText = description;\n if (options.metric && options.metric.length > 0) {\n goalText += ` [metrics: ${options.metric.join(', ')}]`;\n }\n\n const success = addGoalToSquad(squadName, goalText);\n\n writeLine();\n if (success) {\n writeLine(` ${icons.success} Goal added to ${colors.cyan}${squadName}${RESET}`);\n writeLine(` ${bold}${description}${RESET}`);\n if (options.metric && options.metric.length > 0) {\n writeLine(` ${colors.dim}Metrics: ${options.metric.join(', ')}${RESET}`);\n }\n } else {\n writeLine(` ${colors.red}Failed to add goal${RESET}`);\n }\n writeLine();\n}\n\nexport async function goalListCommand(\n squadName?: string,\n options: { all?: boolean } = {}\n): Promise<void> {\n await track(Events.CLI_GOAL_LIST, { squad: squadName || 'all' });\n const squadsDir = findSquadsDir();\n if (!squadsDir) {\n writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);\n writeLine(` ${colors.dim}Run \\`squads init\\` to create one.${RESET}`);\n return;\n }\n\n const squadsToCheck = squadName ? [squadName] : listSquads(squadsDir);\n\n let totalActive = 0;\n let totalCompleted = 0;\n let hasGoals = false;\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}goal list${RESET}`);\n writeLine();\n\n for (const name of squadsToCheck) {\n const squad = loadSquad(name);\n if (!squad || squad.goals.length === 0) {\n if (squadName) {\n writeLine(` ${colors.yellow}No goals set for ${name}${RESET}`);\n }\n continue;\n }\n\n hasGoals = true;\n const activeGoals = squad.goals.filter(g => !g.completed);\n const completedGoals = squad.goals.filter(g => g.completed);\n\n totalActive += activeGoals.length;\n totalCompleted += completedGoals.length;\n\n if (activeGoals.length === 0 && !options.all) continue;\n\n writeLine(` ${colors.cyan}${name}${RESET}`);\n if (squad.mission) {\n writeLine(` ${colors.dim}${truncate(squad.mission, 60)}${RESET}`);\n }\n writeLine();\n\n for (const goal of activeGoals) {\n const globalIdx = squad.goals.indexOf(goal) + 1;\n writeLine(` ${icons.active} ${colors.dim}[${globalIdx}]${RESET} ${goal.description}`);\n if (goal.progress) {\n writeLine(` ${colors.dim}└ ${goal.progress}${RESET}`);\n }\n }\n\n if (options.all && completedGoals.length > 0) {\n for (const goal of completedGoals) {\n const globalIdx = squad.goals.indexOf(goal) + 1;\n writeLine(` ${icons.success} ${colors.dim}[${globalIdx}] ${goal.description}${RESET}`);\n }\n }\n writeLine();\n }\n\n if (hasGoals) {\n writeLine(` ${colors.green}${totalActive}${RESET} active ${colors.dim}│${RESET} ${colors.dim}${totalCompleted} completed${RESET}`);\n } else if (!squadName) {\n writeLine(` ${colors.yellow}No goals defined yet${RESET}`);\n writeLine();\n writeLine(` ${colors.dim}$${RESET} squads goal set ${colors.cyan}<squad>${RESET} ${colors.cyan}\"<goal>\"${RESET}`);\n }\n writeLine();\n}\n\nexport async function goalCompleteCommand(\n squadName: string,\n goalIndex: string\n): Promise<void> {\n await track(Events.CLI_GOAL_COMPLETE, { squad: squadName });\n const squad = loadSquad(squadName);\n if (!squad) {\n writeLine(` ${colors.red}Squad \"${squadName}\" not found${RESET}`);\n return;\n }\n\n const idx = parseInt(goalIndex) - 1;\n if (isNaN(idx) || idx < 0 || idx >= squad.goals.length) {\n writeLine(` ${colors.red}Invalid goal index: ${goalIndex}${RESET}`);\n if (squad.goals.length === 0) {\n writeLine(` ${colors.dim}Squad has no goals${RESET}`);\n } else {\n writeLine(` ${colors.dim}Valid indexes: 1-${squad.goals.length}${RESET}`);\n writeLine(` ${colors.dim}Tip: Run 'squads goal list ${squadName}' to see goals with indexes${RESET}`);\n }\n return;\n }\n\n const success = updateGoalInSquad(squadName, idx, { completed: true });\n\n writeLine();\n if (success) {\n writeLine(` ${icons.success} Goal completed: ${colors.cyan}${squad.goals[idx].description}${RESET}`);\n } else {\n writeLine(` ${colors.red}Failed to update goal${RESET}`);\n }\n writeLine();\n}\n\nexport async function goalProgressCommand(\n squadName: string,\n goalIndex: string,\n progress: string\n): Promise<void> {\n await track(Events.CLI_GOAL_PROGRESS, { squad: squadName });\n const squad = loadSquad(squadName);\n if (!squad) {\n writeLine(` ${colors.red}Squad \"${squadName}\" not found${RESET}`);\n return;\n }\n\n const idx = parseInt(goalIndex) - 1;\n if (isNaN(idx) || idx < 0 || idx >= squad.goals.length) {\n writeLine(` ${colors.red}Invalid goal index: ${goalIndex}${RESET}`);\n if (squad.goals.length === 0) {\n writeLine(` ${colors.dim}Squad has no goals${RESET}`);\n } else {\n writeLine(` ${colors.dim}Valid indexes: 1-${squad.goals.length}${RESET}`);\n writeLine(` ${colors.dim}Tip: Run 'squads goal list ${squadName}' to see goals with indexes${RESET}`);\n }\n return;\n }\n\n const success = updateGoalInSquad(squadName, idx, { progress });\n\n writeLine();\n if (success) {\n writeLine(` ${icons.success} Progress updated: ${colors.cyan}${squad.goals[idx].description}${RESET}`);\n writeLine(` ${colors.dim}${progress}${RESET}`);\n } else {\n writeLine(` ${colors.red}Failed to update progress${RESET}`);\n }\n writeLine();\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ RESET,
4
+ colors,
5
+ gradient,
6
+ icons,
7
+ padEnd,
8
+ writeLine
9
+ } from "./chunk-N7KDWU4W.js";
10
+ import "./chunk-7OCVIDC7.js";
11
+
12
+ // src/commands/health.ts
13
+ var FETCH_TIMEOUT_MS = 2e3;
14
+ var SERVICES = [
15
+ {
16
+ name: "PostgreSQL",
17
+ url: `${process.env.SQUADS_BRIDGE_URL || "http://localhost:8088"}/stats`,
18
+ optional: true,
19
+ fix: "squads stack up postgres"
20
+ },
21
+ {
22
+ name: "Redis",
23
+ url: `${process.env.SQUADS_BRIDGE_URL || "http://localhost:8088"}/stats`,
24
+ optional: true,
25
+ fix: "squads stack up redis"
26
+ },
27
+ {
28
+ name: "Bridge API",
29
+ url: `${process.env.SQUADS_BRIDGE_URL || "http://localhost:8088"}/health`,
30
+ optional: true,
31
+ fix: "squads stack up bridge"
32
+ },
33
+ {
34
+ name: "Scheduler",
35
+ url: `${process.env.SQUADS_API_URL || process.env.SQUADS_SCHEDULER_URL || "http://localhost:8090"}/health`,
36
+ optional: true,
37
+ fix: "squads stack up scheduler"
38
+ },
39
+ {
40
+ name: "Langfuse",
41
+ url: `${process.env.LANGFUSE_HOST || "http://localhost:3100"}/api/public/health`,
42
+ optional: true,
43
+ fix: "squads stack up langfuse"
44
+ }
45
+ ];
46
+ async function fetchWithTimeout(url, timeoutMs = FETCH_TIMEOUT_MS) {
47
+ const controller = new AbortController();
48
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
49
+ try {
50
+ const response = await fetch(url, { signal: controller.signal });
51
+ clearTimeout(timeoutId);
52
+ return response;
53
+ } catch {
54
+ clearTimeout(timeoutId);
55
+ throw new Error("timeout");
56
+ }
57
+ }
58
+ async function checkService(service) {
59
+ const start = Date.now();
60
+ try {
61
+ const response = await fetchWithTimeout(service.url);
62
+ const latencyMs = Date.now() - start;
63
+ if (response.ok) {
64
+ return {
65
+ name: service.name,
66
+ status: "healthy",
67
+ latencyMs,
68
+ optional: service.optional
69
+ };
70
+ }
71
+ return {
72
+ name: service.name,
73
+ status: "degraded",
74
+ latencyMs,
75
+ error: `HTTP ${response.status}`,
76
+ optional: service.optional,
77
+ fix: service.fix
78
+ };
79
+ } catch (error) {
80
+ return {
81
+ name: service.name,
82
+ status: "down",
83
+ error: error instanceof Error ? error.message : "unknown",
84
+ optional: service.optional,
85
+ fix: service.fix
86
+ };
87
+ }
88
+ }
89
+ async function getTriggerStats() {
90
+ try {
91
+ const schedulerUrl = process.env.SQUADS_API_URL || process.env.SQUADS_SCHEDULER_URL || "http://localhost:8090";
92
+ const response = await fetchWithTimeout(`${schedulerUrl}/api/triggers/stats`);
93
+ if (!response.ok) return null;
94
+ const data = await response.json();
95
+ return {
96
+ active: data.active || 0,
97
+ disabled: data.disabled || 0,
98
+ lastFire: data.last_fire ? {
99
+ name: data.last_fire.name || "unknown",
100
+ ago: formatTimeAgo(new Date(data.last_fire.fired_at || Date.now()))
101
+ } : void 0
102
+ };
103
+ } catch {
104
+ return null;
105
+ }
106
+ }
107
+ function formatTimeAgo(date) {
108
+ const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
109
+ if (seconds < 60) return `${seconds}s ago`;
110
+ if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
111
+ if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
112
+ return `${Math.floor(seconds / 86400)}d ago`;
113
+ }
114
+ function formatLatency(ms) {
115
+ if (!ms) return "\u2014";
116
+ return `${ms}ms`;
117
+ }
118
+ async function healthCommand(options = {}) {
119
+ writeLine();
120
+ writeLine(` ${gradient("squads")} ${colors.dim}health${RESET}`);
121
+ writeLine();
122
+ const results = await Promise.all(SERVICES.map(checkService));
123
+ writeLine(` ${colors.purple}\u250C${"\u2500".repeat(48)}\u2510${RESET}`);
124
+ writeLine(` ${colors.purple}\u2502${RESET} ${padEnd("SERVICE", 18)}${padEnd("STATUS", 14)}${padEnd("LATENCY", 12)}${colors.purple}\u2502${RESET}`);
125
+ writeLine(` ${colors.purple}\u251C${"\u2500".repeat(48)}\u2524${RESET}`);
126
+ const issues = [];
127
+ for (const result of results) {
128
+ let statusIcon;
129
+ let statusColor;
130
+ let statusText;
131
+ switch (result.status) {
132
+ case "healthy":
133
+ statusIcon = icons.success;
134
+ statusColor = colors.green;
135
+ statusText = "healthy";
136
+ break;
137
+ case "degraded":
138
+ statusIcon = icons.warning;
139
+ statusColor = colors.yellow;
140
+ statusText = "degraded";
141
+ issues.push(result);
142
+ break;
143
+ case "down":
144
+ statusIcon = icons.error;
145
+ statusColor = colors.red;
146
+ statusText = "down";
147
+ if (!result.optional) {
148
+ issues.push(result);
149
+ }
150
+ break;
151
+ }
152
+ const nameDisplay = result.optional ? `${result.name} ${colors.dim}(opt)${RESET}` : result.name;
153
+ const latency = formatLatency(result.latencyMs);
154
+ writeLine(` ${colors.purple}\u2502${RESET} ${padEnd(nameDisplay, 18)}${statusColor}${statusIcon} ${padEnd(statusText, 11)}${RESET}${padEnd(latency, 12)}${colors.purple}\u2502${RESET}`);
155
+ }
156
+ writeLine(` ${colors.purple}\u2514${"\u2500".repeat(48)}\u2518${RESET}`);
157
+ writeLine();
158
+ const schedulerUp = results.find((r) => r.name === "Scheduler")?.status === "healthy";
159
+ if (schedulerUp) {
160
+ const stats = await getTriggerStats();
161
+ if (stats) {
162
+ const lastFireText = stats.lastFire ? `${colors.dim}Last fire:${RESET} ${stats.lastFire.ago} (${stats.lastFire.name})` : `${colors.dim}No recent fires${RESET}`;
163
+ writeLine(` ${colors.cyan}Triggers:${RESET} ${stats.active} active, ${stats.disabled} disabled`);
164
+ writeLine(` ${lastFireText}`);
165
+ writeLine();
166
+ }
167
+ }
168
+ if (issues.length > 0) {
169
+ const criticalIssues = issues.filter((i) => !i.optional);
170
+ const optionalIssues = issues.filter((i) => i.optional);
171
+ if (criticalIssues.length > 0) {
172
+ writeLine(` ${colors.red}${icons.warning} ${criticalIssues.length} service(s) need attention${RESET}`);
173
+ for (const issue of criticalIssues) {
174
+ writeLine(` ${colors.dim}\u2022${RESET} ${issue.name}: ${issue.error || "not responding"}`);
175
+ if (issue.fix) {
176
+ writeLine(` ${colors.cyan}Fix:${RESET} ${issue.fix}`);
177
+ }
178
+ }
179
+ writeLine();
180
+ }
181
+ if (options.verbose && optionalIssues.length > 0) {
182
+ writeLine(` ${colors.yellow}Optional services down:${RESET}`);
183
+ for (const issue of optionalIssues) {
184
+ writeLine(` ${colors.dim}\u2022${RESET} ${issue.name}`);
185
+ }
186
+ writeLine();
187
+ }
188
+ } else {
189
+ writeLine(` ${colors.green}${icons.success} All services healthy${RESET}`);
190
+ writeLine();
191
+ }
192
+ const allDown = results.every((r) => r.status === "down");
193
+ if (allDown) {
194
+ writeLine(` ${colors.cyan}${icons.progress}${RESET} Running in local mode ${colors.dim}(no database required)${RESET}`);
195
+ writeLine(` Core commands work without infrastructure: ${colors.cyan}init${RESET}, ${colors.cyan}run${RESET}, ${colors.cyan}status${RESET}, ${colors.cyan}eval${RESET}`);
196
+ writeLine(` Memory uses local ${colors.dim}.agents/memory/${RESET} files.`);
197
+ writeLine();
198
+ writeLine(` ${colors.dim}To enable scheduling and telemetry:${RESET} squads stack up`);
199
+ writeLine();
200
+ } else if (!schedulerUp) {
201
+ writeLine(` ${colors.yellow}${icons.warning} Scheduler not running - triggers won't auto-fire${RESET}`);
202
+ writeLine(` ${colors.dim}Start with:${RESET} squads stack up scheduler`);
203
+ writeLine();
204
+ }
205
+ }
206
+ export {
207
+ healthCommand
208
+ };
209
+ //# sourceMappingURL=health-3FZDOSR5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/health.ts"],"sourcesContent":["/**\n * squads health - Quick infrastructure health check\n *\n * Lightweight check that doesn't require Docker - just pings endpoints\n */\n\nimport {\n colors,\n RESET,\n gradient,\n icons,\n writeLine,\n padEnd,\n} from '../lib/terminal.js';\n\nconst FETCH_TIMEOUT_MS = 2000;\n\ninterface ServiceCheck {\n name: string;\n url: string;\n optional?: boolean;\n fix?: string;\n}\n\ninterface ServiceResult {\n name: string;\n status: 'healthy' | 'down' | 'degraded';\n latencyMs?: number;\n error?: string;\n optional?: boolean;\n fix?: string;\n}\n\ninterface TriggerStats {\n active: number;\n disabled: number;\n lastFire?: {\n name: string;\n ago: string;\n };\n}\n\nconst SERVICES: ServiceCheck[] = [\n {\n name: 'PostgreSQL',\n url: `${process.env.SQUADS_BRIDGE_URL || 'http://localhost:8088'}/stats`,\n optional: true,\n fix: 'squads stack up postgres',\n },\n {\n name: 'Redis',\n url: `${process.env.SQUADS_BRIDGE_URL || 'http://localhost:8088'}/stats`,\n optional: true,\n fix: 'squads stack up redis',\n },\n {\n name: 'Bridge API',\n url: `${process.env.SQUADS_BRIDGE_URL || 'http://localhost:8088'}/health`,\n optional: true,\n fix: 'squads stack up bridge',\n },\n {\n name: 'Scheduler',\n url: `${process.env.SQUADS_API_URL || process.env.SQUADS_SCHEDULER_URL || 'http://localhost:8090'}/health`,\n optional: true,\n fix: 'squads stack up scheduler',\n },\n {\n name: 'Langfuse',\n url: `${process.env.LANGFUSE_HOST || 'http://localhost:3100'}/api/public/health`,\n optional: true,\n fix: 'squads stack up langfuse',\n },\n];\n\n/**\n * Fetch with timeout\n */\nasync function fetchWithTimeout(url: string, timeoutMs = FETCH_TIMEOUT_MS): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await fetch(url, { signal: controller.signal });\n clearTimeout(timeoutId);\n return response;\n } catch {\n clearTimeout(timeoutId);\n throw new Error('timeout');\n }\n}\n\n/**\n * Check a single service\n */\nasync function checkService(service: ServiceCheck): Promise<ServiceResult> {\n const start = Date.now();\n\n try {\n const response = await fetchWithTimeout(service.url);\n const latencyMs = Date.now() - start;\n\n if (response.ok) {\n return {\n name: service.name,\n status: 'healthy',\n latencyMs,\n optional: service.optional,\n };\n }\n\n return {\n name: service.name,\n status: 'degraded',\n latencyMs,\n error: `HTTP ${response.status}`,\n optional: service.optional,\n fix: service.fix,\n };\n } catch (error) {\n return {\n name: service.name,\n status: 'down',\n error: error instanceof Error ? error.message : 'unknown',\n optional: service.optional,\n fix: service.fix,\n };\n }\n}\n\n/**\n * Get trigger stats from scheduler\n */\nasync function getTriggerStats(): Promise<TriggerStats | null> {\n try {\n const schedulerUrl = process.env.SQUADS_API_URL || process.env.SQUADS_SCHEDULER_URL || 'http://localhost:8090';\n const response = await fetchWithTimeout(`${schedulerUrl}/api/triggers/stats`);\n\n if (!response.ok) return null;\n\n interface StatsResponse {\n active?: number;\n disabled?: number;\n last_fire?: {\n name?: string;\n fired_at?: string;\n };\n }\n\n const data = await response.json() as StatsResponse;\n return {\n active: data.active || 0,\n disabled: data.disabled || 0,\n lastFire: data.last_fire ? {\n name: data.last_fire.name || 'unknown',\n ago: formatTimeAgo(new Date(data.last_fire.fired_at || Date.now())),\n } : undefined,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Format time ago\n */\nfunction formatTimeAgo(date: Date): string {\n const seconds = Math.floor((Date.now() - date.getTime()) / 1000);\n\n if (seconds < 60) return `${seconds}s ago`;\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;\n if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;\n return `${Math.floor(seconds / 86400)}d ago`;\n}\n\n/**\n * Format latency\n */\nfunction formatLatency(ms?: number): string {\n if (!ms) return '—';\n return `${ms}ms`;\n}\n\nexport interface HealthOptions {\n verbose?: boolean;\n}\n\nexport async function healthCommand(options: HealthOptions = {}): Promise<void> {\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}health${RESET}`);\n writeLine();\n\n // Check all services in parallel\n const results = await Promise.all(SERVICES.map(checkService));\n\n // Display table\n writeLine(` ${colors.purple}┌${'─'.repeat(48)}┐${RESET}`);\n writeLine(` ${colors.purple}│${RESET} ${padEnd('SERVICE', 18)}${padEnd('STATUS', 14)}${padEnd('LATENCY', 12)}${colors.purple}│${RESET}`);\n writeLine(` ${colors.purple}├${'─'.repeat(48)}┤${RESET}`);\n\n const issues: ServiceResult[] = [];\n\n for (const result of results) {\n let statusIcon: string;\n let statusColor: string;\n let statusText: string;\n\n switch (result.status) {\n case 'healthy':\n statusIcon = icons.success;\n statusColor = colors.green;\n statusText = 'healthy';\n break;\n case 'degraded':\n statusIcon = icons.warning;\n statusColor = colors.yellow;\n statusText = 'degraded';\n issues.push(result);\n break;\n case 'down':\n statusIcon = icons.error;\n statusColor = colors.red;\n statusText = 'down';\n if (!result.optional) {\n issues.push(result);\n }\n break;\n }\n\n const nameDisplay = result.optional ? `${result.name} ${colors.dim}(opt)${RESET}` : result.name;\n const latency = formatLatency(result.latencyMs);\n\n writeLine(` ${colors.purple}│${RESET} ${padEnd(nameDisplay, 18)}${statusColor}${statusIcon} ${padEnd(statusText, 11)}${RESET}${padEnd(latency, 12)}${colors.purple}│${RESET}`);\n }\n\n writeLine(` ${colors.purple}└${'─'.repeat(48)}┘${RESET}`);\n writeLine();\n\n // Get trigger stats if scheduler is up\n const schedulerUp = results.find(r => r.name === 'Scheduler')?.status === 'healthy';\n if (schedulerUp) {\n const stats = await getTriggerStats();\n if (stats) {\n const lastFireText = stats.lastFire\n ? `${colors.dim}Last fire:${RESET} ${stats.lastFire.ago} (${stats.lastFire.name})`\n : `${colors.dim}No recent fires${RESET}`;\n\n writeLine(` ${colors.cyan}Triggers:${RESET} ${stats.active} active, ${stats.disabled} disabled`);\n writeLine(` ${lastFireText}`);\n writeLine();\n }\n }\n\n // Show issues and fixes\n if (issues.length > 0) {\n const criticalIssues = issues.filter(i => !i.optional);\n const optionalIssues = issues.filter(i => i.optional);\n\n if (criticalIssues.length > 0) {\n writeLine(` ${colors.red}${icons.warning} ${criticalIssues.length} service(s) need attention${RESET}`);\n for (const issue of criticalIssues) {\n writeLine(` ${colors.dim}•${RESET} ${issue.name}: ${issue.error || 'not responding'}`);\n if (issue.fix) {\n writeLine(` ${colors.cyan}Fix:${RESET} ${issue.fix}`);\n }\n }\n writeLine();\n }\n\n if (options.verbose && optionalIssues.length > 0) {\n writeLine(` ${colors.yellow}Optional services down:${RESET}`);\n for (const issue of optionalIssues) {\n writeLine(` ${colors.dim}•${RESET} ${issue.name}`);\n }\n writeLine();\n }\n } else {\n writeLine(` ${colors.green}${icons.success} All services healthy${RESET}`);\n writeLine();\n }\n\n // Show mode info\n const allDown = results.every(r => r.status === 'down');\n if (allDown) {\n writeLine(` ${colors.cyan}${icons.progress}${RESET} Running in local mode ${colors.dim}(no database required)${RESET}`);\n writeLine(` Core commands work without infrastructure: ${colors.cyan}init${RESET}, ${colors.cyan}run${RESET}, ${colors.cyan}status${RESET}, ${colors.cyan}eval${RESET}`);\n writeLine(` Memory uses local ${colors.dim}.agents/memory/${RESET} files.`);\n writeLine();\n writeLine(` ${colors.dim}To enable scheduling and telemetry:${RESET} squads stack up`);\n writeLine();\n } else if (!schedulerUp) {\n writeLine(` ${colors.yellow}${icons.warning} Scheduler not running - triggers won't auto-fire${RESET}`);\n writeLine(` ${colors.dim}Start with:${RESET} squads stack up scheduler`);\n writeLine();\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ RESET,
4
+ bold,
5
+ colors,
6
+ gradient,
7
+ icons,
8
+ padEnd,
9
+ truncate,
10
+ writeLine
11
+ } from "./chunk-N7KDWU4W.js";
12
+ import "./chunk-7OCVIDC7.js";
13
+
14
+ // src/commands/history.ts
15
+ import { existsSync, readFileSync } from "fs";
16
+ import { join } from "path";
17
+ var BRIDGE_URL = process.env.SQUADS_BRIDGE_URL || "http://localhost:8088";
18
+ var FETCH_TIMEOUT_MS = 3e3;
19
+ async function fetchWithTimeout(url, timeoutMs = FETCH_TIMEOUT_MS) {
20
+ const controller = new AbortController();
21
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
22
+ try {
23
+ const response = await fetch(url, { signal: controller.signal });
24
+ clearTimeout(timeoutId);
25
+ return response;
26
+ } catch {
27
+ clearTimeout(timeoutId);
28
+ throw new Error("Request timed out");
29
+ }
30
+ }
31
+ async function fetchFromBridge(days, squad) {
32
+ try {
33
+ const params = new URLSearchParams({
34
+ days: String(days),
35
+ ...squad && { squad }
36
+ });
37
+ const response = await fetchWithTimeout(`${BRIDGE_URL}/api/executions?${params}`);
38
+ if (!response.ok) {
39
+ return [];
40
+ }
41
+ const data = await response.json();
42
+ return (data.executions || []).map((e) => ({
43
+ id: e.id || "",
44
+ squad: e.squad || "unknown",
45
+ agent: e.agent || "unknown",
46
+ startedAt: new Date(e.started_at || Date.now()),
47
+ endedAt: e.ended_at ? new Date(e.ended_at) : void 0,
48
+ durationMs: e.duration_ms,
49
+ status: e.status || "success",
50
+ cost: e.cost_usd,
51
+ tokens: e.total_tokens,
52
+ error: e.error
53
+ }));
54
+ } catch {
55
+ return [];
56
+ }
57
+ }
58
+ function fetchFromLocal(days, squad) {
59
+ const executions = [];
60
+ const historyPaths = [
61
+ join(process.cwd(), ".agents/sessions/history.jsonl"),
62
+ join(process.env.HOME || "", "agents-squads/hq/.agents/sessions/history.jsonl")
63
+ ];
64
+ let historyPath;
65
+ for (const path of historyPaths) {
66
+ if (existsSync(path)) {
67
+ historyPath = path;
68
+ break;
69
+ }
70
+ }
71
+ if (!historyPath) {
72
+ return [];
73
+ }
74
+ try {
75
+ const content = readFileSync(historyPath, "utf-8");
76
+ const lines = content.trim().split("\n").filter(Boolean);
77
+ const cutoff = Date.now() - days * 24 * 60 * 60 * 1e3;
78
+ for (const line of lines) {
79
+ try {
80
+ const event = JSON.parse(line);
81
+ const timestamp = new Date(event.timestamp || 0);
82
+ if (timestamp.getTime() < cutoff) continue;
83
+ if (squad && event.squad !== squad) continue;
84
+ if (event.type === "session_end" || event.type === "agent_complete") {
85
+ executions.push({
86
+ id: event.sessionId || `local-${Date.now()}`,
87
+ squad: event.squad || "unknown",
88
+ agent: event.agent || "unknown",
89
+ startedAt: timestamp,
90
+ durationMs: event.duration,
91
+ status: event.status === "error" ? "error" : "success",
92
+ cost: event.cost,
93
+ tokens: event.tokens
94
+ });
95
+ }
96
+ } catch {
97
+ }
98
+ }
99
+ } catch {
100
+ }
101
+ return executions;
102
+ }
103
+ function formatDuration(ms) {
104
+ if (!ms) return "\u2014";
105
+ const seconds = Math.floor(ms / 1e3);
106
+ if (seconds < 60) return `${seconds}s`;
107
+ const minutes = Math.floor(seconds / 60);
108
+ const remainingSeconds = seconds % 60;
109
+ if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;
110
+ const hours = Math.floor(minutes / 60);
111
+ const remainingMinutes = minutes % 60;
112
+ return `${hours}h ${remainingMinutes}m`;
113
+ }
114
+ function groupByDate(executions) {
115
+ const groups = /* @__PURE__ */ new Map();
116
+ for (const exec of executions) {
117
+ const dateKey = exec.startedAt.toISOString().split("T")[0];
118
+ if (!groups.has(dateKey)) {
119
+ groups.set(dateKey, []);
120
+ }
121
+ groups.get(dateKey).push(exec);
122
+ }
123
+ return groups;
124
+ }
125
+ function formatDateHeader(dateStr) {
126
+ const date = new Date(dateStr);
127
+ const today = /* @__PURE__ */ new Date();
128
+ const yesterday = new Date(today);
129
+ yesterday.setDate(yesterday.getDate() - 1);
130
+ if (dateStr === today.toISOString().split("T")[0]) {
131
+ return `Today (${date.toLocaleDateString("en-US", { month: "short", day: "numeric" })})`;
132
+ }
133
+ if (dateStr === yesterday.toISOString().split("T")[0]) {
134
+ return `Yesterday (${date.toLocaleDateString("en-US", { month: "short", day: "numeric" })})`;
135
+ }
136
+ return date.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
137
+ }
138
+ async function historyCommand(options = {}) {
139
+ const days = options.days || 7;
140
+ const squad = options.squad;
141
+ const verbose = options.verbose || false;
142
+ const jsonOutput = options.json || false;
143
+ writeLine();
144
+ writeLine(` ${gradient("squads")} ${colors.dim}history${RESET}`);
145
+ writeLine();
146
+ const [bridgeExecs, localExecs] = await Promise.all([
147
+ fetchFromBridge(days, squad),
148
+ Promise.resolve(fetchFromLocal(days, squad))
149
+ ]);
150
+ const seenIds = /* @__PURE__ */ new Set();
151
+ const allExecutions = [];
152
+ for (const exec of bridgeExecs) {
153
+ seenIds.add(exec.id);
154
+ allExecutions.push(exec);
155
+ }
156
+ for (const exec of localExecs) {
157
+ if (!seenIds.has(exec.id)) {
158
+ allExecutions.push(exec);
159
+ }
160
+ }
161
+ allExecutions.sort((a, b) => b.startedAt.getTime() - a.startedAt.getTime());
162
+ if (jsonOutput) {
163
+ console.log(JSON.stringify(allExecutions, null, 2));
164
+ return;
165
+ }
166
+ if (allExecutions.length === 0) {
167
+ writeLine(` ${colors.dim}No executions found in the last ${days} day(s)${RESET}`);
168
+ writeLine();
169
+ writeLine(` ${colors.dim}Tip: Run agents with 'squads run <squad>' to see history${RESET}`);
170
+ writeLine();
171
+ return;
172
+ }
173
+ const grouped = groupByDate(allExecutions);
174
+ const source = bridgeExecs.length > 0 ? "postgres" : "local";
175
+ writeLine(` ${colors.dim}${allExecutions.length} executions (last ${days}d, source: ${source})${RESET}`);
176
+ writeLine();
177
+ for (const [dateStr, execs] of grouped) {
178
+ writeLine(` ${bold}${formatDateHeader(dateStr)}${RESET}`);
179
+ writeLine(` ${colors.purple}\u250C${"\u2500".repeat(60)}\u2510${RESET}`);
180
+ writeLine(` ${colors.purple}\u2502${RESET} ${padEnd("TIME", 7)}${padEnd("SQUAD", 13)}${padEnd("AGENT", 16)}${padEnd("DURATION", 10)}${padEnd("STATUS", 8)}${colors.purple}\u2502${RESET}`);
181
+ writeLine(` ${colors.purple}\u251C${"\u2500".repeat(60)}\u2524${RESET}`);
182
+ for (const exec of execs) {
183
+ const time = exec.startedAt.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", hour12: false });
184
+ const squadName = truncate(exec.squad, 11);
185
+ const agentName = truncate(exec.agent, 14);
186
+ const duration = formatDuration(exec.durationMs);
187
+ let statusIcon;
188
+ let statusColor;
189
+ switch (exec.status) {
190
+ case "success":
191
+ statusIcon = icons.success;
192
+ statusColor = colors.green;
193
+ break;
194
+ case "error":
195
+ statusIcon = icons.error;
196
+ statusColor = colors.red;
197
+ break;
198
+ case "running":
199
+ statusIcon = icons.progress;
200
+ statusColor = colors.cyan;
201
+ break;
202
+ default:
203
+ statusIcon = icons.empty;
204
+ statusColor = colors.dim;
205
+ }
206
+ writeLine(` ${colors.purple}\u2502${RESET} ${colors.dim}${time}${RESET} ${colors.cyan}${padEnd(squadName, 12)}${RESET}${padEnd(agentName, 16)}${padEnd(duration, 10)}${statusColor}${statusIcon}${RESET} ${colors.purple}\u2502${RESET}`);
207
+ if (verbose && (exec.cost || exec.tokens)) {
208
+ const costStr = exec.cost ? `$${exec.cost.toFixed(2)}` : "";
209
+ const tokenStr = exec.tokens ? `${exec.tokens.toLocaleString()} tokens` : "";
210
+ const details = [costStr, tokenStr].filter(Boolean).join(" \u2502 ");
211
+ writeLine(` ${colors.purple}\u2502${RESET} ${colors.dim}\u2514 ${details}${RESET}${" ".repeat(Math.max(0, 45 - details.length))}${colors.purple}\u2502${RESET}`);
212
+ }
213
+ if (exec.error) {
214
+ writeLine(` ${colors.purple}\u2502${RESET} ${colors.red}\u2514 ${truncate(exec.error, 45)}${RESET}${" ".repeat(Math.max(0, 45 - exec.error.length))}${colors.purple}\u2502${RESET}`);
215
+ }
216
+ }
217
+ writeLine(` ${colors.purple}\u2514${"\u2500".repeat(60)}\u2518${RESET}`);
218
+ writeLine();
219
+ }
220
+ const successCount = allExecutions.filter((e) => e.status === "success").length;
221
+ const errorCount = allExecutions.filter((e) => e.status === "error").length;
222
+ const totalCost = allExecutions.reduce((sum, e) => sum + (e.cost || 0), 0);
223
+ writeLine(` ${colors.dim}Summary:${RESET} ${colors.green}${successCount} success${RESET} ${errorCount > 0 ? `${colors.red}${errorCount} errors${RESET} ` : ""}${totalCost > 0 ? `${colors.cyan}$${totalCost.toFixed(2)} total${RESET}` : ""}`);
224
+ writeLine();
225
+ }
226
+ export {
227
+ historyCommand
228
+ };
229
+ //# sourceMappingURL=history-TFVXJEDH.js.map