squads 0.1.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 (85) hide show
  1. package/dist/commands/add.d.ts +3 -0
  2. package/dist/commands/add.d.ts.map +1 -0
  3. package/dist/commands/add.js +98 -0
  4. package/dist/commands/add.js.map +1 -0
  5. package/dist/commands/check.d.ts +3 -0
  6. package/dist/commands/check.d.ts.map +1 -0
  7. package/dist/commands/check.js +127 -0
  8. package/dist/commands/check.js.map +1 -0
  9. package/dist/commands/find.d.ts +3 -0
  10. package/dist/commands/find.d.ts.map +1 -0
  11. package/dist/commands/find.js +84 -0
  12. package/dist/commands/find.js.map +1 -0
  13. package/dist/commands/init.d.ts +3 -0
  14. package/dist/commands/init.d.ts.map +1 -0
  15. package/dist/commands/init.js +281 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/list.d.ts +3 -0
  18. package/dist/commands/list.d.ts.map +1 -0
  19. package/dist/commands/list.js +49 -0
  20. package/dist/commands/list.js.map +1 -0
  21. package/dist/commands/login.d.ts +3 -0
  22. package/dist/commands/login.d.ts.map +1 -0
  23. package/dist/commands/login.js +129 -0
  24. package/dist/commands/login.js.map +1 -0
  25. package/dist/commands/publish.d.ts +3 -0
  26. package/dist/commands/publish.d.ts.map +1 -0
  27. package/dist/commands/publish.js +118 -0
  28. package/dist/commands/publish.js.map +1 -0
  29. package/dist/commands/remove.d.ts +3 -0
  30. package/dist/commands/remove.d.ts.map +1 -0
  31. package/dist/commands/remove.js +67 -0
  32. package/dist/commands/remove.js.map +1 -0
  33. package/dist/commands/update.d.ts +3 -0
  34. package/dist/commands/update.d.ts.map +1 -0
  35. package/dist/commands/update.js +58 -0
  36. package/dist/commands/update.js.map +1 -0
  37. package/dist/commands/validate.d.ts +3 -0
  38. package/dist/commands/validate.d.ts.map +1 -0
  39. package/dist/commands/validate.js +116 -0
  40. package/dist/commands/validate.js.map +1 -0
  41. package/dist/index.d.ts +3 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +48 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/lib/agents.d.ts +26 -0
  46. package/dist/lib/agents.d.ts.map +1 -0
  47. package/dist/lib/agents.js +87 -0
  48. package/dist/lib/agents.js.map +1 -0
  49. package/dist/lib/config.d.ts +9 -0
  50. package/dist/lib/config.d.ts.map +1 -0
  51. package/dist/lib/config.js +44 -0
  52. package/dist/lib/config.js.map +1 -0
  53. package/dist/lib/installer.d.ts +29 -0
  54. package/dist/lib/installer.d.ts.map +1 -0
  55. package/dist/lib/installer.js +124 -0
  56. package/dist/lib/installer.js.map +1 -0
  57. package/dist/lib/lock-file.d.ts +11 -0
  58. package/dist/lib/lock-file.d.ts.map +1 -0
  59. package/dist/lib/lock-file.js +72 -0
  60. package/dist/lib/lock-file.js.map +1 -0
  61. package/dist/lib/sources/github.d.ts +26 -0
  62. package/dist/lib/sources/github.d.ts.map +1 -0
  63. package/dist/lib/sources/github.js +182 -0
  64. package/dist/lib/sources/github.js.map +1 -0
  65. package/dist/lib/sources/local.d.ts +15 -0
  66. package/dist/lib/sources/local.d.ts.map +1 -0
  67. package/dist/lib/sources/local.js +52 -0
  68. package/dist/lib/sources/local.js.map +1 -0
  69. package/dist/lib/sources/registry.d.ts +21 -0
  70. package/dist/lib/sources/registry.d.ts.map +1 -0
  71. package/dist/lib/sources/registry.js +63 -0
  72. package/dist/lib/sources/registry.js.map +1 -0
  73. package/dist/lib/telemetry.d.ts +6 -0
  74. package/dist/lib/telemetry.d.ts.map +1 -0
  75. package/dist/lib/telemetry.js +68 -0
  76. package/dist/lib/telemetry.js.map +1 -0
  77. package/dist/lib/validator.d.ts +29 -0
  78. package/dist/lib/validator.d.ts.map +1 -0
  79. package/dist/lib/validator.js +107 -0
  80. package/dist/lib/validator.js.map +1 -0
  81. package/dist/types.d.ts +86 -0
  82. package/dist/types.d.ts.map +1 -0
  83. package/dist/types.js +2 -0
  84. package/dist/types.js.map +1 -0
  85. package/package.json +47 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import chalk from "chalk";
