@bradygaster/squad-cli 0.9.4 → 0.9.5-insider.2

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.
@@ -0,0 +1,24 @@
1
+ /**
2
+ * squad preset — manage squad presets (curated agent collections)
3
+ *
4
+ * Presets are saved to SQUAD_HOME/presets/ (default: ~/.squad/presets/).
5
+ * Each preset is a directory with a preset.json manifest + agents/ charters.
6
+ *
7
+ * Subcommands:
8
+ * squad preset list — list available presets
9
+ * squad preset show <name> — show preset details
10
+ * squad preset apply <name> — install preset agents into current squad
11
+ * squad preset save <name> — save current project agents as a preset
12
+ * squad preset init — initialize presets directory in squad home
13
+ *
14
+ * Note: Presets capture agents only (charters). For full squad snapshots
15
+ * including casting state, skills, and routing rules — e.g. to share a
16
+ * configured squad or publish to an agent toolbox — use `squad export`.
17
+ *
18
+ * @module cli/commands/preset
19
+ */
20
+ /**
21
+ * Entry point for `squad preset` subcommands.
22
+ */
23
+ export declare function runPreset(cwd: string, subcommand: string, args: string[]): Promise<void>;
24
+ //# sourceMappingURL=preset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/preset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH;;GAEG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiD9F"}
@@ -0,0 +1,352 @@
1
+ /**
2
+ * squad preset — manage squad presets (curated agent collections)
3
+ *
4
+ * Presets are saved to SQUAD_HOME/presets/ (default: ~/.squad/presets/).
5
+ * Each preset is a directory with a preset.json manifest + agents/ charters.
6
+ *
7
+ * Subcommands:
8
+ * squad preset list — list available presets
9
+ * squad preset show <name> — show preset details
10
+ * squad preset apply <name> — install preset agents into current squad
11
+ * squad preset save <name> — save current project agents as a preset
12
+ * squad preset init — initialize presets directory in squad home
13
+ *
14
+ * Note: Presets capture agents only (charters). For full squad snapshots
15
+ * including casting state, skills, and routing rules — e.g. to share a
16
+ * configured squad or publish to an agent toolbox — use `squad export`.
17
+ *
18
+ * @module cli/commands/preset
19
+ */
20
+ import path from 'node:path';
21
+ import { execSync } from 'node:child_process';
22
+ import fs from 'node:fs';
23
+ import { ensureSquadHome, resolvePresetsDir } from '@bradygaster/squad-sdk/resolution';
24
+ import { listPresets, loadPreset, applyPreset, savePreset, seedBuiltinPresets } from '@bradygaster/squad-sdk/presets';
25
+ import { resolveSquad } from '@bradygaster/squad-sdk/resolution';
26
+ import { success, warn, info, BOLD, RESET, DIM } from '../core/output.js';
27
+ import { fatal } from '../core/errors.js';
28
+ /**
29
+ * Entry point for `squad preset` subcommands.
30
+ */
31
+ export async function runPreset(cwd, subcommand, args) {
32
+ switch (subcommand) {
33
+ case 'list':
34
+ await presetList();
35
+ break;
36
+ case 'show': {
37
+ const name = args[0];
38
+ if (!name) {
39
+ fatal('Usage: squad preset show <name>');
40
+ }
41
+ await presetShow(name);
42
+ break;
43
+ }
44
+ case 'apply': {
45
+ const name = args[0];
46
+ if (!name) {
47
+ fatal('Usage: squad preset apply <name> [--force]');
48
+ }
49
+ const force = args.includes('--force');
50
+ await presetApply(cwd, name, force);
51
+ break;
52
+ }
53
+ case 'init': {
54
+ const remote = args.includes('--remote');
55
+ await presetInit(remote);
56
+ break;
57
+ }
58
+ case 'save': {
59
+ const name = args[0];
60
+ if (!name) {
61
+ fatal('Usage: squad preset save <name> [--force] [--description "..."]');
62
+ }
63
+ const force = args.includes('--force');
64
+ const descIdx = args.indexOf('--description');
65
+ const description = descIdx >= 0 ? args[descIdx + 1] : undefined;
66
+ await presetSave(cwd, name, force, description);
67
+ break;
68
+ }
69
+ default:
70
+ fatal(`Unknown preset subcommand: ${subcommand}\n` +
71
+ `Usage:\n` +
72
+ ` squad preset list\n` +
73
+ ` squad preset show <name>\n` +
74
+ ` squad preset apply <name> [--force]\n` +
75
+ ` squad preset save <name>\n` +
76
+ ` squad preset init [--remote]`);
77
+ }
78
+ }
79
+ // ============================================================================
80
+ // Subcommand: init
81
+ // ============================================================================
82
+ async function presetInit(remote) {
83
+ if (remote) {
84
+ await presetInitRemote();
85
+ return;
86
+ }
87
+ const homeDir = ensureSquadHome();
88
+ const presetsDir = path.join(homeDir, 'presets');
89
+ const seeded = seedBuiltinPresets();
90
+ success('Presets directory initialized');
91
+ info(` Path: ${presetsDir}`);
92
+ if (seeded.length > 0) {
93
+ info(` Built-in presets installed: ${seeded.join(', ')}`);
94
+ }
95
+ info(` Run 'squad preset list' to see available presets.`);
96
+ console.log();
97
+ info(`${DIM}Tip: Run 'squad preset init --remote' to back your squad home`);
98
+ info(`with a private GitHub repo so presets roam across machines.${RESET}`);
99
+ }
100
+ async function presetInitRemote() {
101
+ // Check gh CLI is available
102
+ try {
103
+ execSync('gh --version', { stdio: 'pipe' });
104
+ }
105
+ catch {
106
+ fatal('GitHub CLI (gh) is required for --remote. Install it: https://cli.github.com');
107
+ }
108
+ // Check gh auth
109
+ try {
110
+ execSync('gh auth status', { stdio: 'pipe' });
111
+ }
112
+ catch {
113
+ fatal('Not logged in to GitHub CLI. Run: gh auth login');
114
+ }
115
+ const os = await import('node:os');
116
+ const envHome = process.env['SQUAD_HOME'];
117
+ const homeDir = envHome ? path.resolve(envHome) : path.join(os.homedir(), '.squad');
118
+ const repoName = 'squad-home';
119
+ // Get GitHub username
120
+ let ghUser;
121
+ try {
122
+ ghUser = execSync('gh api user --jq .login', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
123
+ }
124
+ catch {
125
+ fatal('Could not determine GitHub username. Run: gh auth login');
126
+ return;
127
+ }
128
+ const repoFullName = `${ghUser}/${repoName}`;
129
+ // Check if SQUAD_HOME is already a git repo
130
+ if (fs.existsSync(path.join(homeDir, '.git'))) {
131
+ info(`Squad home is already a git repo: ${homeDir}`);
132
+ const seeded = seedBuiltinPresets();
133
+ if (seeded.length > 0) {
134
+ info(` Built-in presets installed: ${seeded.join(', ')}`);
135
+ }
136
+ success('Squad home ready — presets roam via git push/pull.');
137
+ return;
138
+ }
139
+ // If ~/.squad/ doesn't exist yet, try to clone existing remote repo
140
+ if (!fs.existsSync(homeDir)) {
141
+ let repoExists = false;
142
+ try {
143
+ execSync(`gh repo view ${repoFullName} --json name`, { stdio: 'pipe' });
144
+ repoExists = true;
145
+ }
146
+ catch {
147
+ repoExists = false;
148
+ }
149
+ if (repoExists) {
150
+ // Second machine — clone existing squad home
151
+ info(`Found existing repo ${repoFullName} — cloning...`);
152
+ try {
153
+ execSync(`gh repo clone ${repoFullName} "${homeDir}"`, { stdio: 'inherit' });
154
+ const seeded = seedBuiltinPresets();
155
+ if (seeded.length > 0) {
156
+ info(` New built-in presets added: ${seeded.join(', ')}`);
157
+ try {
158
+ execSync(`git -C "${homeDir}" add -A && git -C "${homeDir}" commit -m "seed built-in presets" --allow-empty`, { stdio: 'pipe' });
159
+ }
160
+ catch { /* nothing new to commit */ }
161
+ }
162
+ success(`Squad home cloned from ${repoFullName}`);
163
+ info(` Path: ${homeDir}`);
164
+ success('Presets synced — you\'re ready to go.');
165
+ return;
166
+ }
167
+ catch {
168
+ fatal(`Failed to clone ${repoFullName}. Check permissions.`);
169
+ }
170
+ }
171
+ // Repo doesn't exist — create fresh
172
+ info(`Creating private repo ${repoFullName}...`);
173
+ try {
174
+ fs.mkdirSync(homeDir, { recursive: true });
175
+ execSync(`git init`, { cwd: homeDir, stdio: 'pipe' });
176
+ execSync(`gh repo create ${repoName} --private --source "${homeDir}" --push --description "Squad home — presets and config"`, {
177
+ stdio: 'inherit',
178
+ });
179
+ }
180
+ catch {
181
+ fatal(`Failed to create repo. Try manually: gh repo create ${repoName} --private`);
182
+ }
183
+ }
184
+ else {
185
+ // ~/.squad/ exists but isn't a git repo — init and connect
186
+ info(`Initializing git in existing squad home: ${homeDir}`);
187
+ execSync(`git init`, { cwd: homeDir, stdio: 'pipe' });
188
+ let repoExists = false;
189
+ try {
190
+ execSync(`gh repo view ${repoFullName} --json name`, { stdio: 'pipe' });
191
+ repoExists = true;
192
+ }
193
+ catch {
194
+ repoExists = false;
195
+ }
196
+ if (!repoExists) {
197
+ info(`Creating private repo ${repoFullName}...`);
198
+ try {
199
+ execSync(`gh repo create ${repoName} --private --source "${homeDir}" --push --description "Squad home — presets and config"`, {
200
+ stdio: 'inherit',
201
+ });
202
+ }
203
+ catch {
204
+ fatal(`Failed to create repo ${repoFullName}.`);
205
+ }
206
+ }
207
+ else {
208
+ info(`Connecting to existing repo ${repoFullName}...`);
209
+ try {
210
+ execSync(`git remote add origin https://github.com/${repoFullName}.git`, { cwd: homeDir, stdio: 'pipe' });
211
+ execSync(`git pull origin main --allow-unrelated-histories`, { cwd: homeDir, stdio: 'pipe' });
212
+ }
213
+ catch {
214
+ warn('Could not pull from remote. You may need to resolve manually.');
215
+ }
216
+ }
217
+ }
218
+ // Seed built-in presets and push
219
+ const seeded = seedBuiltinPresets();
220
+ try {
221
+ execSync(`git -C "${homeDir}" add -A`, { stdio: 'pipe' });
222
+ execSync(`git -C "${homeDir}" commit -m "Initialize squad home with presets"`, { stdio: 'pipe' });
223
+ execSync(`git -C "${homeDir}" push -u origin main`, { stdio: 'pipe' });
224
+ }
225
+ catch {
226
+ // May fail if nothing to commit or push
227
+ }
228
+ success(`Squad home initialized with private repo: ${repoFullName}`);
229
+ info(` Path: ${homeDir}`);
230
+ if (seeded.length > 0) {
231
+ info(` Built-in presets installed: ${seeded.join(', ')}`);
232
+ }
233
+ console.log();
234
+ info(`On another machine, run the same command to sync your presets:`);
235
+ info(` ${BOLD}squad preset init --remote${RESET}`);
236
+ }
237
+ // ============================================================================
238
+ // Subcommand: list
239
+ // ============================================================================
240
+ async function presetList() {
241
+ const presetsDir = resolvePresetsDir();
242
+ if (!presetsDir) {
243
+ info('No presets directory found.');
244
+ info(' Run `squad preset init --remote` to set up with a GitHub repo (recommended).');
245
+ info(' Or `squad preset init` for local-only setup.');
246
+ return;
247
+ }
248
+ const presets = listPresets();
249
+ if (presets.length === 0) {
250
+ info(`Presets directory exists at ${presetsDir} but contains no presets.`);
251
+ info(' Create a preset directory with a preset.json manifest.');
252
+ return;
253
+ }
254
+ console.log(`\n${BOLD}Available Presets${RESET} (${presets.length}):\n`);
255
+ const maxNameLen = Math.max(...presets.map(p => p.name.length), 4);
256
+ console.log(` ${'Name'.padEnd(maxNameLen)} ` +
257
+ `${'Agents'} ` +
258
+ `Description`);
259
+ console.log(` ${'─'.repeat(maxNameLen)} ` +
260
+ `${'─'.repeat(6)} ` +
261
+ `${'─'.repeat(40)}`);
262
+ for (const preset of presets) {
263
+ console.log(` ${preset.name.padEnd(maxNameLen)} ` +
264
+ `${String(preset.agents.length).padEnd(6)} ` +
265
+ `${DIM}${preset.description}${RESET}`);
266
+ }
267
+ console.log();
268
+ }
269
+ // ============================================================================
270
+ // Subcommand: show
271
+ // ============================================================================
272
+ async function presetShow(name) {
273
+ const preset = loadPreset(name);
274
+ if (!preset) {
275
+ fatal(`Preset '${name}' not found. Run 'squad preset list' to see available presets.`);
276
+ }
277
+ console.log(`\n${BOLD}${preset.name}${RESET} v${preset.version}`);
278
+ console.log(` ${preset.description}`);
279
+ if (preset.author)
280
+ console.log(` Author: ${preset.author}`);
281
+ if (preset.tags?.length)
282
+ console.log(` Tags: ${preset.tags.join(', ')}`);
283
+ console.log(`\n ${BOLD}Agents${RESET} (${preset.agents.length}):`);
284
+ for (const agent of preset.agents) {
285
+ console.log(` • ${BOLD}${agent.name}${RESET} (${agent.role})${agent.description ? ` — ${DIM}${agent.description}${RESET}` : ''}`);
286
+ }
287
+ console.log();
288
+ }
289
+ // ============================================================================
290
+ // Subcommand: apply
291
+ // ============================================================================
292
+ async function presetApply(cwd, name, force) {
293
+ // Find target squad directory
294
+ const squadDir = resolveSquad(cwd);
295
+ if (!squadDir) {
296
+ fatal('No .squad/ directory found. Run `squad init` first, or use from a repo with a squad.');
297
+ }
298
+ const targetAgentsDir = path.join(squadDir, 'agents');
299
+ const results = applyPreset(name, targetAgentsDir, { force });
300
+ if (results.length === 1 && results[0].status === 'error' && results[0].agent === name) {
301
+ fatal(results[0].reason ?? `Failed to apply preset '${name}'`);
302
+ }
303
+ let installed = 0;
304
+ let skipped = 0;
305
+ let errors = 0;
306
+ for (const result of results) {
307
+ switch (result.status) {
308
+ case 'installed':
309
+ success(` ${result.agent}`);
310
+ installed++;
311
+ break;
312
+ case 'skipped':
313
+ warn(` ${result.agent} — ${result.reason}`);
314
+ skipped++;
315
+ break;
316
+ case 'error':
317
+ console.error(` ✗ ${result.agent} — ${result.reason}`);
318
+ errors++;
319
+ break;
320
+ }
321
+ }
322
+ console.log();
323
+ if (installed > 0)
324
+ success(`Applied preset '${name}': ${installed} agents installed`);
325
+ if (skipped > 0)
326
+ info(` ${skipped} agents skipped (already exist)`);
327
+ if (errors > 0)
328
+ warn(` ${errors} agents had errors`);
329
+ }
330
+ // ============================================================================
331
+ // Subcommand: save
332
+ // ============================================================================
333
+ async function presetSave(cwd, name, force, description) {
334
+ const squadDir = resolveSquad(cwd);
335
+ if (!squadDir) {
336
+ fatal('No .squad/ directory found. Initialize a squad first with `squad init`.');
337
+ }
338
+ try {
339
+ const destDir = savePreset(name, squadDir, { force, description });
340
+ success(`Preset '${name}' saved`);
341
+ info(` Location: ${destDir}`);
342
+ info(` Use it in any project: squad preset apply ${name}`);
343
+ console.log();
344
+ info(`${DIM}Tip: Presets save agents only (charters). For a full squad snapshot`);
345
+ info(`including casting state, skills, and routing rules — e.g. to share`);
346
+ info(`a configured squad or publish to an agent toolbox — use 'squad export'.${RESET}`);
347
+ }
348
+ catch (err) {
349
+ fatal(String(err));
350
+ }
351
+ }
352
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../../../src/cli/commands/preset.ts"],"names":[],"mappings":"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"}
package/dist/cli-entry.js CHANGED
@@ -139,6 +139,7 @@ async function main() {
139
139
  console.log(` --roles (use base roles)`);
140
140
  console.log(` --global (personal squad dir)`);
141
141
  console.log(` --no-workflows (skip CI setup)`);
142
+ console.log(` --preset <name> (apply a preset after init)`);
142
143
  console.log(` Usage: init --mode remote <team-repo-path>`);
143
144
  console.log(` Creates .squad/config.json pointing to an external team root`);
144
145
  console.log(` ${BOLD}upgrade${RESET} Update Squad-owned files to latest version`);
@@ -220,6 +221,10 @@ async function main() {
220
221
  console.log(` ${BOLD}personal${RESET} Manage your personal squad (ambient agents)`);
221
222
  console.log(` Usage: personal init | list | add <name>`);
222
223
  console.log(` --role <role> | remove <name>`);
224
+ console.log(` ${BOLD}preset${RESET} Manage squad presets (curated agent collections)`);
225
+ console.log(` Usage: preset list | show <name>`);
226
+ console.log(` apply <name> [--force] | save <name>`);
227
+ console.log(` init [--remote]`);
223
228
  console.log(` ${BOLD}cast${RESET} Show current session cast (project + personal agents)`);
224
229
  console.log(` ${BOLD}rc${RESET} Start Remote Control bridge (phone/browser → Copilot)`);
225
230
  console.log(` Usage: rc [--tunnel] [--port <n>] [--path <dir>]`);
@@ -286,8 +291,41 @@ async function main() {
286
291
  const noWorkflows = args.includes('--no-workflows');
287
292
  const sdk = args.includes('--sdk');
288
293
  const roles = args.includes('--roles');
294
+ const presetIdx = args.indexOf('--preset');
295
+ const presetName = (presetIdx !== -1 && args[presetIdx + 1]) ? args[presetIdx + 1] : undefined;
289
296
  // Global init: suppress workflows (no GitHub CI in ~/.config/squad/) and bootstrap personal squad
290
- runInit(dest, { includeWorkflows: !noWorkflows && !hasGlobal, sdk, roles, isGlobal: hasGlobal }).catch(err => {
297
+ runInit(dest, { includeWorkflows: !noWorkflows && !hasGlobal, sdk, roles, isGlobal: hasGlobal }).then(async () => {
298
+ if (presetName) {
299
+ const { seedBuiltinPresets, applyPreset } = await import('@bradygaster/squad-sdk/presets');
300
+ const { resolvePresetsDir, ensureSquadHome } = await import('@bradygaster/squad-sdk/resolution');
301
+ const nodePath = await import('node:path');
302
+ // Auto-initialize squad home + presets if they don't exist yet
303
+ if (!resolvePresetsDir()) {
304
+ console.log(`\n⚙️ No presets found — setting up squad home...`);
305
+ ensureSquadHome();
306
+ seedBuiltinPresets();
307
+ console.log(`✅ Squad home initialized at ${ensureSquadHome()}`);
308
+ console.log(` Built-in presets ready. Run 'squad preset init --remote' to back with a GitHub repo.\n`);
309
+ }
310
+ else {
311
+ seedBuiltinPresets();
312
+ }
313
+ const targetAgentsDir = nodePath.join(dest, '.squad', 'agents');
314
+ const results = applyPreset(presetName, targetAgentsDir);
315
+ const installed = results.filter(r => r.status === 'installed');
316
+ const skipped = results.filter(r => r.status === 'skipped');
317
+ const errors = results.filter(r => r.status === 'error');
318
+ if (installed.length > 0) {
319
+ console.log(`✅ Applied preset '${presetName}': ${installed.length} agents installed`);
320
+ }
321
+ if (skipped.length > 0) {
322
+ console.log(` ${skipped.length} agents skipped (already exist)`);
323
+ }
324
+ if (errors.length > 0 && installed.length === 0) {
325
+ console.error(`❌ Preset '${presetName}' not found. Run 'squad preset list' to see available presets.`);
326
+ }
327
+ }
328
+ }).catch(err => {
291
329
  fatal(err.message);
292
330
  });
293
331
  return;
@@ -813,16 +851,17 @@ async function main() {
813
851
  await runPersonal(getSquadStartDir(), subcommand, args.slice(2));
814
852
  return;
815
853
  }
854
+ if (cmd === 'preset') {
855
+ const { runPreset } = await import('./cli/commands/preset.js');
856
+ const subcommand = args[1] || 'list';
857
+ await runPreset(getSquadStartDir(), subcommand, args.slice(2));
858
+ return;
859
+ }
816
860
  if (cmd === 'cast') {
817
861
  const { runCast } = await import('./cli/commands/cast.js');
818
862
  await runCast(getSquadStartDir());
819
863
  return;
820
864
  }
821
- if (cmd === 'skill') {
822
- const { runSkill } = await import('./cli/commands/skill.js');
823
- await runSkill(getSquadStartDir(), args.slice(1));
824
- return;
825
- }
826
865
  if (cmd === 'upstream') {
827
866
  const { upstreamCommand } = await import('./cli/commands/upstream.js');
828
867
  await upstreamCommand(args.slice(1));