beth-copilot 2.0.0 → 2.1.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/bin/cli.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { fileURLToPath } from 'url';
4
- import { dirname, join, relative } from 'path';
5
- import { existsSync, mkdirSync, readdirSync, statSync, copyFileSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from 'fs';
4
+ import { basename, dirname, join, relative } from 'path';
5
+ import { existsSync, mkdirSync, readdirSync, statSync, copyFileSync, readFileSync, writeFileSync, unlinkSync, chmodSync, rmSync } from 'fs';
6
6
  import { createRequire } from 'module';
7
- import { execSync, spawn } from 'child_process';
7
+ import { execSync, execFileSync, spawn } from 'child_process';
8
8
 
9
9
  const require = createRequire(import.meta.url);
10
10
  const __filename = fileURLToPath(import.meta.url);
@@ -226,18 +226,12 @@ async function animateBethBanner() {
226
226
  console.log('"' + COLORS.reset);
227
227
  console.log('');
228
228
 
229
- // Show version and quick help
229
+ // Show version line only — commands are shown after install completes
230
230
  console.log(`${COLORS.dim}v${CURRENT_VERSION}${COLORS.reset} ${COLORS.dim}AI Orchestrator for GitHub Copilot${COLORS.reset}`);
231
231
  console.log('');
232
- console.log(`${COLORS.bright}Commands:${COLORS.reset}`);
233
- console.log(` ${COLORS.cyan}npx beth-copilot init${COLORS.reset} Install Beth in your project`);
234
- console.log(` ${COLORS.cyan}npx beth-copilot help${COLORS.reset} Show full documentation`);
235
- console.log('');
236
- console.log(`${COLORS.bright}After install:${COLORS.reset} Open VS Code → Copilot Chat → ${COLORS.cyan}@Beth${COLORS.reset}`);
237
- console.log('');
238
232
  }
239
233
 
240
- function showBethBannerStatic({ showQuickHelp = true } = {}) {
234
+ function showBethBannerStatic() {
241
235
  const bethColors = [
242
236
  '\x1b[38;5;196m',
243
237
  '\x1b[38;5;202m',
@@ -276,17 +270,9 @@ function showBethBannerStatic({ showQuickHelp = true } = {}) {
276
270
  console.log(COLORS.cyan + COLORS.bright + '"' + tagline + '"' + COLORS.reset);
277
271
  console.log('');
278
272
 
279
- // Show version and quick help (optional)
280
- if (showQuickHelp) {
281
- console.log(`${COLORS.dim}v${CURRENT_VERSION}${COLORS.reset} ${COLORS.dim}AI Orchestrator for GitHub Copilot${COLORS.reset}`);
282
- console.log('');
283
- console.log(`${COLORS.bright}Commands:${COLORS.reset}`);
284
- console.log(` ${COLORS.cyan}npx beth-copilot init${COLORS.reset} Install Beth in your project`);
285
- console.log(` ${COLORS.cyan}npx beth-copilot help${COLORS.reset} Show full documentation`);
286
- console.log('');
287
- console.log(`${COLORS.bright}After install:${COLORS.reset} Open VS Code → Copilot Chat → ${COLORS.cyan}@Beth${COLORS.reset}`);
288
- console.log('');
289
- }
273
+ // Show version (always)
274
+ console.log(`${COLORS.dim}v${CURRENT_VERSION}${COLORS.reset} ${COLORS.dim}AI Orchestrator for GitHub Copilot${COLORS.reset}`);
275
+ console.log('');
290
276
  }
291
277
 
292
278
  // Compact Beth portrait with colors
@@ -590,33 +576,47 @@ ${BETH_GUARD_END}
590
576
  }
591
577
 
592
578
  function showHelp() {
593
- showBethBannerStatic({ showQuickHelp: false });
579
+ showBethBannerStatic();
594
580
  console.log(`${COLORS.bright}Beth${COLORS.reset} - AI Orchestrator for GitHub Copilot
595
581
 
596
- ${COLORS.bright}Usage:${COLORS.reset}
597
- npx beth-copilot init [options] Initialize Beth in current directory
598
- npx beth-copilot doctor Check system health and dependencies
599
- npx beth-copilot land [opts] Automated session completion (test, commit, push)
600
- npx beth-copilot pre-push-guard Run branch discipline checks (used by git hook)
601
- npx beth-copilot update [options] Update project files to latest templates
602
- npx beth-copilot quickstart Run init + doctor
603
- npx beth-copilot help Show this help message
604
-
605
- ${COLORS.bright}Options:${COLORS.reset}
582
+ ${COLORS.bright}Commands:${COLORS.reset}
583
+ ${COLORS.cyan}npx beth-copilot init${COLORS.reset} [options] Initialize Beth in current directory
584
+ ${COLORS.cyan}npx beth-copilot update${COLORS.reset} [options] Update project files to latest templates
585
+ ${COLORS.cyan}npx beth-copilot doctor${COLORS.reset} Check system health and dependencies
586
+ ${COLORS.cyan}npx beth-copilot land${COLORS.reset} [options] Automated session completion (test, commit, push)
587
+ ${COLORS.cyan}npx beth-copilot quickstart${COLORS.reset} Run init + doctor
588
+ ${COLORS.cyan}npx beth-copilot pre-push-guard${COLORS.reset} Run branch discipline checks (used by git hook)
589
+ ${COLORS.cyan}npx beth-copilot uninstall${COLORS.reset} Remove all Beth files from current project
590
+ ${COLORS.cyan}npx beth-copilot help${COLORS.reset} Show this help message
591
+
592
+ ${COLORS.bright}Init Options:${COLORS.reset}
606
593
  --force Overwrite existing files
607
594
  --skip-backlog Don't create Backlog.md
608
595
  --skip-mcp Don't create mcp.json.example
609
596
  --verbose Show detailed diagnostics on errors
610
- --check-only Check for updates without modifying files
597
+
598
+ ${COLORS.bright}Update Options:${COLORS.reset}
599
+ --check-only Report update status without modifying files
600
+ --force Overwrite user-modified files with templates
601
+ --verbose Show per-file detail
602
+
603
+ ${COLORS.bright}Land Options:${COLORS.reset}
604
+ --message, -m <msg> Custom commit message
605
+ --skip-tests Skip test execution (not recommended)
606
+ --force, -f Push even if tests fail (dangerous)
607
+ --dry-run Show what would happen without executing
611
608
 
612
609
  ${COLORS.bright}Examples:${COLORS.reset}
613
610
  npx beth-copilot init Set up Beth in current project
614
611
  npx beth-copilot init --force Overwrite existing Beth files
612
+ npx beth-copilot update Update to latest templates
613
+ npx beth-copilot update --check-only See what changed without modifying
615
614
  npx beth-copilot doctor Verify installation health
615
+ npx beth-copilot land -m "feat: new component" Commit and push session work
616
616
 
617
617
  ${COLORS.bright}What gets installed:${COLORS.reset}
618
618
  .github/agents/ 7 specialized AI agents
619
- .github/skills/ 8 domain knowledge modules
619
+ .github/skills/ Domain knowledge modules
620
620
  .github/copilot-instructions.md Copilot configuration
621
621
  .vscode/settings.json Recommended VS Code settings
622
622
  AGENTS.md Workflow documentation
@@ -681,6 +681,44 @@ function copyDirRecursive(src, dest, options = {}) {
681
681
  return copiedFiles;
682
682
  }
683
683
 
684
+ /**
685
+ * Derive a task prefix from the project name.
686
+ * Uses package.json "name" field, falls back to directory name.
687
+ * Takes the first segment (split on - _ . space), lowercased, up to 6 letters.
688
+ */
689
+ function deriveTaskPrefix(cwd) {
690
+ let projectName = '';
691
+
692
+ // Try package.json name field
693
+ const pkgPath = join(cwd, 'package.json');
694
+ if (existsSync(pkgPath)) {
695
+ try {
696
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
697
+ if (pkg.name && typeof pkg.name === 'string') {
698
+ projectName = pkg.name;
699
+ }
700
+ } catch {
701
+ // Ignore parse errors — fall through to directory name
702
+ }
703
+ }
704
+
705
+ // Fall back to directory name
706
+ if (!projectName) {
707
+ projectName = basename(cwd);
708
+ }
709
+
710
+ // Strip npm scope (e.g. @scope/package -> package)
711
+ projectName = projectName.replace(/^@[^/]+\//, '');
712
+
713
+ // Split on common delimiters, take first segment
714
+ const firstSegment = projectName.split(/[-_. ]+/)[0] || '';
715
+
716
+ // Lowercase, keep only letters, take up to 6
717
+ const prefix = firstSegment.toLowerCase().replace(/[^a-z]/g, '').slice(0, 6);
718
+
719
+ return prefix || 'task'; // fallback to 'task' if nothing usable
720
+ }
721
+
684
722
  async function init(options = {}) {
685
723
  const { force = false, skipBacklog = false, skipMcp = false } = options;
686
724
  const cwd = process.cwd();
@@ -700,11 +738,9 @@ ${COLORS.yellow}╔════════════════════
700
738
  if (canAnimate()) {
701
739
  await animateBethBanner();
702
740
  } else {
703
- showBethBannerStatic({ showQuickHelp: false });
741
+ showBethBannerStatic();
704
742
  }
705
743
 
706
- log(`${COLORS.yellow}Tip: Run with --verbose for detailed diagnostics if you hit issues.${COLORS.reset}`);
707
-
708
744
  // Check if templates exist
709
745
  if (!existsSync(TEMPLATES_DIR)) {
710
746
  logError('Templates directory not found. Package may be corrupted.');
@@ -787,6 +823,63 @@ ${COLORS.yellow}╔════════════════════
787
823
  }
788
824
  }
789
825
 
826
+ // Install .vscode/mcp.json with required MCP servers (unless --skip-mcp)
827
+ if (!skipMcp) {
828
+ const mcpJsonDest = join(cwd, '.vscode', 'mcp.json');
829
+ if (!existsSync(join(cwd, '.vscode'))) {
830
+ mkdirSync(join(cwd, '.vscode'), { recursive: true });
831
+ }
832
+
833
+ if (existsSync(mcpJsonDest) && !force) {
834
+ // Verify existing mcp.json has the required servers
835
+ try {
836
+ const existing = JSON.parse(readFileSync(mcpJsonDest, 'utf-8'));
837
+ const missing = [];
838
+ if (!existing.servers?.playwright) missing.push('playwright');
839
+ if (!existing.servers?.backlog) missing.push('backlog');
840
+
841
+ if (missing.length > 0) {
842
+ logWarning(`.vscode/mcp.json exists but missing required servers: ${missing.join(', ')}`);
843
+ logInfo('Add them manually or run with --force to overwrite');
844
+ } else {
845
+ logSuccess('.vscode/mcp.json already has required MCP servers');
846
+ }
847
+ } catch {
848
+ logWarning('.vscode/mcp.json exists but could not be parsed — verify it manually');
849
+ }
850
+ } else {
851
+ const mcpTemplateSrc = join(TEMPLATES_DIR, 'mcp.json.example');
852
+ if (existsSync(mcpTemplateSrc)) {
853
+ copyFileSync(mcpTemplateSrc, mcpJsonDest);
854
+ copiedFiles.push('.vscode/mcp.json');
855
+ }
856
+ }
857
+ }
858
+
859
+ // Initialize Backlog.md project with derived task prefix (unless skipped)
860
+ if (!skipBacklog) {
861
+ const backlogConfigPath = join(cwd, 'backlog', 'config.yml');
862
+ if (!existsSync(backlogConfigPath) || force) {
863
+ const taskPrefix = deriveTaskPrefix(cwd);
864
+ const dirName = basename(cwd);
865
+ try {
866
+ execFileSync(
867
+ 'backlog',
868
+ ['init', dirName, '--defaults', '--task-prefix', taskPrefix.toUpperCase(), '--integration-mode', 'mcp', '--auto-open-browser', 'false', '--bypass-git-hooks', 'true'],
869
+ { cwd, stdio: 'pipe', encoding: 'utf-8' }
870
+ );
871
+ logSuccess(`Initialized Backlog.md with task prefix: ${taskPrefix.toUpperCase()}`);
872
+ copiedFiles.push('backlog/config.yml');
873
+ } catch (err) {
874
+ logWarning('Could not initialize Backlog.md — is the backlog CLI installed?');
875
+ logInfo('Install with: npm install -g backlog-md');
876
+ logDebug(err.message || String(err));
877
+ }
878
+ } else {
879
+ logSuccess('Backlog.md already initialized (backlog/config.yml exists)');
880
+ }
881
+ }
882
+
790
883
  // Summary
791
884
  console.log('');
792
885
  if (copiedFiles.length > 0) {
@@ -808,17 +901,218 @@ ${COLORS.bright}Next steps:${COLORS.reset}
808
901
  2. Open Copilot Chat (${COLORS.cyan}Ctrl+Alt+I${COLORS.reset} / ${COLORS.cyan}Cmd+Alt+I${COLORS.reset})
809
902
  3. Type ${COLORS.cyan}@Beth${COLORS.reset} to start - she's your orchestrator
810
903
 
811
- ${COLORS.bright}Pro tip:${COLORS.reset} Start every session with ${COLORS.cyan}@Beth${COLORS.reset} and let her route work to the right specialists.
812
-
813
- ${COLORS.bright}Documentation:${COLORS.reset}
814
- https://github.com/stephschofield/beth
904
+ ${COLORS.bright}Pro tip:${COLORS.reset} Start every session with ${COLORS.cyan}@Beth${COLORS.reset} and let her route work to the right specialists.`);
815
905
 
816
- ${COLORS.cyan}"They broke my wings and forgot I had claws."${COLORS.reset}
906
+ // Commands at the bottom easy to find and copy-paste
907
+ console.log(`
908
+ ${COLORS.bright}Commands:${COLORS.reset}
909
+ ${COLORS.cyan}npx beth-copilot update${COLORS.reset} Update Beth to the latest templates
910
+ ${COLORS.cyan}npx beth-copilot doctor${COLORS.reset} Check system health and dependencies
911
+ ${COLORS.cyan}npx beth-copilot land${COLORS.reset} Automated session completion (test, commit, push)
912
+ ${COLORS.cyan}npx beth-copilot help${COLORS.reset} Show all commands, options, and documentation
817
913
  `);
914
+
915
+ console.log(`${COLORS.dim}Tip: Run with --verbose for detailed diagnostics if you hit issues.${COLORS.reset}`);
916
+ console.log(`${COLORS.dim}Documentation: https://github.com/stephschofield/beth${COLORS.reset}`);
917
+ console.log(`${COLORS.cyan}"They broke my wings and forgot I had claws."${COLORS.reset}`);
918
+ console.log('');
919
+ }
920
+
921
+ /**
922
+ * Uninstall Beth from the current project.
923
+ * Removes all files/directories that init installed.
924
+ */
925
+ async function uninstall() {
926
+ const cwd = process.cwd();
927
+ const args = process.argv.slice(3);
928
+ const forceFlag = args.includes('--force') || args.includes('-f');
929
+
930
+ showBethBannerStatic();
931
+
932
+ console.log(`${COLORS.bright}${COLORS.red}Uninstalling Beth...${COLORS.reset}\n`);
933
+
934
+ // Verify there's actually a Beth installation here
935
+ const githubDir = join(cwd, '.github');
936
+ const agentsDir = join(githubDir, 'agents');
937
+ const hasInstallation = existsSync(agentsDir) || existsSync(join(cwd, 'AGENTS.md'));
938
+
939
+ if (!hasInstallation) {
940
+ logWarning('No Beth installation detected in this directory.');
941
+ console.log('Are you in the right project? Beth installs into .github/agents/ and AGENTS.md.');
942
+ process.exit(0);
943
+ }
944
+
945
+ // --- Build the removal manifest ---
946
+ // Only remove files/dirs that Beth actually installs (from templates)
947
+
948
+ // Directories Beth owns entirely
949
+ const bethOwnedDirs = [
950
+ join(githubDir, 'agents'),
951
+ join(githubDir, 'skills'),
952
+ join(githubDir, 'hooks'),
953
+ ];
954
+
955
+ // Individual files Beth installs
956
+ const bethOwnedFiles = [
957
+ join(githubDir, 'copilot-instructions.md'),
958
+ join(githubDir, 'copilot-mcp-config.json'),
959
+ join(githubDir, 'pull_request_template.md'),
960
+ join(githubDir, 'dependabot.yml'),
961
+ join(cwd, 'AGENTS.md'),
962
+ join(cwd, 'Backlog.md'),
963
+ join(cwd, 'mcp.json.example'),
964
+ join(cwd, '.vscode', 'settings.json'),
965
+ join(cwd, '.vscode', 'mcp.json'),
966
+ ];
967
+
968
+ // Git pre-push hook (Beth appends a guard block)
969
+ const prePushHook = join(cwd, '.git', 'hooks', 'pre-push');
970
+
971
+ // Backlog.md directory (created by `backlog init`)
972
+ const backlogDir = join(cwd, 'backlog');
973
+
974
+ // --- Collect what actually exists ---
975
+ const dirsToRemove = bethOwnedDirs.filter(d => existsSync(d));
976
+ const filesToRemove = bethOwnedFiles.filter(f => existsSync(f));
977
+ const hasBacklogDir = existsSync(backlogDir);
978
+ const hasPrePushGuard = existsSync(prePushHook) && readFileSync(prePushHook, 'utf-8').includes(BETH_GUARD_BEGIN);
979
+
980
+ if (dirsToRemove.length === 0 && filesToRemove.length === 0 && !hasBacklogDir && !hasPrePushGuard) {
981
+ logWarning('Nothing to remove — Beth files have already been cleaned up.');
982
+ process.exit(0);
983
+ }
984
+
985
+ // --- Show what will be removed ---
986
+ console.log(`${COLORS.bright}The following will be removed:${COLORS.reset}\n`);
987
+
988
+ for (const dir of dirsToRemove) {
989
+ logInfo(`${relative(cwd, dir)}/ (directory)`);
990
+ }
991
+ for (const file of filesToRemove) {
992
+ logInfo(`${relative(cwd, file)}`);
993
+ }
994
+ if (hasBacklogDir) {
995
+ logInfo('backlog/ (directory — Backlog.md task data)');
996
+ }
997
+ if (hasPrePushGuard) {
998
+ logInfo('.git/hooks/pre-push (Beth guard block will be removed)');
999
+ }
1000
+
1001
+ console.log('');
1002
+
1003
+ // --- Confirm unless --force ---
1004
+ if (!forceFlag) {
1005
+ const confirmed = await promptYesNo(`${COLORS.yellow}Are you sure you want to remove Beth from this project?${COLORS.reset}`);
1006
+ if (!confirmed) {
1007
+ console.log('\nUninstall cancelled. Beth lives to fight another day.');
1008
+ process.exit(0);
1009
+ }
1010
+ }
1011
+
1012
+ console.log('');
1013
+ const removed = [];
1014
+
1015
+ // --- Remove directories ---
1016
+ for (const dir of dirsToRemove) {
1017
+ try {
1018
+ rmSync(dir, { recursive: true, force: true });
1019
+ removed.push(relative(cwd, dir) + '/');
1020
+ logSuccess(`Removed ${relative(cwd, dir)}/`);
1021
+ } catch (err) {
1022
+ logError(`Failed to remove ${relative(cwd, dir)}/: ${err.message}`);
1023
+ }
1024
+ }
1025
+
1026
+ // --- Remove files ---
1027
+ for (const file of filesToRemove) {
1028
+ try {
1029
+ unlinkSync(file);
1030
+ removed.push(relative(cwd, file));
1031
+ logSuccess(`Removed ${relative(cwd, file)}`);
1032
+ } catch (err) {
1033
+ logError(`Failed to remove ${relative(cwd, file)}: ${err.message}`);
1034
+ }
1035
+ }
1036
+
1037
+ // --- Remove backlog directory ---
1038
+ if (hasBacklogDir) {
1039
+ try {
1040
+ rmSync(backlogDir, { recursive: true, force: true });
1041
+ removed.push('backlog/');
1042
+ logSuccess('Removed backlog/');
1043
+ } catch (err) {
1044
+ logError(`Failed to remove backlog/: ${err.message}`);
1045
+ }
1046
+ }
1047
+
1048
+ // --- Clean pre-push hook ---
1049
+ if (hasPrePushGuard) {
1050
+ try {
1051
+ const hookContent = readFileSync(prePushHook, 'utf-8');
1052
+ const beginIdx = hookContent.indexOf(BETH_GUARD_BEGIN);
1053
+ const endIdx = hookContent.indexOf(BETH_GUARD_END);
1054
+
1055
+ if (beginIdx !== -1 && endIdx !== -1) {
1056
+ const cleaned = hookContent.slice(0, beginIdx) + hookContent.slice(endIdx + BETH_GUARD_END.length + 1);
1057
+ const trimmed = cleaned.trim();
1058
+
1059
+ if (trimmed === '' || trimmed === '#!/bin/sh' || trimmed === '#!/bin/bash') {
1060
+ // Hook is now empty — remove the whole file
1061
+ unlinkSync(prePushHook);
1062
+ logSuccess('Removed .git/hooks/pre-push (was Beth-only)');
1063
+ } else {
1064
+ writeFileSync(prePushHook, cleaned);
1065
+ logSuccess('Removed Beth guard block from .git/hooks/pre-push');
1066
+ }
1067
+ removed.push('.git/hooks/pre-push (guard block)');
1068
+ }
1069
+ } catch (err) {
1070
+ logError(`Failed to clean pre-push hook: ${err.message}`);
1071
+ }
1072
+ }
1073
+
1074
+ // --- Clean up empty parent directories ---
1075
+ // If .github/ is now empty, remove it
1076
+ if (existsSync(githubDir)) {
1077
+ try {
1078
+ const remaining = readdirSync(githubDir);
1079
+ if (remaining.length === 0) {
1080
+ rmSync(githubDir, { recursive: true, force: true });
1081
+ logSuccess('Removed empty .github/');
1082
+ }
1083
+ } catch {
1084
+ // Not critical
1085
+ }
1086
+ }
1087
+
1088
+ // If .vscode/ is now empty, remove it
1089
+ const vscodeDir = join(cwd, '.vscode');
1090
+ if (existsSync(vscodeDir)) {
1091
+ try {
1092
+ const remaining = readdirSync(vscodeDir);
1093
+ if (remaining.length === 0) {
1094
+ rmSync(vscodeDir, { recursive: true, force: true });
1095
+ logSuccess('Removed empty .vscode/');
1096
+ }
1097
+ } catch {
1098
+ // Not critical
1099
+ }
1100
+ }
1101
+
1102
+ // --- Summary ---
1103
+ console.log('');
1104
+ if (removed.length > 0) {
1105
+ logSuccess(`Removed ${removed.length} items. Beth has left the building.`);
1106
+ console.log(`\n${COLORS.dim}To reinstall: npx beth-copilot init${COLORS.reset}`);
1107
+ } else {
1108
+ logWarning('No items were removed. Check file permissions.');
1109
+ }
1110
+
1111
+ console.log(`\n${COLORS.cyan}"I'm not leaving. I'm choosing to go."${COLORS.reset}\n`);
818
1112
  }
819
1113
 
820
1114
  // Input validation constants
821
- const ALLOWED_COMMANDS = ['init', 'help', '--help', '-h', 'doctor', 'quickstart', 'pre-push-guard', 'update', 'land'];
1115
+ const ALLOWED_COMMANDS = ['init', 'help', '--help', '-h', 'doctor', 'quickstart', 'pre-push-guard', 'update', 'land', 'uninstall'];
822
1116
  const ALLOWED_FLAGS = ['--force', '--skip-backlog', '--skip-mcp', '--verbose', '--reason', '-r', '-f', '--skip-tests', '--message', '-m', '--dry-run', '--check-only'];
823
1117
  const MAX_ARG_LENGTH = 50;
824
1118
 
@@ -826,7 +1120,7 @@ const MAX_ARG_LENGTH = 50;
826
1120
  function validateArgs(args) {
827
1121
  // The 'land' and 'update' commands handle their own arg validation
828
1122
  const command = args[0]?.toLowerCase();
829
- if (command === 'land' || command === 'update') return;
1123
+ if (command === 'land' || command === 'update' || command === 'uninstall') return;
830
1124
 
831
1125
  for (const arg of args) {
832
1126
  // Prevent excessively long arguments (log injection, DoS)
@@ -860,7 +1154,7 @@ globalThis.VERBOSE = options.verbose;
860
1154
 
861
1155
  // Validate unknown flags (exclude --help which is handled as a command)
862
1156
  // Skip for 'land' and 'update' commands which handle their own arg parsing
863
- if (command !== 'land' && command !== 'update') {
1157
+ if (command !== 'land' && command !== 'update' && command !== 'uninstall') {
864
1158
  const unknownFlags = args.filter(arg => arg.startsWith('--') && !ALLOWED_FLAGS.includes(arg) && arg !== '--help');
865
1159
  if (unknownFlags.length > 0) {
866
1160
  logError(`Unknown flag: ${unknownFlags[0].slice(0, MAX_ARG_LENGTH)}`);
@@ -914,6 +1208,17 @@ switch (command) {
914
1208
  await prePushGuard();
915
1209
  }
916
1210
  break;
1211
+ case 'uninstall':
1212
+ try {
1213
+ await uninstall();
1214
+ } catch (error) {
1215
+ if (error instanceof UserError) {
1216
+ showUserError(error);
1217
+ process.exit(1);
1218
+ }
1219
+ throw error;
1220
+ }
1221
+ break;
917
1222
  case 'help':
918
1223
  case '--help':
919
1224
  case '-h':
@@ -7,16 +7,27 @@
7
7
  * - .github/agents/ exists with valid frontmatter
8
8
  * - .github/skills/ exists
9
9
  * - backlog.md initialization
10
+ * - Required MCP servers configured (.vscode/mcp.json)
10
11
  */
11
12
  interface DoctorOptions {
12
13
  verbose?: boolean;
13
14
  }
15
+ interface CheckResult {
16
+ name: string;
17
+ status: 'pass' | 'warn' | 'fail';
18
+ message: string;
19
+ details?: string;
20
+ }
14
21
  /**
15
22
  * Parse the minimum major Node.js version from package.json engines.node.
16
23
  * Supports formats like ">=18", "^18", ">=18.0.0", etc.
17
24
  * Returns the parsed major version, or a fallback if parsing fails.
18
25
  */
19
26
  export declare function getMinNodeVersion(cwd: string): number;
27
+ /**
28
+ * Check .vscode/mcp.json for required MCP servers
29
+ */
30
+ export declare function checkMcpServers(cwd: string): CheckResult;
20
31
  /**
21
32
  * Main doctor command
22
33
  * @param options - Command options
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkBH,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAwBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWrD;AAwLD;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,EAAE,aAAa,UAAO,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA4C3I"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkBH,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAiBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWrD;AA8LD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAmDxD;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,EAAE,aAAa,UAAO,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA6C3I"}
@@ -7,6 +7,7 @@
7
7
  * - .github/agents/ exists with valid frontmatter
8
8
  * - .github/skills/ exists
9
9
  * - backlog.md initialization
10
+ * - Required MCP servers configured (.vscode/mcp.json)
10
11
  */
11
12
  import { execSync } from 'child_process';
12
13
  import { existsSync, readdirSync, readFileSync } from 'fs';
@@ -211,6 +212,61 @@ function checkBacklogInit(cwd) {
211
212
  details: 'Run: backlog init',
212
213
  };
213
214
  }
215
+ /** Required MCP servers that agents depend on */
216
+ const REQUIRED_MCP_SERVERS = [
217
+ { key: 'playwright', label: 'Playwright', hint: '"playwright": { "command": "npx", "args": ["@playwright/mcp@0.0.68"] }' },
218
+ { key: 'backlog', label: 'Backlog.md', hint: '"backlog": { "command": "backlog", "args": ["mcp", "start"] }' },
219
+ ];
220
+ /**
221
+ * Check .vscode/mcp.json for required MCP servers
222
+ */
223
+ export function checkMcpServers(cwd) {
224
+ const mcpPath = join(cwd, '.vscode', 'mcp.json');
225
+ if (!existsSync(mcpPath)) {
226
+ return {
227
+ name: 'MCP Servers',
228
+ status: 'fail',
229
+ message: '.vscode/mcp.json not found',
230
+ details: 'Run: npx beth-copilot init (or npx beth-copilot init --force to regenerate)',
231
+ };
232
+ }
233
+ let config;
234
+ try {
235
+ config = JSON.parse(readFileSync(mcpPath, 'utf-8'));
236
+ }
237
+ catch {
238
+ return {
239
+ name: 'MCP Servers',
240
+ status: 'fail',
241
+ message: '.vscode/mcp.json is not valid JSON',
242
+ details: 'Fix the JSON syntax or run: npx beth-copilot init --force',
243
+ };
244
+ }
245
+ const servers = config.servers;
246
+ if (!servers || typeof servers !== 'object') {
247
+ return {
248
+ name: 'MCP Servers',
249
+ status: 'fail',
250
+ message: '.vscode/mcp.json missing "servers" object',
251
+ details: 'Run: npx beth-copilot init --force',
252
+ };
253
+ }
254
+ const missing = REQUIRED_MCP_SERVERS.filter(s => !servers[s.key]);
255
+ if (missing.length > 0) {
256
+ return {
257
+ name: 'MCP Servers',
258
+ status: 'fail',
259
+ message: `missing required server(s): ${missing.map(m => m.label).join(', ')}`,
260
+ details: missing.map(m => `Add to .vscode/mcp.json servers: ${m.hint}`).join('\n '),
261
+ };
262
+ }
263
+ const totalServers = Object.keys(servers).length;
264
+ return {
265
+ name: 'MCP Servers',
266
+ status: 'pass',
267
+ message: `${totalServers} servers configured (playwright ✓, backlog ✓)`,
268
+ };
269
+ }
214
270
  /**
215
271
  * Main doctor command
216
272
  * @param options - Command options
@@ -229,6 +285,7 @@ export async function doctor(options = {}, exitOnFailure = true) {
229
285
  checkAgents(cwd),
230
286
  checkSkills(cwd),
231
287
  checkBacklogInit(cwd),
288
+ checkMcpServers(cwd),
232
289
  ];
233
290
  // Display results
234
291
  for (const result of results) {
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,6BAA6B;AAC7B,MAAM,MAAM,GAAG;IACb,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,SAAS;IACjB,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,UAAU;IACf,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,UAAU;CACjB,CAAC;AAaF,SAAS,GAAG,CAAC,OAAe,EAAE,KAAK,GAAG,EAAE;IACtC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,SAAS,CAAC,MAAmB,EAAE,OAAgB;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnF,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IAE9G,GAAG,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;IAExD,IAAI,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,GAAG,CAAC,OAAO,MAAM,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACzE,MAAM,UAAU,GAAG,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC;QACtC,IAAI,OAAO,UAAU,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QACpD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAExC,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,GAAG,OAAO,MAAM,QAAQ,YAAY;SAC9C,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,GAAG,OAAO,MAAM,QAAQ,YAAY;QAC7C,OAAO,EAAE,sCAAsC;KAChD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,IAAY,EAAE,OAAe,EAAE,WAAmB;IAClE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,OAAO,YAAY,EAAE;YAC9C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,cAAc,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG;SAChD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,YAAY,WAAW,EAAE;SACnC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEjD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,2BAA2B;YACpC,OAAO,EAAE,4BAA4B;SACtC,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,0BAA0B;YACnC,OAAO,EAAE,oCAAoC;SAC9C,CAAC;IACJ,CAAC;IAED,sCAAsC;IACtC,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAC7D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAEjC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,iCAAiC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,uBAAuB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,YAAY,MAAM,CAAC,MAAM,cAAc;YACpE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;SAC3B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,oBAAoB;KAClD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEjD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,2BAA2B;YACpC,OAAO,EAAE,4BAA4B;SACtC,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC9D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEpB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,4BAA4B;SACtC,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,GAAG,SAAS,CAAC,MAAM,YAAY,cAAc,CAAC,MAAM,mBAAmB;YAChF,OAAO,EAAE,YAAY,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACjD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,GAAG,SAAS,CAAC,MAAM,oBAAoB;KACjD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAEtD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,iBAAiB;YACvB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,4BAA4B;SACtC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,0BAA0B;QACnC,OAAO,EAAE,mBAAmB;KAC7B,CAAC;AACJ,CAAC;AAED,iDAAiD;AACjD,MAAM,oBAAoB,GAAwD;IAChF,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,wEAAwE,EAAE;IAC1H,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,+DAA+D,EAAE;CAC/G,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAEjD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,4BAA4B;YACrC,OAAO,EAAE,6EAA6E;SACvF,CAAC;IACJ,CAAC;IAED,IAAI,MAA+B,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,oCAAoC;YAC7C,OAAO,EAAE,2DAA2D;SACrE,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAA8C,CAAC;IACtE,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,2CAA2C;YACpD,OAAO,EAAE,oCAAoC;SAC9C,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAElE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,+BAA+B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC9E,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,oCAAoC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;SACvF,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACjD,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,GAAG,YAAY,+CAA+C;KACxE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,UAAyB,EAAE,EAAE,aAAa,GAAG,IAAI;IAC5E,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,GAAG,CAAC,mCAAmC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,OAAO,GAAkB;QAC7B,gBAAgB,CAAC,GAAG,CAAC;QACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,EAAE,qBAAqB,CAAC;QACxD,WAAW,CAAC,GAAG,CAAC;QAChB,WAAW,CAAC,GAAG,CAAC;QAChB,gBAAgB,CAAC,GAAG,CAAC;QACrB,eAAe,CAAC,GAAG,CAAC;KACrB,CAAC;IAEF,kBAAkB;IAClB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAEhC,UAAU;IACV,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAE/D,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,MAAM,0DAA0D,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACvF,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,GAAG,CAAC,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,YAAY,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACnF,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,SAAS,OAAO,CAAC,MAAM,gCAAgC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC"}