4
+ import { createAddCommand } from "./commands/add.js";
5
+ import { createFindCommand } from "./commands/find.js";
6
+ import { createListCommand } from "./commands/list.js";
7
+ import { createCheckCommand } from "./commands/check.js";
8
+ import { createUpdateCommand } from "./commands/update.js";
9
+ import { createRemoveCommand } from "./commands/remove.js";
10
+ import { createInitCommand } from "./commands/init.js";
11
+ import { createPublishCommand } from "./commands/publish.js";
12
+ import { createValidateCommand } from "./commands/validate.js";
13
+ import { createLoginCommand } from "./commands/login.js";
14
+ const program = new Command();
15
+ program
16
+ .name("squads")
17
+ .description("CLI for squads.sh — Install and manage AIOS squads")
18
+ .version("0.1.0")
19
+ .addHelpText("after", `
20
+ ${chalk.bold("Examples:")}
21
+ ${chalk.dim("$")} squads add owner/repo Install a squad from GitHub
22
+ ${chalk.dim("$")} squads add ./my-squad Install from local directory
23
+ ${chalk.dim("$")} squads add design-system Install from squads.sh registry
24
+ ${chalk.dim("$")} squads find code-review Search for squads
25
+ ${chalk.dim("$")} squads list List installed squads
26
+ ${chalk.dim("$")} squads init my-squad Create a new squad project
27
+ ${chalk.dim("$")} squads validate Validate a squad deeply
28
+ ${chalk.dim("$")} squads publish Publish to squads.sh
29
+
30
+ ${chalk.dim("Documentation: https://squads.sh/docs")}
31
+ `);
32
+ // Register all subcommands
33
+ program.addCommand(createAddCommand());
34
+ program.addCommand(createFindCommand());
35
+ program.addCommand(createListCommand());
36
+ program.addCommand(createCheckCommand());
37
+ program.addCommand(createUpdateCommand());
38
+ program.addCommand(createRemoveCommand());
39
+ program.addCommand(createInitCommand());
40
+ program.addCommand(createPublishCommand());
41
+ program.addCommand(createValidateCommand());
42
+ program.addCommand(createLoginCommand());
43
+ // Parse arguments and run
44
+ program.parseAsync(process.argv).catch((err) => {
45
+ console.error(chalk.red(`Error: ${err.message}`));
46
+ process.exit(1);
47
+ });
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CACV,OAAO,EACP;EACF,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;IACrB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;;EAEhB,KAAK,CAAC,GAAG,CAAC,uCAAuC,CAAC;CACnD,CACE,CAAC;AAEJ,2BAA2B;AAC3B,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEzC,0BAA0B;AAC1B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { SquadManifest } from "../types.js";
2
+ /**
3
+ * Get the IDE-specific agents installation path for a squad.
4
+ * For Claude Code: .claude/squads/{squad-name}/agents/
5
+ */
6
+ export declare function getAgentsInstallPath(projectDir: string, squadName: string): string;
7
+ /**
8
+ * Get the slash commands path for a squad based on its prefix.
9
+ * For Claude Code: .claude/commands/{prefix}/agents/
10
+ */
11
+ export declare function getCommandsPath(projectDir: string, prefix: string): string;
12
+ /**
13
+ * Copy agent files to IDE-specific paths.
14
+ * - Always copies to .claude/squads/{name}/agents/
15
+ * - If slashPrefix is defined, also copies to .claude/commands/{prefix}/agents/
16
+ */
17
+ export declare function installAgentFiles(squadDir: string, projectDir: string, manifest: SquadManifest, specificAgent?: string): Promise<string[]>;
18
+ /**
19
+ * Remove agent files from IDE-specific paths.
20
+ */
21
+ export declare function removeAgentFiles(projectDir: string, squadName: string, prefix?: string): Promise<void>;
22
+ /**
23
+ * Read the slashPrefix from a squad.yaml file.
24
+ */
25
+ export declare function readSlashPrefix(squadDir: string): Promise<string | undefined>;
26
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/lib/agents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,EACvB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,EAAE,CAAC,CAiDnB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQ7B"}
@@ -0,0 +1,87 @@
1
+ import { readFile, writeFile, readdir, mkdir, rm } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Get the IDE-specific agents installation path for a squad.
5
+ * For Claude Code: .claude/squads/{squad-name}/agents/
6
+ */
7
+ export function getAgentsInstallPath(projectDir, squadName) {
8
+ return join(projectDir, ".claude", "squads", squadName, "agents");
9
+ }
10
+ /**
11
+ * Get the slash commands path for a squad based on its prefix.
12
+ * For Claude Code: .claude/commands/{prefix}/agents/
13
+ */
14
+ export function getCommandsPath(projectDir, prefix) {
15
+ return join(projectDir, ".claude", "commands", prefix, "agents");
16
+ }
17
+ /**
18
+ * Copy agent files to IDE-specific paths.
19
+ * - Always copies to .claude/squads/{name}/agents/
20
+ * - If slashPrefix is defined, also copies to .claude/commands/{prefix}/agents/
21
+ */
22
+ export async function installAgentFiles(squadDir, projectDir, manifest, specificAgent) {
23
+ const agentsSourceDir = join(squadDir, "agents");
24
+ const installedAgents = [];
25
+ let agentFiles;
26
+ try {
27
+ const allFiles = await readdir(agentsSourceDir);
28
+ agentFiles = allFiles.filter((f) => f.endsWith(".md"));
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ if (specificAgent) {
34
+ const target = specificAgent.endsWith(".md")
35
+ ? specificAgent
36
+ : `${specificAgent}.md`;
37
+ agentFiles = agentFiles.filter((f) => f === target);
38
+ if (agentFiles.length === 0) {
39
+ throw new Error(`Agent "${specificAgent}" not found in squad "${manifest.name}"`);
40
+ }
41
+ }
42
+ // Install to .claude/squads/{name}/agents/
43
+ const squadsAgentPath = getAgentsInstallPath(projectDir, manifest.name);
44
+ await mkdir(squadsAgentPath, { recursive: true });
45
+ for (const file of agentFiles) {
46
+ const content = await readFile(join(agentsSourceDir, file), "utf-8");
47
+ await writeFile(join(squadsAgentPath, file), content, "utf-8");
48
+ installedAgents.push(file.replace(/\.md$/, ""));
49
+ }
50
+ // If slashPrefix is defined, also copy to .claude/commands/{prefix}/agents/
51
+ if (manifest.slashPrefix) {
52
+ const commandsAgentPath = getCommandsPath(projectDir, manifest.slashPrefix);
53
+ await mkdir(commandsAgentPath, { recursive: true });
54
+ for (const file of agentFiles) {
55
+ const content = await readFile(join(agentsSourceDir, file), "utf-8");
56
+ await writeFile(join(commandsAgentPath, file), content, "utf-8");
57
+ }
58
+ }
59
+ return installedAgents;
60
+ }
61
+ /**
62
+ * Remove agent files from IDE-specific paths.
63
+ */
64
+ export async function removeAgentFiles(projectDir, squadName, prefix) {
65
+ // Remove .claude/squads/{name}/
66
+ const squadsPath = join(projectDir, ".claude", "squads", squadName);
67
+ await rm(squadsPath, { recursive: true, force: true });
68
+ // Remove .claude/commands/{prefix}/ if prefix was set
69
+ if (prefix) {
70
+ const commandsPath = join(projectDir, ".claude", "commands", prefix, "agents");
71
+ await rm(commandsPath, { recursive: true, force: true });
72
+ }
73
+ }
74
+ /**
75
+ * Read the slashPrefix from a squad.yaml file.
76
+ */
77
+ export async function readSlashPrefix(squadDir) {
78
+ try {
79
+ const content = await readFile(join(squadDir, "squad.yaml"), "utf-8");
80
+ const match = content.match(/^slashPrefix:\s*["']?([^"'\n]+)["']?\s*$/m);
81
+ return match?.[1]?.trim();
82
+ }
83
+ catch {
84
+ return undefined;
85
+ }
86
+ }
87
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/lib/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { CLIConfig } from "../types.js";
2
+ export declare function ensureConfigDir(): Promise<void>;
3
+ export declare function readConfig(): Promise<CLIConfig>;
4
+ export declare function writeConfig(config: CLIConfig): Promise<void>;
5
+ export declare function updateConfig(updates: Partial<CLIConfig>): Promise<CLIConfig>;
6
+ export declare function getAuthToken(): Promise<string | undefined>;
7
+ export declare function getRegistryUrl(): Promise<string>;
8
+ export declare function getGlobalSquadsDir(): string;
9
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAU7C,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAQrD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlE;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,GAC1B,OAAO,CAAC,SAAS,CAAC,CAKpB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAGhE;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAGtD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
@@ -0,0 +1,44 @@
1
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ const CONFIG_DIR = join(homedir(), ".squads");
5
+ const CONFIG_FILE = join(CONFIG_DIR, "config.json");
6
+ const DEFAULT_CONFIG = {
7
+ registry: "https://squads.sh",
8
+ telemetryOptOut: false,
9
+ };
10
+ export async function ensureConfigDir() {
11
+ await mkdir(CONFIG_DIR, { recursive: true });
12
+ }
13
+ export async function readConfig() {
14
+ try {
15
+ const raw = await readFile(CONFIG_FILE, "utf-8");
16
+ const parsed = JSON.parse(raw);
17
+ return { ...DEFAULT_CONFIG, ...parsed };
18
+ }
19
+ catch {
20
+ return { ...DEFAULT_CONFIG };
21
+ }
22
+ }
23
+ export async function writeConfig(config) {
24
+ await ensureConfigDir();
25
+ await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", "utf-8");
26
+ }
27
+ export async function updateConfig(updates) {
28
+ const current = await readConfig();
29
+ const updated = { ...current, ...updates };
30
+ await writeConfig(updated);
31
+ return updated;
32
+ }
33
+ export async function getAuthToken() {
34
+ const config = await readConfig();
35
+ return config.authToken;
36
+ }
37
+ export async function getRegistryUrl() {
38
+ const config = await readConfig();
39
+ return config.registry;
40
+ }
41
+ export function getGlobalSquadsDir() {
42
+ return join(CONFIG_DIR, "global");
43
+ }
44
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,MAAM,cAAc,GAAc;IAChC,QAAQ,EAAE,mBAAmB;IAC7B,eAAe,EAAE,KAAK;CACvB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAuB,CAAC;QACrD,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAiB;IACjD,MAAM,eAAe,EAAE,CAAC;IACxB,MAAM,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAA2B;IAE3B,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAC3C,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC,SAAS,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { SquadSource } from "../types.js";
2
+ export interface InstallOptions {
3
+ source: SquadSource;
4
+ projectDir: string;
5
+ specificAgent?: string;
6
+ global?: boolean;
7
+ skipConfirmation?: boolean;
8
+ }
9
+ export interface InstallResult {
10
+ squadName: string;
11
+ version: string;
12
+ agents: string[];
13
+ squadDir: string;
14
+ }
15
+ /**
16
+ * Orchestrate the full installation of a squad:
17
+ * 1. Resolve source
18
+ * 2. Download/copy files to squads/{name}/
19
+ * 3. Validate
20
+ * 4. Install agent files to IDE paths
21
+ * 5. Update lock file
22
+ * 6. Fire telemetry
23
+ */
24
+ export declare function installSquad(options: InstallOptions): Promise<InstallResult>;
25
+ /**
26
+ * Re-install a squad from its lock entry source.
27
+ */
28
+ export declare function reinstallSquad(projectDir: string, squadName: string, sourceString: string): Promise<InstallResult>;
29
+ //# sourceMappingURL=installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/lib/installer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,aAAa,CAAC;AAc1D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AASD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA2FxB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAMxB"}
@@ -0,0 +1,124 @@
1
+ import { mkdir, rm, cp } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { validateSquadDirectory, listAgentFiles } from "./validator.js";
4
+ import { installAgentFiles } from "./agents.js";
5
+ import { addLockEntry, generateSquadHash } from "./lock-file.js";
6
+ import { trackInstall } from "./telemetry.js";
7
+ import { downloadSquad, formatGitHubSource, parseGitHubSource, } from "./sources/github.js";
8
+ import { copyLocalSquad } from "./sources/local.js";
9
+ import { downloadRegistrySquad } from "./sources/registry.js";
10
+ import { getGlobalSquadsDir } from "./config.js";
11
+ /**
12
+ * Determine the effective project directory for installation.
13
+ */
14
+ function getEffectiveProjectDir(projectDir, global) {
15
+ return global ? getGlobalSquadsDir() : projectDir;
16
+ }
17
+ /**
18
+ * Orchestrate the full installation of a squad:
19
+ * 1. Resolve source
20
+ * 2. Download/copy files to squads/{name}/
21
+ * 3. Validate
22
+ * 4. Install agent files to IDE paths
23
+ * 5. Update lock file
24
+ * 6. Fire telemetry
25
+ */
26
+ export async function installSquad(options) {
27
+ const { source, specificAgent, global } = options;
28
+ const effectiveDir = getEffectiveProjectDir(options.projectDir, global);
29
+ // Step 1: Download or copy to a temporary staging area,
30
+ // then we validate and move to final location.
31
+ const stagingDir = join(effectiveDir, ".squads-staging");
32
+ await mkdir(stagingDir, { recursive: true });
33
+ let sourceLabel;
34
+ try {
35
+ switch (source.type) {
36
+ case "github": {
37
+ await downloadSquad(source, stagingDir);
38
+ sourceLabel = formatGitHubSource(source);
39
+ break;
40
+ }
41
+ case "local": {
42
+ await copyLocalSquad(source, stagingDir);
43
+ sourceLabel = source.path || "local";
44
+ break;
45
+ }
46
+ case "registry": {
47
+ const slug = source.squad || source.repo || "unknown";
48
+ const result = await downloadRegistrySquad(slug, stagingDir);
49
+ source.owner = result.source.owner;
50
+ source.repo = result.source.repo;
51
+ sourceLabel = `registry:${slug}`;
52
+ break;
53
+ }
54
+ default:
55
+ throw new Error(`Unknown source type: ${source.type}`);
56
+ }
57
+ // Step 2: Validate the downloaded squad
58
+ const validation = await validateSquadDirectory(stagingDir);
59
+ if (!validation.valid) {
60
+ throw new Error(`Invalid squad:\n - ${validation.errors.join("\n - ")}`);
61
+ }
62
+ const manifest = validation.manifest;
63
+ const squadName = manifest.name;
64
+ // Step 3: Move from staging to final location
65
+ const finalSquadDir = join(effectiveDir, "squads", squadName);
66
+ await rm(finalSquadDir, { recursive: true, force: true });
67
+ await mkdir(join(effectiveDir, "squads"), { recursive: true });
68
+ // Copy from staging to final location (cp is reliable cross-device)
69
+ await cp(stagingDir, finalSquadDir, { recursive: true });
70
+ // Step 4: Install agent files to IDE-specific paths
71
+ const agents = await installAgentFiles(finalSquadDir, effectiveDir, manifest, specificAgent);
72
+ // Step 5: Generate hash and update lock file
73
+ const hash = await generateSquadHash(finalSquadDir);
74
+ const agentFiles = await listAgentFiles(finalSquadDir);
75
+ const lockEntry = {
76
+ source: sourceLabel,
77
+ squad: squadName,
78
+ version: manifest.version,
79
+ hash,
80
+ installedAt: new Date().toISOString(),
81
+ agents: agentFiles.map((f) => f.replace(/\.md$/, "")),
82
+ };
83
+ await addLockEntry(effectiveDir, squadName, lockEntry);
84
+ // Step 6: Fire telemetry (non-blocking)
85
+ trackInstall(squadName, source.type, !!global);
86
+ return {
87
+ squadName,
88
+ version: manifest.version,
89
+ agents,
90
+ squadDir: finalSquadDir,
91
+ };
92
+ }
93
+ finally {
94
+ // Clean up staging directory
95
+ await rm(stagingDir, { recursive: true, force: true });
96
+ }
97
+ }
98
+ /**
99
+ * Re-install a squad from its lock entry source.
100
+ */
101
+ export async function reinstallSquad(projectDir, squadName, sourceString) {
102
+ const source = parseSourceString(sourceString);
103
+ return installSquad({
104
+ source,
105
+ projectDir,
106
+ });
107
+ }
108
+ /**
109
+ * Parse a stored source string back into a SquadSource.
110
+ */
111
+ function parseSourceString(sourceStr) {
112
+ if (sourceStr.startsWith("registry:")) {
113
+ return {
114
+ type: "registry",
115
+ squad: sourceStr.slice("registry:".length),
116
+ };
117
+ }
118
+ if (sourceStr.startsWith("/") || sourceStr.startsWith("./")) {
119
+ return { type: "local", path: sourceStr };
120
+ }
121
+ // Assume GitHub
122
+ return parseGitHubSource(sourceStr);
123
+ }
124
+ //# sourceMappingURL=installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/lib/installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { LockFile, LockEntry } from "../types.js";
2
+ export declare function readLockFile(projectDir: string): Promise<LockFile>;
3
+ export declare function writeLockFile(projectDir: string, lockFile: LockFile): Promise<void>;
4
+ export declare function addLockEntry(projectDir: string, name: string, entry: LockEntry): Promise<void>;
5
+ export declare function removeLockEntry(projectDir: string, name: string): Promise<void>;
6
+ export declare function getLockEntry(projectDir: string, name: string): Promise<LockEntry | undefined>;
7
+ /**
8
+ * Generate a hash of a squad directory contents for integrity checking.
9
+ */
10
+ export declare function generateSquadHash(squadDir: string): Promise<string>;
11
+ //# sourceMappingURL=lock-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-file.d.ts","sourceRoot":"","sources":["../../src/lib/lock-file.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQvD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAYxE;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAGhC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAIjB"}
@@ -0,0 +1,72 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { createHash } from "node:crypto";
3
+ import { join } from "node:path";
4
+ import { readdir, stat } from "node:fs/promises";
5
+ const LOCK_FILE_NAME = ".squad-lock.json";
6
+ function getLockFilePath(projectDir) {
7
+ return join(projectDir, LOCK_FILE_NAME);
8
+ }
9
+ export async function readLockFile(projectDir) {
10
+ const lockPath = getLockFilePath(projectDir);
11
+ try {
12
+ const raw = await readFile(lockPath, "utf-8");
13
+ const parsed = JSON.parse(raw);
14
+ if (parsed.version !== 1) {
15
+ throw new Error(`Unsupported lock file version: ${parsed.version}`);
16
+ }
17
+ return parsed;
18
+ }
19
+ catch {
20
+ return { version: 1, squads: {} };
21
+ }
22
+ }
23
+ export async function writeLockFile(projectDir, lockFile) {
24
+ const lockPath = getLockFilePath(projectDir);
25
+ await writeFile(lockPath, JSON.stringify(lockFile, null, 2) + "\n", "utf-8");
26
+ }
27
+ export async function addLockEntry(projectDir, name, entry) {
28
+ const lockFile = await readLockFile(projectDir);
29
+ lockFile.squads[name] = entry;
30
+ await writeLockFile(projectDir, lockFile);
31
+ }
32
+ export async function removeLockEntry(projectDir, name) {
33
+ const lockFile = await readLockFile(projectDir);
34
+ delete lockFile.squads[name];
35
+ await writeLockFile(projectDir, lockFile);
36
+ }
37
+ export async function getLockEntry(projectDir, name) {
38
+ const lockFile = await readLockFile(projectDir);
39
+ return lockFile.squads[name];
40
+ }
41
+ /**
42
+ * Generate a hash of a squad directory contents for integrity checking.
43
+ */
44
+ export async function generateSquadHash(squadDir) {
45
+ const hash = createHash("sha256");
46
+ await hashDirectory(squadDir, hash);
47
+ return hash.digest("hex").slice(0, 16);
48
+ }
49
+ async function hashDirectory(dirPath, hash) {
50
+ let entries;
51
+ try {
52
+ entries = await readdir(dirPath);
53
+ }
54
+ catch {
55
+ return;
56
+ }
57
+ entries.sort();
58
+ for (const entry of entries) {
59
+ const fullPath = join(dirPath, entry);
60
+ const entryStat = await stat(fullPath);
61
+ if (entryStat.isDirectory()) {
62
+ hash.update(`dir:${entry}\n`);
63
+ await hashDirectory(fullPath, hash);
64
+ }
65
+ else if (entryStat.isFile()) {
66
+ const content = await readFile(fullPath);
67
+ hash.update(`file:${entry}:${content.length}\n`);
68
+ hash.update(content);
69
+ }
70
+ }
71
+ }
72
+ //# sourceMappingURL=lock-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-file.js","sourceRoot":"","sources":["../../src/lib/lock-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGjD,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAE1C,SAAS,eAAe,CAAC,UAAkB;IACzC,OAAO,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB;IACnD,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAC;QAC3C,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACpC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAkB,EAClB,QAAkB;IAElB,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC7C,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAkB,EAClB,IAAY,EACZ,KAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAChD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAC9B,MAAM,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,IAAY;IAEZ,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAkB,EAClB,IAAY;IAEZ,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAgB;IAEhB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAAe,EACf,IAAmC;IAEnC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvC,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;YAC9B,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;aAAM,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { SquadSource, GitHubTreeEntry } from "../../types.js";
2
+ /**
3
+ * Parse a GitHub source string into a SquadSource object.
4
+ *
5
+ * Supported formats:
6
+ * owner/repo
7
+ * owner/repo/squad-name
8
+ * owner/repo#branch
9
+ * owner/repo/squad-name#branch
10
+ * https://github.com/owner/repo
11
+ * https://github.com/owner/repo/tree/branch/path
12
+ */
13
+ export declare function parseGitHubSource(input: string): SquadSource;
14
+ /**
15
+ * Find squad directories in a repository tree.
16
+ * A squad is identified by the presence of squad.yaml.
17
+ */
18
+ export declare function findSquadsInTree(tree: GitHubTreeEntry[]): string[];
19
+ /**
20
+ * Download a squad from GitHub to a local directory.
21
+ */
22
+ export declare function downloadSquad(source: SquadSource, targetDir: string): Promise<{
23
+ sha: string;
24
+ }>;
25
+ export declare function formatGitHubSource(source: SquadSource): string;
26
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../src/lib/sources/github.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAsB,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIvF;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAwC5D;AAsED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAclE;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CA6E1B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAS9D"}