@wundr.io/cli 1.0.3 → 1.0.4
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/dist/commands/ai.d.ts +2 -2
- package/dist/commands/ai.d.ts.map +1 -1
- package/dist/commands/ai.js +93 -29
- package/dist/commands/ai.js.map +1 -1
- package/dist/commands/analyze-optimized.d.ts.map +1 -1
- package/dist/commands/analyze-optimized.js +187 -27
- package/dist/commands/analyze-optimized.js.map +1 -1
- package/package.json +9 -26
- package/src/cli.ts +4 -4
- package/src/commands/ai.ts +141 -35
- package/src/commands/alignment.ts +74 -74
- package/src/commands/analyze-optimized.ts +324 -27
- package/src/commands/computer-setup.ts +33 -33
- package/src/commands/governance.ts +34 -34
- package/src/commands/guardian.ts +56 -56
- package/src/commands/session.ts +35 -35
- package/src/commands/vp.ts +26 -26
- package/src/commands/worktree.ts +49 -49
package/src/commands/worktree.ts
CHANGED
|
@@ -176,7 +176,7 @@ async function getGitRepoRoot(): Promise<string> {
|
|
|
176
176
|
async function executeGitCommand(
|
|
177
177
|
command: string,
|
|
178
178
|
args: string[],
|
|
179
|
-
cwd: string
|
|
179
|
+
cwd: string,
|
|
180
180
|
): Promise<string> {
|
|
181
181
|
const fullCommand = `git ${command} ${args.join(' ')}`;
|
|
182
182
|
try {
|
|
@@ -195,7 +195,7 @@ async function listGitWorktrees(repoPath: string): Promise<GitWorktreeInfo[]> {
|
|
|
195
195
|
const output = await executeGitCommand(
|
|
196
196
|
'worktree',
|
|
197
197
|
['list', '--porcelain'],
|
|
198
|
-
repoPath
|
|
198
|
+
repoPath,
|
|
199
199
|
);
|
|
200
200
|
const entries = output.split('\n\n').filter(Boolean);
|
|
201
201
|
|
|
@@ -323,7 +323,7 @@ Examples:
|
|
|
323
323
|
${chalk.green('wundr worktree cleanup --dry-run')} Preview what would be cleaned up
|
|
324
324
|
${chalk.green('wundr worktree sync')} Sync all worktrees from remote
|
|
325
325
|
${chalk.green('wundr worktree sync <taskId>')} Sync specific worktree
|
|
326
|
-
`)
|
|
326
|
+
`),
|
|
327
327
|
);
|
|
328
328
|
|
|
329
329
|
// List command (default)
|
|
@@ -333,7 +333,7 @@ Examples:
|
|
|
333
333
|
.option('-s, --session <id>', 'Filter by session ID')
|
|
334
334
|
.option(
|
|
335
335
|
'--status <status>',
|
|
336
|
-
'Filter by status (active, paused, syncing, error, etc.)'
|
|
336
|
+
'Filter by status (active, paused, syncing, error, etc.)',
|
|
337
337
|
)
|
|
338
338
|
.option('-f, --format <format>', 'Output format (table, json)', 'table')
|
|
339
339
|
.action(async options => {
|
|
@@ -363,7 +363,7 @@ Examples:
|
|
|
363
363
|
.description('Clean up stale worktrees')
|
|
364
364
|
.option(
|
|
365
365
|
'--dry-run',
|
|
366
|
-
'Preview what would be cleaned up without making changes'
|
|
366
|
+
'Preview what would be cleaned up without making changes',
|
|
367
367
|
)
|
|
368
368
|
.option('--force', 'Force cleanup even with uncommitted changes')
|
|
369
369
|
.option('--age <days>', 'Clean up worktrees older than specified days', '7')
|
|
@@ -417,8 +417,8 @@ async function listWorktrees(options: {
|
|
|
417
417
|
worktrees: worktrees,
|
|
418
418
|
},
|
|
419
419
|
null,
|
|
420
|
-
2
|
|
421
|
-
)
|
|
420
|
+
2,
|
|
421
|
+
),
|
|
422
422
|
);
|
|
423
423
|
return;
|
|
424
424
|
}
|
|
@@ -442,8 +442,8 @@ async function listWorktrees(options: {
|
|
|
442
442
|
padRight('Branch', 25) +
|
|
443
443
|
padRight('Status', 12) +
|
|
444
444
|
padRight('Created', 12) +
|
|
445
|
-
padRight('Path', 40)
|
|
446
|
-
)
|
|
445
|
+
padRight('Path', 40),
|
|
446
|
+
),
|
|
447
447
|
);
|
|
448
448
|
console.log(chalk.gray('-'.repeat(110)));
|
|
449
449
|
|
|
@@ -459,7 +459,7 @@ async function listWorktrees(options: {
|
|
|
459
459
|
chalk.blue(padRight(branchName, 25)) +
|
|
460
460
|
statusColor(padRight(getStatusIcon(wt.status), 12)) +
|
|
461
461
|
padRight(createdAge, 12) +
|
|
462
|
-
chalk.gray(padRight(worktreePath, 40))
|
|
462
|
+
chalk.gray(padRight(worktreePath, 40)),
|
|
463
463
|
);
|
|
464
464
|
}
|
|
465
465
|
|
|
@@ -469,14 +469,14 @@ async function listWorktrees(options: {
|
|
|
469
469
|
} catch (error) {
|
|
470
470
|
spinner.fail('Failed to load worktrees');
|
|
471
471
|
console.error(
|
|
472
|
-
chalk.red(error instanceof Error ? error.message : String(error))
|
|
472
|
+
chalk.red(error instanceof Error ? error.message : String(error)),
|
|
473
473
|
);
|
|
474
474
|
}
|
|
475
475
|
}
|
|
476
476
|
|
|
477
477
|
async function createWorktree(
|
|
478
478
|
taskId: string,
|
|
479
|
-
options: { base?: string }
|
|
479
|
+
options: { base?: string },
|
|
480
480
|
): Promise<void> {
|
|
481
481
|
const spinner = ora(`Creating worktree for task: ${taskId}...`).start();
|
|
482
482
|
|
|
@@ -490,7 +490,7 @@ async function createWorktree(
|
|
|
490
490
|
if (existing) {
|
|
491
491
|
spinner.fail(`Worktree already exists for task: ${taskId}`);
|
|
492
492
|
console.log(
|
|
493
|
-
chalk.yellow(`Use "wundr worktree switch ${taskId}" to switch to it.`)
|
|
493
|
+
chalk.yellow(`Use "wundr worktree switch ${taskId}" to switch to it.`),
|
|
494
494
|
);
|
|
495
495
|
return;
|
|
496
496
|
}
|
|
@@ -515,7 +515,7 @@ async function createWorktree(
|
|
|
515
515
|
await executeGitCommand(
|
|
516
516
|
'worktree',
|
|
517
517
|
['add', '-b', branchName, worktreePath, `origin/${baseBranch}`],
|
|
518
|
-
repoPath
|
|
518
|
+
repoPath,
|
|
519
519
|
);
|
|
520
520
|
|
|
521
521
|
// Save to state
|
|
@@ -539,13 +539,13 @@ async function createWorktree(
|
|
|
539
539
|
console.log(chalk.white(' Path: ') + chalk.gray(worktreePath));
|
|
540
540
|
console.log('');
|
|
541
541
|
console.log(
|
|
542
|
-
chalk.gray(`Use "wundr worktree switch ${taskId}" to start working.`)
|
|
542
|
+
chalk.gray(`Use "wundr worktree switch ${taskId}" to start working.`),
|
|
543
543
|
);
|
|
544
544
|
console.log('');
|
|
545
545
|
} catch (error) {
|
|
546
546
|
spinner.fail('Failed to create worktree');
|
|
547
547
|
console.error(
|
|
548
|
-
chalk.red(error instanceof Error ? error.message : String(error))
|
|
548
|
+
chalk.red(error instanceof Error ? error.message : String(error)),
|
|
549
549
|
);
|
|
550
550
|
}
|
|
551
551
|
}
|
|
@@ -561,7 +561,7 @@ async function switchWorktree(taskId: string): Promise<void> {
|
|
|
561
561
|
if (!worktree) {
|
|
562
562
|
spinner.fail(`Worktree not found: ${taskId}`);
|
|
563
563
|
console.log(
|
|
564
|
-
chalk.yellow(`Use "wundr worktree create ${taskId}" to create it.`)
|
|
564
|
+
chalk.yellow(`Use "wundr worktree create ${taskId}" to create it.`),
|
|
565
565
|
);
|
|
566
566
|
return;
|
|
567
567
|
}
|
|
@@ -573,8 +573,8 @@ async function switchWorktree(taskId: string): Promise<void> {
|
|
|
573
573
|
spinner.fail(`Worktree directory not found: ${worktree.worktreePath}`);
|
|
574
574
|
console.log(
|
|
575
575
|
chalk.yellow(
|
|
576
|
-
'The worktree may have been deleted. Consider running cleanup.'
|
|
577
|
-
)
|
|
576
|
+
'The worktree may have been deleted. Consider running cleanup.',
|
|
577
|
+
),
|
|
578
578
|
);
|
|
579
579
|
return;
|
|
580
580
|
}
|
|
@@ -588,10 +588,10 @@ async function switchWorktree(taskId: string): Promise<void> {
|
|
|
588
588
|
console.log('');
|
|
589
589
|
console.log(chalk.white(' Task ID: ') + chalk.green(taskId));
|
|
590
590
|
console.log(
|
|
591
|
-
chalk.white(' Branch: ') + chalk.blue(worktree.branchName)
|
|
591
|
+
chalk.white(' Branch: ') + chalk.blue(worktree.branchName),
|
|
592
592
|
);
|
|
593
593
|
console.log(
|
|
594
|
-
chalk.white(' Path: ') + chalk.gray(worktree.worktreePath)
|
|
594
|
+
chalk.white(' Path: ') + chalk.gray(worktree.worktreePath),
|
|
595
595
|
);
|
|
596
596
|
console.log('');
|
|
597
597
|
console.log(chalk.cyan('To navigate to this worktree, run:'));
|
|
@@ -600,7 +600,7 @@ async function switchWorktree(taskId: string): Promise<void> {
|
|
|
600
600
|
} catch (error) {
|
|
601
601
|
spinner.fail('Failed to switch worktree');
|
|
602
602
|
console.error(
|
|
603
|
-
chalk.red(error instanceof Error ? error.message : String(error))
|
|
603
|
+
chalk.red(error instanceof Error ? error.message : String(error)),
|
|
604
604
|
);
|
|
605
605
|
}
|
|
606
606
|
}
|
|
@@ -613,7 +613,7 @@ async function cleanupWorktrees(options: {
|
|
|
613
613
|
const maxAgeDays = parseInt(options.age || '7', 10);
|
|
614
614
|
const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
|
|
615
615
|
const spinner = ora(
|
|
616
|
-
options.dryRun ? 'Analyzing worktrees...' : 'Cleaning up worktrees...'
|
|
616
|
+
options.dryRun ? 'Analyzing worktrees...' : 'Cleaning up worktrees...',
|
|
617
617
|
).start();
|
|
618
618
|
|
|
619
619
|
try {
|
|
@@ -687,7 +687,7 @@ async function cleanupWorktrees(options: {
|
|
|
687
687
|
}
|
|
688
688
|
|
|
689
689
|
console.log(
|
|
690
|
-
chalk.yellow(`\nWorktrees to be removed: ${toRemove.length}`)
|
|
690
|
+
chalk.yellow(`\nWorktrees to be removed: ${toRemove.length}`),
|
|
691
691
|
);
|
|
692
692
|
console.log(chalk.gray('-'.repeat(80)));
|
|
693
693
|
|
|
@@ -695,10 +695,10 @@ async function cleanupWorktrees(options: {
|
|
|
695
695
|
if (entry) {
|
|
696
696
|
console.log(chalk.white(' Task ID: ') + chalk.green(entry.taskId));
|
|
697
697
|
console.log(
|
|
698
|
-
chalk.white(' Path: ') + chalk.gray(entry.worktreePath)
|
|
698
|
+
chalk.white(' Path: ') + chalk.gray(entry.worktreePath),
|
|
699
699
|
);
|
|
700
700
|
console.log(
|
|
701
|
-
chalk.white(' Branch: ') + chalk.blue(entry.branchName)
|
|
701
|
+
chalk.white(' Branch: ') + chalk.blue(entry.branchName),
|
|
702
702
|
);
|
|
703
703
|
console.log(chalk.white(' Reason: ') + chalk.yellow(reason));
|
|
704
704
|
console.log('');
|
|
@@ -707,7 +707,7 @@ async function cleanupWorktrees(options: {
|
|
|
707
707
|
|
|
708
708
|
if (toSkip.length > 0) {
|
|
709
709
|
console.log(
|
|
710
|
-
chalk.yellow(`\nWorktrees to be skipped: ${toSkip.length}`)
|
|
710
|
+
chalk.yellow(`\nWorktrees to be skipped: ${toSkip.length}`),
|
|
711
711
|
);
|
|
712
712
|
console.log(chalk.gray('-'.repeat(80)));
|
|
713
713
|
|
|
@@ -715,7 +715,7 @@ async function cleanupWorktrees(options: {
|
|
|
715
715
|
if (entry) {
|
|
716
716
|
console.log(chalk.white(' Task ID: ') + chalk.green(entry.taskId));
|
|
717
717
|
console.log(
|
|
718
|
-
chalk.white(' Path: ') + chalk.gray(entry.worktreePath)
|
|
718
|
+
chalk.white(' Path: ') + chalk.gray(entry.worktreePath),
|
|
719
719
|
);
|
|
720
720
|
console.log(chalk.white(' Reason: ') + chalk.gray(reason));
|
|
721
721
|
console.log('');
|
|
@@ -725,7 +725,7 @@ async function cleanupWorktrees(options: {
|
|
|
725
725
|
|
|
726
726
|
console.log(chalk.gray('-'.repeat(80)));
|
|
727
727
|
console.log(
|
|
728
|
-
chalk.gray('Run without --dry-run to perform actual cleanup.')
|
|
728
|
+
chalk.gray('Run without --dry-run to perform actual cleanup.'),
|
|
729
729
|
);
|
|
730
730
|
console.log('');
|
|
731
731
|
} else {
|
|
@@ -750,7 +750,7 @@ async function cleanupWorktrees(options: {
|
|
|
750
750
|
await executeGitCommand(
|
|
751
751
|
'worktree',
|
|
752
752
|
['remove', forceFlag, entry.worktreePath].filter(Boolean),
|
|
753
|
-
repoPath
|
|
753
|
+
repoPath,
|
|
754
754
|
);
|
|
755
755
|
|
|
756
756
|
result.removedCount++;
|
|
@@ -789,7 +789,7 @@ async function cleanupWorktrees(options: {
|
|
|
789
789
|
// Update state file to remove cleaned worktrees
|
|
790
790
|
const removedPaths = new Set(result.removedPaths);
|
|
791
791
|
state.worktrees = state.worktrees.filter(
|
|
792
|
-
wt => !removedPaths.has(wt.worktreePath)
|
|
792
|
+
wt => !removedPaths.has(wt.worktreePath),
|
|
793
793
|
);
|
|
794
794
|
await saveWorktreeState(state);
|
|
795
795
|
|
|
@@ -805,7 +805,7 @@ async function cleanupWorktrees(options: {
|
|
|
805
805
|
|
|
806
806
|
if (result.removedCount > 0) {
|
|
807
807
|
console.log(
|
|
808
|
-
chalk.green(`\nRemoved ${result.removedCount} worktree(s):`)
|
|
808
|
+
chalk.green(`\nRemoved ${result.removedCount} worktree(s):`),
|
|
809
809
|
);
|
|
810
810
|
for (const removedPath of result.removedPaths) {
|
|
811
811
|
console.log(chalk.gray(` - ${removedPath}`));
|
|
@@ -814,7 +814,7 @@ async function cleanupWorktrees(options: {
|
|
|
814
814
|
|
|
815
815
|
if (result.skippedPaths.length > 0) {
|
|
816
816
|
console.log(
|
|
817
|
-
chalk.yellow(`\nSkipped ${result.skippedPaths.length} worktree(s):`)
|
|
817
|
+
chalk.yellow(`\nSkipped ${result.skippedPaths.length} worktree(s):`),
|
|
818
818
|
);
|
|
819
819
|
for (const skippedPath of result.skippedPaths) {
|
|
820
820
|
const reason = result.skipReasons.get(skippedPath) || 'unknown';
|
|
@@ -834,17 +834,17 @@ async function cleanupWorktrees(options: {
|
|
|
834
834
|
} catch (error) {
|
|
835
835
|
spinner.fail('Failed to cleanup worktrees');
|
|
836
836
|
console.error(
|
|
837
|
-
chalk.red(error instanceof Error ? error.message : String(error))
|
|
837
|
+
chalk.red(error instanceof Error ? error.message : String(error)),
|
|
838
838
|
);
|
|
839
839
|
}
|
|
840
840
|
}
|
|
841
841
|
|
|
842
842
|
async function syncWorktrees(
|
|
843
843
|
taskId: string | undefined,
|
|
844
|
-
options: { all?: boolean }
|
|
844
|
+
options: { all?: boolean },
|
|
845
845
|
): Promise<void> {
|
|
846
846
|
const spinner = ora(
|
|
847
|
-
taskId ? `Syncing worktree: ${taskId}...` : 'Syncing worktrees...'
|
|
847
|
+
taskId ? `Syncing worktree: ${taskId}...` : 'Syncing worktrees...',
|
|
848
848
|
).start();
|
|
849
849
|
|
|
850
850
|
try {
|
|
@@ -852,7 +852,7 @@ async function syncWorktrees(
|
|
|
852
852
|
const repoPath = state.repoPath || (await getGitRepoRoot());
|
|
853
853
|
|
|
854
854
|
const syncSingleWorktree = async (
|
|
855
|
-
worktree: WorktreeEntry
|
|
855
|
+
worktree: WorktreeEntry,
|
|
856
856
|
): Promise<SyncResult> => {
|
|
857
857
|
const timestamp = new Date();
|
|
858
858
|
let stashedChanges = false;
|
|
@@ -866,7 +866,7 @@ async function syncWorktrees(
|
|
|
866
866
|
await executeGitCommand(
|
|
867
867
|
'stash',
|
|
868
868
|
['push', '-m', 'auto-stash before sync'],
|
|
869
|
-
worktree.worktreePath
|
|
869
|
+
worktree.worktreePath,
|
|
870
870
|
);
|
|
871
871
|
stashedChanges = true;
|
|
872
872
|
}
|
|
@@ -878,7 +878,7 @@ async function syncWorktrees(
|
|
|
878
878
|
const branchName = await executeGitCommand(
|
|
879
879
|
'rev-parse',
|
|
880
880
|
['--abbrev-ref', 'HEAD'],
|
|
881
|
-
worktree.worktreePath
|
|
881
|
+
worktree.worktreePath,
|
|
882
882
|
);
|
|
883
883
|
|
|
884
884
|
// Try fast-forward pull
|
|
@@ -886,14 +886,14 @@ async function syncWorktrees(
|
|
|
886
886
|
await executeGitCommand(
|
|
887
887
|
'pull',
|
|
888
888
|
['--ff-only', 'origin', branchName],
|
|
889
|
-
worktree.worktreePath
|
|
889
|
+
worktree.worktreePath,
|
|
890
890
|
);
|
|
891
891
|
} catch {
|
|
892
892
|
// Fast-forward not possible, try rebase
|
|
893
893
|
await executeGitCommand(
|
|
894
894
|
'rebase',
|
|
895
895
|
[`origin/${branchName}`],
|
|
896
|
-
worktree.worktreePath
|
|
896
|
+
worktree.worktreePath,
|
|
897
897
|
);
|
|
898
898
|
}
|
|
899
899
|
|
|
@@ -902,7 +902,7 @@ async function syncWorktrees(
|
|
|
902
902
|
try {
|
|
903
903
|
const { stdout } = await execAsync(
|
|
904
904
|
`git rev-list --count origin/${branchName}..HEAD`,
|
|
905
|
-
{ cwd: worktree.worktreePath, timeout: 10000 }
|
|
905
|
+
{ cwd: worktree.worktreePath, timeout: 10000 },
|
|
906
906
|
);
|
|
907
907
|
commitsUpdated = parseInt(stdout.trim(), 10) || 0;
|
|
908
908
|
} catch {
|
|
@@ -973,15 +973,15 @@ async function syncWorktrees(
|
|
|
973
973
|
console.log(chalk.green(`\nSuccessfully synced worktree: ${taskId}`));
|
|
974
974
|
console.log(
|
|
975
975
|
chalk.white(' Branch: ') +
|
|
976
|
-
chalk.blue(result.branchName || 'unknown')
|
|
976
|
+
chalk.blue(result.branchName || 'unknown'),
|
|
977
977
|
);
|
|
978
978
|
console.log(
|
|
979
979
|
chalk.white(' Commits: ') +
|
|
980
|
-
chalk.cyan(`${result.commitsUpdated || 0} updated`)
|
|
980
|
+
chalk.cyan(`${result.commitsUpdated || 0} updated`),
|
|
981
981
|
);
|
|
982
982
|
if (result.stashedChanges) {
|
|
983
983
|
console.log(
|
|
984
|
-
chalk.yellow(' Note: Local changes were stashed and restored.')
|
|
984
|
+
chalk.yellow(' Note: Local changes were stashed and restored.'),
|
|
985
985
|
);
|
|
986
986
|
}
|
|
987
987
|
} else {
|
|
@@ -992,7 +992,7 @@ async function syncWorktrees(
|
|
|
992
992
|
} else if (options.all || !taskId) {
|
|
993
993
|
// Sync all active worktrees
|
|
994
994
|
const activeWorktrees = state.worktrees.filter(
|
|
995
|
-
wt => wt.status === 'active' || wt.status === 'paused'
|
|
995
|
+
wt => wt.status === 'active' || wt.status === 'paused',
|
|
996
996
|
);
|
|
997
997
|
|
|
998
998
|
if (activeWorktrees.length === 0) {
|
|
@@ -1030,8 +1030,8 @@ async function syncWorktrees(
|
|
|
1030
1030
|
for (const { taskId: tid, result } of successful) {
|
|
1031
1031
|
console.log(
|
|
1032
1032
|
chalk.gray(
|
|
1033
|
-
` - ${tid}: ${result.commitsUpdated || 0} commit(s) updated
|
|
1034
|
-
)
|
|
1033
|
+
` - ${tid}: ${result.commitsUpdated || 0} commit(s) updated`,
|
|
1034
|
+
),
|
|
1035
1035
|
);
|
|
1036
1036
|
}
|
|
1037
1037
|
}
|
|
@@ -1048,7 +1048,7 @@ async function syncWorktrees(
|
|
|
1048
1048
|
} catch (error) {
|
|
1049
1049
|
spinner.fail('Failed to sync worktrees');
|
|
1050
1050
|
console.error(
|
|
1051
|
-
chalk.red(error instanceof Error ? error.message : String(error))
|
|
1051
|
+
chalk.red(error instanceof Error ? error.message : String(error)),
|
|
1052
1052
|
);
|
|
1053
1053
|
}
|
|
1054
1054
|
}
|