@wundr.io/cli 1.0.0 → 1.0.2-dev.20260530174250.ef0ec927

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/README.md +696 -280
  2. package/bin/wundr.js +13 -5
  3. package/package.json +30 -9
  4. package/src/ai/ai-service.ts +6 -4
  5. package/src/ai/claude-client.ts +6 -2
  6. package/src/ai/conversation-manager.ts +12 -5
  7. package/src/cli.ts +42 -13
  8. package/src/commands/ai.ts +340 -64
  9. package/src/commands/alignment.ts +1212 -0
  10. package/src/commands/analyze-optimized.ts +371 -33
  11. package/src/commands/analyze.ts +8 -6
  12. package/src/commands/batch.ts +166 -26
  13. package/src/commands/chat.ts +20 -10
  14. package/src/commands/claude-init.ts +31 -27
  15. package/src/commands/claude-setup.ts +761 -81
  16. package/src/commands/computer-setup.ts +524 -12
  17. package/src/commands/create-command.ts +3 -3
  18. package/src/commands/create.ts +9 -6
  19. package/src/commands/dashboard.ts +11 -6
  20. package/src/commands/govern.ts +11 -6
  21. package/src/commands/governance.ts +1005 -0
  22. package/src/commands/guardian.ts +887 -0
  23. package/src/commands/init.ts +104 -11
  24. package/src/commands/orchestrator.ts +789 -0
  25. package/src/commands/performance-optimizer.ts +15 -10
  26. package/src/commands/plugins.ts +8 -5
  27. package/src/commands/project-update.ts +1156 -0
  28. package/src/commands/rag.ts +1011 -0
  29. package/src/commands/session.ts +631 -0
  30. package/src/commands/setup.ts +42 -344
  31. package/src/commands/test-init.ts +3 -2
  32. package/src/commands/test.ts +3 -2
  33. package/src/commands/watch.ts +21 -11
  34. package/src/commands/worktree.ts +1057 -0
  35. package/src/context/context-manager.ts +5 -2
  36. package/src/context/session-manager.ts +18 -7
  37. package/src/framework/command-interface.ts +520 -0
  38. package/src/framework/command-registry.ts +942 -0
  39. package/src/framework/completion-exporter.ts +383 -0
  40. package/src/framework/debug-logger.ts +519 -0
  41. package/src/framework/error-handler.ts +867 -0
  42. package/src/framework/help-generator.ts +540 -0
  43. package/src/framework/index.ts +169 -0
  44. package/src/framework/interactive-repl.ts +703 -0
  45. package/src/framework/output-formatter.ts +834 -0
  46. package/src/framework/progress-manager.ts +539 -0
  47. package/src/index.ts +3 -2
  48. package/src/interactive/interactive-mode.ts +14 -7
  49. package/src/lib/conflict-resolution.ts +818 -0
  50. package/src/lib/merge-strategy.ts +550 -0
  51. package/src/lib/safety-mechanisms.ts +451 -0
  52. package/src/lib/state-detection.ts +1030 -0
  53. package/src/nlp/command-mapper.ts +8 -3
  54. package/src/nlp/command-parser.ts +5 -2
  55. package/src/nlp/intent-parser.ts +23 -9
  56. package/src/plugins/plugin-manager.ts +50 -24
  57. package/src/tests/computer-setup-integration.test.ts +470 -0
  58. package/src/types/index.ts +1 -1
  59. package/src/types/modules.d.ts +425 -1
  60. package/src/utils/backup-rollback-manager.ts +366 -0
  61. package/src/utils/claude-config-installer.ts +823 -0
  62. package/src/utils/config-manager.ts +9 -6
  63. package/src/utils/error-handler.ts +3 -1
  64. package/src/utils/logger.ts +35 -12
  65. package/templates/batch/ci-cd.yaml +7 -7
  66. package/test-suites/api/health.spec.ts +20 -23
  67. package/test-suites/helpers/test-config.ts +14 -13
  68. package/test-suites/ui/accessibility.spec.ts +27 -22
  69. package/test-suites/ui/smoke.spec.ts +26 -21
  70. package/dist/ai/ai-service.d.ts +0 -152
  71. package/dist/ai/ai-service.d.ts.map +0 -1
  72. package/dist/ai/ai-service.js +0 -430
  73. package/dist/ai/ai-service.js.map +0 -1
  74. package/dist/ai/claude-client.d.ts +0 -130
  75. package/dist/ai/claude-client.d.ts.map +0 -1
  76. package/dist/ai/claude-client.js +0 -339
  77. package/dist/ai/claude-client.js.map +0 -1
  78. package/dist/ai/conversation-manager.d.ts +0 -164
  79. package/dist/ai/conversation-manager.d.ts.map +0 -1
  80. package/dist/ai/conversation-manager.js +0 -612
  81. package/dist/ai/conversation-manager.js.map +0 -1
  82. package/dist/ai/index.d.ts +0 -5
  83. package/dist/ai/index.d.ts.map +0 -1
  84. package/dist/ai/index.js +0 -8
  85. package/dist/ai/index.js.map +0 -1
  86. package/dist/cli.d.ts +0 -36
  87. package/dist/cli.d.ts.map +0 -1
  88. package/dist/cli.js +0 -173
  89. package/dist/cli.js.map +0 -1
  90. package/dist/commands/ai.d.ts +0 -89
  91. package/dist/commands/ai.d.ts.map +0 -1
  92. package/dist/commands/ai.js +0 -735
  93. package/dist/commands/ai.js.map +0 -1
  94. package/dist/commands/analyze-optimized.d.ts +0 -14
  95. package/dist/commands/analyze-optimized.d.ts.map +0 -1
  96. package/dist/commands/analyze-optimized.js +0 -437
  97. package/dist/commands/analyze-optimized.js.map +0 -1
  98. package/dist/commands/analyze.d.ts +0 -65
  99. package/dist/commands/analyze.d.ts.map +0 -1
  100. package/dist/commands/analyze.js +0 -435
  101. package/dist/commands/analyze.js.map +0 -1
  102. package/dist/commands/batch.d.ts +0 -71
  103. package/dist/commands/batch.d.ts.map +0 -1
  104. package/dist/commands/batch.js +0 -738
  105. package/dist/commands/batch.js.map +0 -1
  106. package/dist/commands/chat.d.ts +0 -71
  107. package/dist/commands/chat.d.ts.map +0 -1
  108. package/dist/commands/chat.js +0 -674
  109. package/dist/commands/chat.js.map +0 -1
  110. package/dist/commands/claude-init.d.ts +0 -28
  111. package/dist/commands/claude-init.d.ts.map +0 -1
  112. package/dist/commands/claude-init.js +0 -587
  113. package/dist/commands/claude-init.js.map +0 -1
  114. package/dist/commands/claude-setup.d.ts +0 -32
  115. package/dist/commands/claude-setup.d.ts.map +0 -1
  116. package/dist/commands/claude-setup.js +0 -570
  117. package/dist/commands/claude-setup.js.map +0 -1
  118. package/dist/commands/computer-setup-commands.d.ts +0 -39
  119. package/dist/commands/computer-setup-commands.d.ts.map +0 -1
  120. package/dist/commands/computer-setup-commands.js +0 -563
  121. package/dist/commands/computer-setup-commands.js.map +0 -1
  122. package/dist/commands/computer-setup.d.ts +0 -7
  123. package/dist/commands/computer-setup.d.ts.map +0 -1
  124. package/dist/commands/computer-setup.js +0 -481
  125. package/dist/commands/computer-setup.js.map +0 -1
  126. package/dist/commands/create-command.d.ts +0 -7
  127. package/dist/commands/create-command.d.ts.map +0 -1
  128. package/dist/commands/create-command.js +0 -158
  129. package/dist/commands/create-command.js.map +0 -1
  130. package/dist/commands/create.d.ts +0 -74
  131. package/dist/commands/create.d.ts.map +0 -1
  132. package/dist/commands/create.js +0 -556
  133. package/dist/commands/create.js.map +0 -1
  134. package/dist/commands/dashboard.d.ts +0 -91
  135. package/dist/commands/dashboard.d.ts.map +0 -1
  136. package/dist/commands/dashboard.js +0 -537
  137. package/dist/commands/dashboard.js.map +0 -1
  138. package/dist/commands/govern.d.ts +0 -70
  139. package/dist/commands/govern.d.ts.map +0 -1
  140. package/dist/commands/govern.js +0 -480
  141. package/dist/commands/govern.js.map +0 -1
  142. package/dist/commands/init.d.ts +0 -55
  143. package/dist/commands/init.d.ts.map +0 -1
  144. package/dist/commands/init.js +0 -584
  145. package/dist/commands/init.js.map +0 -1
  146. package/dist/commands/performance-optimizer.d.ts +0 -30
  147. package/dist/commands/performance-optimizer.d.ts.map +0 -1
  148. package/dist/commands/performance-optimizer.js +0 -649
  149. package/dist/commands/performance-optimizer.js.map +0 -1
  150. package/dist/commands/plugins.d.ts +0 -87
  151. package/dist/commands/plugins.d.ts.map +0 -1
  152. package/dist/commands/plugins.js +0 -685
  153. package/dist/commands/plugins.js.map +0 -1
  154. package/dist/commands/setup.d.ts +0 -29
  155. package/dist/commands/setup.d.ts.map +0 -1
  156. package/dist/commands/setup.js +0 -399
  157. package/dist/commands/setup.js.map +0 -1
  158. package/dist/commands/test-init.d.ts +0 -9
  159. package/dist/commands/test-init.d.ts.map +0 -1
  160. package/dist/commands/test-init.js +0 -222
  161. package/dist/commands/test-init.js.map +0 -1
  162. package/dist/commands/test.d.ts +0 -25
  163. package/dist/commands/test.d.ts.map +0 -1
  164. package/dist/commands/test.js +0 -217
  165. package/dist/commands/test.js.map +0 -1
  166. package/dist/commands/watch.d.ts +0 -76
  167. package/dist/commands/watch.d.ts.map +0 -1
  168. package/dist/commands/watch.js +0 -610
  169. package/dist/commands/watch.js.map +0 -1
  170. package/dist/context/context-manager.d.ts +0 -155
  171. package/dist/context/context-manager.d.ts.map +0 -1
  172. package/dist/context/context-manager.js +0 -383
  173. package/dist/context/context-manager.js.map +0 -1
  174. package/dist/context/index.d.ts +0 -3
  175. package/dist/context/index.d.ts.map +0 -1
  176. package/dist/context/index.js +0 -6
  177. package/dist/context/index.js.map +0 -1
  178. package/dist/context/session-manager.d.ts +0 -207
  179. package/dist/context/session-manager.d.ts.map +0 -1
  180. package/dist/context/session-manager.js +0 -682
  181. package/dist/context/session-manager.js.map +0 -1
  182. package/dist/index.d.ts +0 -8
  183. package/dist/index.d.ts.map +0 -1
  184. package/dist/index.js +0 -51
  185. package/dist/index.js.map +0 -1
  186. package/dist/interactive/interactive-mode.d.ts +0 -76
  187. package/dist/interactive/interactive-mode.d.ts.map +0 -1
  188. package/dist/interactive/interactive-mode.js +0 -730
  189. package/dist/interactive/interactive-mode.js.map +0 -1
  190. package/dist/nlp/command-mapper.d.ts +0 -174
  191. package/dist/nlp/command-mapper.d.ts.map +0 -1
  192. package/dist/nlp/command-mapper.js +0 -623
  193. package/dist/nlp/command-mapper.js.map +0 -1
  194. package/dist/nlp/command-parser.d.ts +0 -106
  195. package/dist/nlp/command-parser.d.ts.map +0 -1
  196. package/dist/nlp/command-parser.js +0 -416
  197. package/dist/nlp/command-parser.js.map +0 -1
  198. package/dist/nlp/index.d.ts +0 -5
  199. package/dist/nlp/index.d.ts.map +0 -1
  200. package/dist/nlp/index.js +0 -8
  201. package/dist/nlp/index.js.map +0 -1
  202. package/dist/nlp/intent-classifier.d.ts +0 -59
  203. package/dist/nlp/intent-classifier.d.ts.map +0 -1
  204. package/dist/nlp/intent-classifier.js +0 -384
  205. package/dist/nlp/intent-classifier.js.map +0 -1
  206. package/dist/nlp/intent-parser.d.ts +0 -152
  207. package/dist/nlp/intent-parser.d.ts.map +0 -1
  208. package/dist/nlp/intent-parser.js +0 -739
  209. package/dist/nlp/intent-parser.js.map +0 -1
  210. package/dist/plugins/plugin-manager.d.ts +0 -120
  211. package/dist/plugins/plugin-manager.d.ts.map +0 -1
  212. package/dist/plugins/plugin-manager.js +0 -595
  213. package/dist/plugins/plugin-manager.js.map +0 -1
  214. package/dist/types/index.d.ts +0 -224
  215. package/dist/types/index.d.ts.map +0 -1
  216. package/dist/types/index.js +0 -3
  217. package/dist/types/index.js.map +0 -1
  218. package/dist/utils/config-manager.d.ts +0 -73
  219. package/dist/utils/config-manager.d.ts.map +0 -1
  220. package/dist/utils/config-manager.js +0 -339
  221. package/dist/utils/config-manager.js.map +0 -1
  222. package/dist/utils/error-handler.d.ts +0 -46
  223. package/dist/utils/error-handler.d.ts.map +0 -1
  224. package/dist/utils/error-handler.js +0 -169
  225. package/dist/utils/error-handler.js.map +0 -1
  226. package/dist/utils/logger.d.ts +0 -25
  227. package/dist/utils/logger.d.ts.map +0 -1
  228. package/dist/utils/logger.js +0 -94
  229. package/dist/utils/logger.js.map +0 -1
  230. package/src/commands/computer-setup-commands.ts +0 -709
