squidsquad 0.15.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.
- package/README.md +33 -0
- package/index.js +263 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# squidsquad
|
|
2
|
+
|
|
3
|
+
Bootstrap [SquidSquad](https://github.com/WallyDoodlez/SquidSquad) onto your project.
|
|
4
|
+
|
|
5
|
+
SquidSquad is an autonomous AI dev team that coordinates through markdown, not meetings. It spins up Claude Code agents — one per dev role you define, plus PM and QA — that work on your codebase in parallel.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx squidsquad
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Run this from inside a git repository. The bootstrapper will:
|
|
14
|
+
|
|
15
|
+
1. Verify prerequisites (Node.js 18+, Python 3.8+, GitHub CLI, Claude Code CLI)
|
|
16
|
+
2. Fetch `SKILL.md` and the `/squidsquad-setup` command into your project
|
|
17
|
+
3. Prompt to launch the setup wizard immediately
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- [Node.js 18+](https://nodejs.org/)
|
|
22
|
+
- [Python 3.8+](https://www.python.org/downloads/)
|
|
23
|
+
- [GitHub CLI (`gh`)](https://cli.github.com/) — authenticated
|
|
24
|
+
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code/overview)
|
|
25
|
+
- A git repository
|
|
26
|
+
|
|
27
|
+
## What It Does
|
|
28
|
+
|
|
29
|
+
The bootstrapper is intentionally thin. It checks your environment, seeds two files into your project (`SKILL.md` at the root and a `/squidsquad-setup` slash command), then offers to launch Claude Code to run the interactive setup wizard. The wizard handles everything else: project config, agent roles, boot scripts, GitHub Issues labels, and more.
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
[AGPL-3.0](https://github.com/WallyDoodlez/SquidSquad/blob/main/LICENSE)
|
package/index.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { execSync, spawn } = require("child_process");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const readline = require("readline");
|
|
9
|
+
|
|
10
|
+
const REPO_OWNER = "WallyDoodlez";
|
|
11
|
+
const REPO_NAME = "SquidSquad";
|
|
12
|
+
const BRANCH = "main";
|
|
13
|
+
const RAW_BASE = `https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${BRANCH}`;
|
|
14
|
+
|
|
15
|
+
// --- Output helpers ---
|
|
16
|
+
|
|
17
|
+
function info(msg) {
|
|
18
|
+
console.log(` ${msg}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function success(msg) {
|
|
22
|
+
console.log(` \x1b[32m\u2713\x1b[0m ${msg}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function fail(msg) {
|
|
26
|
+
console.error(` \x1b[31m\u2717\x1b[0m ${msg}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function banner() {
|
|
30
|
+
console.log();
|
|
31
|
+
console.log(" \u2597\u2584\u2596");
|
|
32
|
+
console.log(" \u259F\u2588 \u2588\u2599");
|
|
33
|
+
console.log(" \u2590\u2588\u2022 \u2022\u2588\u258C");
|
|
34
|
+
console.log(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588");
|
|
35
|
+
console.log(" \u2590\u2588\u2588\u2588\u2588\u2588\u258C");
|
|
36
|
+
console.log(" \u2590\u258C\u2590\u258C\u2590\u258C");
|
|
37
|
+
console.log(" S Q U I D S Q U A D");
|
|
38
|
+
console.log();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// --- Prerequisite checks ---
|
|
42
|
+
|
|
43
|
+
function checkNodeVersion() {
|
|
44
|
+
const major = parseInt(process.versions.node.split(".")[0], 10);
|
|
45
|
+
if (major < 18) {
|
|
46
|
+
fail(`Node.js 18+ is required (found v${process.versions.node}).`);
|
|
47
|
+
info("Install the latest LTS from https://nodejs.org/");
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
success(`Node.js v${process.versions.node}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function tryExec(cmd) {
|
|
54
|
+
try {
|
|
55
|
+
return execSync(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function checkGitRepo() {
|
|
62
|
+
const root = tryExec("git rev-parse --show-toplevel");
|
|
63
|
+
if (!root) {
|
|
64
|
+
fail("Not a git repository.");
|
|
65
|
+
info("Run this command from inside a git repository.");
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
success("Git repository detected");
|
|
69
|
+
return root;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function checkPython() {
|
|
73
|
+
for (const bin of ["python3", "python"]) {
|
|
74
|
+
const out = tryExec(`${bin} --version`);
|
|
75
|
+
if (out) {
|
|
76
|
+
const match = out.match(/Python (\d+)\.(\d+)/);
|
|
77
|
+
if (match) {
|
|
78
|
+
const major = parseInt(match[1], 10);
|
|
79
|
+
const minor = parseInt(match[2], 10);
|
|
80
|
+
if ((major === 3 && minor >= 8) || major > 3) {
|
|
81
|
+
success(`${out}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
fail("Python 3.8+ is required.");
|
|
88
|
+
info("Install from https://www.python.org/downloads/");
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function checkGhCli() {
|
|
93
|
+
const ver = tryExec("gh --version");
|
|
94
|
+
if (!ver) {
|
|
95
|
+
fail("GitHub CLI (gh) is required.");
|
|
96
|
+
info("Install from https://cli.github.com/");
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
success("GitHub CLI installed");
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
execSync("gh auth status", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
103
|
+
success("GitHub CLI authenticated");
|
|
104
|
+
} catch {
|
|
105
|
+
fail("GitHub CLI is not authenticated.");
|
|
106
|
+
info("Run `gh auth login` first.");
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function checkClaudeCli() {
|
|
112
|
+
const ver = tryExec("claude --version");
|
|
113
|
+
if (!ver) {
|
|
114
|
+
fail("Claude Code CLI is required.");
|
|
115
|
+
info("Install from https://docs.anthropic.com/en/docs/claude-code/overview");
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
success(`Claude Code CLI v${ver}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// --- File fetching ---
|
|
122
|
+
|
|
123
|
+
function fetchRawFile(repoPath) {
|
|
124
|
+
const url = `${RAW_BASE}/${repoPath}`;
|
|
125
|
+
try {
|
|
126
|
+
const content = execSync(
|
|
127
|
+
`gh api -H "Accept: application/vnd.github.raw+json" "/repos/${REPO_OWNER}/${REPO_NAME}/contents/${repoPath}?ref=${BRANCH}"`,
|
|
128
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], maxBuffer: 1024 * 1024 }
|
|
129
|
+
);
|
|
130
|
+
return content;
|
|
131
|
+
} catch {
|
|
132
|
+
// Fallback: try curl/wget for raw URL
|
|
133
|
+
const fallback = tryExec(`curl -fsSL "${url}"`);
|
|
134
|
+
if (fallback) return fallback;
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function installFiles(gitRoot) {
|
|
140
|
+
// 1. Fetch SKILL.md → project root
|
|
141
|
+
info("Fetching SKILL.md...");
|
|
142
|
+
const skillContent = fetchRawFile("SKILL.md");
|
|
143
|
+
if (!skillContent) {
|
|
144
|
+
fail("Failed to fetch SKILL.md from GitHub.");
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
fs.writeFileSync(path.join(gitRoot, "SKILL.md"), skillContent, "utf-8");
|
|
148
|
+
success("SKILL.md placed in project root");
|
|
149
|
+
|
|
150
|
+
// 2. Create .claude/commands/ and fetch squidsquad-setup.md
|
|
151
|
+
const commandsDir = path.join(gitRoot, ".claude", "commands");
|
|
152
|
+
fs.mkdirSync(commandsDir, { recursive: true });
|
|
153
|
+
|
|
154
|
+
// The setup command tells Claude to read SKILL.md and run setup
|
|
155
|
+
const setupCommand = [
|
|
156
|
+
"---",
|
|
157
|
+
"description: Run the SquidSquad setup wizard to configure your project",
|
|
158
|
+
"---",
|
|
159
|
+
"",
|
|
160
|
+
'Read the SKILL.md file in the project root and follow its "Setup Instructions" section exactly.',
|
|
161
|
+
"",
|
|
162
|
+
"The setup wizard will ask for project details, generate the .squidsquad/ folder, create agent configs, boot scripts, and GitHub Issues labels.",
|
|
163
|
+
"",
|
|
164
|
+
"Important: The setup flow will need to fetch files from the SquidSquad repo. Use `gh api` or `curl` to download from https://raw.githubusercontent.com/WallyDoodlez/SquidSquad/main/ as needed.",
|
|
165
|
+
"",
|
|
166
|
+
].join("\n");
|
|
167
|
+
|
|
168
|
+
fs.writeFileSync(path.join(commandsDir, "squidsquad-setup.md"), setupCommand, "utf-8");
|
|
169
|
+
success("Created /squidsquad-setup command");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// --- Launch prompt ---
|
|
173
|
+
|
|
174
|
+
function askLaunch() {
|
|
175
|
+
return new Promise((resolve) => {
|
|
176
|
+
const rl = readline.createInterface({
|
|
177
|
+
input: process.stdin,
|
|
178
|
+
output: process.stdout,
|
|
179
|
+
});
|
|
180
|
+
rl.question(" Launch SquidSquad setup now? (Y/n) ", (answer) => {
|
|
181
|
+
rl.close();
|
|
182
|
+
const trimmed = answer.trim().toLowerCase();
|
|
183
|
+
resolve(trimmed === "" || trimmed === "y" || trimmed === "yes");
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function launchClaude() {
|
|
189
|
+
info("Launching Claude Code with /squidsquad-setup...");
|
|
190
|
+
console.log();
|
|
191
|
+
|
|
192
|
+
const child = spawn("claude", ["/squidsquad-setup"], {
|
|
193
|
+
stdio: "inherit",
|
|
194
|
+
shell: true,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
child.on("error", (err) => {
|
|
198
|
+
fail(`Failed to launch Claude: ${err.message}`);
|
|
199
|
+
info("Run manually: claude /squidsquad-setup");
|
|
200
|
+
process.exit(1);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
child.on("exit", (code) => {
|
|
204
|
+
process.exit(code || 0);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// --- Main ---
|
|
209
|
+
|
|
210
|
+
async function main() {
|
|
211
|
+
banner();
|
|
212
|
+
|
|
213
|
+
// Check if already set up in this project
|
|
214
|
+
const gitRoot = checkGitRepo();
|
|
215
|
+
const squidDir = path.join(gitRoot, ".squidsquad");
|
|
216
|
+
if (fs.existsSync(squidDir)) {
|
|
217
|
+
console.log();
|
|
218
|
+
info("SquidSquad is already installed in this project.");
|
|
219
|
+
info("To upgrade, run `/squidsquad-upgrade` from a Claude session.");
|
|
220
|
+
console.log();
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
console.log();
|
|
225
|
+
info("Checking prerequisites...");
|
|
226
|
+
console.log();
|
|
227
|
+
|
|
228
|
+
checkNodeVersion();
|
|
229
|
+
checkPython();
|
|
230
|
+
checkGhCli();
|
|
231
|
+
checkClaudeCli();
|
|
232
|
+
|
|
233
|
+
console.log();
|
|
234
|
+
info("All prerequisites met. Fetching SquidSquad files...");
|
|
235
|
+
console.log();
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
installFiles(gitRoot);
|
|
239
|
+
} catch (err) {
|
|
240
|
+
console.log();
|
|
241
|
+
fail("Installation failed.");
|
|
242
|
+
info(err.message || String(err));
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
console.log();
|
|
247
|
+
console.log(" \x1b[32m\x1b[1mSquidSquad is ready!\x1b[0m");
|
|
248
|
+
console.log();
|
|
249
|
+
|
|
250
|
+
const shouldLaunch = await askLaunch();
|
|
251
|
+
|
|
252
|
+
if (shouldLaunch) {
|
|
253
|
+
launchClaude();
|
|
254
|
+
} else {
|
|
255
|
+
console.log();
|
|
256
|
+
info("To set up later, run:");
|
|
257
|
+
console.log();
|
|
258
|
+
info(" claude /squidsquad-setup");
|
|
259
|
+
console.log();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "squidsquad",
|
|
3
|
+
"version": "0.15.0",
|
|
4
|
+
"description": "Bootstrap SquidSquad onto your project — autonomous AI dev team coordination via Claude Code",
|
|
5
|
+
"bin": {
|
|
6
|
+
"squidsquad": "./index.js"
|
|
7
|
+
},
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=18"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"index.js"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"claude",
|
|
16
|
+
"claude-code",
|
|
17
|
+
"ai",
|
|
18
|
+
"agents",
|
|
19
|
+
"dev-team",
|
|
20
|
+
"autonomous",
|
|
21
|
+
"squidsquad"
|
|
22
|
+
],
|
|
23
|
+
"license": "AGPL-3.0",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/WallyDoodlez/SquidSquad.git",
|
|
27
|
+
"directory": "packages/cli"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/WallyDoodlez/SquidSquad",
|
|
30
|
+
"author": "WallyDoodlez"
|
|
31
|
+
}
|