specweave 0.28.57 β†’ 0.28.61

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 (44) hide show
  1. package/bin/specweave.js +36 -0
  2. package/dist/src/cli/commands/init.d.ts.map +1 -1
  3. package/dist/src/cli/commands/init.js +13 -1
  4. package/dist/src/cli/commands/init.js.map +1 -1
  5. package/dist/src/cli/commands/jobs.d.ts +20 -0
  6. package/dist/src/cli/commands/jobs.d.ts.map +1 -0
  7. package/dist/src/cli/commands/jobs.js +448 -0
  8. package/dist/src/cli/commands/jobs.js.map +1 -0
  9. package/dist/src/cli/helpers/init/ado-repo-cloning.d.ts +32 -0
  10. package/dist/src/cli/helpers/init/ado-repo-cloning.d.ts.map +1 -0
  11. package/dist/src/cli/helpers/init/ado-repo-cloning.js +161 -0
  12. package/dist/src/cli/helpers/init/ado-repo-cloning.js.map +1 -0
  13. package/dist/src/cli/helpers/init/external-import.d.ts +18 -1
  14. package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
  15. package/dist/src/cli/helpers/init/external-import.js +61 -21
  16. package/dist/src/cli/helpers/init/external-import.js.map +1 -1
  17. package/dist/src/cli/helpers/selection-strategy.d.ts +28 -0
  18. package/dist/src/cli/helpers/selection-strategy.d.ts.map +1 -1
  19. package/dist/src/cli/helpers/selection-strategy.js +48 -0
  20. package/dist/src/cli/helpers/selection-strategy.js.map +1 -1
  21. package/dist/src/cli/workers/import-worker.d.ts +18 -0
  22. package/dist/src/cli/workers/import-worker.d.ts.map +1 -0
  23. package/dist/src/cli/workers/import-worker.js +268 -0
  24. package/dist/src/cli/workers/import-worker.js.map +1 -0
  25. package/dist/src/core/background/index.d.ts +8 -0
  26. package/dist/src/core/background/index.d.ts.map +1 -1
  27. package/dist/src/core/background/index.js +8 -0
  28. package/dist/src/core/background/index.js.map +1 -1
  29. package/dist/src/core/background/job-launcher.d.ts +54 -0
  30. package/dist/src/core/background/job-launcher.d.ts.map +1 -0
  31. package/dist/src/core/background/job-launcher.js +206 -0
  32. package/dist/src/core/background/job-launcher.js.map +1 -0
  33. package/dist/src/core/repo-structure/providers/azure-devops-provider.d.ts +15 -0
  34. package/dist/src/core/repo-structure/providers/azure-devops-provider.d.ts.map +1 -1
  35. package/dist/src/core/repo-structure/providers/azure-devops-provider.js +56 -0
  36. package/dist/src/core/repo-structure/providers/azure-devops-provider.js.map +1 -1
  37. package/dist/src/importers/ado-importer.d.ts +7 -1
  38. package/dist/src/importers/ado-importer.d.ts.map +1 -1
  39. package/dist/src/importers/ado-importer.js +108 -61
  40. package/dist/src/importers/ado-importer.js.map +1 -1
  41. package/package.json +1 -1
  42. package/plugins/specweave/commands/specweave-jobs.md +133 -29
  43. package/plugins/specweave-ado/commands/specweave-ado-clone-repos.md +379 -0
  44. package/plugins/specweave-release/commands/specweave-release-npm.md +51 -14
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: specweave:jobs
3
- description: Monitor background jobs (repo cloning, issue import). Shows progress, allows pause/resume.
4
- usage: /specweave:jobs [--active|--all|--id <job-id>] [--resume <job-id>]
3
+ description: Monitor background jobs (repo cloning, issue import). Shows progress, allows pause/resume/kill.
4
+ usage: /specweave:jobs [--active|--all|--id <job-id>] [--resume <job-id>] [--kill <job-id>] [--follow <job-id>] [--logs <job-id>]
5
5
  ---
6
6
 
