@imdeadpool/guardex 7.0.20 → 7.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/cli/args.js CHANGED
@@ -1,7 +1,809 @@
1
- function parseDoctorArgs(rawArgs, options = {}) {
2
- return { rawArgs, options };
1
+ const {
2
+ path,
3
+ DEFAULT_SHADOW_CLEANUP_IDLE_MINUTES,
4
+ TARGETED_FORCEABLE_MANAGED_PATHS,
5
+ } = require('../context');
6
+ const { DEFAULT_NESTED_REPO_MAX_DEPTH } = require('../git');
7
+
8
+ function requireValue(rawArgs, index, flagName) {
9
+ const value = rawArgs[index + 1];
10
+ if (!value || value.startsWith('-')) {
11
+ throw new Error(`${flagName} requires a value`);
12
+ }
13
+ return value;
14
+ }
15
+
16
+ function normalizeManagedForcePath(rawPath) {
17
+ if (typeof rawPath !== 'string') {
18
+ return null;
19
+ }
20
+ const normalized = path.posix.normalize(rawPath.replace(/\\/g, '/'));
21
+ if (!normalized || normalized === '.' || normalized.startsWith('../') || path.posix.isAbsolute(normalized)) {
22
+ return null;
23
+ }
24
+ return normalized.startsWith('./') ? normalized.slice(2) : normalized;
25
+ }
26
+
27
+ function collectForceManagedPaths(rawArgs, startIndex) {
28
+ const forceManagedPaths = [];
29
+ let nextIndex = startIndex;
30
+
31
+ while (nextIndex + 1 < rawArgs.length) {
32
+ const candidate = rawArgs[nextIndex + 1];
33
+ if (!candidate || candidate.startsWith('-')) {
34
+ break;
35
+ }
36
+ const normalized = normalizeManagedForcePath(candidate);
37
+ if (!normalized || !TARGETED_FORCEABLE_MANAGED_PATHS.has(normalized)) {
38
+ throw new Error(`Unknown managed path after --force: ${candidate}`);
39
+ }
40
+ forceManagedPaths.push(normalized);
41
+ nextIndex += 1;
42
+ }
43
+
44
+ return { forceManagedPaths, nextIndex };
45
+ }
46
+
47
+ function parseCommonArgs(rawArgs, defaults) {
48
+ const options = { ...defaults };
49
+ const supportsForce = Object.prototype.hasOwnProperty.call(options, 'force');
50
+ if (supportsForce && !Array.isArray(options.forceManagedPaths)) {
51
+ options.forceManagedPaths = [];
52
+ }
53
+
54
+ for (let index = 0; index < rawArgs.length; index += 1) {
55
+ const arg = rawArgs[index];
56
+ if (arg === '--target' || arg === '-t') {
57
+ options.target = requireValue(rawArgs, index, '--target');
58
+ index += 1;
59
+ continue;
60
+ }
61
+ if (arg === '--dry-run') {
62
+ options.dryRun = true;
63
+ continue;
64
+ }
65
+ if (arg === '--skip-agents') {
66
+ options.skipAgents = true;
67
+ continue;
68
+ }
69
+ if (arg === '--skip-package-json') {
70
+ options.skipPackageJson = true;
71
+ continue;
72
+ }
73
+ if (arg === '--force') {
74
+ if (!supportsForce) {
75
+ throw new Error(`Unknown option: ${arg}`);
76
+ }
77
+ options.force = true;
78
+ const parsed = collectForceManagedPaths(rawArgs, index);
79
+ if (parsed.forceManagedPaths.length > 0) {
80
+ options.forceManagedPaths = Array.from(
81
+ new Set([...(options.forceManagedPaths || []), ...parsed.forceManagedPaths]),
82
+ );
83
+ }
84
+ index = parsed.nextIndex;
85
+ continue;
86
+ }
87
+ if (arg === '--keep-stale-locks') {
88
+ options.dropStaleLocks = false;
89
+ continue;
90
+ }
91
+ if (arg === '--json') {
92
+ options.json = true;
93
+ continue;
94
+ }
95
+ if (arg === '--yes-global-install') {
96
+ options.yesGlobalInstall = true;
97
+ continue;
98
+ }
99
+ if (arg === '--no-global-install') {
100
+ options.noGlobalInstall = true;
101
+ continue;
102
+ }
103
+ if (arg === '--no-gitignore') {
104
+ options.skipGitignore = true;
105
+ continue;
106
+ }
107
+ if (arg === '--allow-protected-base-write') {
108
+ options.allowProtectedBaseWrite = true;
109
+ continue;
110
+ }
111
+ if (Object.prototype.hasOwnProperty.call(options, 'waitForMerge') && arg === '--wait-for-merge') {
112
+ options.waitForMerge = true;
113
+ continue;
114
+ }
115
+ if (Object.prototype.hasOwnProperty.call(options, 'waitForMerge') && arg === '--no-wait-for-merge') {
116
+ options.waitForMerge = false;
117
+ continue;
118
+ }
119
+
120
+ throw new Error(`Unknown option: ${arg}`);
121
+ }
122
+
123
+ if (!options.target) {
124
+ throw new Error('--target requires a path value');
125
+ }
126
+
127
+ return options;
128
+ }
129
+
130
+ function parseRepoTraversalArgs(rawArgs, defaults) {
131
+ const traversalDefaults = {
132
+ ...defaults,
133
+ recursive: true,
134
+ nestedMaxDepth: DEFAULT_NESTED_REPO_MAX_DEPTH,
135
+ nestedSkipDirs: [],
136
+ includeSubmodules: false,
137
+ };
138
+ const forwardedArgs = [];
139
+
140
+ for (let index = 0; index < rawArgs.length; index += 1) {
141
+ const arg = rawArgs[index];
142
+ if (arg === '--no-recursive' || arg === '--no-nested' || arg === '--single-repo' || arg === '--current') {
143
+ traversalDefaults.recursive = false;
144
+ continue;
145
+ }
146
+ if (arg === '--recursive' || arg === '--nested') {
147
+ traversalDefaults.recursive = true;
148
+ continue;
149
+ }
150
+ if (arg === '--max-depth') {
151
+ const raw = requireValue(rawArgs, index, '--max-depth');
152
+ const parsed = Number.parseInt(raw, 10);
153
+ if (!Number.isFinite(parsed) || parsed < 1) {
154
+ throw new Error('--max-depth requires a positive integer');
155
+ }
156
+ traversalDefaults.nestedMaxDepth = parsed;
157
+ index += 1;
158
+ continue;
159
+ }
160
+ if (arg === '--skip-nested') {
161
+ const raw = requireValue(rawArgs, index, '--skip-nested');
162
+ traversalDefaults.nestedSkipDirs.push(raw);
163
+ index += 1;
164
+ continue;
165
+ }
166
+ if (arg === '--include-submodules') {
167
+ traversalDefaults.includeSubmodules = true;
168
+ continue;
169
+ }
170
+ forwardedArgs.push(arg);
171
+ }
172
+
173
+ return parseCommonArgs(forwardedArgs, traversalDefaults);
174
+ }
175
+
176
+ function parseSetupArgs(rawArgs, defaults) {
177
+ const setupDefaults = {
178
+ ...defaults,
179
+ parentWorkspaceView: false,
180
+ };
181
+ const forwardedArgs = [];
182
+
183
+ for (let index = 0; index < rawArgs.length; index += 1) {
184
+ const arg = rawArgs[index];
185
+ if (arg === '--parent-workspace-view') {
186
+ setupDefaults.parentWorkspaceView = true;
187
+ continue;
188
+ }
189
+ if (arg === '--no-parent-workspace-view') {
190
+ setupDefaults.parentWorkspaceView = false;
191
+ continue;
192
+ }
193
+ forwardedArgs.push(arg);
194
+ }
195
+
196
+ return parseRepoTraversalArgs(forwardedArgs, setupDefaults);
197
+ }
198
+
199
+ function parseDoctorArgs(rawArgs) {
200
+ const doctorDefaults = {
201
+ target: process.cwd(),
202
+ force: false,
203
+ dropStaleLocks: true,
204
+ skipAgents: false,
205
+ skipPackageJson: false,
206
+ skipGitignore: false,
207
+ dryRun: false,
208
+ json: false,
209
+ allowProtectedBaseWrite: false,
210
+ waitForMerge: true,
211
+ verboseAutoFinish: false,
212
+ };
213
+ const forwardedArgs = [];
214
+
215
+ for (let index = 0; index < rawArgs.length; index += 1) {
216
+ const arg = rawArgs[index];
217
+ if (arg === '--verbose-auto-finish') {
218
+ doctorDefaults.verboseAutoFinish = true;
219
+ continue;
220
+ }
221
+ if (arg === '--compact-auto-finish') {
222
+ doctorDefaults.verboseAutoFinish = false;
223
+ continue;
224
+ }
225
+ forwardedArgs.push(arg);
226
+ }
227
+
228
+ return parseRepoTraversalArgs(forwardedArgs, doctorDefaults);
229
+ }
230
+
231
+ function parseTargetFlag(rawArgs, defaultTarget = process.cwd()) {
232
+ const remaining = [];
233
+ let target = defaultTarget;
234
+
235
+ for (let index = 0; index < rawArgs.length; index += 1) {
236
+ const arg = rawArgs[index];
237
+ if (arg === '--target') {
238
+ const next = rawArgs[index + 1];
239
+ if (!next) {
240
+ throw new Error('--target requires a path value');
241
+ }
242
+ target = next;
243
+ index += 1;
244
+ continue;
245
+ }
246
+ remaining.push(arg);
247
+ }
248
+
249
+ return { target, args: remaining };
250
+ }
251
+
252
+ function parseReviewArgs(rawArgs) {
253
+ const parsed = parseTargetFlag(rawArgs, process.cwd());
254
+ const passthroughArgs = [...parsed.args];
255
+ if (passthroughArgs[0] === 'start') {
256
+ passthroughArgs.shift();
257
+ }
258
+ return {
259
+ target: parsed.target,
260
+ passthroughArgs,
261
+ };
262
+ }
263
+
264
+ function parseAgentsArgs(rawArgs) {
265
+ const parsed = parseTargetFlag(rawArgs, process.cwd());
266
+ const [subcommandRaw = '', ...rest] = parsed.args;
267
+ const subcommand = subcommandRaw || 'status';
268
+ const options = {
269
+ target: parsed.target,
270
+ subcommand,
271
+ reviewIntervalSeconds: 30,
272
+ cleanupIntervalSeconds: 60,
273
+ idleMinutes: DEFAULT_SHADOW_CLEANUP_IDLE_MINUTES,
274
+ };
275
+
276
+ for (let index = 0; index < rest.length; index += 1) {
277
+ const arg = rest[index];
278
+ if (arg === '--review-interval') {
279
+ const next = rest[index + 1];
280
+ if (!next) {
281
+ throw new Error('--review-interval requires an integer seconds value');
282
+ }
283
+ const parsedValue = Number.parseInt(next, 10);
284
+ if (!Number.isInteger(parsedValue) || parsedValue < 5) {
285
+ throw new Error('--review-interval must be an integer >= 5 seconds');
286
+ }
287
+ options.reviewIntervalSeconds = parsedValue;
288
+ index += 1;
289
+ continue;
290
+ }
291
+ if (arg === '--cleanup-interval') {
292
+ const next = rest[index + 1];
293
+ if (!next) {
294
+ throw new Error('--cleanup-interval requires an integer seconds value');
295
+ }
296
+ const parsedValue = Number.parseInt(next, 10);
297
+ if (!Number.isInteger(parsedValue) || parsedValue < 5) {
298
+ throw new Error('--cleanup-interval must be an integer >= 5 seconds');
299
+ }
300
+ options.cleanupIntervalSeconds = parsedValue;
301
+ index += 1;
302
+ continue;
303
+ }
304
+ if (arg === '--idle-minutes') {
305
+ const next = rest[index + 1];
306
+ if (!next) {
307
+ throw new Error('--idle-minutes requires an integer minutes value');
308
+ }
309
+ const parsedValue = Number.parseInt(next, 10);
310
+ if (!Number.isInteger(parsedValue) || parsedValue < 1) {
311
+ throw new Error('--idle-minutes must be an integer >= 1');
312
+ }
313
+ options.idleMinutes = parsedValue;
314
+ index += 1;
315
+ continue;
316
+ }
317
+ throw new Error(`Unknown option: ${arg}`);
318
+ }
319
+
320
+ if (!['start', 'stop', 'status'].includes(options.subcommand)) {
321
+ throw new Error(`Unknown agents subcommand: ${options.subcommand}`);
322
+ }
323
+
324
+ return options;
325
+ }
326
+
327
+ function parseReportArgs(rawArgs) {
328
+ const options = {
329
+ target: process.cwd(),
330
+ subcommand: '',
331
+ repo: '',
332
+ scorecardJson: '',
333
+ outputDir: '',
334
+ date: '',
335
+ dryRun: false,
336
+ json: false,
337
+ };
338
+
339
+ for (let index = 0; index < rawArgs.length; index += 1) {
340
+ const arg = rawArgs[index];
341
+ if (arg === '--target') {
342
+ const next = rawArgs[index + 1];
343
+ if (!next) throw new Error('--target requires a path value');
344
+ options.target = next;
345
+ index += 1;
346
+ continue;
347
+ }
348
+ if (arg === '--repo') {
349
+ const next = rawArgs[index + 1];
350
+ if (!next) throw new Error('--repo requires a value like github.com/owner/repo');
351
+ options.repo = next;
352
+ index += 1;
353
+ continue;
354
+ }
355
+ if (arg === '--scorecard-json') {
356
+ const next = rawArgs[index + 1];
357
+ if (!next) throw new Error('--scorecard-json requires a path value');
358
+ options.scorecardJson = next;
359
+ index += 1;
360
+ continue;
361
+ }
362
+ if (arg === '--output-dir') {
363
+ const next = rawArgs[index + 1];
364
+ if (!next) throw new Error('--output-dir requires a path value');
365
+ options.outputDir = next;
366
+ index += 1;
367
+ continue;
368
+ }
369
+ if (arg === '--date') {
370
+ const next = rawArgs[index + 1];
371
+ if (!next) throw new Error('--date requires a YYYY-MM-DD value');
372
+ options.date = next;
373
+ index += 1;
374
+ continue;
375
+ }
376
+ if (arg === '--dry-run') {
377
+ options.dryRun = true;
378
+ continue;
379
+ }
380
+ if (arg === '--json') {
381
+ options.json = true;
382
+ continue;
383
+ }
384
+ if (arg.startsWith('-')) {
385
+ throw new Error(`Unknown option: ${arg}`);
386
+ }
387
+ if (!options.subcommand) {
388
+ options.subcommand = arg;
389
+ continue;
390
+ }
391
+ throw new Error(`Unexpected argument: ${arg}`);
392
+ }
393
+
394
+ return options;
395
+ }
396
+
397
+ function parseSyncArgs(rawArgs) {
398
+ const options = {
399
+ target: process.cwd(),
400
+ check: false,
401
+ base: '',
402
+ strategy: '',
403
+ ffOnly: false,
404
+ dryRun: false,
405
+ json: false,
406
+ allAgentBranches: false,
407
+ allowNonAgent: false,
408
+ allowDirty: false,
409
+ };
410
+
411
+ for (let index = 0; index < rawArgs.length; index += 1) {
412
+ const arg = rawArgs[index];
413
+ if (arg === '--target') {
414
+ const next = rawArgs[index + 1];
415
+ if (!next) {
416
+ throw new Error('--target requires a path value');
417
+ }
418
+ options.target = next;
419
+ index += 1;
420
+ continue;
421
+ }
422
+ if (arg === '--base') {
423
+ const next = rawArgs[index + 1];
424
+ if (!next) {
425
+ throw new Error('--base requires a branch value');
426
+ }
427
+ options.base = next;
428
+ index += 1;
429
+ continue;
430
+ }
431
+ if (arg === '--strategy') {
432
+ const next = rawArgs[index + 1];
433
+ if (!next) {
434
+ throw new Error('--strategy requires a value (rebase|merge)');
435
+ }
436
+ options.strategy = next;
437
+ index += 1;
438
+ continue;
439
+ }
440
+ if (arg === '--check') {
441
+ options.check = true;
442
+ continue;
443
+ }
444
+ if (arg === '--ff-only') {
445
+ options.ffOnly = true;
446
+ continue;
447
+ }
448
+ if (arg === '--dry-run') {
449
+ options.dryRun = true;
450
+ continue;
451
+ }
452
+ if (arg === '--json') {
453
+ options.json = true;
454
+ continue;
455
+ }
456
+ if (arg === '--all-agent-branches') {
457
+ options.allAgentBranches = true;
458
+ continue;
459
+ }
460
+ if (arg === '--allow-non-agent') {
461
+ options.allowNonAgent = true;
462
+ continue;
463
+ }
464
+ if (arg === '--allow-dirty') {
465
+ options.allowDirty = true;
466
+ continue;
467
+ }
468
+ throw new Error(`Unknown option: ${arg}`);
469
+ }
470
+
471
+ return options;
472
+ }
473
+
474
+ function parseCleanupArgs(rawArgs) {
475
+ const options = {
476
+ target: process.cwd(),
477
+ base: '',
478
+ branch: '',
479
+ dryRun: false,
480
+ forceDirty: false,
481
+ keepRemote: false,
482
+ keepCleanWorktrees: false,
483
+ includePrMerged: false,
484
+ idleMinutes: 0,
485
+ watch: false,
486
+ intervalSeconds: 60,
487
+ once: false,
488
+ maxBranches: 0,
489
+ };
490
+
491
+ for (let index = 0; index < rawArgs.length; index += 1) {
492
+ const arg = rawArgs[index];
493
+ if (arg === '--target') {
494
+ const next = rawArgs[index + 1];
495
+ if (!next) {
496
+ throw new Error('--target requires a path value');
497
+ }
498
+ options.target = next;
499
+ index += 1;
500
+ continue;
501
+ }
502
+ if (arg === '--base') {
503
+ const next = rawArgs[index + 1];
504
+ if (!next) {
505
+ throw new Error('--base requires a branch value');
506
+ }
507
+ options.base = next;
508
+ index += 1;
509
+ continue;
510
+ }
511
+ if (arg === '--branch') {
512
+ const next = rawArgs[index + 1];
513
+ if (!next) {
514
+ throw new Error('--branch requires an agent branch value');
515
+ }
516
+ options.branch = next;
517
+ index += 1;
518
+ continue;
519
+ }
520
+ if (arg === '--dry-run') {
521
+ options.dryRun = true;
522
+ continue;
523
+ }
524
+ if (arg === '--force-dirty') {
525
+ options.forceDirty = true;
526
+ continue;
527
+ }
528
+ if (arg === '--keep-remote') {
529
+ options.keepRemote = true;
530
+ continue;
531
+ }
532
+ if (arg === '--keep-clean-worktrees') {
533
+ options.keepCleanWorktrees = true;
534
+ continue;
535
+ }
536
+ if (arg === '--include-pr-merged') {
537
+ options.includePrMerged = true;
538
+ continue;
539
+ }
540
+ if (arg === '--idle-minutes') {
541
+ const next = rawArgs[index + 1];
542
+ if (!next) {
543
+ throw new Error('--idle-minutes requires an integer value');
544
+ }
545
+ const parsed = Number.parseInt(next, 10);
546
+ if (!Number.isInteger(parsed) || parsed < 0) {
547
+ throw new Error('--idle-minutes must be an integer >= 0');
548
+ }
549
+ options.idleMinutes = parsed;
550
+ index += 1;
551
+ continue;
552
+ }
553
+ if (arg === '--watch') {
554
+ options.watch = true;
555
+ continue;
556
+ }
557
+ if (arg === '--interval') {
558
+ const next = rawArgs[index + 1];
559
+ if (!next) {
560
+ throw new Error('--interval requires an integer seconds value');
561
+ }
562
+ const parsed = Number.parseInt(next, 10);
563
+ if (!Number.isInteger(parsed) || parsed < 5) {
564
+ throw new Error('--interval must be an integer >= 5 seconds');
565
+ }
566
+ options.intervalSeconds = parsed;
567
+ index += 1;
568
+ continue;
569
+ }
570
+ if (arg === '--once') {
571
+ options.once = true;
572
+ continue;
573
+ }
574
+ if (arg === '--max-branches') {
575
+ const next = rawArgs[index + 1];
576
+ if (!next) {
577
+ throw new Error('--max-branches requires an integer value');
578
+ }
579
+ const parsed = Number.parseInt(next, 10);
580
+ if (!Number.isInteger(parsed) || parsed < 1) {
581
+ throw new Error('--max-branches must be an integer >= 1');
582
+ }
583
+ options.maxBranches = parsed;
584
+ index += 1;
585
+ continue;
586
+ }
587
+ throw new Error(`Unknown option: ${arg}`);
588
+ }
589
+
590
+ if (options.watch && options.idleMinutes === 0) {
591
+ options.idleMinutes = DEFAULT_SHADOW_CLEANUP_IDLE_MINUTES;
592
+ }
593
+
594
+ return options;
595
+ }
596
+
597
+ function parseMergeArgs(rawArgs) {
598
+ const options = {
599
+ target: process.cwd(),
600
+ base: '',
601
+ into: '',
602
+ branches: [],
603
+ task: '',
604
+ agent: '',
605
+ };
606
+
607
+ for (let index = 0; index < rawArgs.length; index += 1) {
608
+ const arg = rawArgs[index];
609
+ if (arg === '--target') {
610
+ const next = rawArgs[index + 1];
611
+ if (!next) {
612
+ throw new Error('--target requires a path value');
613
+ }
614
+ options.target = next;
615
+ index += 1;
616
+ continue;
617
+ }
618
+ if (arg === '--base') {
619
+ const next = rawArgs[index + 1];
620
+ if (!next) {
621
+ throw new Error('--base requires a branch value');
622
+ }
623
+ options.base = next;
624
+ index += 1;
625
+ continue;
626
+ }
627
+ if (arg === '--into') {
628
+ const next = rawArgs[index + 1];
629
+ if (!next) {
630
+ throw new Error('--into requires an agent/* branch value');
631
+ }
632
+ options.into = next;
633
+ index += 1;
634
+ continue;
635
+ }
636
+ if (arg === '--branch') {
637
+ const next = rawArgs[index + 1];
638
+ if (!next) {
639
+ throw new Error('--branch requires an agent/* branch value');
640
+ }
641
+ options.branches.push(next);
642
+ index += 1;
643
+ continue;
644
+ }
645
+ if (arg === '--task') {
646
+ const next = rawArgs[index + 1];
647
+ if (!next) {
648
+ throw new Error('--task requires a task value');
649
+ }
650
+ options.task = next;
651
+ index += 1;
652
+ continue;
653
+ }
654
+ if (arg === '--agent') {
655
+ const next = rawArgs[index + 1];
656
+ if (!next) {
657
+ throw new Error('--agent requires an agent value');
658
+ }
659
+ options.agent = next;
660
+ index += 1;
661
+ continue;
662
+ }
663
+ throw new Error(`Unknown option: ${arg}`);
664
+ }
665
+
666
+ if (options.branches.length === 0) {
667
+ throw new Error('merge requires at least one --branch <agent/*> input');
668
+ }
669
+
670
+ return options;
671
+ }
672
+
673
+ function parseFinishArgs(rawArgs, defaults = {}) {
674
+ const options = {
675
+ target: process.cwd(),
676
+ base: '',
677
+ branch: '',
678
+ all: false,
679
+ dryRun: false,
680
+ waitForMerge: defaults.waitForMerge ?? true,
681
+ cleanup: defaults.cleanup ?? true,
682
+ keepRemote: false,
683
+ noAutoCommit: false,
684
+ failFast: false,
685
+ commitMessage: '',
686
+ mergeMode: defaults.mergeMode || 'pr',
687
+ };
688
+
689
+ for (let index = 0; index < rawArgs.length; index += 1) {
690
+ const arg = rawArgs[index];
691
+ if (arg === '--target') {
692
+ const next = rawArgs[index + 1];
693
+ if (!next) {
694
+ throw new Error('--target requires a path value');
695
+ }
696
+ options.target = next;
697
+ index += 1;
698
+ continue;
699
+ }
700
+ if (arg === '--base') {
701
+ const next = rawArgs[index + 1];
702
+ if (!next) {
703
+ throw new Error('--base requires a branch value');
704
+ }
705
+ options.base = next;
706
+ index += 1;
707
+ continue;
708
+ }
709
+ if (arg === '--branch') {
710
+ const next = rawArgs[index + 1];
711
+ if (!next) {
712
+ throw new Error('--branch requires an agent/* branch value');
713
+ }
714
+ options.branch = next;
715
+ index += 1;
716
+ continue;
717
+ }
718
+ if (arg === '--commit-message') {
719
+ const next = rawArgs[index + 1];
720
+ if (!next) {
721
+ throw new Error('--commit-message requires a value');
722
+ }
723
+ options.commitMessage = next;
724
+ index += 1;
725
+ continue;
726
+ }
727
+ if (arg === '--all') {
728
+ options.all = true;
729
+ continue;
730
+ }
731
+ if (arg === '--dry-run') {
732
+ options.dryRun = true;
733
+ continue;
734
+ }
735
+ if (arg === '--wait-for-merge') {
736
+ options.waitForMerge = true;
737
+ continue;
738
+ }
739
+ if (arg === '--no-wait-for-merge') {
740
+ options.waitForMerge = false;
741
+ continue;
742
+ }
743
+ if (arg === '--via-pr') {
744
+ options.mergeMode = 'pr';
745
+ continue;
746
+ }
747
+ if (arg === '--direct-only') {
748
+ options.mergeMode = 'direct';
749
+ continue;
750
+ }
751
+ if (arg === '--mode') {
752
+ const next = rawArgs[index + 1];
753
+ if (!next) {
754
+ throw new Error('--mode requires a value');
755
+ }
756
+ if (!['auto', 'direct', 'pr'].includes(next)) {
757
+ throw new Error(`Invalid --mode value: ${next} (expected auto|direct|pr)`);
758
+ }
759
+ options.mergeMode = next;
760
+ index += 1;
761
+ continue;
762
+ }
763
+ if (arg === '--cleanup') {
764
+ options.cleanup = true;
765
+ continue;
766
+ }
767
+ if (arg === '--no-cleanup') {
768
+ options.cleanup = false;
769
+ continue;
770
+ }
771
+ if (arg === '--keep-remote') {
772
+ options.keepRemote = true;
773
+ continue;
774
+ }
775
+ if (arg === '--no-auto-commit') {
776
+ options.noAutoCommit = true;
777
+ continue;
778
+ }
779
+ if (arg === '--fail-fast') {
780
+ options.failFast = true;
781
+ continue;
782
+ }
783
+ throw new Error(`Unknown option: ${arg}`);
784
+ }
785
+
786
+ if (options.branch && !options.branch.startsWith('agent/')) {
787
+ throw new Error(`--branch must reference an agent/* branch (received: ${options.branch})`);
788
+ }
789
+
790
+ return options;
3
791
  }
4
792
 
5
793
  module.exports = {
794
+ requireValue,
795
+ normalizeManagedForcePath,
796
+ collectForceManagedPaths,
797
+ parseCommonArgs,
798
+ parseRepoTraversalArgs,
799
+ parseSetupArgs,
6
800
  parseDoctorArgs,
801
+ parseTargetFlag,
802
+ parseReviewArgs,
803
+ parseAgentsArgs,
804
+ parseReportArgs,
805
+ parseSyncArgs,
806
+ parseCleanupArgs,
807
+ parseMergeArgs,
808
+ parseFinishArgs,
7
809
  };