@bradygaster/squad-cli 0.9.5-insider.1 → 0.9.6-insider.1

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 (68) hide show
  1. package/dist/cli/commands/install-hooks.d.ts +26 -0
  2. package/dist/cli/commands/install-hooks.d.ts.map +1 -0
  3. package/dist/cli/commands/install-hooks.js +244 -0
  4. package/dist/cli/commands/install-hooks.js.map +1 -0
  5. package/dist/cli/commands/migrate-backend.d.ts +16 -0
  6. package/dist/cli/commands/migrate-backend.d.ts.map +1 -0
  7. package/dist/cli/commands/migrate-backend.js +87 -0
  8. package/dist/cli/commands/migrate-backend.js.map +1 -0
  9. package/dist/cli/commands/preset.d.ts +24 -0
  10. package/dist/cli/commands/preset.d.ts.map +1 -0
  11. package/dist/cli/commands/preset.js +352 -0
  12. package/dist/cli/commands/preset.js.map +1 -0
  13. package/dist/cli/commands/sync.d.ts +24 -0
  14. package/dist/cli/commands/sync.d.ts.map +1 -0
  15. package/dist/cli/commands/sync.js +257 -0
  16. package/dist/cli/commands/sync.js.map +1 -0
  17. package/dist/cli/commands/watch/capabilities/board.d.ts.map +1 -1
  18. package/dist/cli/commands/watch/capabilities/board.js +7 -10
  19. package/dist/cli/commands/watch/capabilities/board.js.map +1 -1
  20. package/dist/cli/commands/watch/capabilities/fleet-dispatch.d.ts.map +1 -1
  21. package/dist/cli/commands/watch/capabilities/fleet-dispatch.js +7 -13
  22. package/dist/cli/commands/watch/capabilities/fleet-dispatch.js.map +1 -1
  23. package/dist/cli/commands/watch/capabilities/self-pull.d.ts.map +1 -1
  24. package/dist/cli/commands/watch/capabilities/self-pull.js +9 -10
  25. package/dist/cli/commands/watch/capabilities/self-pull.js.map +1 -1
  26. package/dist/cli/commands/watch/capabilities/two-pass.d.ts.map +1 -1
  27. package/dist/cli/commands/watch/capabilities/two-pass.js +5 -7
  28. package/dist/cli/commands/watch/capabilities/two-pass.js.map +1 -1
  29. package/dist/cli/commands/watch/config.d.ts +4 -1
  30. package/dist/cli/commands/watch/config.d.ts.map +1 -1
  31. package/dist/cli/commands/watch/config.js +2 -1
  32. package/dist/cli/commands/watch/config.js.map +1 -1
  33. package/dist/cli/commands/watch/types.d.ts +1 -5
  34. package/dist/cli/commands/watch/types.d.ts.map +1 -1
  35. package/dist/cli/core/gh-cli.d.ts.map +1 -1
  36. package/dist/cli/core/gh-cli.js +6 -7
  37. package/dist/cli/core/gh-cli.js.map +1 -1
  38. package/dist/cli/core/init.d.ts +2 -10
  39. package/dist/cli/core/init.d.ts.map +1 -1
  40. package/dist/cli/core/init.js +63 -56
  41. package/dist/cli/core/init.js.map +1 -1
  42. package/dist/cli/index.d.ts +0 -2
  43. package/dist/cli/index.d.ts.map +1 -1
  44. package/dist/cli/index.js +0 -2
  45. package/dist/cli/index.js.map +1 -1
  46. package/dist/cli-entry.js +71 -10
  47. package/dist/cli-entry.js.map +1 -1
  48. package/package.json +4 -3
  49. package/templates/notes-protocol.md +202 -0
  50. package/templates/scribe-charter.md +95 -1
  51. package/templates/scripts/notes/fetch.ps1 +88 -0
  52. package/templates/scripts/notes/write-note.ps1 +126 -0
  53. package/templates/skills/cross-machine-coordination/SKILL.md +8 -0
  54. package/templates/skills/init-mode/SKILL.md +3 -3
  55. package/templates/skills/model-selection/SKILL.md +8 -0
  56. package/templates/skills/nap/SKILL.md +8 -0
  57. package/templates/skills/personal-squad/SKILL.md +8 -0
  58. package/templates/skills/ralph-two-pass-scan/SKILL.md +8 -0
  59. package/templates/skills/release-process/SKILL.md +91 -5
  60. package/templates/squad.agent.md.template +137 -14
  61. package/dist/cli/commands/skill.d.ts +0 -31
  62. package/dist/cli/commands/skill.d.ts.map +0 -1
  63. package/dist/cli/commands/skill.js +0 -496
  64. package/dist/cli/commands/skill.js.map +0 -1
  65. package/dist/cli/commands/watch/agent-spawn.d.ts +0 -62
  66. package/dist/cli/commands/watch/agent-spawn.d.ts.map +0 -1
  67. package/dist/cli/commands/watch/agent-spawn.js +0 -127
  68. package/dist/cli/commands/watch/agent-spawn.js.map +0 -1
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Git Hook Installation — installs squad sync hooks into the repo's .git/hooks/.
3
+ *
4
+ * Hooks are installed with chaining: if a user already has a hook (e.g., from husky),
5
+ * the squad hook is appended and the existing hook is called first.
6
+ *
7
+ * Installed hooks:
8
+ * - pre-push: pushes squad-state branches alongside the user's push
9
+ * - post-merge: fetches squad-state after the user pulls
10
+ * - post-rewrite: fetches squad-state after rebase
11
+ * - post-checkout: fetches squad-state on branch switch
12
+ */
13
+ export interface InstallHooksOptions {
14
+ force?: boolean;
15
+ }
16
+ /**
17
+ * Main hook installation entrypoint.
18
+ */
19
+ export declare function installGitHooks(cwd: string, options?: InstallHooksOptions): void;
20
+ /**
21
+ * Ensure hooks are installed if the backend requires them.
22
+ * Called by `squad upgrade` to silently ensure hooks exist for orphan/two-layer repos.
23
+ * Does not print anything if hooks are already installed or backend doesn't need them.
24
+ */
25
+ export declare function ensureHooksForBackend(cwd: string): void;
26
+ //# sourceMappingURL=install-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-hooks.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/install-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoGH,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA2DD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI,CAgDpF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA4BvD"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Git Hook Installation — installs squad sync hooks into the repo's .git/hooks/.
3
+ *
4
+ * Hooks are installed with chaining: if a user already has a hook (e.g., from husky),
5
+ * the squad hook is appended and the existing hook is called first.
6
+ *
7
+ * Installed hooks:
8
+ * - pre-push: pushes squad-state branches alongside the user's push
9
+ * - post-merge: fetches squad-state after the user pulls
10
+ * - post-rewrite: fetches squad-state after rebase
11
+ * - post-checkout: fetches squad-state on branch switch
12
+ */
13
+ import { execFileSync } from 'node:child_process';
14
+ import path from 'node:path';
15
+ import fs from 'node:fs';
16
+ const GREEN = '\x1b[32m';
17
+ const YELLOW = '\x1b[33m';
18
+ const DIM = '\x1b[2m';
19
+ const BOLD = '\x1b[1m';
20
+ const RESET = '\x1b[0m';
21
+ const SQUAD_HOOK_MARKER = '# --- squad-sync-hook ---';
22
+ /**
23
+ * The shell script content for each hook.
24
+ * These are minimal wrappers that call `squad sync`.
25
+ * The SQUAD_SYNC_ACTIVE env guard prevents recursion.
26
+ */
27
+ const HOOK_TEMPLATES = {
28
+ 'pre-push': `#!/bin/sh
29
+ ${SQUAD_HOOK_MARKER}
30
+ # Auto-push squad-state branches alongside the user's push.
31
+ # Installed by: squad init / squad upgrade --state-backend
32
+ # The remote name and URL are passed as arguments by git.
33
+ if [ -z "$SQUAD_SYNC_ACTIVE" ]; then
34
+ REMOTE="\$1"
35
+ export SQUAD_SYNC_ACTIVE=1
36
+ # Push all squad-state branches (including subsquad branches)
37
+ for branch in $(git for-each-ref --format='%(refname:short)' 'refs/heads/squad-state' 'refs/heads/squad-state/*' 2>/dev/null); do
38
+ git push --no-verify "$REMOTE" "refs/heads/$branch:refs/heads/$branch" 2>/dev/null || true
39
+ done
40
+ # Push git notes for two-layer backend
41
+ git push --no-verify "$REMOTE" 'refs/notes/squad*:refs/notes/squad*' 2>/dev/null || true
42
+ unset SQUAD_SYNC_ACTIVE
43
+ fi
44
+ `,
45
+ 'post-merge': `#!/bin/sh
46
+ ${SQUAD_HOOK_MARKER}
47
+ # Auto-fetch squad-state branches after pull/merge.
48
+ # Installed by: squad init / squad upgrade --state-backend
49
+ if [ -z "$SQUAD_SYNC_ACTIVE" ]; then
50
+ export SQUAD_SYNC_ACTIVE=1
51
+ REMOTE=$(git config "branch.$(git symbolic-ref --short HEAD 2>/dev/null).remote" 2>/dev/null || echo origin)
52
+ # Fetch squad-state branches
53
+ git fetch "$REMOTE" '+refs/heads/squad-state:refs/remotes/'"$REMOTE"'/squad-state' '+refs/heads/squad-state/*:refs/remotes/'"$REMOTE"'/squad-state/*' 2>/dev/null || true
54
+ # Fast-forward local squad-state from remote
55
+ for remote_ref in $(git for-each-ref --format='%(refname:short)' "refs/remotes/$REMOTE/squad-state" "refs/remotes/$REMOTE/squad-state/*" 2>/dev/null); do
56
+ local_name=\${remote_ref#"$REMOTE/"}
57
+ local_sha=$(git rev-parse "refs/heads/$local_name" 2>/dev/null) || { git update-ref "refs/heads/$local_name" "$(git rev-parse "$remote_ref")" 2>/dev/null; continue; }
58
+ remote_sha=$(git rev-parse "$remote_ref" 2>/dev/null) || continue
59
+ [ "$local_sha" = "$remote_sha" ] && continue
60
+ git merge-base --is-ancestor "$local_sha" "$remote_sha" 2>/dev/null && git update-ref "refs/heads/$local_name" "$remote_sha" 2>/dev/null || true
61
+ done
62
+ # Fetch git notes for two-layer backend
63
+ git fetch "$REMOTE" '+refs/notes/squad*:refs/notes/squad*' 2>/dev/null || true
64
+ unset SQUAD_SYNC_ACTIVE
65
+ fi
66
+ `,
67
+ 'post-rewrite': `#!/bin/sh
68
+ ${SQUAD_HOOK_MARKER}
69
+ # Auto-fetch squad-state branches after rebase.
70
+ # Installed by: squad init / squad upgrade --state-backend
71
+ if [ -z "$SQUAD_SYNC_ACTIVE" ]; then
72
+ export SQUAD_SYNC_ACTIVE=1
73
+ REMOTE=$(git config "branch.$(git symbolic-ref --short HEAD 2>/dev/null).remote" 2>/dev/null || echo origin)
74
+ git fetch "$REMOTE" '+refs/heads/squad-state:refs/remotes/'"$REMOTE"'/squad-state' '+refs/heads/squad-state/*:refs/remotes/'"$REMOTE"'/squad-state/*' 2>/dev/null || true
75
+ for remote_ref in $(git for-each-ref --format='%(refname:short)' "refs/remotes/$REMOTE/squad-state" "refs/remotes/$REMOTE/squad-state/*" 2>/dev/null); do
76
+ local_name=\${remote_ref#"$REMOTE/"}
77
+ local_sha=$(git rev-parse "refs/heads/$local_name" 2>/dev/null) || { git update-ref "refs/heads/$local_name" "$(git rev-parse "$remote_ref")" 2>/dev/null; continue; }
78
+ remote_sha=$(git rev-parse "$remote_ref" 2>/dev/null) || continue
79
+ [ "$local_sha" = "$remote_sha" ] && continue
80
+ git merge-base --is-ancestor "$local_sha" "$remote_sha" 2>/dev/null && git update-ref "refs/heads/$local_name" "$remote_sha" 2>/dev/null || true
81
+ done
82
+ git fetch "$REMOTE" '+refs/notes/squad*:refs/notes/squad*' 2>/dev/null || true
83
+ unset SQUAD_SYNC_ACTIVE
84
+ fi
85
+ `,
86
+ 'post-checkout': `#!/bin/sh
87
+ ${SQUAD_HOOK_MARKER}
88
+ # Auto-fetch squad-state branches on branch switch.
89
+ # Installed by: squad init / squad upgrade --state-backend
90
+ # Only run on branch checkout (3rd arg = 1), not file checkout.
91
+ if [ "\$3" = "1" ] && [ -z "$SQUAD_SYNC_ACTIVE" ]; then
92
+ export SQUAD_SYNC_ACTIVE=1
93
+ REMOTE=$(git config "branch.$(git symbolic-ref --short HEAD 2>/dev/null).remote" 2>/dev/null || echo origin)
94
+ git fetch "$REMOTE" '+refs/heads/squad-state:refs/remotes/'"$REMOTE"'/squad-state' '+refs/heads/squad-state/*:refs/remotes/'"$REMOTE"'/squad-state/*' 2>/dev/null || true
95
+ for remote_ref in $(git for-each-ref --format='%(refname:short)' "refs/remotes/$REMOTE/squad-state" "refs/remotes/$REMOTE/squad-state/*" 2>/dev/null); do
96
+ local_name=\${remote_ref#"$REMOTE/"}
97
+ local_sha=$(git rev-parse "refs/heads/$local_name" 2>/dev/null) || { git update-ref "refs/heads/$local_name" "$(git rev-parse "$remote_ref")" 2>/dev/null; continue; }
98
+ remote_sha=$(git rev-parse "$remote_ref" 2>/dev/null) || continue
99
+ [ "$local_sha" = "$remote_sha" ] && continue
100
+ git merge-base --is-ancestor "$local_sha" "$remote_sha" 2>/dev/null && git update-ref "refs/heads/$local_name" "$remote_sha" 2>/dev/null || true
101
+ done
102
+ git fetch "$REMOTE" '+refs/notes/squad*:refs/notes/squad*' 2>/dev/null || true
103
+ unset SQUAD_SYNC_ACTIVE
104
+ fi
105
+ `,
106
+ };
107
+ /**
108
+ * Get the .git/hooks directory path for the repo.
109
+ */
110
+ function getHooksDir(cwd) {
111
+ // Respect core.hooksPath if already set
112
+ try {
113
+ const customPath = execFileSync('git', ['config', '--get', 'core.hooksPath'], {
114
+ cwd, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
115
+ }).trim();
116
+ if (customPath) {
117
+ return path.isAbsolute(customPath) ? customPath : path.resolve(cwd, customPath);
118
+ }
119
+ }
120
+ catch {
121
+ // Not set — use default
122
+ }
123
+ const gitDir = execFileSync('git', ['rev-parse', '--git-dir'], {
124
+ cwd, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
125
+ }).trim();
126
+ return path.resolve(cwd, gitDir, 'hooks');
127
+ }
128
+ /**
129
+ * Install a single hook, chaining with any existing hook.
130
+ */
131
+ function installHook(hooksDir, hookName, content, force) {
132
+ const hookPath = path.join(hooksDir, hookName);
133
+ // Check if hook already exists
134
+ if (fs.existsSync(hookPath)) {
135
+ const existing = fs.readFileSync(hookPath, 'utf-8');
136
+ // Already has our marker — skip unless force
137
+ if (existing.includes(SQUAD_HOOK_MARKER)) {
138
+ if (!force)
139
+ return 'skipped';
140
+ // Force: remove old squad section and re-append
141
+ const cleaned = existing.split('\n').filter(line => {
142
+ // Remove lines between markers
143
+ return true; // simplified: just replace the file
144
+ }).join('\n');
145
+ // For simplicity on force, rewrite with chaining
146
+ }
147
+ // Chain: existing hook runs first, then squad hook (without shebang)
148
+ const squadSection = content.split('\n').slice(1).join('\n'); // remove #!/bin/sh
149
+ const chained = existing.trimEnd() + '\n\n' + squadSection;
150
+ fs.writeFileSync(hookPath, chained, { mode: 0o755 });
151
+ return 'chained';
152
+ }
153
+ // No existing hook — write fresh
154
+ fs.mkdirSync(hooksDir, { recursive: true });
155
+ fs.writeFileSync(hookPath, content, { mode: 0o755 });
156
+ return 'installed';
157
+ }
158
+ /**
159
+ * Main hook installation entrypoint.
160
+ */
161
+ export function installGitHooks(cwd, options = {}) {
162
+ const { force = false } = options;
163
+ // Verify we're in a git repo
164
+ try {
165
+ execFileSync('git', ['rev-parse', '--git-dir'], {
166
+ cwd, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
167
+ });
168
+ }
169
+ catch {
170
+ console.log(`${YELLOW}⚠${RESET} Not a git repository. Cannot install hooks.`);
171
+ return;
172
+ }
173
+ // Check if backend needs hooks (only orphan/two-layer)
174
+ let backend = null;
175
+ try {
176
+ const configPath = path.join(cwd, '.squad', 'config.json');
177
+ if (fs.existsSync(configPath)) {
178
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
179
+ backend = config.stateBackend || null;
180
+ }
181
+ }
182
+ catch { /* proceed anyway */ }
183
+ if (backend === 'local' || backend === 'external' || backend === null) {
184
+ console.log(`${DIM}squad install-hooks: backend is '${backend || 'local'}' — hooks not needed (state syncs with normal git operations).${RESET}`);
185
+ return;
186
+ }
187
+ const hooksDir = getHooksDir(cwd);
188
+ console.log(`\n${BOLD}Installing squad sync hooks${RESET}`);
189
+ console.log(`${DIM} hooks dir: ${hooksDir}${RESET}\n`);
190
+ for (const [hookName, template] of Object.entries(HOOK_TEMPLATES)) {
191
+ const result = installHook(hooksDir, hookName, template, force);
192
+ switch (result) {
193
+ case 'installed':
194
+ console.log(` ${GREEN}✓${RESET} ${hookName}: installed`);
195
+ break;
196
+ case 'chained':
197
+ console.log(` ${GREEN}✓${RESET} ${hookName}: chained (existing hook preserved)`);
198
+ break;
199
+ case 'skipped':
200
+ console.log(` ${DIM} ${hookName}: already installed (use --force to reinstall)${RESET}`);
201
+ break;
202
+ }
203
+ }
204
+ console.log(`\n${GREEN}${BOLD}Done.${RESET} Squad state will sync automatically on push/pull.\n`);
205
+ }
206
+ /**
207
+ * Ensure hooks are installed if the backend requires them.
208
+ * Called by `squad upgrade` to silently ensure hooks exist for orphan/two-layer repos.
209
+ * Does not print anything if hooks are already installed or backend doesn't need them.
210
+ */
211
+ export function ensureHooksForBackend(cwd) {
212
+ // Check backend
213
+ let backend = null;
214
+ try {
215
+ const configPath = path.join(cwd, '.squad', 'config.json');
216
+ if (fs.existsSync(configPath)) {
217
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
218
+ backend = config.stateBackend || null;
219
+ }
220
+ }
221
+ catch {
222
+ return;
223
+ }
224
+ // Only orphan/two-layer need hooks
225
+ if (backend !== 'orphan' && backend !== 'two-layer')
226
+ return;
227
+ // Check if hooks are already installed
228
+ let hooksDir;
229
+ try {
230
+ hooksDir = getHooksDir(cwd);
231
+ }
232
+ catch {
233
+ return;
234
+ }
235
+ const prePushPath = path.join(hooksDir, 'pre-push');
236
+ if (fs.existsSync(prePushPath)) {
237
+ const content = fs.readFileSync(prePushPath, 'utf-8');
238
+ if (content.includes(SQUAD_HOOK_MARKER))
239
+ return; // Already installed
240
+ }
241
+ // Hooks missing — install them
242
+ installGitHooks(cwd, { force: false });
243
+ }
244
+ //# sourceMappingURL=install-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../../../src/cli/commands/install-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Backend migration — upgrades state backend from local to orphan or two-layer.
3
+ *
4
+ * Currently supports:
5
+ * - local → orphan
6
+ * - local → two-layer
7
+ *
8
+ * Migration from orphan/two-layer back to local is not supported (would require
9
+ * materializing all state from the orphan branch back to the working tree).
10
+ */
11
+ /**
12
+ * Migrate the state backend for an existing squad project.
13
+ * Only local → orphan/two-layer is supported.
14
+ */
15
+ export declare function migrateStateBackend(dest: string, target: string): Promise<void>;
16
+ //# sourceMappingURL=migrate-backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-backend.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/migrate-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqErF"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Backend migration — upgrades state backend from local to orphan or two-layer.
3
+ *
4
+ * Currently supports:
5
+ * - local → orphan
6
+ * - local → two-layer
7
+ *
8
+ * Migration from orphan/two-layer back to local is not supported (would require
9
+ * materializing all state from the orphan branch back to the working tree).
10
+ */
11
+ import { execFileSync } from 'node:child_process';
12
+ import path from 'node:path';
13
+ import fs from 'node:fs';
14
+ import { installGitHooks } from './install-hooks.js';
15
+ const GREEN = '\x1b[32m';
16
+ const YELLOW = '\x1b[33m';
17
+ const BOLD = '\x1b[1m';
18
+ const RESET = '\x1b[0m';
19
+ const VALID_TARGETS = ['orphan', 'two-layer'];
20
+ /**
21
+ * Migrate the state backend for an existing squad project.
22
+ * Only local → orphan/two-layer is supported.
23
+ */
24
+ export async function migrateStateBackend(dest, target) {
25
+ if (!VALID_TARGETS.includes(target)) {
26
+ console.log(`${YELLOW}⚠ Invalid backend target '${target}'. Supported: ${VALID_TARGETS.join(', ')}${RESET}`);
27
+ return;
28
+ }
29
+ const configPath = path.join(dest, '.squad', 'config.json');
30
+ let config = {};
31
+ try {
32
+ if (fs.existsSync(configPath)) {
33
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
34
+ }
35
+ }
36
+ catch { /* start fresh */ }
37
+ const current = config['stateBackend'] || 'local';
38
+ // Validate migration direction
39
+ if (current === target) {
40
+ console.log(`${YELLOW}⚠ Backend is already '${target}'. Nothing to do.${RESET}`);
41
+ return;
42
+ }
43
+ if (current !== 'local' && current !== null) {
44
+ console.log(`${YELLOW}⚠ Migration from '${current}' to '${target}' is not supported.${RESET}`);
45
+ console.log(` Only local → orphan or local → two-layer is supported at this time.`);
46
+ return;
47
+ }
48
+ console.log(`\n${BOLD}Migrating state backend: ${current} → ${target}${RESET}\n`);
49
+ // Step 1: Create orphan branch if needed
50
+ try {
51
+ execFileSync('git', ['rev-parse', '--verify', 'refs/heads/squad-state'], {
52
+ cwd: dest, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
53
+ });
54
+ console.log(` ${GREEN}✓${RESET} squad-state branch already exists`);
55
+ }
56
+ catch {
57
+ try {
58
+ const readmeContent = '# Squad State\n\nThis orphan branch stores mutable squad state.\nIt is managed automatically and should not be edited by hand.\n';
59
+ const blobHash = execFileSync('git', ['hash-object', '-w', '--stdin'], {
60
+ cwd: dest, encoding: 'utf-8', input: readmeContent, stdio: ['pipe', 'pipe', 'pipe'],
61
+ }).trim();
62
+ const treeInput = `100644 blob ${blobHash}\tREADME.md\n`;
63
+ const treeHash = execFileSync('git', ['mktree'], {
64
+ cwd: dest, encoding: 'utf-8', input: treeInput, stdio: ['pipe', 'pipe', 'pipe'],
65
+ }).trim();
66
+ const commitHash = execFileSync('git', ['commit-tree', treeHash, '-m', 'init: squad-state orphan branch'], {
67
+ cwd: dest, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
68
+ }).trim();
69
+ execFileSync('git', ['update-ref', 'refs/heads/squad-state', commitHash], {
70
+ cwd: dest, stdio: ['pipe', 'pipe', 'pipe'],
71
+ });
72
+ console.log(` ${GREEN}✓${RESET} squad-state orphan branch created`);
73
+ }
74
+ catch (err) {
75
+ console.log(`${YELLOW}⚠ Could not create squad-state branch: ${err instanceof Error ? err.message : err}${RESET}`);
76
+ return;
77
+ }
78
+ }
79
+ // Step 2: Update config
80
+ config['stateBackend'] = target;
81
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
82
+ console.log(` ${GREEN}✓${RESET} config.json updated: stateBackend = ${target}`);
83
+ // Step 3: Install git hooks
84
+ installGitHooks(dest, { force: true });
85
+ console.log(`\n${GREEN}${BOLD}✓ Migration complete.${RESET} Backend is now '${target}'.\n`);
86
+ }
87
+ //# sourceMappingURL=migrate-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-backend.js","sourceRoot":"","sources":["../../../src/cli/commands/migrate-backend.ts"],"names":[],"mappings":"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"}
@@ -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"}