@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.
- package/README.md +696 -280
- package/bin/wundr.js +13 -5
- package/package.json +30 -9
- package/src/ai/ai-service.ts +6 -4
- package/src/ai/claude-client.ts +6 -2
- package/src/ai/conversation-manager.ts +12 -5
- package/src/cli.ts +42 -13
- package/src/commands/ai.ts +340 -64
- package/src/commands/alignment.ts +1212 -0
- package/src/commands/analyze-optimized.ts +371 -33
- package/src/commands/analyze.ts +8 -6
- package/src/commands/batch.ts +166 -26
- package/src/commands/chat.ts +20 -10
- package/src/commands/claude-init.ts +31 -27
- package/src/commands/claude-setup.ts +761 -81
- package/src/commands/computer-setup.ts +524 -12
- package/src/commands/create-command.ts +3 -3
- package/src/commands/create.ts +9 -6
- package/src/commands/dashboard.ts +11 -6
- package/src/commands/govern.ts +11 -6
- package/src/commands/governance.ts +1005 -0
- package/src/commands/guardian.ts +887 -0
- package/src/commands/init.ts +104 -11
- package/src/commands/orchestrator.ts +789 -0
- package/src/commands/performance-optimizer.ts +15 -10
- package/src/commands/plugins.ts +8 -5
- package/src/commands/project-update.ts +1156 -0
- package/src/commands/rag.ts +1011 -0
- package/src/commands/session.ts +631 -0
- package/src/commands/setup.ts +42 -344
- package/src/commands/test-init.ts +3 -2
- package/src/commands/test.ts +3 -2
- package/src/commands/watch.ts +21 -11
- package/src/commands/worktree.ts +1057 -0
- package/src/context/context-manager.ts +5 -2
- package/src/context/session-manager.ts +18 -7
- package/src/framework/command-interface.ts +520 -0
- package/src/framework/command-registry.ts +942 -0
- package/src/framework/completion-exporter.ts +383 -0
- package/src/framework/debug-logger.ts +519 -0
- package/src/framework/error-handler.ts +867 -0
- package/src/framework/help-generator.ts +540 -0
- package/src/framework/index.ts +169 -0
- package/src/framework/interactive-repl.ts +703 -0
- package/src/framework/output-formatter.ts +834 -0
- package/src/framework/progress-manager.ts +539 -0
- package/src/index.ts +3 -2
- package/src/interactive/interactive-mode.ts +14 -7
- package/src/lib/conflict-resolution.ts +818 -0
- package/src/lib/merge-strategy.ts +550 -0
- package/src/lib/safety-mechanisms.ts +451 -0
- package/src/lib/state-detection.ts +1030 -0
- package/src/nlp/command-mapper.ts +8 -3
- package/src/nlp/command-parser.ts +5 -2
- package/src/nlp/intent-parser.ts +23 -9
- package/src/plugins/plugin-manager.ts +50 -24
- package/src/tests/computer-setup-integration.test.ts +470 -0
- package/src/types/index.ts +1 -1
- package/src/types/modules.d.ts +425 -1
- package/src/utils/backup-rollback-manager.ts +366 -0
- package/src/utils/claude-config-installer.ts +823 -0
- package/src/utils/config-manager.ts +9 -6
- package/src/utils/error-handler.ts +3 -1
- package/src/utils/logger.ts +35 -12
- package/templates/batch/ci-cd.yaml +7 -7
- package/test-suites/api/health.spec.ts +20 -23
- package/test-suites/helpers/test-config.ts +14 -13
- package/test-suites/ui/accessibility.spec.ts +27 -22
- package/test-suites/ui/smoke.spec.ts +26 -21
- package/dist/ai/ai-service.d.ts +0 -152
- package/dist/ai/ai-service.d.ts.map +0 -1
- package/dist/ai/ai-service.js +0 -430
- package/dist/ai/ai-service.js.map +0 -1
- package/dist/ai/claude-client.d.ts +0 -130
- package/dist/ai/claude-client.d.ts.map +0 -1
- package/dist/ai/claude-client.js +0 -339
- package/dist/ai/claude-client.js.map +0 -1
- package/dist/ai/conversation-manager.d.ts +0 -164
- package/dist/ai/conversation-manager.d.ts.map +0 -1
- package/dist/ai/conversation-manager.js +0 -612
- package/dist/ai/conversation-manager.js.map +0 -1
- package/dist/ai/index.d.ts +0 -5
- package/dist/ai/index.d.ts.map +0 -1
- package/dist/ai/index.js +0 -8
- package/dist/ai/index.js.map +0 -1
- package/dist/cli.d.ts +0 -36
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -173
- package/dist/cli.js.map +0 -1
- package/dist/commands/ai.d.ts +0 -89
- package/dist/commands/ai.d.ts.map +0 -1
- package/dist/commands/ai.js +0 -735
- package/dist/commands/ai.js.map +0 -1
- package/dist/commands/analyze-optimized.d.ts +0 -14
- package/dist/commands/analyze-optimized.d.ts.map +0 -1
- package/dist/commands/analyze-optimized.js +0 -437
- package/dist/commands/analyze-optimized.js.map +0 -1
- package/dist/commands/analyze.d.ts +0 -65
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js +0 -435
- package/dist/commands/analyze.js.map +0 -1
- package/dist/commands/batch.d.ts +0 -71
- package/dist/commands/batch.d.ts.map +0 -1
- package/dist/commands/batch.js +0 -738
- package/dist/commands/batch.js.map +0 -1
- package/dist/commands/chat.d.ts +0 -71
- package/dist/commands/chat.d.ts.map +0 -1
- package/dist/commands/chat.js +0 -674
- package/dist/commands/chat.js.map +0 -1
- package/dist/commands/claude-init.d.ts +0 -28
- package/dist/commands/claude-init.d.ts.map +0 -1
- package/dist/commands/claude-init.js +0 -587
- package/dist/commands/claude-init.js.map +0 -1
- package/dist/commands/claude-setup.d.ts +0 -32
- package/dist/commands/claude-setup.d.ts.map +0 -1
- package/dist/commands/claude-setup.js +0 -570
- package/dist/commands/claude-setup.js.map +0 -1
- package/dist/commands/computer-setup-commands.d.ts +0 -39
- package/dist/commands/computer-setup-commands.d.ts.map +0 -1
- package/dist/commands/computer-setup-commands.js +0 -563
- package/dist/commands/computer-setup-commands.js.map +0 -1
- package/dist/commands/computer-setup.d.ts +0 -7
- package/dist/commands/computer-setup.d.ts.map +0 -1
- package/dist/commands/computer-setup.js +0 -481
- package/dist/commands/computer-setup.js.map +0 -1
- package/dist/commands/create-command.d.ts +0 -7
- package/dist/commands/create-command.d.ts.map +0 -1
- package/dist/commands/create-command.js +0 -158
- package/dist/commands/create-command.js.map +0 -1
- package/dist/commands/create.d.ts +0 -74
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js +0 -556
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/dashboard.d.ts +0 -91
- package/dist/commands/dashboard.d.ts.map +0 -1
- package/dist/commands/dashboard.js +0 -537
- package/dist/commands/dashboard.js.map +0 -1
- package/dist/commands/govern.d.ts +0 -70
- package/dist/commands/govern.d.ts.map +0 -1
- package/dist/commands/govern.js +0 -480
- package/dist/commands/govern.js.map +0 -1
- package/dist/commands/init.d.ts +0 -55
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -584
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/performance-optimizer.d.ts +0 -30
- package/dist/commands/performance-optimizer.d.ts.map +0 -1
- package/dist/commands/performance-optimizer.js +0 -649
- package/dist/commands/performance-optimizer.js.map +0 -1
- package/dist/commands/plugins.d.ts +0 -87
- package/dist/commands/plugins.d.ts.map +0 -1
- package/dist/commands/plugins.js +0 -685
- package/dist/commands/plugins.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -29
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -399
- package/dist/commands/setup.js.map +0 -1
- package/dist/commands/test-init.d.ts +0 -9
- package/dist/commands/test-init.d.ts.map +0 -1
- package/dist/commands/test-init.js +0 -222
- package/dist/commands/test-init.js.map +0 -1
- package/dist/commands/test.d.ts +0 -25
- package/dist/commands/test.d.ts.map +0 -1
- package/dist/commands/test.js +0 -217
- package/dist/commands/test.js.map +0 -1
- package/dist/commands/watch.d.ts +0 -76
- package/dist/commands/watch.d.ts.map +0 -1
- package/dist/commands/watch.js +0 -610
- package/dist/commands/watch.js.map +0 -1
- package/dist/context/context-manager.d.ts +0 -155
- package/dist/context/context-manager.d.ts.map +0 -1
- package/dist/context/context-manager.js +0 -383
- package/dist/context/context-manager.js.map +0 -1
- package/dist/context/index.d.ts +0 -3
- package/dist/context/index.d.ts.map +0 -1
- package/dist/context/index.js +0 -6
- package/dist/context/index.js.map +0 -1
- package/dist/context/session-manager.d.ts +0 -207
- package/dist/context/session-manager.d.ts.map +0 -1
- package/dist/context/session-manager.js +0 -682
- package/dist/context/session-manager.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -51
- package/dist/index.js.map +0 -1
- package/dist/interactive/interactive-mode.d.ts +0 -76
- package/dist/interactive/interactive-mode.d.ts.map +0 -1
- package/dist/interactive/interactive-mode.js +0 -730
- package/dist/interactive/interactive-mode.js.map +0 -1
- package/dist/nlp/command-mapper.d.ts +0 -174
- package/dist/nlp/command-mapper.d.ts.map +0 -1
- package/dist/nlp/command-mapper.js +0 -623
- package/dist/nlp/command-mapper.js.map +0 -1
- package/dist/nlp/command-parser.d.ts +0 -106
- package/dist/nlp/command-parser.d.ts.map +0 -1
- package/dist/nlp/command-parser.js +0 -416
- package/dist/nlp/command-parser.js.map +0 -1
- package/dist/nlp/index.d.ts +0 -5
- package/dist/nlp/index.d.ts.map +0 -1
- package/dist/nlp/index.js +0 -8
- package/dist/nlp/index.js.map +0 -1
- package/dist/nlp/intent-classifier.d.ts +0 -59
- package/dist/nlp/intent-classifier.d.ts.map +0 -1
- package/dist/nlp/intent-classifier.js +0 -384
- package/dist/nlp/intent-classifier.js.map +0 -1
- package/dist/nlp/intent-parser.d.ts +0 -152
- package/dist/nlp/intent-parser.d.ts.map +0 -1
- package/dist/nlp/intent-parser.js +0 -739
- package/dist/nlp/intent-parser.js.map +0 -1
- package/dist/plugins/plugin-manager.d.ts +0 -120
- package/dist/plugins/plugin-manager.d.ts.map +0 -1
- package/dist/plugins/plugin-manager.js +0 -595
- package/dist/plugins/plugin-manager.js.map +0 -1
- package/dist/types/index.d.ts +0 -224
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
- package/dist/utils/config-manager.d.ts +0 -73
- package/dist/utils/config-manager.d.ts.map +0 -1
- package/dist/utils/config-manager.js +0 -339
- package/dist/utils/config-manager.js.map +0 -1
- package/dist/utils/error-handler.d.ts +0 -46
- package/dist/utils/error-handler.d.ts.map +0 -1
- package/dist/utils/error-handler.js +0 -169
- package/dist/utils/error-handler.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -25
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -94
- package/dist/utils/logger.js.map +0 -1
- package/src/commands/computer-setup-commands.ts +0 -709
package/src/commands/batch.ts
CHANGED
|
@@ -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
|
|
4
|
+
import fs from 'fs-extra';
|
|
6
5
|
import { Listr } from 'listr2';
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
import { logger } from '../utils/logger';
|
|
6
|
+
import YAML from 'yaml';
|
|
7
|
+
|
|
10
8
|
import { errorHandler } from '../utils/error-handler';
|
|
11
|
-
import {
|
|
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
|
|
577
|
-
if (
|
|
578
|
-
|
|
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
|
-
//
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
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
|
-
|
|
590
|
-
|
|
591
|
-
|
|
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
|
|
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
|
-
|
|
661
|
-
|
|
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 +=
|
|
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 +=
|
|
844
|
-
dockerfile +=
|
|
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:
|
|
1030
|
+
description: 'Imported from package.json scripts',
|
|
891
1031
|
commands,
|
|
892
1032
|
};
|
|
893
1033
|
}
|
package/src/commands/chat.ts
CHANGED
|
@@ -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
|
|
7
|
-
import
|
|
8
|
-
|
|
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 {
|
|
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
|
-
|
|
626
|
-
|
|
627
|
-
|
|
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
|
|
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
|
|
83
|
-
await this.
|
|
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
|
-
|
|
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: '
|
|
295
|
-
message: 'Setup
|
|
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
|
|
565
|
+
private async setupRuflo(
|
|
564
566
|
projectInfo: ProjectInfo,
|
|
565
567
|
options: any
|
|
566
568
|
): Promise<void> {
|
|
567
|
-
if (!options.
|
|
569
|
+
if (!options.setupRuflo) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
568
572
|
|
|
569
|
-
this.spinner.start('Setting up
|
|
573
|
+
this.spinner.start('Setting up Ruflo...');
|
|
570
574
|
|
|
571
575
|
try {
|
|
572
|
-
// Initialize
|
|
573
|
-
execSync('npx
|
|
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: '.
|
|
588
|
+
path: '.ruflo/memory.db',
|
|
585
589
|
},
|
|
586
590
|
neural: {
|
|
587
591
|
enabled: true,
|
|
588
|
-
modelPath: '.
|
|
592
|
+
modelPath: '.ruflo/models',
|
|
589
593
|
},
|
|
590
594
|
};
|
|
591
595
|
|
|
592
|
-
await fs.writeJson('.
|
|
593
|
-
this.spinner.succeed('
|
|
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
|
|
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)
|
|
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
|
}
|