7
7
  # Background Jobs Monitor
@@ -17,6 +17,25 @@ Monitor and manage long-running background operations:
17
17
  - **Issue import** (10K+ items from GitHub/JIRA/ADO)
18
18
  - **External sync** operations
19
19
 
20
+ **ASYNC ARCHITECTURE (2025-12-01)**:
21
+ - Jobs run as **detached processes** that survive terminal close
22
+ - Progress tracked via filesystem (`.specweave/state/jobs/`)
23
+ - Can check status anytime with `/specweave:jobs`
24
+
25
+ ---
26
+
27
+ ## Command Options
28
+
29
+ | Option | Description |
30
+ |--------|-------------|
31
+ | (none) | Show active jobs |
32
+ | `--all` | Show all jobs (including completed) |
33
+ | `--id <jobId>` | Show details for specific job |
34
+ | `--follow <jobId>` | Follow job progress in real-time |
35
+ | `--logs <jobId>` | Show worker log output |
36
+ | `--resume <jobId>` | Resume paused job |
37
+ | `--kill <jobId>` | Kill running background job |
38
+
20
39
  ---
21
40
 
22
41
  ## Check Job Status
@@ -26,6 +45,12 @@ Read the background jobs state file and display status:
26
45
  ```bash
27
46
  # Find and read the state file
28
47
  STATE_FILE=".specweave/state/background-jobs.json"
48
+
49
+ # Also check job-specific files:
50
+ # .specweave/state/jobs/<jobId>/config.json - Job configuration
51
+ # .specweave/state/jobs/<jobId>/worker.pid - Process ID (if running)
52
+ # .specweave/state/jobs/<jobId>/worker.log - Worker output log
53
+ # .specweave/state/jobs/<jobId>/result.json - Results (when complete)
29
54
  ```
30
55
 
31
56
  ### Display Format
@@ -34,25 +59,28 @@ STATE_FILE=".specweave/state/background-jobs.json"
34
59
  πŸ“‹ Background Jobs
35
60
 
36
61
  πŸ”„ Running (1):
37
- [abc12345] clone-repos
38
- Progress: 2/4 (50%) β†’ sw-meeting-cost-be
39
- Rate: 0.5/s | ETA: ~4s
40
- Started: 2 mins ago
62
+ [abc12345] import-issues (ADO)
63
+ Progress: 2,500/10,000 (25%)
64
+ Rate: 15.2/s | ETA: ~8m 14s
65
+ PID: 45678 | Started: 2 mins ago
41
66
 
42
67
  ⏸️ Paused (1):
43
68
  [def67890] import-issues (GitHub)
44
69
  Progress: 1,234/10,000 (12%)
45
- Reason: Rate limited
70
+ Reason: Rate limited (resumes in 45s)
46
71
  Resume: /specweave:jobs --resume def67890
47
72
 
48
73
  βœ… Completed (2):
49
- [ghi11111] clone-repos - 4/4 repos - 5 mins ago
50
- [jkl22222] import-issues - 500 items - 1 hour ago
74
+ [ghi11111] import-issues - 4,500 items - 5 mins ago
75
+ [jkl22222] clone-repos - 4/4 repos - 1 hour ago
51
76
 
52
77
  πŸ’‘ Commands:
