squads-cli 0.4.0 → 0.4.5
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/README.md +168 -0
- package/dist/cli.js +178 -73
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -511,6 +511,84 @@ squads stack logs bridge # View container logs
|
|
|
511
511
|
squads stack logs postgres -n 100 # Last 100 lines
|
|
512
512
|
```
|
|
513
513
|
|
|
514
|
+
### Tonight Mode (Autonomous Execution)
|
|
515
|
+
|
|
516
|
+
Run agents autonomously overnight with safety guardrails:
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
# Run intelligence squad overnight
|
|
520
|
+
squads tonight intelligence
|
|
521
|
+
|
|
522
|
+
# Multiple targets with cost cap
|
|
523
|
+
squads tonight intelligence customer/outreach --cost-cap 25
|
|
524
|
+
|
|
525
|
+
# Preview what would run
|
|
526
|
+
squads tonight engineering --dry-run
|
|
527
|
+
|
|
528
|
+
# Check status while running
|
|
529
|
+
squads tonight status
|
|
530
|
+
|
|
531
|
+
# Stop all overnight agents
|
|
532
|
+
squads tonight stop
|
|
533
|
+
|
|
534
|
+
# View the morning report
|
|
535
|
+
squads tonight report
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**Example output:**
|
|
539
|
+
|
|
540
|
+
```
|
|
541
|
+
$ squads tonight intelligence customer/outreach
|
|
542
|
+
|
|
543
|
+
squads tonight
|
|
544
|
+
|
|
545
|
+
Config:
|
|
546
|
+
Cost cap: $50
|
|
547
|
+
Stop at: 07:00
|
|
548
|
+
Max retries: 3
|
|
549
|
+
Targets: intelligence, customer/outreach
|
|
550
|
+
|
|
551
|
+
✓ Launched 2 agent(s)
|
|
552
|
+
|
|
553
|
+
✓ Tonight mode active
|
|
554
|
+
|
|
555
|
+
Monitor:
|
|
556
|
+
squads tonight status - Check progress
|
|
557
|
+
squads tonight stop - Kill all agents
|
|
558
|
+
tmux ls | grep tonight - List sessions
|
|
559
|
+
|
|
560
|
+
Logs: .agents/outputs/tonight/
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**Safety features:**
|
|
564
|
+
- **Cost cap** — Automatically stops when spending limit reached (default: $50)
|
|
565
|
+
- **Time limit** — Stops at specified time (default: 7:00 AM)
|
|
566
|
+
- **Max retries** — Limits restart attempts for crashed agents (default: 3)
|
|
567
|
+
- **Session isolation** — Each agent runs in isolated tmux session
|
|
568
|
+
- **Logging** — All output captured to `.agents/outputs/tonight/`
|
|
569
|
+
- **Morning report** — Summary generated on completion
|
|
570
|
+
|
|
571
|
+
**Monitoring commands:**
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
# Check current status
|
|
575
|
+
squads tonight status
|
|
576
|
+
|
|
577
|
+
# Attach to a running session
|
|
578
|
+
tmux attach -t squads-tonight-intelligence-...
|
|
579
|
+
|
|
580
|
+
# View live logs
|
|
581
|
+
tail -f .agents/outputs/tonight/*.log
|
|
582
|
+
|
|
583
|
+
# Stop everything immediately
|
|
584
|
+
squads tonight stop
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
> **Warning**: Tonight mode uses `--dangerously-skip-permissions` which bypasses
|
|
588
|
+
> Claude's safety confirmations. Only use with trusted agent definitions. Review
|
|
589
|
+
> your agent prompts and ensure they have appropriate scope limits before running
|
|
590
|
+
> autonomously.
|
|
591
|
+
|
|
514
592
|
### Smart Triggers
|
|
515
593
|
|
|
516
594
|
Triggers execute agents based on conditions in PostgreSQL:
|
|
@@ -694,6 +772,16 @@ squads trigger enable <name> Enable trigger
|
|
|
694
772
|
squads trigger disable <name> Disable trigger
|
|
695
773
|
squads trigger status Scheduler stats
|
|
696
774
|
|
|
775
|
+
squads tonight <targets...> Autonomous overnight execution
|
|
776
|
+
--cost-cap <usd> Max spend (default: $50)
|
|
777
|
+
--stop-at <time> Stop time HH:MM (default: 07:00)
|
|
778
|
+
--max-retries <n> Restart limit (default: 3)
|
|
779
|
+
-d, --dry-run Preview only
|
|
780
|
+
-v, --verbose Verbose output
|
|
781
|
+
squads tonight status Check progress
|
|
782
|
+
squads tonight stop Kill all agents
|
|
783
|
+
squads tonight report View morning report
|
|
784
|
+
|
|
697
785
|
squads update Interactive update
|
|
698
786
|
-y, --yes Auto-confirm
|
|
699
787
|
-c, --check Check only
|
|
@@ -761,6 +849,86 @@ your-project/
|
|
|
761
849
|
└── CLAUDE.md # Project instructions
|
|
762
850
|
```
|
|
763
851
|
|
|
852
|
+
## Analytics
|
|
853
|
+
|
|
854
|
+
Track token usage, costs, and API calls across your squads.
|
|
855
|
+
|
|
856
|
+
### Setup
|
|
857
|
+
|
|
858
|
+
1. **Configure your Claude plan:**
|
|
859
|
+
```bash
|
|
860
|
+
export SQUADS_PLAN_TYPE=max # $200/mo flat rate
|
|
861
|
+
# or
|
|
862
|
+
export SQUADS_PLAN_TYPE=usage # pay-per-token
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
2. **Connect to telemetry (optional):**
|
|
866
|
+
```bash
|
|
867
|
+
# Self-hosted via Docker
|
|
868
|
+
cd docker && docker-compose up -d
|
|
869
|
+
|
|
870
|
+
# Or configure external services
|
|
871
|
+
export LANGFUSE_HOST=https://your-langfuse.com
|
|
872
|
+
export LANGFUSE_PUBLIC_KEY=pk-...
|
|
873
|
+
export LANGFUSE_SECRET_KEY=sk-...
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
3. **View in dashboard:**
|
|
877
|
+
```bash
|
|
878
|
+
squads dash
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### Metrics Tracked
|
|
882
|
+
|
|
883
|
+
- Token usage (input/output/cache)
|
|
884
|
+
- API costs per squad/agent
|
|
885
|
+
- Rate limit status
|
|
886
|
+
- Generation counts
|
|
887
|
+
|
|
888
|
+
## Infrastructure
|
|
889
|
+
|
|
890
|
+
Optional services that enhance squad capabilities.
|
|
891
|
+
|
|
892
|
+
### Services
|
|
893
|
+
|
|
894
|
+
| Service | Purpose |
|
|
895
|
+
|---------|---------|
|
|
896
|
+
| postgres | Session storage, trigger conditions |
|
|
897
|
+
| redis | Caching, rate limiting |
|
|
898
|
+
| otel | OpenTelemetry metrics pipeline |
|
|
899
|
+
| langfuse | Telemetry dashboard |
|
|
900
|
+
| bridge | Conversation capture API |
|
|
901
|
+
|
|
902
|
+
### Self-Hosted Setup
|
|
903
|
+
|
|
904
|
+
```bash
|
|
905
|
+
# Clone the infrastructure
|
|
906
|
+
git clone https://github.com/agents-squads/squads-infra
|
|
907
|
+
cd squads-infra
|
|
908
|
+
|
|
909
|
+
# Start services
|
|
910
|
+
docker-compose up -d
|
|
911
|
+
|
|
912
|
+
# Configure CLI
|
|
913
|
+
squads stack env >> ~/.zshrc
|
|
914
|
+
source ~/.zshrc
|
|
915
|
+
|
|
916
|
+
# Verify
|
|
917
|
+
squads stack health
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
### Minimal Setup (Postgres only)
|
|
921
|
+
|
|
922
|
+
```bash
|
|
923
|
+
# Just need triggers and session storage
|
|
924
|
+
docker run -d --name squads-postgres \
|
|
925
|
+
-e POSTGRES_PASSWORD=squads \
|
|
926
|
+
-p 5432:5432 \
|
|
927
|
+
postgres:16
|
|
928
|
+
|
|
929
|
+
export SQUADS_POSTGRES_URL=postgres://postgres:squads@localhost:5432/squads
|
|
930
|
+
```
|
|
931
|
+
|
|
764
932
|
## Development
|
|
765
933
|
|
|
766
934
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -37,12 +37,15 @@ import {
|
|
|
37
37
|
import { config } from "dotenv";
|
|
38
38
|
import { existsSync as existsSync17 } from "fs";
|
|
39
39
|
import { join as join17 } from "path";
|
|
40
|
-
import { homedir as
|
|
40
|
+
import { homedir as homedir5 } from "os";
|
|
41
41
|
import { Command } from "commander";
|
|
42
42
|
import chalk4 from "chalk";
|
|
43
43
|
|
|
44
44
|
// src/version.ts
|
|
45
|
-
|
|
45
|
+
import { createRequire } from "module";
|
|
46
|
+
var require2 = createRequire(import.meta.url);
|
|
47
|
+
var pkg = require2("../package.json");
|
|
48
|
+
var version = pkg.version;
|
|
46
49
|
|
|
47
50
|
// src/commands/init.ts
|
|
48
51
|
import chalk from "chalk";
|
|
@@ -797,6 +800,10 @@ async function initCommand(options) {
|
|
|
797
800
|
if (hasMissingRequired) {
|
|
798
801
|
console.log(chalk.yellow(" Install missing tools to continue, then run squads init again."));
|
|
799
802
|
console.log();
|
|
803
|
+
track(Events.CLI_INIT, {
|
|
804
|
+
success: false,
|
|
805
|
+
reason: "missing_requirements"
|
|
806
|
+
});
|
|
800
807
|
return;
|
|
801
808
|
}
|
|
802
809
|
console.log(chalk.dim(" Checking project setup..."));
|
|
@@ -830,6 +837,10 @@ async function initCommand(options) {
|
|
|
830
837
|
|
|
831
838
|
Demonstrates squads functionality with safe, educational examples.
|
|
832
839
|
|
|
840
|
+
## Goals
|
|
841
|
+
|
|
842
|
+
- [ ] Run the demo agents and explore the dashboard
|
|
843
|
+
|
|
833
844
|
## Agents
|
|
834
845
|
|
|
835
846
|
| Agent | Purpose |
|
|
@@ -965,50 +976,90 @@ Markdown report saved to .agents/outputs/demo/project-analysis.md
|
|
|
965
976
|
claudeMdPath,
|
|
966
977
|
`# Project Instructions
|
|
967
978
|
|
|
968
|
-
## Squads
|
|
969
|
-
|
|
970
|
-
This project uses AI agent squads for automation.
|
|
971
|
-
|
|
972
|
-
### Quick Start
|
|
979
|
+
## What is Squads?
|
|
973
980
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
squads dash # Full dashboard
|
|
977
|
-
squads run demo # Try the demo squad
|
|
978
|
-
squads run <squad> # Execute a squad
|
|
979
|
-
\`\`\`
|
|
981
|
+
Squads is a framework for building AI agent teams that automate real work.
|
|
982
|
+
Each **squad** is a team of **agents** (markdown prompts) that execute via Claude.
|
|
980
983
|
|
|
981
|
-
|
|
984
|
+
## For Claude (READ THIS)
|
|
982
985
|
|
|
983
|
-
|
|
986
|
+
When helping users with squad-related tasks:
|
|
984
987
|
|
|
988
|
+
### Check Context First
|
|
985
989
|
\`\`\`bash
|
|
986
|
-
squads
|
|
987
|
-
squads memory
|
|
990
|
+
squads status # What squads exist?
|
|
991
|
+
squads memory query "X" # What do we know about X?
|
|
988
992
|
\`\`\`
|
|
989
993
|
|
|
990
994
|
### Creating Agents
|
|
991
|
-
|
|
992
|
-
Agents are markdown files in \`.agents/squads/<squad>/\`:
|
|
995
|
+
Agents live in \`.agents/squads/<squad-name>/<agent-name>.md\`:
|
|
993
996
|
|
|
994
997
|
\`\`\`markdown
|
|
995
|
-
#
|
|
998
|
+
# Agent Name
|
|
996
999
|
|
|
997
1000
|
## Purpose
|
|
998
|
-
|
|
1001
|
+
One sentence: what this agent does.
|
|
999
1002
|
|
|
1000
1003
|
## Instructions
|
|
1001
|
-
1.
|
|
1002
|
-
2.
|
|
1004
|
+
1. Specific step
|
|
1005
|
+
2. Another step
|
|
1006
|
+
3. Output location
|
|
1003
1007
|
|
|
1004
1008
|
## Output
|
|
1005
|
-
What it produces.
|
|
1009
|
+
What it produces and where it goes.
|
|
1010
|
+
\`\`\`
|
|
1011
|
+
|
|
1012
|
+
### Running Agents
|
|
1013
|
+
\`\`\`bash
|
|
1014
|
+
squads run <squad> # Run all agents in squad
|
|
1015
|
+
squads run <squad>/<agent> # Run specific agent
|
|
1016
|
+
\`\`\`
|
|
1017
|
+
|
|
1018
|
+
### Tracking Progress
|
|
1019
|
+
\`\`\`bash
|
|
1020
|
+
squads dash # Full dashboard with goals
|
|
1021
|
+
squads goal list # View all goals
|
|
1022
|
+
squads goal set <squad> "X" # Add a goal
|
|
1023
|
+
\`\`\`
|
|
1024
|
+
|
|
1025
|
+
### Common User Requests
|
|
1026
|
+
|
|
1027
|
+
| User says | You should |
|
|
1028
|
+
|-----------|------------|
|
|
1029
|
+
| "Create an agent to..." | Create \`.agents/squads/<squad>/<name>.md\` |
|
|
1030
|
+
| "Automate X" | Create agent, then \`squads run\` |
|
|
1031
|
+
| "What's the status?" | Run \`squads dash\` or \`squads status\` |
|
|
1032
|
+
| "Run the X agent" | \`squads run <squad>/x\` |
|
|
1033
|
+
| "Check memory" | \`squads memory query "<topic>"\` |
|
|
1034
|
+
|
|
1035
|
+
## Quick Reference
|
|
1036
|
+
|
|
1037
|
+
\`\`\`bash
|
|
1038
|
+
squads status # Overview
|
|
1039
|
+
squads dash # Full dashboard
|
|
1040
|
+
squads run demo # Try demo squad
|
|
1041
|
+
squads list # All agents
|
|
1042
|
+
squads memory query X # Search memory
|
|
1043
|
+
squads goal list # View goals
|
|
1044
|
+
\`\`\`
|
|
1045
|
+
|
|
1046
|
+
## Project Structure
|
|
1047
|
+
|
|
1048
|
+
\`\`\`
|
|
1049
|
+
.agents/
|
|
1050
|
+
\u251C\u2500\u2500 squads/ # Agent teams
|
|
1051
|
+
\u2502 \u2514\u2500\u2500 <squad>/
|
|
1052
|
+
\u2502 \u251C\u2500\u2500 SQUAD.md # Squad definition
|
|
1053
|
+
\u2502 \u2514\u2500\u2500 *.md # Agent files
|
|
1054
|
+
\u251C\u2500\u2500 memory/ # Persistent context
|
|
1055
|
+
\u2514\u2500\u2500 outputs/ # Agent outputs
|
|
1006
1056
|
\`\`\`
|
|
1007
1057
|
`
|
|
1008
1058
|
);
|
|
1009
1059
|
}
|
|
1010
1060
|
spinner.succeed("Squad structure created");
|
|
1011
1061
|
await track(Events.CLI_INIT, {
|
|
1062
|
+
success: true,
|
|
1012
1063
|
hasGit: gitStatus.isGitRepo,
|
|
1013
1064
|
hasRemote: gitStatus.hasRemote,
|
|
1014
1065
|
template: options.template,
|
|
@@ -1017,6 +1068,11 @@ What it produces.
|
|
|
1017
1068
|
} catch (error) {
|
|
1018
1069
|
spinner.fail("Failed to create structure");
|
|
1019
1070
|
console.error(chalk.red(` ${error}`));
|
|
1071
|
+
track(Events.CLI_INIT, {
|
|
1072
|
+
success: false,
|
|
1073
|
+
reason: "structure_creation_failed",
|
|
1074
|
+
error: String(error)
|
|
1075
|
+
});
|
|
1020
1076
|
process.exit(1);
|
|
1021
1077
|
}
|
|
1022
1078
|
if (!options.skipInfra && hasDocker) {
|
|
@@ -1038,19 +1094,21 @@ What it produces.
|
|
|
1038
1094
|
}
|
|
1039
1095
|
}
|
|
1040
1096
|
console.log();
|
|
1041
|
-
console.log(chalk.green(" \u2713
|
|
1097
|
+
console.log(chalk.green.bold(" \u2713 Squads initialized!"));
|
|
1042
1098
|
console.log();
|
|
1043
|
-
console.log(
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1099
|
+
console.log(chalk.dim(" Created:"));
|
|
1100
|
+
console.log(chalk.dim(" \u2022 .agents/squads/demo/ - Demo squad with 2 agents"));
|
|
1101
|
+
console.log(chalk.dim(" \u2022 .claude/settings.json - Claude Code hooks"));
|
|
1102
|
+
console.log(chalk.dim(" \u2022 CLAUDE.md - Agent instructions"));
|
|
1047
1103
|
console.log();
|
|
1048
|
-
console.log(chalk.
|
|
1049
|
-
console.log(` ${chalk.cyan("1.")} Try the demo: ${chalk.yellow("squads run demo")}`);
|
|
1050
|
-
console.log(` ${chalk.cyan("2.")} Check status: ${chalk.yellow("squads dash")}`);
|
|
1051
|
-
console.log(` ${chalk.cyan("3.")} Create your own squad in ${chalk.cyan(".agents/squads/")}`);
|
|
1104
|
+
console.log(chalk.bold(" \u{1F449} Try it now:"));
|
|
1052
1105
|
console.log();
|
|
1053
|
-
console.log(chalk.
|
|
1106
|
+
console.log(` ${chalk.yellow.bold("squads status")}`);
|
|
1107
|
+
console.log();
|
|
1108
|
+
console.log(chalk.dim(" Then explore:"));
|
|
1109
|
+
console.log(chalk.dim(` \u2022 ${chalk.cyan("squads dash")} Full dashboard`));
|
|
1110
|
+
console.log(chalk.dim(` \u2022 ${chalk.cyan("squads run demo")} Try demo agents`));
|
|
1111
|
+
console.log(chalk.dim(` \u2022 ${chalk.cyan("squads --help")} All commands`));
|
|
1054
1112
|
console.log();
|
|
1055
1113
|
}
|
|
1056
1114
|
|
|
@@ -1076,6 +1134,20 @@ function findSquadsDir() {
|
|
|
1076
1134
|
}
|
|
1077
1135
|
return null;
|
|
1078
1136
|
}
|
|
1137
|
+
function findProjectRoot() {
|
|
1138
|
+
const squadsDir = findSquadsDir();
|
|
1139
|
+
if (!squadsDir) return null;
|
|
1140
|
+
return join3(squadsDir, "..", "..");
|
|
1141
|
+
}
|
|
1142
|
+
function hasLocalInfraConfig() {
|
|
1143
|
+
const projectRoot = findProjectRoot();
|
|
1144
|
+
if (!projectRoot) return false;
|
|
1145
|
+
const envPath = join3(projectRoot, ".env");
|
|
1146
|
+
if (!existsSync3(envPath)) return false;
|
|
1147
|
+
const content = readFileSync2(envPath, "utf-8");
|
|
1148
|
+
const infraKeys = ["LANGFUSE_", "SQUADS_BRIDGE", "SQUADS_POSTGRES", "SQUADS_REDIS"];
|
|
1149
|
+
return infraKeys.some((key) => content.includes(key));
|
|
1150
|
+
}
|
|
1079
1151
|
function listSquads(squadsDir) {
|
|
1080
1152
|
const squads = [];
|
|
1081
1153
|
const entries = readdirSync(squadsDir, { withFileTypes: true });
|
|
@@ -1749,7 +1821,7 @@ async function executeWithClaude(prompt2, verbose, _timeoutMinutes = 30, foregro
|
|
|
1749
1821
|
writeLine(` ${colors.dim}Session: ${sessionName}${RESET}`);
|
|
1750
1822
|
writeLine(` ${colors.dim}Auth: ${useApi ? "API credits" : "subscription"}${RESET}`);
|
|
1751
1823
|
}
|
|
1752
|
-
const claudeCmd = `cd '${projectRoot}' && claude --dangerously-skip-permissions --mcp-config '${userConfigPath}' -- '${escapedPrompt}'`;
|
|
1824
|
+
const claudeCmd = `cd '${projectRoot}' && claude --dangerously-skip-permissions --mcp-config '${userConfigPath}' -- '${escapedPrompt}'; tmux kill-session -t ${sessionName} 2>/dev/null`;
|
|
1753
1825
|
const tmux = spawn2("tmux", [
|
|
1754
1826
|
"new-session",
|
|
1755
1827
|
"-d",
|
|
@@ -1854,8 +1926,8 @@ function getPackageVersion() {
|
|
|
1854
1926
|
];
|
|
1855
1927
|
for (const pkgPath of possiblePaths) {
|
|
1856
1928
|
if (existsSync5(pkgPath)) {
|
|
1857
|
-
const
|
|
1858
|
-
return
|
|
1929
|
+
const pkg2 = JSON.parse(readFileSync4(pkgPath, "utf-8"));
|
|
1930
|
+
return pkg2.version || "0.0.0";
|
|
1859
1931
|
}
|
|
1860
1932
|
}
|
|
1861
1933
|
} catch {
|
|
@@ -3533,6 +3605,7 @@ async function goalListCommand(squadName, options = {}) {
|
|
|
3533
3605
|
const squadsDir = findSquadsDir();
|
|
3534
3606
|
if (!squadsDir) {
|
|
3535
3607
|
writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);
|
|
3608
|
+
writeLine(` ${colors.dim}Run \`squads init\` to create one.${RESET}`);
|
|
3536
3609
|
return;
|
|
3537
3610
|
}
|
|
3538
3611
|
const squadsToCheck = squadName ? [squadName] : listSquads(squadsDir);
|
|
@@ -3844,7 +3917,6 @@ async function feedbackStatsCommand() {
|
|
|
3844
3917
|
// src/commands/dashboard.ts
|
|
3845
3918
|
import { readdirSync as readdirSync4, existsSync as existsSync10, statSync as statSync2 } from "fs";
|
|
3846
3919
|
import { join as join10 } from "path";
|
|
3847
|
-
import { homedir as homedir4 } from "os";
|
|
3848
3920
|
|
|
3849
3921
|
// src/lib/providers.ts
|
|
3850
3922
|
var PROVIDERS = {
|
|
@@ -4155,7 +4227,7 @@ function detectPlan() {
|
|
|
4155
4227
|
if (tier >= 1 && tier <= 2) {
|
|
4156
4228
|
return { plan: "usage", confidence: "inferred", reason: `Tier ${tier} (new user)` };
|
|
4157
4229
|
}
|
|
4158
|
-
return { plan: "
|
|
4230
|
+
return { plan: "unknown", confidence: "inferred", reason: "Not configured" };
|
|
4159
4231
|
}
|
|
4160
4232
|
function getPlanType() {
|
|
4161
4233
|
return detectPlan().plan;
|
|
@@ -4547,7 +4619,7 @@ async function fetchInsights(period = "week") {
|
|
|
4547
4619
|
};
|
|
4548
4620
|
}
|
|
4549
4621
|
}
|
|
4550
|
-
async function fetchNpmStats(packageName = "squads-cli") {
|
|
4622
|
+
async function fetchNpmStats(packageName = process.env.SQUADS_NPM_PACKAGE || "squads-cli") {
|
|
4551
4623
|
try {
|
|
4552
4624
|
const [dayRes, weekRes, monthRes] = await Promise.all([
|
|
4553
4625
|
fetch(`https://api.npmjs.org/downloads/point/last-day/${packageName}`),
|
|
@@ -4577,9 +4649,9 @@ async function fetchNpmStats(packageName = "squads-cli") {
|
|
|
4577
4649
|
}
|
|
4578
4650
|
|
|
4579
4651
|
// src/lib/db.ts
|
|
4580
|
-
import { createRequire } from "module";
|
|
4581
|
-
var
|
|
4582
|
-
var pg =
|
|
4652
|
+
import { createRequire as createRequire2 } from "module";
|
|
4653
|
+
var require3 = createRequire2(import.meta.url);
|
|
4654
|
+
var pg = require3("pg");
|
|
4583
4655
|
var { Pool } = pg;
|
|
4584
4656
|
var DATABASE_URL = process.env.SQUADS_DATABASE_URL || "postgresql://squads:squads_local_dev@localhost:5433/squads";
|
|
4585
4657
|
var pool = null;
|
|
@@ -4735,6 +4807,7 @@ async function dashboardCommand(options = {}) {
|
|
|
4735
4807
|
const squadsDir = findSquadsDir();
|
|
4736
4808
|
if (!squadsDir) {
|
|
4737
4809
|
writeLine(`${colors.red}No .agents/squads directory found${RESET}`);
|
|
4810
|
+
writeLine(`${colors.dim}Run \`squads init\` to create one.${RESET}`);
|
|
4738
4811
|
return;
|
|
4739
4812
|
}
|
|
4740
4813
|
if (options.ceo) {
|
|
@@ -4877,12 +4950,12 @@ async function dashboardCommand(options = {}) {
|
|
|
4877
4950
|
const prs = gh?.prsMerged || 0;
|
|
4878
4951
|
const issuesClosed = gh?.issuesClosed || 0;
|
|
4879
4952
|
const issuesOpen = gh?.issuesOpen || 0;
|
|
4880
|
-
const
|
|
4953
|
+
const completedCount = squad.goals.filter((g) => g.completed).length;
|
|
4881
4954
|
const totalCount = squad.goals.length;
|
|
4882
4955
|
const commitColor = commits > 10 ? colors.green : commits > 0 ? colors.cyan : colors.dim;
|
|
4883
4956
|
const prColor = prs > 0 ? colors.green : colors.dim;
|
|
4884
4957
|
const issueColor = issuesClosed > 0 ? colors.green : colors.dim;
|
|
4885
|
-
writeLine(` ${colors.purple}${box.vertical}${RESET} ${colors.cyan}${padEnd(squad.name, w.name)}${RESET}${commitColor}${padEnd(String(commits), w.commits)}${RESET}${prColor}${padEnd(String(prs), w.prs)}${RESET}${issueColor}${padEnd(`${issuesClosed}/${issuesOpen}`, w.issues)}${RESET}${padEnd(`${
|
|
4958
|
+
writeLine(` ${colors.purple}${box.vertical}${RESET} ${colors.cyan}${padEnd(squad.name, w.name)}${RESET}${commitColor}${padEnd(String(commits), w.commits)}${RESET}${prColor}${padEnd(String(prs), w.prs)}${RESET}${issueColor}${padEnd(`${issuesClosed}/${issuesOpen}`, w.issues)}${RESET}${padEnd(`${completedCount}/${totalCount}`, w.goals)}${progressBar(squad.goalProgress, 8)} ${colors.purple}${box.vertical}${RESET}`);
|
|
4886
4959
|
}
|
|
4887
4960
|
writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);
|
|
4888
4961
|
writeLine();
|
|
@@ -4924,14 +4997,12 @@ async function dashboardCommand(options = {}) {
|
|
|
4924
4997
|
await closeDatabase();
|
|
4925
4998
|
}
|
|
4926
4999
|
function findAgentsSquadsDir() {
|
|
4927
|
-
const
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
return dir;
|
|
4934
|
-
}
|
|
5000
|
+
const parentDir = join10(process.cwd(), "..");
|
|
5001
|
+
if (existsSync10(join10(parentDir, "hq"))) {
|
|
5002
|
+
return parentDir;
|
|
5003
|
+
}
|
|
5004
|
+
if (existsSync10(join10(process.cwd(), ".git"))) {
|
|
5005
|
+
return process.cwd();
|
|
4935
5006
|
}
|
|
4936
5007
|
return null;
|
|
4937
5008
|
}
|
|
@@ -4983,19 +5054,36 @@ function renderGitPerformanceCached(cache) {
|
|
|
4983
5054
|
function renderTokenEconomicsCached(cache, goalCount) {
|
|
4984
5055
|
const costs = cache.costs;
|
|
4985
5056
|
const stats = cache.bridgeStats;
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
5057
|
+
const hasInfra = hasLocalInfraConfig();
|
|
5058
|
+
const hasData = costs || stats;
|
|
5059
|
+
writeLine(` ${bold}Token Economics${RESET}`);
|
|
5060
|
+
writeLine();
|
|
5061
|
+
const planType = getPlanType();
|
|
5062
|
+
const tier = parseInt(process.env.ANTHROPIC_TIER || "0", 10);
|
|
5063
|
+
if (planType === "unknown") {
|
|
5064
|
+
writeLine(` ${colors.dim}\u25CB${RESET} ${bold}Plan${RESET} ${colors.yellow}not configured${RESET}`);
|
|
5065
|
+
writeLine();
|
|
5066
|
+
writeLine(` ${colors.dim}Set your Claude plan:${RESET}`);
|
|
5067
|
+
writeLine(` ${colors.dim}$${RESET} export SQUADS_PLAN_TYPE=max ${colors.dim}# $200/mo flat${RESET}`);
|
|
5068
|
+
writeLine(` ${colors.dim}$${RESET} export SQUADS_PLAN_TYPE=usage ${colors.dim}# pay-per-token${RESET}`);
|
|
5069
|
+
writeLine();
|
|
5070
|
+
} else {
|
|
5071
|
+
const maxPlan = planType === "max";
|
|
5072
|
+
const planIcon = maxPlan ? `${colors.purple}\u25C6${RESET}` : `${colors.dim}\u25CB${RESET}`;
|
|
5073
|
+
const planLabel = maxPlan ? "Claude Max" : "Claude Pro";
|
|
5074
|
+
const planCost = maxPlan ? "$200/mo flat" : "pay-per-token";
|
|
5075
|
+
const tierDisplay = tier > 0 ? ` ${colors.dim}Tier ${tier}${RESET}` : "";
|
|
5076
|
+
writeLine(` ${planIcon} ${bold}${planLabel}${RESET} ${colors.dim}${planCost}${RESET}${tierDisplay}`);
|
|
5077
|
+
writeLine();
|
|
5078
|
+
}
|
|
5079
|
+
if (!hasInfra || !hasData) {
|
|
5080
|
+
writeLine(` ${colors.dim}\u25CB${RESET} Track costs, tokens, and API usage`);
|
|
5081
|
+
writeLine(` ${colors.dim}\u25CB${RESET} Monitor rate limits and budgets`);
|
|
5082
|
+
writeLine();
|
|
5083
|
+
writeLine(` ${colors.dim}Setup:${RESET} github.com/agents-squads/squads-cli#analytics`);
|
|
4989
5084
|
writeLine();
|
|
4990
5085
|
return;
|
|
4991
5086
|
}
|
|
4992
|
-
writeLine(` ${bold}Token Economics${RESET}`);
|
|
4993
|
-
writeLine();
|
|
4994
|
-
const maxPlan = isMaxPlan();
|
|
4995
|
-
const tier = parseInt(process.env.ANTHROPIC_TIER || "4", 10);
|
|
4996
|
-
const planIcon = maxPlan ? `${colors.purple}\u25C6${RESET}` : `${colors.dim}\u25CB${RESET}`;
|
|
4997
|
-
writeLine(` ${planIcon} ${bold}Claude Max${RESET} ${colors.dim}$200/mo flat${RESET} ${colors.dim}Tier ${tier}${RESET}`);
|
|
4998
|
-
writeLine();
|
|
4999
5087
|
const todayTokens = stats ? stats.today.inputTokens + stats.today.outputTokens : 0;
|
|
5000
5088
|
const todayCalls = stats?.today.generations || costs?.totalCalls || 0;
|
|
5001
5089
|
const todayCost = stats?.today.costUsd || costs?.totalCost || 0;
|
|
@@ -5041,12 +5129,13 @@ function renderTokenEconomicsCached(cache, goalCount) {
|
|
|
5041
5129
|
}
|
|
5042
5130
|
function renderInfrastructureCached(cache) {
|
|
5043
5131
|
const stats = cache.bridgeStats;
|
|
5044
|
-
|
|
5045
|
-
|
|
5132
|
+
const hasInfra = hasLocalInfraConfig();
|
|
5133
|
+
if (!hasInfra || !stats) {
|
|
5134
|
+
writeLine(` ${bold}Infrastructure${RESET} ${colors.dim}(not connected)${RESET}`);
|
|
5046
5135
|
writeLine();
|
|
5047
|
-
writeLine(` ${colors.dim}
|
|
5048
|
-
writeLine(
|
|
5049
|
-
writeLine(` ${colors.
|
|
5136
|
+
writeLine(` ${colors.dim}\u25CB${RESET} postgres ${colors.dim}\u25CB${RESET} redis ${colors.dim}\u25CB${RESET} otel`);
|
|
5137
|
+
writeLine();
|
|
5138
|
+
writeLine(` ${colors.dim}Setup:${RESET} github.com/agents-squads/squads-cli#infrastructure`);
|
|
5050
5139
|
writeLine();
|
|
5051
5140
|
return;
|
|
5052
5141
|
}
|
|
@@ -5081,6 +5170,10 @@ function renderInfrastructureCached(cache) {
|
|
|
5081
5170
|
writeLine();
|
|
5082
5171
|
}
|
|
5083
5172
|
function renderAcquisitionCached(cache) {
|
|
5173
|
+
const npmPackage = process.env.SQUADS_NPM_PACKAGE;
|
|
5174
|
+
if (!npmPackage) {
|
|
5175
|
+
return;
|
|
5176
|
+
}
|
|
5084
5177
|
const npm = cache.npmStats;
|
|
5085
5178
|
if (!npm) {
|
|
5086
5179
|
return;
|
|
@@ -5092,8 +5185,6 @@ function renderAcquisitionCached(cache) {
|
|
|
5092
5185
|
writeLine(` ${colors.cyan}${npm.downloads.lastWeek}${RESET} installs/week ${trendIcon} ${trendColor}${Math.abs(npm.weekOverWeek)}%${RESET} ${colors.dim}wow${RESET}`);
|
|
5093
5186
|
writeLine(` ${colors.dim}Today${RESET} ${npm.downloads.lastDay} ${colors.dim}\u2502${RESET} ${colors.dim}Month${RESET} ${npm.downloads.lastMonth}`);
|
|
5094
5187
|
writeLine();
|
|
5095
|
-
writeLine(` ${colors.dim}GitHub \u2192 npm install \u2192 squads dash \u2192 ?${RESET}`);
|
|
5096
|
-
writeLine();
|
|
5097
5188
|
}
|
|
5098
5189
|
async function saveSnapshotCached(squadData, cache, _baseDir) {
|
|
5099
5190
|
if (!cache.dbAvailable) return;
|
|
@@ -5564,6 +5655,7 @@ async function openIssuesCommand(options = {}) {
|
|
|
5564
5655
|
const squadsDir = findSquadsDir();
|
|
5565
5656
|
if (!squadsDir) {
|
|
5566
5657
|
writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);
|
|
5658
|
+
writeLine(` ${colors.dim}Run \`squads init\` to create one.${RESET}`);
|
|
5567
5659
|
return;
|
|
5568
5660
|
}
|
|
5569
5661
|
const evalAgents = findEvalAgents(squadsDir, options.squad);
|
|
@@ -5729,7 +5821,7 @@ import open from "open";
|
|
|
5729
5821
|
import { createClient } from "@supabase/supabase-js";
|
|
5730
5822
|
import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7 } from "fs";
|
|
5731
5823
|
import { join as join12 } from "path";
|
|
5732
|
-
import { homedir as
|
|
5824
|
+
import { homedir as homedir4 } from "os";
|
|
5733
5825
|
import "open";
|
|
5734
5826
|
import http from "http";
|
|
5735
5827
|
var PERSONAL_DOMAINS = [
|
|
@@ -5758,7 +5850,7 @@ var PERSONAL_DOMAINS = [
|
|
|
5758
5850
|
"tutanota.com",
|
|
5759
5851
|
"hey.com"
|
|
5760
5852
|
];
|
|
5761
|
-
var AUTH_DIR = join12(
|
|
5853
|
+
var AUTH_DIR = join12(homedir4(), ".squads-cli");
|
|
5762
5854
|
var AUTH_PATH = join12(AUTH_DIR, "auth.json");
|
|
5763
5855
|
function isPersonalEmail(email) {
|
|
5764
5856
|
const domain = email.split("@")[1]?.toLowerCase();
|
|
@@ -6306,6 +6398,7 @@ async function resultsCommand(options = {}) {
|
|
|
6306
6398
|
const squadsDir = findSquadsDir();
|
|
6307
6399
|
if (!squadsDir) {
|
|
6308
6400
|
writeLine(`${colors.red}No .agents/squads directory found${RESET}`);
|
|
6401
|
+
writeLine(`${colors.dim}Run \`squads init\` to create one.${RESET}`);
|
|
6309
6402
|
return;
|
|
6310
6403
|
}
|
|
6311
6404
|
const days = parseInt(options.days || "7", 10);
|
|
@@ -8157,10 +8250,22 @@ async function tonightReportCommand() {
|
|
|
8157
8250
|
if (!process.stdout.isTTY) {
|
|
8158
8251
|
chalk4.level = 0;
|
|
8159
8252
|
}
|
|
8253
|
+
process.stdout.on("error", (err) => {
|
|
8254
|
+
if (err.code === "EPIPE") {
|
|
8255
|
+
process.exit(0);
|
|
8256
|
+
}
|
|
8257
|
+
throw err;
|
|
8258
|
+
});
|
|
8259
|
+
process.stderr.on("error", (err) => {
|
|
8260
|
+
if (err.code === "EPIPE") {
|
|
8261
|
+
process.exit(0);
|
|
8262
|
+
}
|
|
8263
|
+
throw err;
|
|
8264
|
+
});
|
|
8160
8265
|
var envPaths = [
|
|
8161
8266
|
join17(process.cwd(), ".env"),
|
|
8162
8267
|
join17(process.cwd(), "..", "hq", ".env"),
|
|
8163
|
-
join17(
|
|
8268
|
+
join17(homedir5(), "agents-squads", "hq", ".env")
|
|
8164
8269
|
];
|
|
8165
8270
|
for (const envPath of envPaths) {
|
|
8166
8271
|
if (existsSync17(envPath)) {
|