@camaradesuk/git-worktree-tools 1.12.0 → 1.14.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.
- package/README.md +14 -14
- package/dist/api/create.d.ts.map +1 -1
- package/dist/api/create.js +30 -4
- package/dist/api/create.js.map +1 -1
- package/dist/cli/lswt.js +4 -0
- package/dist/cli/lswt.js.map +1 -1
- package/dist/cli/newpr.d.ts.map +1 -1
- package/dist/cli/newpr.js +53 -31
- package/dist/cli/newpr.js.map +1 -1
- package/dist/cli/prs.d.ts.map +1 -1
- package/dist/cli/prs.js +34 -2
- package/dist/cli/prs.js.map +1 -1
- package/dist/cli/wt/config.d.ts.map +1 -1
- package/dist/cli/wt/config.js +62 -58
- package/dist/cli/wt/config.js.map +1 -1
- package/dist/cli/wt/list.d.ts.map +1 -1
- package/dist/cli/wt/list.js +5 -0
- package/dist/cli/wt/list.js.map +1 -1
- package/dist/cli/wt/prs.d.ts.map +1 -1
- package/dist/cli/wt/prs.js +2 -0
- package/dist/cli/wt/prs.js.map +1 -1
- package/dist/cli/wtconfig.js +135 -107
- package/dist/cli/wtconfig.js.map +1 -1
- package/dist/cli/wtstate.js +27 -7
- package/dist/cli/wtstate.js.map +1 -1
- package/dist/lib/ai/gemini-api-provider.d.ts +31 -0
- package/dist/lib/ai/gemini-api-provider.d.ts.map +1 -0
- package/dist/lib/ai/gemini-api-provider.js +100 -0
- package/dist/lib/ai/gemini-api-provider.js.map +1 -0
- package/dist/lib/ai/index.d.ts +1 -0
- package/dist/lib/ai/index.d.ts.map +1 -1
- package/dist/lib/ai/index.js +1 -0
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/provider-manager.d.ts +1 -0
- package/dist/lib/ai/provider-manager.d.ts.map +1 -1
- package/dist/lib/ai/provider-manager.js +12 -0
- package/dist/lib/ai/provider-manager.js.map +1 -1
- package/dist/lib/ai/types.d.ts +2 -2
- package/dist/lib/ai/types.d.ts.map +1 -1
- package/dist/lib/ai/types.js.map +1 -1
- package/dist/lib/cleanpr/index.d.ts +2 -1
- package/dist/lib/cleanpr/index.d.ts.map +1 -1
- package/dist/lib/cleanpr/index.js +3 -1
- package/dist/lib/cleanpr/index.js.map +1 -1
- package/dist/lib/cleanpr/worktree-info.d.ts +0 -4
- package/dist/lib/cleanpr/worktree-info.d.ts.map +1 -1
- package/dist/lib/cleanpr/worktree-info.js +2 -28
- package/dist/lib/cleanpr/worktree-info.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +21 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/lswt/formatters.d.ts +0 -4
- package/dist/lib/lswt/formatters.d.ts.map +1 -1
- package/dist/lib/lswt/formatters.js +0 -14
- package/dist/lib/lswt/formatters.js.map +1 -1
- package/dist/lib/lswt/index.d.ts +2 -1
- package/dist/lib/lswt/index.d.ts.map +1 -1
- package/dist/lib/lswt/index.js +3 -1
- package/dist/lib/lswt/index.js.map +1 -1
- package/dist/lib/lswt/types.d.ts +2 -0
- package/dist/lib/lswt/types.d.ts.map +1 -1
- package/dist/lib/lswt/worktree-info.d.ts.map +1 -1
- package/dist/lib/lswt/worktree-info.js +3 -2
- package/dist/lib/lswt/worktree-info.js.map +1 -1
- package/dist/lib/prs/command.d.ts.map +1 -1
- package/dist/lib/prs/command.js +22 -16
- package/dist/lib/prs/command.js.map +1 -1
- package/dist/lib/worktree-setup.d.ts +32 -0
- package/dist/lib/worktree-setup.d.ts.map +1 -0
- package/dist/lib/worktree-setup.js +114 -0
- package/dist/lib/worktree-setup.js.map +1 -0
- package/dist/lib/worktree-utils.d.ts +32 -0
- package/dist/lib/worktree-utils.d.ts.map +1 -0
- package/dist/lib/worktree-utils.js +101 -0
- package/dist/lib/worktree-utils.js.map +1 -0
- package/package.json +1 -1
- package/schemas/worktreerc.schema.json +2 -2
package/dist/cli/wtconfig.js
CHANGED
|
@@ -15,10 +15,13 @@ import { execSync } from 'child_process';
|
|
|
15
15
|
import inquirer from 'inquirer';
|
|
16
16
|
import { printDeprecationNotice } from '../lib/deprecation.js';
|
|
17
17
|
import * as colors from '../lib/colors.js';
|
|
18
|
+
import { setColorEnabled } from '../lib/colors.js';
|
|
18
19
|
import * as git from '../lib/git.js';
|
|
19
20
|
import { getDefaultConfig } from '../lib/config.js';
|
|
20
21
|
import { detectMigrationIssues, runMigration, formatMigrationReport, formatMigrationReportJSON, } from '../lib/config-migration/index.js';
|
|
21
22
|
import { createSuccessResult, createErrorResult, formatJsonResult, ErrorCode, } from '../lib/json-output.js';
|
|
23
|
+
import { initializeLogger } from '../lib/logger.js';
|
|
24
|
+
import { print, printErr, printError, printStatus, printDim, setJsonMode, } from '../lib/ui/index.js';
|
|
22
25
|
/**
|
|
23
26
|
* Safely get repository root, returning null if not in a git repo
|
|
24
27
|
*/
|
|
@@ -35,6 +38,9 @@ import { detectEnvironment, detectDefaultBranch, getInstallCommand, getEditorCom
|
|
|
35
38
|
const args = process.argv.slice(2);
|
|
36
39
|
const command = args[0] || 'show';
|
|
37
40
|
const jsonMode = args.includes('--json');
|
|
41
|
+
const verbose = args.includes('--verbose');
|
|
42
|
+
const quiet = args.includes('--quiet');
|
|
43
|
+
const noColor = args.includes('--no-color');
|
|
38
44
|
// Entry point
|
|
39
45
|
main().catch((error) => {
|
|
40
46
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -43,12 +49,24 @@ main().catch((error) => {
|
|
|
43
49
|
console.log(formatJsonResult(errorResult));
|
|
44
50
|
}
|
|
45
51
|
else {
|
|
46
|
-
|
|
52
|
+
printError({ title: `Error: ${message}` });
|
|
47
53
|
}
|
|
48
54
|
process.exit(1);
|
|
49
55
|
});
|
|
50
56
|
async function main() {
|
|
51
57
|
printDeprecationNotice('wtconfig', 'wt config');
|
|
58
|
+
initializeLogger({
|
|
59
|
+
verbose,
|
|
60
|
+
quiet,
|
|
61
|
+
noColor,
|
|
62
|
+
json: jsonMode,
|
|
63
|
+
commandName: 'wtconfig',
|
|
64
|
+
});
|
|
65
|
+
setJsonMode(jsonMode);
|
|
66
|
+
if (noColor) {
|
|
67
|
+
process.env.NO_COLOR = '1';
|
|
68
|
+
setColorEnabled(false);
|
|
69
|
+
}
|
|
52
70
|
switch (command) {
|
|
53
71
|
case 'init':
|
|
54
72
|
case 'wizard':
|
|
@@ -83,14 +101,14 @@ async function main() {
|
|
|
83
101
|
console.log(formatJsonResult(errorResult));
|
|
84
102
|
}
|
|
85
103
|
else {
|
|
86
|
-
|
|
104
|
+
printError({ title: `Unknown command: ${command}` });
|
|
87
105
|
showHelp();
|
|
88
106
|
}
|
|
89
107
|
process.exit(1);
|
|
90
108
|
}
|
|
91
109
|
}
|
|
92
110
|
function showHelp() {
|
|
93
|
-
|
|
111
|
+
print(`
|
|
94
112
|
${colors.cyan('wtconfig')} - Configuration management for git-worktree-tools
|
|
95
113
|
|
|
96
114
|
${colors.cyan('Usage:')}
|
|
@@ -105,6 +123,9 @@ ${colors.cyan('Usage:')}
|
|
|
105
123
|
|
|
106
124
|
${colors.cyan('Global Options:')}
|
|
107
125
|
--json Output results as JSON (for show, get, validate, migrate)
|
|
126
|
+
--verbose Enable verbose logging
|
|
127
|
+
--quiet Suppress non-essential output
|
|
128
|
+
--no-color Disable colored output
|
|
108
129
|
|
|
109
130
|
${colors.cyan('Migration Options:')}
|
|
110
131
|
--yes Skip confirmation prompts
|
|
@@ -143,20 +164,20 @@ async function showConfig(json = false) {
|
|
|
143
164
|
return;
|
|
144
165
|
}
|
|
145
166
|
const defaults = getDefaultConfig();
|
|
146
|
-
|
|
147
|
-
|
|
167
|
+
printStatus('info', 'Current Configuration');
|
|
168
|
+
print('');
|
|
148
169
|
if (source.type === 'none') {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
170
|
+
printDim('No configuration file found. Using defaults.');
|
|
171
|
+
printDim(`Run 'wtconfig init' to create a configuration file.`);
|
|
172
|
+
print('');
|
|
152
173
|
}
|
|
153
174
|
else {
|
|
154
|
-
|
|
155
|
-
|
|
175
|
+
printDim(`Source: ${source.path}`);
|
|
176
|
+
print('');
|
|
156
177
|
}
|
|
157
178
|
// Show merged config with sources indicated
|
|
158
179
|
const mergedDisplay = formatConfigWithDefaults(config, defaults, source.type !== 'none');
|
|
159
|
-
|
|
180
|
+
print(mergedDisplay);
|
|
160
181
|
}
|
|
161
182
|
function formatConfigWithDefaults(config, defaults, hasUserConfig) {
|
|
162
183
|
const lines = [];
|
|
@@ -235,12 +256,14 @@ function formatConfigWithDefaults(config, defaults, hasUserConfig) {
|
|
|
235
256
|
}
|
|
236
257
|
async function setConfig(key, value) {
|
|
237
258
|
if (!key) {
|
|
238
|
-
|
|
239
|
-
|
|
259
|
+
printError({
|
|
260
|
+
title: 'Usage: wtconfig set <key> <value>',
|
|
261
|
+
hint: 'Example: wtconfig set baseBranch develop',
|
|
262
|
+
});
|
|
240
263
|
process.exit(1);
|
|
241
264
|
}
|
|
242
265
|
if (value === undefined) {
|
|
243
|
-
|
|
266
|
+
printError({ title: `Missing value for key: ${key}` });
|
|
244
267
|
process.exit(1);
|
|
245
268
|
}
|
|
246
269
|
// Determine scope
|
|
@@ -263,28 +286,30 @@ async function setConfig(key, value) {
|
|
|
263
286
|
// Validate before saving
|
|
264
287
|
const validation = validateConfig(newConfig);
|
|
265
288
|
if (!validation.valid) {
|
|
266
|
-
|
|
267
|
-
for (const
|
|
268
|
-
|
|
289
|
+
printError({ title: 'Configuration validation failed:' });
|
|
290
|
+
for (const validationError of validation.errors) {
|
|
291
|
+
printErr(colors.error(` ${validationError.path}: ${validationError.message}`));
|
|
269
292
|
}
|
|
270
293
|
process.exit(1);
|
|
271
294
|
}
|
|
272
295
|
// Show warnings
|
|
273
296
|
for (const warning of validation.warnings) {
|
|
274
|
-
|
|
297
|
+
printErr(colors.warning(`Warning: ${warning.path}: ${warning.message}`));
|
|
275
298
|
}
|
|
276
299
|
// Save
|
|
277
300
|
if (saveLocation === 'repo' && repoRoot) {
|
|
278
301
|
saveRepoConfig(repoRoot, newConfig);
|
|
279
|
-
|
|
302
|
+
printStatus('success', `Set ${key} = ${value} in .worktreerc`);
|
|
280
303
|
}
|
|
281
304
|
else {
|
|
282
305
|
saveGlobalConfig(newConfig);
|
|
283
|
-
|
|
306
|
+
printStatus('success', `Set ${key} = ${value} in ~/.worktreerc`);
|
|
284
307
|
}
|
|
285
308
|
}
|
|
286
309
|
catch (error) {
|
|
287
|
-
|
|
310
|
+
printError({
|
|
311
|
+
title: `Failed to set value: ${error instanceof Error ? error.message : String(error)}`,
|
|
312
|
+
});
|
|
288
313
|
process.exit(1);
|
|
289
314
|
}
|
|
290
315
|
}
|
|
@@ -295,8 +320,7 @@ async function getConfig(key, json = false) {
|
|
|
295
320
|
console.log(formatJsonResult(errorResult));
|
|
296
321
|
}
|
|
297
322
|
else {
|
|
298
|
-
|
|
299
|
-
console.error(colors.dim('Example: wtconfig get ai.provider'));
|
|
323
|
+
printError({ title: 'Usage: wtconfig get <key>', hint: 'Example: wtconfig get ai.provider' });
|
|
300
324
|
}
|
|
301
325
|
process.exit(1);
|
|
302
326
|
}
|
|
@@ -314,7 +338,7 @@ async function getConfig(key, json = false) {
|
|
|
314
338
|
console.log(formatJsonResult(errorResult));
|
|
315
339
|
}
|
|
316
340
|
else {
|
|
317
|
-
|
|
341
|
+
printError({ title: `Unknown configuration key: ${key}` });
|
|
318
342
|
}
|
|
319
343
|
process.exit(1);
|
|
320
344
|
}
|
|
@@ -328,10 +352,10 @@ async function getConfig(key, json = false) {
|
|
|
328
352
|
return;
|
|
329
353
|
}
|
|
330
354
|
if (typeof value === 'object') {
|
|
331
|
-
|
|
355
|
+
print(JSON.stringify(value, null, 2));
|
|
332
356
|
}
|
|
333
357
|
else {
|
|
334
|
-
|
|
358
|
+
print(String(value));
|
|
335
359
|
}
|
|
336
360
|
}
|
|
337
361
|
async function editConfig() {
|
|
@@ -364,19 +388,19 @@ async function editConfig() {
|
|
|
364
388
|
},
|
|
365
389
|
]);
|
|
366
390
|
if (!create) {
|
|
367
|
-
|
|
391
|
+
printDim('Cancelled.');
|
|
368
392
|
return;
|
|
369
393
|
}
|
|
370
394
|
fs.writeFileSync(configPath, '{\n \n}\n', 'utf8');
|
|
371
395
|
}
|
|
372
396
|
// Open in editor
|
|
373
397
|
const editor = process.env.EDITOR || process.env.VISUAL || 'vi';
|
|
374
|
-
|
|
398
|
+
printDim(`Opening ${configPath} in ${editor}...`);
|
|
375
399
|
try {
|
|
376
400
|
execSync(`${editor} "${configPath}"`, { stdio: 'inherit' });
|
|
377
401
|
}
|
|
378
402
|
catch {
|
|
379
|
-
|
|
403
|
+
printError({ title: 'Failed to open editor' });
|
|
380
404
|
process.exit(1);
|
|
381
405
|
}
|
|
382
406
|
}
|
|
@@ -395,7 +419,7 @@ async function validateCurrentConfig(json = false) {
|
|
|
395
419
|
console.log(formatJsonResult(result));
|
|
396
420
|
}
|
|
397
421
|
else {
|
|
398
|
-
|
|
422
|
+
printStatus('success', 'No configuration file found. Nothing to validate.');
|
|
399
423
|
}
|
|
400
424
|
return;
|
|
401
425
|
}
|
|
@@ -415,21 +439,21 @@ async function validateCurrentConfig(json = false) {
|
|
|
415
439
|
}
|
|
416
440
|
return;
|
|
417
441
|
}
|
|
418
|
-
|
|
442
|
+
printStatus('info', `Validating: ${source.path}`);
|
|
419
443
|
if (validationResult.valid && validationResult.warnings.length === 0) {
|
|
420
|
-
|
|
444
|
+
printStatus('success', 'Configuration is valid.');
|
|
421
445
|
return;
|
|
422
446
|
}
|
|
423
447
|
if (validationResult.errors.length > 0) {
|
|
424
|
-
|
|
448
|
+
printErr(colors.error('\nErrors:'));
|
|
425
449
|
for (const error of validationResult.errors) {
|
|
426
|
-
|
|
450
|
+
printErr(colors.error(` ${error.path}: ${error.message}`));
|
|
427
451
|
}
|
|
428
452
|
}
|
|
429
453
|
if (validationResult.warnings.length > 0) {
|
|
430
|
-
|
|
454
|
+
printErr(colors.warning('\nWarnings:'));
|
|
431
455
|
for (const warning of validationResult.warnings) {
|
|
432
|
-
|
|
456
|
+
printErr(colors.warning(` ${warning.path}: ${warning.message}`));
|
|
433
457
|
}
|
|
434
458
|
}
|
|
435
459
|
if (!validationResult.valid) {
|
|
@@ -448,8 +472,10 @@ async function runMigrateCommand() {
|
|
|
448
472
|
console.log(JSON.stringify({ success: false, error: 'Not in a git repository' }));
|
|
449
473
|
}
|
|
450
474
|
else {
|
|
451
|
-
|
|
452
|
-
|
|
475
|
+
printError({
|
|
476
|
+
title: 'Error: Not in a git repository',
|
|
477
|
+
hint: 'Run this command from within a git repository.',
|
|
478
|
+
});
|
|
453
479
|
}
|
|
454
480
|
process.exit(1);
|
|
455
481
|
}
|
|
@@ -487,16 +513,16 @@ async function runMigrateCommand() {
|
|
|
487
513
|
}
|
|
488
514
|
// Interactive console mode
|
|
489
515
|
if (detection.issues.length === 0) {
|
|
490
|
-
|
|
516
|
+
printStatus('success', 'Config is up to date, no migration needed.');
|
|
491
517
|
return;
|
|
492
518
|
}
|
|
493
519
|
// Show detection report
|
|
494
|
-
|
|
495
|
-
|
|
520
|
+
print(formatMigrationReport(detection, { verbose: true }));
|
|
521
|
+
print('');
|
|
496
522
|
// Dry run mode - just show what would happen
|
|
497
523
|
if (dryRun) {
|
|
498
|
-
|
|
499
|
-
|
|
524
|
+
printStatus('info', '[DRY RUN] No changes were made.');
|
|
525
|
+
printDim('Remove --dry-run flag to apply the migration.');
|
|
500
526
|
return;
|
|
501
527
|
}
|
|
502
528
|
// Confirm migration
|
|
@@ -510,41 +536,43 @@ async function runMigrateCommand() {
|
|
|
510
536
|
},
|
|
511
537
|
]);
|
|
512
538
|
if (!confirm) {
|
|
513
|
-
|
|
539
|
+
printDim('Migration cancelled.');
|
|
514
540
|
return;
|
|
515
541
|
}
|
|
516
542
|
}
|
|
517
543
|
// Run migration
|
|
518
544
|
const result = await runMigration(repoRoot, detection, { deleteLegacyFiles: deleteLegacy });
|
|
519
545
|
if (result.success) {
|
|
520
|
-
|
|
521
|
-
|
|
546
|
+
print('');
|
|
547
|
+
printStatus('success', 'Migration completed successfully!');
|
|
522
548
|
if (result.backupPath) {
|
|
523
|
-
|
|
549
|
+
printDim(`Backup created: ${result.backupPath}`);
|
|
524
550
|
}
|
|
525
|
-
|
|
551
|
+
printDim(`Config updated: ${result.newConfigPath}`);
|
|
526
552
|
if (result.actionsExecuted.length > 0) {
|
|
527
|
-
|
|
553
|
+
printDim(`${result.actionsExecuted.length} change(s) applied.`);
|
|
528
554
|
}
|
|
529
555
|
}
|
|
530
556
|
else {
|
|
531
|
-
|
|
532
|
-
|
|
557
|
+
print('');
|
|
558
|
+
printError({ title: 'Migration failed:' });
|
|
533
559
|
for (const error of result.errors) {
|
|
534
|
-
|
|
560
|
+
printErr(colors.error(` ${error}`));
|
|
535
561
|
}
|
|
536
562
|
process.exit(1);
|
|
537
563
|
}
|
|
538
564
|
}
|
|
539
565
|
async function runWizard() {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
566
|
+
print('');
|
|
567
|
+
print(colors.info('\u250C' + '\u2500'.repeat(56) + '\u2510'));
|
|
568
|
+
print(colors.info('\u2502') +
|
|
569
|
+
' git-worktree-tools Setup Wizard ' +
|
|
570
|
+
colors.info('\u2502'));
|
|
571
|
+
print(colors.info('\u2514' + '\u2500'.repeat(56) + '\u2518'));
|
|
572
|
+
print('');
|
|
545
573
|
// Detect environment
|
|
546
|
-
|
|
547
|
-
|
|
574
|
+
printDim('Detecting your environment...');
|
|
575
|
+
print('');
|
|
548
576
|
const repoRoot = findRepoRoot();
|
|
549
577
|
const env = detectEnvironment(repoRoot ?? undefined);
|
|
550
578
|
// Show detected environment
|
|
@@ -554,11 +582,11 @@ async function runWizard() {
|
|
|
554
582
|
// Build configuration
|
|
555
583
|
const config = buildConfigFromState(state, env);
|
|
556
584
|
// Preview configuration
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
585
|
+
print('');
|
|
586
|
+
printStatus('info', 'Configuration Preview:');
|
|
587
|
+
print('');
|
|
588
|
+
print(formatConfigDisplay(config));
|
|
589
|
+
print('');
|
|
562
590
|
// Confirm save
|
|
563
591
|
const { saveChoice } = await inquirer.prompt([
|
|
564
592
|
{
|
|
@@ -574,55 +602,55 @@ async function runWizard() {
|
|
|
574
602
|
},
|
|
575
603
|
]);
|
|
576
604
|
if (saveChoice === 'cancel') {
|
|
577
|
-
|
|
605
|
+
printDim('Setup cancelled.');
|
|
578
606
|
return;
|
|
579
607
|
}
|
|
580
608
|
// Save configuration
|
|
581
609
|
if (saveChoice === 'repo' && repoRoot) {
|
|
582
610
|
saveRepoConfig(repoRoot, config);
|
|
583
|
-
|
|
584
|
-
|
|
611
|
+
print('');
|
|
612
|
+
printStatus('success', `Configuration saved to ${getDefaultRepoConfigPath(repoRoot)}`);
|
|
585
613
|
}
|
|
586
614
|
else {
|
|
587
615
|
saveGlobalConfig(config);
|
|
588
|
-
|
|
589
|
-
|
|
616
|
+
print('');
|
|
617
|
+
printStatus('success', `Configuration saved to ${getGlobalConfigPath()}`);
|
|
590
618
|
}
|
|
591
619
|
// Show quick start
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
620
|
+
print('');
|
|
621
|
+
printStatus('info', 'Quick Start:');
|
|
622
|
+
print(` ${colors.warning('newpr "Add feature"')} Create a new PR`);
|
|
623
|
+
print(` ${colors.warning('lswt')} List worktrees`);
|
|
624
|
+
print(` ${colors.warning('cleanpr')} Clean merged PRs`);
|
|
625
|
+
print('');
|
|
598
626
|
}
|
|
599
627
|
function displayEnvironment(env) {
|
|
600
|
-
const check = colors.success('
|
|
601
|
-
const cross = colors.error('
|
|
602
|
-
const warn = colors.warning('
|
|
628
|
+
const check = colors.success('\u2713');
|
|
629
|
+
const cross = colors.error('\u2717');
|
|
630
|
+
const warn = colors.warning('\u25CB');
|
|
603
631
|
// Git
|
|
604
632
|
if (env.git.version) {
|
|
605
633
|
if (env.git.configured) {
|
|
606
|
-
|
|
634
|
+
print(`${check} Git ${env.git.version} configured (${env.git.email})`);
|
|
607
635
|
}
|
|
608
636
|
else {
|
|
609
|
-
|
|
637
|
+
print(`${warn} Git ${env.git.version} (not configured - run: git config --global user.name/email)`);
|
|
610
638
|
}
|
|
611
639
|
}
|
|
612
640
|
else {
|
|
613
|
-
|
|
641
|
+
print(`${cross} Git not found`);
|
|
614
642
|
}
|
|
615
643
|
// GitHub CLI
|
|
616
644
|
if (env.github.installed) {
|
|
617
645
|
if (env.github.authenticated) {
|
|
618
|
-
|
|
646
|
+
print(`${check} GitHub CLI authenticated${env.github.user ? ` (${env.github.user})` : ''}`);
|
|
619
647
|
}
|
|
620
648
|
else {
|
|
621
|
-
|
|
649
|
+
print(`${warn} GitHub CLI installed but not authenticated (run: gh auth login)`);
|
|
622
650
|
}
|
|
623
651
|
}
|
|
624
652
|
else {
|
|
625
|
-
|
|
653
|
+
print(`${cross} GitHub CLI not installed (optional, install from: https://cli.github.com)`);
|
|
626
654
|
}
|
|
627
655
|
// AI tools
|
|
628
656
|
const aiTools = [];
|
|
@@ -635,14 +663,14 @@ function displayEnvironment(env) {
|
|
|
635
663
|
if (env.ai.codexCLI)
|
|
636
664
|
aiTools.push('Codex CLI');
|
|
637
665
|
if (aiTools.length > 0) {
|
|
638
|
-
|
|
666
|
+
print(`${check} AI tools: ${aiTools.join(', ')}`);
|
|
639
667
|
}
|
|
640
668
|
else {
|
|
641
|
-
|
|
669
|
+
print(`${colors.dim('\u25CB')} No AI tools detected (optional)`);
|
|
642
670
|
}
|
|
643
671
|
// Package manager
|
|
644
672
|
if (env.packageManager) {
|
|
645
|
-
|
|
673
|
+
print(`${check} Package manager: ${env.packageManager}`);
|
|
646
674
|
}
|
|
647
675
|
// IDE
|
|
648
676
|
const ides = [];
|
|
@@ -651,14 +679,14 @@ function displayEnvironment(env) {
|
|
|
651
679
|
if (env.ide.cursor)
|
|
652
680
|
ides.push('Cursor');
|
|
653
681
|
if (ides.length > 0) {
|
|
654
|
-
|
|
682
|
+
print(`${check} IDE: ${ides.join(', ')}`);
|
|
655
683
|
}
|
|
656
|
-
|
|
684
|
+
print('');
|
|
657
685
|
}
|
|
658
686
|
async function runWizardSteps(env, repoRoot) {
|
|
659
687
|
// Step 1: Base Configuration
|
|
660
|
-
|
|
661
|
-
|
|
688
|
+
printStatus('info', 'Step 1/4: Base Configuration');
|
|
689
|
+
print('');
|
|
662
690
|
const defaultBranch = repoRoot ? detectDefaultBranch(repoRoot) : 'main';
|
|
663
691
|
const step1 = await inquirer.prompt([
|
|
664
692
|
{
|
|
@@ -706,9 +734,9 @@ async function runWizardSteps(env, repoRoot) {
|
|
|
706
734
|
baseBranch = customBranch;
|
|
707
735
|
}
|
|
708
736
|
// Step 2: Worktree Location
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
737
|
+
print('');
|
|
738
|
+
printStatus('info', 'Step 2/4: Worktree Location');
|
|
739
|
+
print('');
|
|
712
740
|
const step2 = await inquirer.prompt([
|
|
713
741
|
{
|
|
714
742
|
type: 'list',
|
|
@@ -749,9 +777,9 @@ async function runWizardSteps(env, repoRoot) {
|
|
|
749
777
|
worktreeParent = customParent;
|
|
750
778
|
}
|
|
751
779
|
// Step 3: AI Integration
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
780
|
+
print('');
|
|
781
|
+
printStatus('info', 'Step 3/4: AI Integration');
|
|
782
|
+
print('');
|
|
755
783
|
let aiEnabled = false;
|
|
756
784
|
let aiProvider = 'none';
|
|
757
785
|
let aiBranchName = false;
|
|
@@ -836,13 +864,13 @@ async function runWizardSteps(env, repoRoot) {
|
|
|
836
864
|
}
|
|
837
865
|
}
|
|
838
866
|
else {
|
|
839
|
-
|
|
840
|
-
|
|
867
|
+
printDim('No AI tools detected. Skipping AI configuration.');
|
|
868
|
+
printDim('Install Claude Code, Gemini CLI, or Ollama to enable AI features.');
|
|
841
869
|
}
|
|
842
870
|
// Step 4: Automation Hooks
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
871
|
+
print('');
|
|
872
|
+
printStatus('info', 'Step 4/4: Automation Hooks');
|
|
873
|
+
print('');
|
|
846
874
|
const hookChoices = [];
|
|
847
875
|
if (env.packageManager) {
|
|
848
876
|
hookChoices.push({
|
|
@@ -897,10 +925,10 @@ async function runWizardSteps(env, repoRoot) {
|
|
|
897
925
|
}
|
|
898
926
|
}
|
|
899
927
|
else {
|
|
900
|
-
|
|
928
|
+
printDim('No automation hooks available for your environment.');
|
|
901
929
|
}
|
|
902
930
|
// Step 5: Advanced Configuration (optional)
|
|
903
|
-
|
|
931
|
+
print('');
|
|
904
932
|
const { configureAdvanced } = await inquirer.prompt([
|
|
905
933
|
{
|
|
906
934
|
type: 'confirm',
|
|
@@ -913,9 +941,9 @@ async function runWizardSteps(env, repoRoot) {
|
|
|
913
941
|
const generators = {};
|
|
914
942
|
const integrations = {};
|
|
915
943
|
if (configureAdvanced) {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
944
|
+
print('');
|
|
945
|
+
printStatus('info', 'Step 5: Advanced Configuration');
|
|
946
|
+
print('');
|
|
919
947
|
// Plugins
|
|
920
948
|
const { addPlugins } = await inquirer.prompt([
|
|
921
949
|
{
|