53
- /specweave:jobs --id abc12345 β†’ Details for specific job
54
- /specweave:jobs --resume def67890 β†’ Resume paused job
55
- /specweave:jobs --all β†’ Show all jobs (including old)
78
+ /specweave:jobs --id abc12345 β†’ Details for specific job
79
+ /specweave:jobs --follow abc12345 β†’ Follow progress live
80
+ /specweave:jobs --logs abc12345 β†’ View worker logs
81
+ /specweave:jobs --resume def67890 β†’ Resume paused job
82
+ /specweave:jobs --kill abc12345 β†’ Kill running job
83
+ /specweave:jobs --all β†’ Show all jobs (including old)
56
84
  ```
57
85
 
58
86
  ---
@@ -66,32 +94,92 @@ STATE_FILE=".specweave/state/background-jobs.json"
66
94
 
67
95
  πŸ“¦ Job Details: abc12345
68
96
 
69
- Type: clone-repos
97
+ Type: import-issues
70
98
  Status: running
99
+ Provider: ADO
100
+ PID: 45678
101
+
71
102
  Started: 2024-01-15 10:30:00
72
103
  Updated: 2024-01-15 10:32:15
73
104
 
74
- Progress: 2/4 (50%)
75
- Current: sw-meeting-cost-be
76
- Rate: 0.5 repos/sec
77
- ETA: ~4 seconds
105
+ Progress: 2,500/10,000 (25%)
106
+ Current: OlySense\Core-Operations
107
+ Rate: 15.2 items/sec
108
+ ETA: ~8 minutes
109
+
110
+ Files:
111
+ Config: .specweave/state/jobs/abc12345/config.json
112
+ Logs: .specweave/state/jobs/abc12345/worker.log
113
+ PID: .specweave/state/jobs/abc12345/worker.pid
114
+ ```
115
+
116
+ ### Follow Job Progress Live
117
+
118
+ Watch job progress in real-time (like `tail -f`):
78
119
 
79
- Completed:
80
- βœ… sw-meeting-cost-fe
81
- βœ… sw-meeting-cost-shared
120
+ ```
121
+ /specweave:jobs --follow abc12345
82
122
 
83
- Remaining:
84
- ⏳ sw-meeting-cost-be
85
- ⏳ sw-meeting-cost
123
+ πŸ“¦ Following job abc12345 (Ctrl+C to stop)
86
124
 
87
- Config:
88
- Project: /path/to/project
89
- Repos: 4 total
125
+ [10:30:15] Progress: 2,500/10,000 (25%) - OlySense\Core-Operations
126
+ [10:30:16] Progress: 2,520/10,000 (25%) - OlySense\Core-Operations
127
+ [10:30:17] Progress: 2,545/10,000 (25%) - OlySense\AI-Platform
128
+ [10:30:18] Progress: 2,570/10,000 (26%) - OlySense\AI-Platform
129
+ ...
130
+ ```
131
+
132
+ **Implementation**: Read `.specweave/state/jobs/<jobId>/worker.log` with tail-like behavior, or poll the job state file every second.
133
+
134
+ ### View Worker Logs
135
+
136
+ Show detailed worker output:
137
+
138
+ ```
139
+ /specweave:jobs --logs abc12345
140
+
141
+ πŸ“‹ Worker Logs for abc12345 (last 50 lines):
142
+
143
+ [2024-01-15T10:30:00.123Z] Worker started for job abc12345
144
+ [2024-01-15T10:30:00.456Z] Project path: /Users/dev/my-project
145
+ [2024-01-15T10:30:00.789Z] PID: 45678
146
+ [2024-01-15T10:30:01.234Z] Dependencies loaded, starting import...
147
+ [2024-01-15T10:30:02.567Z] Progress: 100/10000 - ado OlySense\Core-Operations
148
+ [2024-01-15T10:30:03.890Z] Progress: 200/10000 - ado OlySense\Core-Operations
149
+ ...
150
+ ```
151
+
152
+ **Implementation**: Read `.specweave/state/jobs/<jobId>/worker.log`
153
+
154
+ ### Kill Running Job
155
+
156
+ Stop a background job:
157
+
158
+ ```
159
+ /specweave:jobs --kill abc12345
160
+
161
+ ⚠️ Killing job abc12345...
162
+ Type: import-issues
163
+ PID: 45678
164
+ Progress: 2,500/10,000 (25%)
165
+
166
+ βœ… Job killed. Status changed to 'paused'.
167
+ Resume later: /specweave:jobs --resume abc12345
168
+ ```
169
+
170
+ **Implementation**:
171
+ ```typescript
172
+ import { killJob } from '../../../src/core/background/job-launcher.js';
173
+
174
+ const success = killJob(projectPath, jobId);
175
+ if (success) {
176
+ console.log('Job killed successfully');
177
+ }
90
178
  ```