@@ -1,14 +1,17 @@
1
- import { Command } from 'commander';
2
- import fs from 'fs-extra';
3
1
  import path from 'path';
2
+
4
3
  import chalk from 'chalk';
5
- import YAML from 'yaml';
4
+ import fs from 'fs-extra';
6
5
  import { Listr } from 'listr2';
7
- import { ConfigManager } from '../utils/config-manager';
8
- import { PluginManager } from '../plugins/plugin-manager';
9
- import { logger } from '../utils/logger';
6
+ import YAML from 'yaml';
7
+
10
8
  import { errorHandler } from '../utils/error-handler';
11
- import { BatchJob, BatchCommand } from '../types';
9
+ import { logger } from '../utils/logger';
10
+
11
+ import type { PluginManager } from '../plugins/plugin-manager';
12
+ import type { BatchJob, BatchCommand } from '../types';
13
+ import type { ConfigManager } from '../utils/config-manager';
14
+ import type { Command } from 'commander';
12
15
 
13
16
  /**
14
17
  * Batch commands for YAML automation and batch processing
@@ -560,6 +563,11 @@ export class BatchCommands {
560
563
  return { valid: errors.length === 0, errors };
561
564
  }
562
565
 
566
+ /**
567
+ * Regex for valid variable names in batch templates.
568
+ */
569
+ private static readonly VALID_VARIABLE_NAME = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
570
+
563
571
  private async processJobVariables(
564
572
  job: BatchJob,
565
573
  vars?: string
@@ -573,25 +581,58 @@ export class BatchCommands {
573
581
  } catch {
574
582
  // Parse as key=value pairs
575
583
  vars.split(',').forEach(pair => {
576
- const [key, value] = pair.split('=');
577
- if (key && value) {
578
- variables[key.trim()] = value.trim();
584
+ const eqIndex = pair.indexOf('=');
585
+ if (eqIndex > 0) {
586
+ const key = pair.slice(0, eqIndex).trim();
587
+ const value = pair.slice(eqIndex + 1).trim();
588
+ if (key) {
589
+ variables[key] = value;
590
+ }
579
591
  }
580
592
  });
581
593
  }
582
594
  }
583
595
 
584
- // Replace variables in job
585
- const processedJob = JSON.parse(JSON.stringify(job));
586
- const jobString = JSON.stringify(processedJob);
587
- let processedString = jobString;
596
+ // Validate variable names to prevent regex injection
597
+ for (const key of Object.keys(variables)) {
598
+ if (!BatchCommands.VALID_VARIABLE_NAME.test(key)) {
599
+ throw new Error(
600
+ `Invalid variable name "${key}": must match [a-zA-Z_][a-zA-Z0-9_]*`
601
+ );
602
+ }
603
+ }
588
604
 
589
- Object.entries(variables).forEach(([key, value]) => {
590
- const placeholder = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
591
- processedString = processedString.replace(placeholder, String(value));
592
- });
605
+ // SECURITY: Instead of replacing {{var}} in a JSON-stringified string
606
+ // (which allows JSON structure breakout via quotes in values), we walk
607
+ // the job structure and only replace in string leaf values. Values are
608
+ // JSON-escaped to prevent structure injection.
609
+ const processedJob: BatchJob = JSON.parse(JSON.stringify(job));
610
+
611
+ const replaceVarsInString = (str: string): string => {
612
+ let result = str;
613
+ for (const [key, value] of Object.entries(variables)) {
614
+ const placeholder = `{{${key}}}`;
615
+ // Only replace exact placeholder matches, not regex patterns
616
+ while (result.includes(placeholder)) {
617
+ result = result.replace(placeholder, String(value));
618
+ }
619
+ }
620
+ return result;
621
+ };
622
+
623
+ // Walk commands and replace variables in string fields only
624
+ processedJob.commands = processedJob.commands.map(cmd => ({
625
+ ...cmd,
626
+ command: replaceVarsInString(cmd.command),
627
+ args: cmd.args?.map(arg => replaceVarsInString(arg)),
628
+ condition: cmd.condition ? replaceVarsInString(cmd.condition) : undefined,
629
+ }));
630
+
631
+ if (processedJob.description) {
632
+ processedJob.description = replaceVarsInString(processedJob.description);
633
+ }
593
634
 
594
- return JSON.parse(processedString);
635
+ return processedJob;
595
636
  }