91
179
 
92
180
  ### Resume Paused Job
93
181
 
94
- When a job is paused (rate limited, user requested), resume it:
182
+ When a job is paused (rate limited, killed, or user requested), resume it:
95
183
 
96
184
  ```
97
185
  /specweave:jobs --resume def67890
@@ -101,8 +189,24 @@ When a job is paused (rate limited, user requested), resume it:
101
189
  Provider: GitHub
102
190
  Resuming from: item 1,234 of 10,000
103
191
 
104
- ⏳ Import in progress...
105
- [1,234/10,000] 12% β†’ PROJ-1234
192
+ ⏳ Spawning background worker...
193
+ New PID: 45679
194
+
195
+ βœ… Job resumed in background.
196
+ Check progress: /specweave:jobs --follow def67890
197
+ ```
198
+
199
+ **Implementation**:
200
+ ```typescript
201
+ import { launchImportJob } from '../../../src/core/background/job-launcher.js';
202
+
203
+ // Re-launch the worker with existing config
204
+ const result = await launchImportJob({
205
+ type: 'import-issues',
206
+ projectPath,
207
+ coordinatorConfig: existingConfig,
208
+ estimatedTotal: job.progress.total
209
+ });
106
210
  ```
107
211
 
108
212
  ---
@@ -0,0 +1,379 @@
1
+ ---
2
+ name: specweave-ado:clone-repos
3
+ description: Clone Azure DevOps repositories to local workspace. Use after init if cloning was skipped, or to add repos later.
4
+ ---
5
+
6
+ # Clone Azure DevOps Repositories Command
7
+
8
+ You are an Azure DevOps repository cloning expert. Help users clone repositories from ADO projects to their local workspace.
9
+
10
+ ## Purpose
11
+
12
+ This command clones Azure DevOps repositories **after** initial SpecWeave setup (`specweave init`). Use when:
13
+ - User skipped cloning during init
14
+ - Adding repositories from additional projects
15
+ - Re-cloning after cleanup
16
+ - Selective cloning with pattern filtering
17
+
18
+ ## Command Syntax
19
+
20
+ ```bash
21
+ # Interactive mode (prompts for everything)
22
+ /specweave-ado:clone-repos
23
+
24
+ # With pattern filter
25
+ /specweave-ado:clone-repos --pattern "sw-*"
26
+
27
+ # Regex pattern
28
+ /specweave-ado:clone-repos --pattern "regex:^api-.*$"
29
+
30
+ # Specific project only
31
+ /specweave-ado:clone-repos --project "MyProject"
32
+
33
+ # Dry-run (preview only)
34
+ /specweave-ado:clone-repos --dry-run
35
+ ```
36
+
37
+ ## Your Task
38
+
39
+ When the user runs this command:
40
+
41
+ ### Step 1: Check Prerequisites
42
+
43
+ ```typescript
44
+ import { readEnvFile, parseEnvFile } from '../../../src/utils/env-file.js';
45
+ import chalk from 'chalk';
46
+
47
+ const projectPath = process.cwd();
48
+ const envContent = readEnvFile(projectPath);
49
+
50
+ if (!envContent) {
51
+ console.log(chalk.red('❌ No .env file found. Run `specweave init` first.'));
52
+ return;
53
+ }
54
+
55
+ const parsed = parseEnvFile(envContent);
56
+
57
+ if (!parsed.AZURE_DEVOPS_PAT || !parsed.AZURE_DEVOPS_ORG) {
58
+ console.log(chalk.red('❌ Missing Azure DevOps credentials.'));
59
+ console.log(chalk.gray(' Run `specweave init` with Azure DevOps provider.'));
60
+ return;
61
+ }
62
+
63
+ const org = parsed.AZURE_DEVOPS_ORG;
64
+ const pat = parsed.AZURE_DEVOPS_PAT;
65
+
66
+ console.log(chalk.blue('\nπŸ“¦ ADO Repository Cloning\n'));
67
+ console.log(chalk.gray(` Organization: ${org}`));
68
+ ```
69
+
70
+ ### Step 2: Get Project Selection
71
+
72
+ ```typescript
73
+ import { AzureDevOpsProvider } from '../../../src/core/repo-structure/providers/azure-devops-provider.js';
74
+
75
+ const provider = new AzureDevOpsProvider();
76
+
77
+ // If project specified via CLI, use it
78
+ let selectedProjects: string[] = [];
79
+
80
+ if (args.project) {
81
+ selectedProjects = [args.project];
82
+ console.log(chalk.gray(` Project: ${args.project} (from CLI)`));
83
+ } else {
84
+ // Fetch available projects
85
+ console.log(chalk.gray('\n Fetching projects...'));
86
+
87
+ const response = await fetch(
88
+ `https://dev.azure.com/${org}/_apis/projects?api-version=7.0`,
89
+ {
90
+ headers: {
91
+ 'Authorization': `Basic ${Buffer.from(':' + pat).toString('base64')}`,
92
+ 'Accept': 'application/json'
93
+ }
94
+ }
95
+ );
96
+
97
+ if (!response.ok) {
98
+ console.log(chalk.red(`❌ Failed to fetch projects: ${response.status}`));
99
+ return;
100
+ }
101
+
102
+ const data = await response.json();
103
+ const projects = data.value || [];
104
+
105
+ if (projects.length === 0) {
106
+ console.log(chalk.yellow('⚠️ No projects found in organization.'));
107
+ return;
108
+ }
109
+
110
+ // Prompt for project selection
111
+ const { checkbox } = await import('@inquirer/prompts');
112
+
113
+ selectedProjects = await checkbox({
114
+ message: 'Select project(s) to clone repositories from:',
115
+ choices: projects.map(p => ({ name: p.name, value: p.name })),
116
+ required: true
117
+ });
118
+
119
+ console.log(chalk.green(` βœ“ ${selectedProjects.length} project(s) selected`));
120
+ }
121
+ ```
122
+
123
+ ### Step 3: Fetch Repositories
124
+
125
+ ```typescript
126
+ const allRepos = [];
127
+
128
+ for (const project of selectedProjects) {
129
+ console.log(chalk.gray(`\n Fetching repos from ${project}...`));
130
+
131
+ try {
132
+ const repos = await provider.listRepositories(org, project, pat);
133
+ const reposWithProject = repos.map(r => ({ ...r, project }));
134
+ allRepos.push(...reposWithProject);
135
+ console.log(chalk.green(` βœ“ Found ${repos.length} repositories`));
136
+ } catch (error) {
137
+ console.log(chalk.yellow(` ⚠️ Failed: ${error.message}`));
138
+ }
139
+ }
140
+
141
+ if (allRepos.length === 0) {
142
+ console.log(chalk.yellow('\n⚠️ No repositories found.'));
143
+ return;
144
+ }
145
+
146
+ console.log(chalk.blue(`\nπŸ“‹ Total: ${allRepos.length} repositories available\n`));
147
+ ```
148
+
149
+ ### Step 4: Apply Pattern Filter
150
+
151
+ ```typescript
152
+ import { filterRepositoriesByPattern } from '../../../src/cli/helpers/selection-strategy.js';
153
+
154
+ let filteredRepos = allRepos;
155
+ let patternDescription = 'all';
156
+
157
+ if (args.pattern) {
158
+ // Determine pattern type
159
+ const isRegex = args.pattern.startsWith('regex:');
160
+ const pattern = isRegex ? args.pattern.slice(6) : args.pattern;
161
+
162
+ const clonePattern = {
163
+ strategy: isRegex ? 'pattern-regex' : 'pattern-glob',
164
+ pattern: pattern,
165
+ isRegex
166
+ };
167
+
168
+ filteredRepos = filterRepositoriesByPattern(allRepos, clonePattern);
169
+ patternDescription = `matching "${pattern}"`;
170
+
171
+ console.log(chalk.gray(` Pattern: ${args.pattern}`));
172
+ console.log(chalk.gray(` Matched: ${filteredRepos.length} of ${allRepos.length} repos\n`));
173
+ } else {
174
+ // Prompt for pattern selection
175
+ const { select, input } = await import('@inquirer/prompts');
176
+
177
+ const strategy = await select({
178
+ message: 'How do you want to select repositories?',
179
+ choices: [
180
+ { name: 'All - Clone all repositories', value: 'all' },
181
+ { name: 'Pattern (glob) - e.g., "sw-*", "*-backend"', value: 'pattern-glob' },
182
+ { name: 'Pattern (regex) - e.g., "^api-.*$"', value: 'pattern-regex' }
183
+ ]
184
+ });
185
+
186
+ if (strategy !== 'all') {
187
+ const pattern = await input({
188
+ message: 'Enter pattern:',
189
+ validate: v => v.trim() ? true : 'Pattern required'
190
+ });
191
+
192
+ const clonePattern = {
193
+ strategy,
194
+ pattern: pattern.trim(),
195
+ isRegex: strategy === 'pattern-regex'
196
+ };
197
+
198
+ filteredRepos = filterRepositoriesByPattern(allRepos, clonePattern);
199
+ patternDescription = `matching "${pattern.trim()}"`;
200
+ }
201
+ }
202
+
203
+ if (filteredRepos.length === 0) {
204
+ console.log(chalk.yellow(`⚠️ No repositories ${patternDescription}.`));
205
+ return;
206
+ }
207
+ ```
208
+
209
+ ### Step 5: Preview and Confirm
210
+
211
+ ```typescript
212
+ console.log(chalk.blue(`\nπŸ“¦ Repositories to clone (${filteredRepos.length}):\n`));
213
+
214
+ // Show preview (max 20)
215
+ filteredRepos.slice(0, 20).forEach(repo => {
216
+ console.log(chalk.gray(` β€’ ${repo.name} (${repo.project})`));
217
+ });
218
+
219
+ if (filteredRepos.length > 20) {
220
+ console.log(chalk.gray(` ... and ${filteredRepos.length - 20} more\n`));
221
+ }
222
+
223
+ if (args.dryRun) {
224
+ console.log(chalk.cyan('\nπŸ”Ž DRY RUN: No repositories will be cloned.\n'));
225
+ return;
226
+ }
227
+
228
+ const { confirm } = await import('@inquirer/prompts');
229
+
230
+ const confirmed = await confirm({
231
+ message: `Clone ${filteredRepos.length} repositories to ./repos/?`,
232
+ default: true
233
+ });
234
+
235
+ if (!confirmed) {
236
+ console.log(chalk.gray('\n⏭️ Cloning cancelled.\n'));
237
+ return;
238
+ }
239
+ ```
240
+
241
+ ### Step 6: Start Background Cloning
242
+
243
+ ```typescript
244
+ import { triggerAdoRepoCloning } from '../../../src/cli/helpers/init/ado-repo-cloning.js';
245
+
246
+ // Build adoProjectSelection
247
+ const adoProjectSelection = {
248
+ org,
249
+ pat,
250
+ projects: selectedProjects
251
+ };
252
+
253
+ // Build clonePattern
254
+ const clonePatternResult = args.pattern
255
+ ? {
256
+ strategy: args.pattern.startsWith('regex:') ? 'pattern-regex' : 'pattern-glob',
257
+ pattern: args.pattern.startsWith('regex:') ? args.pattern.slice(6) : args.pattern
258
+ }
259
+ : { strategy: 'all' };
260
+
261
+ // Trigger background cloning
262
+ await triggerAdoRepoCloning(projectPath, adoProjectSelection, clonePatternResult);
263
+ ```
264
+
265
+ ## Examples
266
+
267
+ ### Example 1: Interactive Clone
268
+ **User**: `/specweave-ado:clone-repos`
269
+
270
+ **Output**:
271
+ ```
272
+ πŸ“¦ ADO Repository Cloning
273
+
274
+ Organization: mycompany
275
+
276
+ Fetching projects...
277
+ βœ“ 3 projects found
278
+
279
+ Select project(s) to clone repositories from:
280
+ > [x] Platform
281
+ [x] Shared
282
+ [ ] Legacy
283
+
284
+ βœ“ 2 project(s) selected
285
+
286
+ Fetching repos from Platform...
287
+ βœ“ Found 12 repositories
288
+ Fetching repos from Shared...
289
+ βœ“ Found 4 repositories
290
+
291
+ πŸ“‹ Total: 16 repositories available
292
+
293
+ How do you want to select repositories?
294
+ > All - Clone all repositories
295
+
296
+ πŸ“¦ Repositories to clone (16):
297
+
298
+ β€’ sw-frontend (Platform)
299
+ β€’ sw-backend (Platform)
300
+ β€’ sw-shared-lib (Shared)
301
+ ... and 13 more
302
+
303
+ Clone 16 repositories to ./repos/? (Y/n)
304
+
305
+ πŸ“¦ Fetching ADO Repositories
306
+
307
+ Fetching from mycompany/Platform...
308
+ βœ“ Found 12 repositories in Platform
309
+ Fetching from mycompany/Shared...
310
+ βœ“ Found 4 repositories in Shared
311
+
312
+ πŸ”„ Cloning 16 repositories in background...
313
+
314
+ Repositories will be cloned to: ./repos/
315
+ Job ID: abc12345
316
+
317
+ Check progress: /specweave:jobs
318
+ Resume if interrupted: /specweave:jobs --resume abc12345
319
+ ```
320
+
321
+ ### Example 2: Pattern Filter
322
+ **User**: `/specweave-ado:clone-repos --pattern "sw-*"`
323
+
324
+ **Output**:
325
+ ```
326
+ πŸ“¦ ADO Repository Cloning
327
+
328
+ Organization: mycompany
329
+ Pattern: sw-*
330
+ Matched: 8 of 16 repos
331
+
332
+ πŸ“¦ Repositories to clone (8):
333
+
334
+ β€’ sw-frontend (Platform)
335
+ β€’ sw-backend (Platform)
336
+ β€’ sw-shared-lib (Shared)
337
+ ...
338
+
339
+ Clone 8 repositories to ./repos/? (Y/n)
340
+ ```
341
+
342
+ ### Example 3: Dry Run
343
+ **User**: `/specweave-ado:clone-repos --dry-run`
344
+
345
+ **Output**:
346
+ ```
347
+ πŸ“¦ Repositories to clone (16):
348
+
349
+ β€’ sw-frontend (Platform)
350
+ β€’ sw-backend (Platform)
351
+ ...
352
+
353
+ πŸ”Ž DRY RUN: No repositories will be cloned.
354
+ ```
355
+
356
+ ## Important Notes
357
+
358
+ - **Background Cloning**: Repositories clone in background (non-blocking)
359
+ - **Progress Tracking**: Check progress with `/specweave:jobs`
360
+ - **Resumable**: Interrupted clones can resume with `/specweave:jobs --resume <id>`
361
+ - **Auth via PAT**: Uses HTTPS clone URLs with PAT authentication
362
+ - **Target Directory**: Repos are cloned to `./repos/<repo-name>/`
363
+
364
+ ## Related Commands
365
+
366
+ - `/specweave:init` - Initial SpecWeave setup (includes repo cloning option)
367
+ - `/specweave:jobs` - Monitor background jobs
368
+ - `/specweave-ado:import-projects` - Import ADO projects with area path mapping
369
+
370
+ ## Error Handling
371
+
372
+ - **Missing Credentials**: Prompt to run `specweave init` first
373
+ - **Auth Failures**: Check PAT permissions (vso.code_read scope required)
374
+ - **Clone Failures**: Individual repo failures logged, others continue
375
+ - **Network Errors**: Job pauses, resume with `/specweave:jobs --resume`
376
+
377
+ ---
378
+
379
+ **Multi-Repo Support**: Perfect for microservices architectures with many ADO repositories.