596
637
 
597
638
  private async showDryRun(job: BatchJob): Promise<void> {
@@ -646,6 +687,91 @@ export class BatchCommands {
646
687
  await listr.run();
647
688
  }
648
689
 
690
+ /**
691
+ * Shell metacharacters that indicate injection attempts.
692
+ * These characters have special meaning in sh/bash and must not
693
+ * appear in arguments passed to spawn().
694
+ */
695
+ private static readonly SHELL_METACHARACTERS = /[;&|`$(){}[\]<>!#~*?\n\r\\]/;
696
+
697
+ /**
698
+ * Tokenize a command string into [binary, ...args] without shell
699
+ * interpretation. Supports simple single/double quoting.
700
+ */
701
+ private tokenizeCommand(command: string): string[] {
702
+ const tokens: string[] = [];
703
+ let current = '';
704
+ let inSingle = false;
705
+ let inDouble = false;
706
+
707
+ for (let i = 0; i < command.length; i++) {
708
+ const ch = command[i];
709
+
710
+ if (inSingle) {
711
+ if (ch === "'") {
712
+ inSingle = false;
713
+ } else {
714
+ current += ch;
715
+ }
716
+ continue;
717
+ }
718
+
719
+ if (inDouble) {
720
+ if (ch === '"') {
721
+ inDouble = false;
722
+ } else {
723
+ current += ch;
724
+ }
725
+ continue;
726
+ }
727
+
728
+ if (ch === "'") {
729
+ inSingle = true;
730
+ continue;
731
+ }
732
+ if (ch === '"') {
733
+ inDouble = true;
734
+ continue;
735
+ }
736
+
737
+ if (ch === ' ' || ch === '\t') {
738
+ if (current.length > 0) {
739
+ tokens.push(current);
740
+ current = '';
741
+ }
742
+ continue;
743
+ }
744
+
745
+ current += ch;
746
+ }
747
+
748
+ if (current.length > 0) {
749
+ tokens.push(current);
750
+ }
751
+
752
+ if (inSingle || inDouble) {
753
+ throw new Error(`Unterminated quote in command: ${command}`);
754
+ }
755
+
756
+ return tokens;
757
+ }
758
+
759
+ /**
760
+ * Validate that no argument contains shell metacharacters.
761
+ * This is a defense-in-depth measure: since we never use shell: true,
762
+ * metacharacters would be treated literally, but their presence strongly
763
+ * suggests a command injection attempt.
764
+ */
765
+ private validateArgs(args: string[]): void {
766
+ for (const arg of args) {
767
+ if (BatchCommands.SHELL_METACHARACTERS.test(arg)) {
768
+ throw new Error(
769
+ `Argument contains shell metacharacters (possible injection): "${arg}"`
770
+ );
771
+ }
772
+ }
773
+ }
774
+
649
775
  private async executeCommand(
650
776
  cmd: BatchCommand,
651
777
  _options: any
@@ -657,13 +783,27 @@ export class BatchCommands {
657
783
  }
658
784
 
659
785
  const { spawn } = await import('child_process');
660
- const [command, ...args] = cmd.command.split(' ');
661
- const finalArgs = cmd.args ? [...args, ...cmd.args] : args;
786
+
787
+ // Tokenize the command string into binary + args without shell
788
+ // interpretation. This prevents command injection via shell metacharacters
789
+ // like ; | & ` $() etc.
790
+ const tokens = this.tokenizeCommand(cmd.command);
791
+ if (tokens.length === 0) {
792
+ throw new Error('Empty command');
793
+ }
794
+
795
+ const [command, ...parsedArgs] = tokens;
796
+ const finalArgs = cmd.args ? [...parsedArgs, ...cmd.args] : parsedArgs;
797
+
798
+ // Validate arguments for shell metacharacters as defense-in-depth
799
+ this.validateArgs(finalArgs);
662
800
 
663
801
  return new Promise((resolve, reject) => {
802
+ // SECURITY: No shell: true. The command is executed directly via
803
+ // execvp(), so shell metacharacters in arguments are treated as
804
+ // literal characters rather than being interpreted by a shell.
664
805
  const child = spawn(command ?? 'echo', finalArgs, {
665
806
  stdio: ['ignore', 'pipe', 'pipe'],
666
- shell: true,
667
807
  });
668
808
 
669
809
  let output = '';
@@ -834,14 +974,14 @@ export class BatchCommands {
834
974
 
835
975
  private convertToDockerfile(job: BatchJob): string {
836
976
  let dockerfile = `# Generated from batch job: ${job.name}\n`;
837
- dockerfile += `FROM node:18-alpine\n\n`;
977
+ dockerfile += 'FROM node:18-alpine\n\n';
838
978
 
839
979
  if (job.description) {
840
980
  dockerfile += `# ${job.description}\n`;
841
981
  }
842
982
 
843
- dockerfile += `WORKDIR /app\n`;
844
- dockerfile += `COPY . .\n\n`;
983
+ dockerfile += 'WORKDIR /app\n';
984
+ dockerfile += 'COPY . .\n\n';
845
985
 
846
986
  job.commands.forEach(cmd => {
847
987
  dockerfile += `RUN ${cmd.command}\n`;
@@ -887,7 +1027,7 @@ export class BatchCommands {
887
1027
 
888
1028
  return {
889
1029
  name: name || 'package-scripts',
890
- description: `Imported from package.json scripts`,
1030
+ description: 'Imported from package.json scripts',
891
1031
  commands,
892
1032
  };
893
1033
  }
@@ -1,25 +1,31 @@
1
- import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
- import fs from 'fs-extra';
4
1
  import path from 'path';
2
+
5
3
  import chalk from 'chalk';
6
- import { ConfigManager } from '../utils/config-manager';
7
- import { PluginManager } from '../plugins/plugin-manager';
8
- import { logger } from '../utils/logger';
4
+ import fs from 'fs-extra';
5
+ import inquirer from 'inquirer';
6
+
7
+ import { AIService } from '../ai/ai-service';
9
8
  import { errorHandler } from '../utils/error-handler';
10
- import { ChatSession, ChatMessage } from '../types';
9
+ import { logger } from '../utils/logger';
10
+
11
+ import type { PluginManager } from '../plugins/plugin-manager';
12
+ import type { ChatSession, ChatMessage } from '../types';
13
+ import type { ConfigManager } from '../utils/config-manager';
14
+ import type { Command } from 'commander';
11
15
 
12
16
  /**
13
17
  * Chat commands for natural language interface
14
18
  */
15
19
  export class ChatCommands {
16
20
  private activeSessions: Map<string, ChatSession> = new Map();
21
+ private aiService: AIService;
17
22
 
18
23
  constructor(
19
24
  private program: Command,
20
25
  private configManager: ConfigManager,
21
26
  private pluginManager: PluginManager
22
27
  ) {
28
+ this.aiService = new AIService(configManager);
23
29
  this.registerCommands();
24
30
  }
25
31
 
@@ -622,9 +628,13 @@ export class ChatCommands {
622
628
  }
623
629
 
624
630
  private async callAI(session: ChatSession, message: string): Promise<string> {
625
- // Mock AI service call
626
- // In a real implementation, this would call Claude, GPT, etc.
627
- return `This is a mock response to: "${message}". The AI would provide a helpful response here based on the context and conversation history.`;
631
+ if (!this.aiService.isReady()) {
632
+ throw new Error(
633
+ 'AI service not configured. Set ANTHROPIC_API_KEY environment variable to enable chat.'
634
+ );
635
+ }
636
+
637
+ return this.aiService.sendMessage(session.id, message);
628
638
  }
629
639
 
630
640
  private showChatHelp(): void {
@@ -1,10 +1,12 @@
1
- import { Command } from 'commander';
2
- import * as fs from 'fs-extra';
3
- import * as path from 'path';
4
1
  import { execSync } from 'child_process';
2
+ import * as path from 'path';
3
+
5
4
  import chalk from 'chalk';
6
- import ora from 'ora';
5
+ import * as fs from 'fs-extra';
7
6
  import inquirer from 'inquirer';
7
+ import ora from 'ora';
8
+
9
+ import type { Command } from 'commander';
8
10
 
9
11
  interface ProjectInfo {
10
12
  name: string;
@@ -29,9 +31,7 @@ export class ClaudeInitCommand {
29
31
  this.program
30
32
  .command('claude-init')
31
33
  .alias('ci')
32
- .description(
33
- 'Initialize Claude Code and Claude Flow in current repository'
34
- )
34
+ .description('Initialize Claude Code and Ruflo in current repository')
35
35
  .option('-i, --interactive', 'Interactive mode with prompts')
36
36
  .option('-a, --audit', 'Run repository audit first')
37
37
  .option('-f, --force', 'Force overwrite existing CLAUDE.md')
@@ -79,8 +79,8 @@ export class ClaudeInitCommand {
79
79
  // Generate CLAUDE.md
80
80
  await this.generateClaudeMd(projectInfo, options);
81
81
 
82
- // Setup Claude Flow
83
- await this.setupClaudeFlow(projectInfo, options);
82
+ // Setup Ruflo
83
+ await this.setupRuflo(projectInfo, options);
84
84
 
85
85
  // Setup MCP tools
86
86
  await this.setupMcpTools(options.mcpTools);
@@ -183,10 +183,12 @@ export class ClaudeInitCommand {
183
183
  };
184
184
 
185
185
  // Structure checks
186
- if (await fs.pathExists('src'))
186
+ if (await fs.pathExists('src')) {
187
187
  auditResults.categories.structure.score += 10;
188
- if (await fs.pathExists('.gitignore'))
188
+ }
189
+ if (await fs.pathExists('.gitignore')) {
189
190
  auditResults.categories.structure.score += 5;
191
+ }
190
192
  if (projectInfo.isMonorepo && (await fs.pathExists('packages'))) {
191
193
  auditResults.categories.structure.score += 5;
192
194
  }
@@ -291,8 +293,8 @@ export class ClaudeInitCommand {
291
293
  const answers = await inquirer.prompt([
292
294
  {
293
295
  type: 'confirm',
294
- name: 'setupClaudeFlow',
295
- message: 'Setup Claude Flow orchestration?',
296
+ name: 'setupRuflo',
297
+ message: 'Setup Ruflo orchestration?',
296
298
  default: true,
297
299
  },
298
300
  {
@@ -560,17 +562,19 @@ By: Wundr Claude Init
560
562
  return patterns.join('\n\n');
561
563
  }
562
564
 
563
- private async setupClaudeFlow(
565
+ private async setupRuflo(
564
566
  projectInfo: ProjectInfo,
565
567
  options: any
566
568
  ): Promise<void> {
567
- if (!options.setupClaudeFlow) return;
569
+ if (!options.setupRuflo) {
570
+ return;
571
+ }
568
572
 
569
- this.spinner.start('Setting up Claude Flow...');
573
+ this.spinner.start('Setting up Ruflo...');
570
574
 
571
575
  try {
572
- // Initialize Claude Flow
573
- execSync('npx claude-flow@alpha init', { stdio: 'ignore' });
576
+ // Initialize Ruflo
577
+ execSync('npx ruflo@latest init', { stdio: 'ignore' });
574
578
 
575
579
  // Configure for project
576
580
  const config = {
@@ -581,24 +585,26 @@ By: Wundr Claude Init
581
585
  : this.getDefaultAgents(projectInfo),
582
586
  memory: {
583
587
  backend: 'sqlite',
584
- path: '.claude-flow/memory.db',
588
+ path: '.ruflo/memory.db',
585
589
  },
586
590
  neural: {
587
591
  enabled: true,
588
- modelPath: '.claude-flow/models',
592
+ modelPath: '.ruflo/models',
589
593
  },
590
594
  };
591
595
 
592
- await fs.writeJson('.claude-flow/config.json', config, { spaces: 2 });
593
- this.spinner.succeed('Claude Flow configured');
596
+ await fs.writeJson('.ruflo/config.json', config, { spaces: 2 });
597
+ this.spinner.succeed('Ruflo configured');
594
598
  } catch (error) {
595
- this.spinner.fail('Failed to setup Claude Flow');
599
+ this.spinner.fail('Failed to setup Ruflo');
596
600
  console.error(chalk.red(error));
597
601
  }
598
602
  }
599
603
 
600
604
  private async setupMcpTools(mcpTools: string | string[]): Promise<void> {
601
- if (!mcpTools) return;
605
+ if (!mcpTools) {
606
+ return;
607
+ }
602
608
 
603
609
  const tools = Array.isArray(mcpTools) ? mcpTools : mcpTools.split(',');
604
610
 
@@ -702,9 +708,7 @@ echo "āœ… All quality checks passed!"
702
708
  chalk.white('3. Restart Claude Desktop to load new configurations')
703
709
  );
704
710
  console.log(
705
- chalk.white(
706
- '4. Run: npx claude-flow@alpha sparc tdd "your first feature"'
707
- )
711
+ chalk.white('4. Run: npx ruflo@latest sparc tdd "your first feature"')
708
712
  );
709
713
  console.log(chalk.cyan('\nšŸš€ Happy coding with Claude!\n'));
710
714
  }