galaxy-code 0.1.6 → 0.1.7
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/cli.bundle.js +588 -0
- package/package.json +6 -6
- package/dist/app.d.ts +0 -7
- package/dist/app.js +0 -597
- package/dist/auto-updater.d.ts +0 -21
- package/dist/auto-updater.js +0 -144
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -159
- package/dist/cli.min.js +0 -589
- package/dist/connections/claude.d.ts +0 -71
- package/dist/connections/claude.js +0 -303
- package/dist/connections/gemini.d.ts +0 -40
- package/dist/connections/gemini.js +0 -232
- package/dist/connections/index.d.ts +0 -11
- package/dist/connections/index.js +0 -11
- package/dist/connections/ollama.d.ts +0 -37
- package/dist/connections/ollama.js +0 -73
- package/dist/connections/types.d.ts +0 -22
- package/dist/connections/types.js +0 -7
- package/dist/env.d.ts +0 -1
- package/dist/env.js +0 -29
- package/dist/prompts/ba-it-analyzer.d.ts +0 -1
- package/dist/prompts/ba-it-analyzer.js +0 -143
- package/dist/prompts/index.d.ts +0 -11
- package/dist/prompts/index.js +0 -11
- package/dist/prompts/orchestrator.d.ts +0 -8
- package/dist/prompts/orchestrator.js +0 -88
- package/dist/prompts/planning-agent.d.ts +0 -8
- package/dist/prompts/planning-agent.js +0 -195
- package/dist/prompts/universal-agent.d.ts +0 -7
- package/dist/prompts/universal-agent.js +0 -111
- package/dist/providers/agent-selector.d.ts +0 -29
- package/dist/providers/agent-selector.js +0 -84
- package/dist/providers/claude-agent.d.ts +0 -29
- package/dist/providers/claude-agent.js +0 -121
- package/dist/providers/gemini-agent.d.ts +0 -36
- package/dist/providers/gemini-agent.js +0 -168
- package/dist/providers/index.d.ts +0 -12
- package/dist/providers/index.js +0 -12
- package/dist/providers/ollama-agent.d.ts +0 -53
- package/dist/providers/ollama-agent.js +0 -276
- package/dist/providers/orchestrator.d.ts +0 -16
- package/dist/providers/orchestrator.js +0 -76
- package/dist/tools/ba-it-analyzer.d.ts +0 -66
- package/dist/tools/ba-it-analyzer.js +0 -90
- package/dist/tools/code-generate-agent.d.ts +0 -51
- package/dist/tools/code-generate-agent.js +0 -159
- package/dist/tools/command-runner.d.ts +0 -14
- package/dist/tools/command-runner.js +0 -120
- package/dist/tools/document-parser.d.ts +0 -11
- package/dist/tools/document-parser.js +0 -83
- package/dist/tools/file-operations.d.ts +0 -17
- package/dist/tools/file-operations.js +0 -127
- package/dist/tools/galaxy-ui-integration.d.ts +0 -94
- package/dist/tools/galaxy-ui-integration.js +0 -244
- package/dist/tools/git-operations.d.ts +0 -11
- package/dist/tools/git-operations.js +0 -114
- package/dist/tools/index.d.ts +0 -10
- package/dist/tools/index.js +0 -10
- package/dist/tools/planning-agent.d.ts +0 -29
- package/dist/tools/planning-agent.js +0 -134
- package/dist/tools/progress-reporter.d.ts +0 -19
- package/dist/tools/progress-reporter.js +0 -52
- package/dist/tools/registry.d.ts +0 -21
- package/dist/tools/registry.js +0 -695
- package/dist/tools/tool-event-emitter.d.ts +0 -24
- package/dist/tools/tool-event-emitter.js +0 -25
- package/dist/tools/types.d.ts +0 -31
- package/dist/tools/types.js +0 -1
- package/dist/types.d.ts +0 -39
- package/dist/types.js +0 -8
- package/dist/update-checker.d.ts +0 -22
- package/dist/update-checker.js +0 -85
- package/dist/utils/config-manager.d.ts +0 -102
- package/dist/utils/config-manager.js +0 -326
- package/dist/utils/devtools.d.ts +0 -21
- package/dist/utils/devtools.js +0 -61
- package/dist/utils/message-formatters.d.ts +0 -32
- package/dist/utils/message-formatters.js +0 -590
- package/dist/utils/progress-tracker.d.ts +0 -59
- package/dist/utils/progress-tracker.js +0 -213
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code Generate Agent - Planning only (no execution)
|
|
3
|
-
* Receives feature spec → Plans actions → Returns action list
|
|
4
|
-
* Orchestrator will execute the actions
|
|
5
|
-
*/
|
|
6
|
-
import { OllamaConnection } from '../connections/ollama.js';
|
|
7
|
-
export class CodeGenerateAgent {
|
|
8
|
-
constructor() {
|
|
9
|
-
Object.defineProperty(this, "ollama", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
configurable: true,
|
|
12
|
-
writable: true,
|
|
13
|
-
value: null
|
|
14
|
-
});
|
|
15
|
-
Object.defineProperty(this, "model", {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
configurable: true,
|
|
18
|
-
writable: true,
|
|
19
|
-
value: 'qwen3-coder:480b-cloud'
|
|
20
|
-
});
|
|
21
|
-
// Lazy initialization - only create connection when needed
|
|
22
|
-
}
|
|
23
|
-
getConnection() {
|
|
24
|
-
if (!this.ollama) {
|
|
25
|
-
this.ollama = new OllamaConnection({
|
|
26
|
-
model: this.model,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
return this.ollama;
|
|
30
|
-
}
|
|
31
|
-
async execute(input) {
|
|
32
|
-
try {
|
|
33
|
-
const systemPrompt = this.buildSystemPrompt();
|
|
34
|
-
const userPrompt = this.buildUserPrompt(input);
|
|
35
|
-
const response = await this.getConnection().generate({
|
|
36
|
-
prompt: userPrompt,
|
|
37
|
-
system: systemPrompt,
|
|
38
|
-
model: this.model,
|
|
39
|
-
});
|
|
40
|
-
// Parse action plan from AI
|
|
41
|
-
const actions = this.parseActionPlan(response.response);
|
|
42
|
-
return {
|
|
43
|
-
step: input.step,
|
|
44
|
-
featureName: input.featureName,
|
|
45
|
-
actions,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
// Return empty actions on error
|
|
50
|
-
return {
|
|
51
|
-
step: input.step,
|
|
52
|
-
featureName: input.featureName,
|
|
53
|
-
actions: [],
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
buildSystemPrompt() {
|
|
58
|
-
return `You are an EXPERT CODE GENERATION PLANNER.
|
|
59
|
-
|
|
60
|
-
# Your Mission:
|
|
61
|
-
Generate a detailed action plan for implementing a feature. You do NOT execute - only plan.
|
|
62
|
-
|
|
63
|
-
# Available Actions:
|
|
64
|
-
1. read_file - Read existing file for context
|
|
65
|
-
2. write_file - Create/update a file
|
|
66
|
-
3. run_command - Execute shell command
|
|
67
|
-
4. search_files - Search for pattern in files
|
|
68
|
-
|
|
69
|
-
# Planning Guidelines:
|
|
70
|
-
1. Start by reading relevant existing files
|
|
71
|
-
2. Plan all necessary file writes (components, APIs, types, tests, etc.)
|
|
72
|
-
3. Include dependency installations if needed
|
|
73
|
-
4. Be thorough - include ALL files needed
|
|
74
|
-
|
|
75
|
-
# Code Quality Requirements:
|
|
76
|
-
- Production-ready, no TODOs or placeholders
|
|
77
|
-
- Full file content, not snippets
|
|
78
|
-
- Proper imports and exports
|
|
79
|
-
- Type safety (TypeScript)
|
|
80
|
-
- Error handling
|
|
81
|
-
- Comments for complex logic
|
|
82
|
-
- Follow framework best practices
|
|
83
|
-
|
|
84
|
-
# Output Format (VALID JSON ARRAY):
|
|
85
|
-
[
|
|
86
|
-
{"action": "read_file", "path": "package.json"},
|
|
87
|
-
{"action": "write_file", "path": "components/Feature.tsx", "content": "full content here"},
|
|
88
|
-
{"action": "write_file", "path": "api/feature.ts", "content": "full content here"},
|
|
89
|
-
{"action": "run_command", "command": "npm install new-package"}
|
|
90
|
-
]
|
|
91
|
-
|
|
92
|
-
CRITICAL:
|
|
93
|
-
- Output ONLY the JSON array, nothing else. Start with [ and end with ]
|
|
94
|
-
- Include full file content in "content" field, not placeholders`;
|
|
95
|
-
}
|
|
96
|
-
buildUserPrompt(input) {
|
|
97
|
-
let prompt = `# Feature Implementation Plan Request
|
|
98
|
-
|
|
99
|
-
**Feature**: ${input.featureName}
|
|
100
|
-
**Description**: ${input.featureDescription}
|
|
101
|
-
**Priority**: ${input.priority}
|
|
102
|
-
|
|
103
|
-
## Technical Stack:
|
|
104
|
-
${JSON.stringify(input.technicalStack, null, 2)}
|
|
105
|
-
`;
|
|
106
|
-
if (input.userStories && input.userStories.length > 0) {
|
|
107
|
-
prompt += `\n## User Stories:\n`;
|
|
108
|
-
input.userStories.forEach(story => {
|
|
109
|
-
prompt += `- As ${story.as}, I want ${story.want}, so that ${story.so}\n`;
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
if (input.dataModel && input.dataModel.length > 0) {
|
|
113
|
-
prompt += `\n## Data Model:\n${JSON.stringify(input.dataModel, null, 2)}\n`;
|
|
114
|
-
}
|
|
115
|
-
if (input.apiEndpoints && input.apiEndpoints.length > 0) {
|
|
116
|
-
prompt += `\n## API Endpoints:\n`;
|
|
117
|
-
input.apiEndpoints.forEach(endpoint => {
|
|
118
|
-
prompt += `- ${endpoint.method} ${endpoint.path}: ${endpoint.description}\n`;
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
if (input.acceptanceCriteria && input.acceptanceCriteria.length > 0) {
|
|
122
|
-
prompt += `\n## Acceptance Criteria:\n`;
|
|
123
|
-
input.acceptanceCriteria.forEach((criteria, i) => {
|
|
124
|
-
prompt += `${i + 1}. ${criteria}\n`;
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
prompt += `\n## Working Directory: ${process.cwd()}
|
|
128
|
-
|
|
129
|
-
Generate the action plan as JSON array to implement this feature completely.`;
|
|
130
|
-
return prompt;
|
|
131
|
-
}
|
|
132
|
-
parseActionPlan(content) {
|
|
133
|
-
// Clean response
|
|
134
|
-
let cleanContent = content.trim();
|
|
135
|
-
// Remove markdown code blocks
|
|
136
|
-
cleanContent = cleanContent.replace(/```json\s*/g, '');
|
|
137
|
-
cleanContent = cleanContent.replace(/```\s*/g, '');
|
|
138
|
-
// Find JSON array
|
|
139
|
-
const startIdx = cleanContent.indexOf('[');
|
|
140
|
-
const endIdx = cleanContent.lastIndexOf(']');
|
|
141
|
-
if (startIdx === -1 || endIdx === -1) {
|
|
142
|
-
console.warn('Invalid action plan format - no JSON array found');
|
|
143
|
-
return [];
|
|
144
|
-
}
|
|
145
|
-
const jsonStr = cleanContent.substring(startIdx, endIdx + 1);
|
|
146
|
-
try {
|
|
147
|
-
const actions = JSON.parse(jsonStr);
|
|
148
|
-
// Filter to only valid action types
|
|
149
|
-
return actions.filter((action) => action.action === 'read_file' ||
|
|
150
|
-
action.action === 'write_file' ||
|
|
151
|
-
action.action === 'run_command' ||
|
|
152
|
-
action.action === 'search_files');
|
|
153
|
-
}
|
|
154
|
-
catch (error) {
|
|
155
|
-
console.warn(`Failed to parse action plan: ${error}`);
|
|
156
|
-
return [];
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export interface CommandResult {
|
|
2
|
-
stdout: string;
|
|
3
|
-
stderr: string;
|
|
4
|
-
exitCode: number;
|
|
5
|
-
command?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare class CommandRunner {
|
|
8
|
-
runCommand(command: string, cwd: string, timeout?: number): Promise<CommandResult>;
|
|
9
|
-
detectTestCommand(cwd: string): Promise<string | null>;
|
|
10
|
-
detectDevCommand(cwd: string): Promise<string | null>;
|
|
11
|
-
detectBuildCommand(cwd: string): Promise<string | null>;
|
|
12
|
-
private detectPackageManager;
|
|
13
|
-
installDependencies(cwd: string): Promise<CommandResult>;
|
|
14
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { exec } from 'child_process';
|
|
2
|
-
import { promisify } from 'util';
|
|
3
|
-
import fs from 'fs/promises';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
const execAsync = promisify(exec);
|
|
6
|
-
export class CommandRunner {
|
|
7
|
-
async runCommand(command, cwd, timeout = 180000) {
|
|
8
|
-
try {
|
|
9
|
-
const { stdout, stderr } = await execAsync(command, {
|
|
10
|
-
cwd,
|
|
11
|
-
timeout, // Increased to 3 minutes for project creation
|
|
12
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
13
|
-
});
|
|
14
|
-
return {
|
|
15
|
-
stdout,
|
|
16
|
-
stderr,
|
|
17
|
-
exitCode: 0,
|
|
18
|
-
command,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
return {
|
|
23
|
-
stdout: error.stdout || '',
|
|
24
|
-
stderr: error.stderr || error.message,
|
|
25
|
-
exitCode: error.code || 1,
|
|
26
|
-
command,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async detectTestCommand(cwd) {
|
|
31
|
-
try {
|
|
32
|
-
const pkgJsonPath = path.join(cwd, 'package.json');
|
|
33
|
-
const content = await fs.readFile(pkgJsonPath, 'utf-8');
|
|
34
|
-
const pkgJson = JSON.parse(content);
|
|
35
|
-
if (pkgJson.scripts?.test) {
|
|
36
|
-
return pkgJson.scripts.test;
|
|
37
|
-
}
|
|
38
|
-
const packageManager = await this.detectPackageManager(cwd);
|
|
39
|
-
if (packageManager === 'bun')
|
|
40
|
-
return 'bun test';
|
|
41
|
-
if (packageManager === 'pnpm')
|
|
42
|
-
return 'pnpm test';
|
|
43
|
-
if (packageManager === 'yarn')
|
|
44
|
-
return 'yarn test';
|
|
45
|
-
return 'npm test';
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
async detectDevCommand(cwd) {
|
|
52
|
-
try {
|
|
53
|
-
const pkgJsonPath = path.join(cwd, 'package.json');
|
|
54
|
-
const content = await fs.readFile(pkgJsonPath, 'utf-8');
|
|
55
|
-
const pkgJson = JSON.parse(content);
|
|
56
|
-
if (pkgJson.scripts?.dev)
|
|
57
|
-
return pkgJson.scripts.dev;
|
|
58
|
-
if (pkgJson.scripts?.start)
|
|
59
|
-
return pkgJson.scripts.start;
|
|
60
|
-
const packageManager = await this.detectPackageManager(cwd);
|
|
61
|
-
if (packageManager === 'bun')
|
|
62
|
-
return 'bun run dev';
|
|
63
|
-
if (packageManager === 'pnpm')
|
|
64
|
-
return 'pnpm dev';
|
|
65
|
-
if (packageManager === 'yarn')
|
|
66
|
-
return 'yarn dev';
|
|
67
|
-
return 'npm run dev';
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async detectBuildCommand(cwd) {
|
|
74
|
-
try {
|
|
75
|
-
const pkgJsonPath = path.join(cwd, 'package.json');
|
|
76
|
-
const content = await fs.readFile(pkgJsonPath, 'utf-8');
|
|
77
|
-
const pkgJson = JSON.parse(content);
|
|
78
|
-
if (pkgJson.scripts?.build) {
|
|
79
|
-
const packageManager = await this.detectPackageManager(cwd);
|
|
80
|
-
if (packageManager === 'bun')
|
|
81
|
-
return 'bun run build';
|
|
82
|
-
if (packageManager === 'pnpm')
|
|
83
|
-
return 'pnpm build';
|
|
84
|
-
if (packageManager === 'yarn')
|
|
85
|
-
return 'yarn build';
|
|
86
|
-
return 'npm run build';
|
|
87
|
-
}
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
async detectPackageManager(cwd) {
|
|
95
|
-
try {
|
|
96
|
-
const files = await fs.readdir(cwd);
|
|
97
|
-
if (files.includes('bun.lockb'))
|
|
98
|
-
return 'bun';
|
|
99
|
-
if (files.includes('pnpm-lock.yaml'))
|
|
100
|
-
return 'pnpm';
|
|
101
|
-
if (files.includes('yarn.lock'))
|
|
102
|
-
return 'yarn';
|
|
103
|
-
return 'npm';
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
return 'bun'; // Default to bun instead of npm
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
async installDependencies(cwd) {
|
|
110
|
-
const packageManager = await this.detectPackageManager(cwd);
|
|
111
|
-
const installCmd = packageManager === 'npm'
|
|
112
|
-
? 'npm install'
|
|
113
|
-
: packageManager === 'yarn'
|
|
114
|
-
? 'yarn install'
|
|
115
|
-
: packageManager === 'pnpm'
|
|
116
|
-
? 'pnpm install'
|
|
117
|
-
: 'bun install';
|
|
118
|
-
return this.runCommand(installCmd, cwd, 180000); // 3 minutes timeout
|
|
119
|
-
}
|
|
120
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare class DocumentParser {
|
|
2
|
-
parseDocument(filePath: string, type: 'docx' | 'xlsx' | 'pdf'): Promise<string>;
|
|
3
|
-
private parsePDF;
|
|
4
|
-
private parseDOCX;
|
|
5
|
-
private parseXLSX;
|
|
6
|
-
checkDependencies(): Promise<{
|
|
7
|
-
pdf: boolean;
|
|
8
|
-
docx: boolean;
|
|
9
|
-
xlsx: boolean;
|
|
10
|
-
}>;
|
|
11
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { exec } from 'child_process';
|
|
2
|
-
import { promisify } from 'util';
|
|
3
|
-
const execAsync = promisify(exec);
|
|
4
|
-
export class DocumentParser {
|
|
5
|
-
async parseDocument(filePath, type) {
|
|
6
|
-
try {
|
|
7
|
-
switch (type) {
|
|
8
|
-
case 'pdf':
|
|
9
|
-
return await this.parsePDF(filePath);
|
|
10
|
-
case 'docx':
|
|
11
|
-
return await this.parseDOCX(filePath);
|
|
12
|
-
case 'xlsx':
|
|
13
|
-
return await this.parseXLSX(filePath);
|
|
14
|
-
default:
|
|
15
|
-
throw new Error(`Unsupported document type: ${type}`);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
return `Failed to parse document: ${error.message}`;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
async parsePDF(filePath) {
|
|
23
|
-
try {
|
|
24
|
-
const { stdout } = await execAsync(`pdftotext "${filePath}" -`, {
|
|
25
|
-
timeout: 30000,
|
|
26
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
27
|
-
});
|
|
28
|
-
return stdout || 'No text content found in PDF';
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
if (error.message.includes('command not found')) {
|
|
32
|
-
return 'PDF parsing requires pdftotext (install: apt-get install poppler-utils)';
|
|
33
|
-
}
|
|
34
|
-
throw error;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
async parseDOCX(filePath) {
|
|
38
|
-
try {
|
|
39
|
-
const { stdout } = await execAsync(`pandoc "${filePath}" -t plain`, {
|
|
40
|
-
timeout: 30000,
|
|
41
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
42
|
-
});
|
|
43
|
-
return stdout || 'No text content found in DOCX';
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
if (error.message.includes('command not found')) {
|
|
47
|
-
return 'DOCX parsing requires pandoc (install: apt-get install pandoc)';
|
|
48
|
-
}
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
async parseXLSX(filePath) {
|
|
53
|
-
try {
|
|
54
|
-
const { stdout } = await execAsync(`ssconvert "${filePath}" fd://1`, {
|
|
55
|
-
timeout: 30000,
|
|
56
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
57
|
-
});
|
|
58
|
-
return stdout || 'No content found in XLSX';
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
if (error.message.includes('command not found')) {
|
|
62
|
-
return 'XLSX parsing requires ssconvert (install: apt-get install gnumeric)';
|
|
63
|
-
}
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
async checkDependencies() {
|
|
68
|
-
const checkCommand = async (cmd) => {
|
|
69
|
-
try {
|
|
70
|
-
await execAsync(`which ${cmd}`, { timeout: 1000 });
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
return {
|
|
78
|
-
pdf: await checkCommand('pdftotext'),
|
|
79
|
-
docx: await checkCommand('pandoc'),
|
|
80
|
-
xlsx: await checkCommand('ssconvert'),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export interface FileWriteResult {
|
|
2
|
-
isNewFile: boolean;
|
|
3
|
-
oldContent?: string;
|
|
4
|
-
newContent: string;
|
|
5
|
-
linesAdded: number;
|
|
6
|
-
linesRemoved: number;
|
|
7
|
-
path: string;
|
|
8
|
-
}
|
|
9
|
-
export declare class FileOperations {
|
|
10
|
-
readFile(filePath: string): Promise<string>;
|
|
11
|
-
writeFile(filePath: string, content: string): Promise<FileWriteResult>;
|
|
12
|
-
listFiles(dirPath: string, recursive?: boolean): Promise<string[]>;
|
|
13
|
-
searchFiles(dirPath: string, pattern: string): Promise<string[]>;
|
|
14
|
-
getFileDiff(filePath: string): Promise<string>;
|
|
15
|
-
applyPatch(filePath: string, patch: string): Promise<void>;
|
|
16
|
-
getFileTree(dirPath: string): Promise<string>;
|
|
17
|
-
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { exec } from 'child_process';
|
|
4
|
-
import { promisify } from 'util';
|
|
5
|
-
const execAsync = promisify(exec);
|
|
6
|
-
export class FileOperations {
|
|
7
|
-
async readFile(filePath) {
|
|
8
|
-
try {
|
|
9
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
10
|
-
return content;
|
|
11
|
-
}
|
|
12
|
-
catch (error) {
|
|
13
|
-
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
async writeFile(filePath, content) {
|
|
17
|
-
try {
|
|
18
|
-
// Check if file exists and read old content
|
|
19
|
-
let isNewFile = false;
|
|
20
|
-
let oldContent;
|
|
21
|
-
try {
|
|
22
|
-
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
23
|
-
oldContent = fileContent;
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
isNewFile = true;
|
|
27
|
-
}
|
|
28
|
-
// Create directory if needed
|
|
29
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
30
|
-
// Write new content
|
|
31
|
-
await fs.writeFile(filePath, content, 'utf-8');
|
|
32
|
-
// Calculate diff stats
|
|
33
|
-
const newLines = content.split('\n');
|
|
34
|
-
const oldLines = oldContent ? oldContent.split('\n') : [];
|
|
35
|
-
let linesAdded = 0;
|
|
36
|
-
let linesRemoved = 0;
|
|
37
|
-
if (isNewFile) {
|
|
38
|
-
linesAdded = newLines.length;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
// Simple line-based diff calculation
|
|
42
|
-
// Count removed lines (in old but not in new)
|
|
43
|
-
linesRemoved = oldLines.length;
|
|
44
|
-
linesAdded = newLines.length;
|
|
45
|
-
// Better approach: use set intersection
|
|
46
|
-
const oldSet = new Set(oldLines);
|
|
47
|
-
const newSet = new Set(newLines);
|
|
48
|
-
// Lines only in old = removed
|
|
49
|
-
const onlyInOld = oldLines.filter(line => !newSet.has(line));
|
|
50
|
-
// Lines only in new = added
|
|
51
|
-
const onlyInNew = newLines.filter(line => !oldSet.has(line));
|
|
52
|
-
linesRemoved = onlyInOld.length;
|
|
53
|
-
linesAdded = onlyInNew.length;
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
isNewFile,
|
|
57
|
-
oldContent,
|
|
58
|
-
newContent: content,
|
|
59
|
-
linesAdded,
|
|
60
|
-
linesRemoved,
|
|
61
|
-
path: filePath,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
throw new Error(`Failed to write file ${filePath}: ${error.message}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
async listFiles(dirPath, recursive = false) {
|
|
69
|
-
try {
|
|
70
|
-
if (recursive) {
|
|
71
|
-
const { stdout } = await execAsync(`find "${dirPath}" -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/build/*" | head -500`, { timeout: 10000 });
|
|
72
|
-
return stdout.trim().split('\n').filter(Boolean);
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
76
|
-
return entries
|
|
77
|
-
.filter(entry => entry.isFile())
|
|
78
|
-
.map(entry => path.join(dirPath, entry.name));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
throw new Error(`Failed to list files in ${dirPath}: ${error.message}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
async searchFiles(dirPath, pattern) {
|
|
86
|
-
try {
|
|
87
|
-
const { stdout } = await execAsync(`grep -r "${pattern}" "${dirPath}" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.json" --exclude-dir="node_modules" --exclude-dir=".git" --exclude-dir="dist" -l | head -100`, { timeout: 10000 });
|
|
88
|
-
return stdout.trim().split('\n').filter(Boolean);
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
return [];
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
async getFileDiff(filePath) {
|
|
95
|
-
try {
|
|
96
|
-
const { stdout } = await execAsync(`git diff "${filePath}"`, {
|
|
97
|
-
timeout: 5000,
|
|
98
|
-
});
|
|
99
|
-
return stdout || 'No changes';
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
return `Not a git repository or file doesn't exist: ${error.message}`;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
async applyPatch(filePath, patch) {
|
|
106
|
-
try {
|
|
107
|
-
const tempPatchFile = path.join('/tmp', `patch-${Date.now()}.patch`);
|
|
108
|
-
await fs.writeFile(tempPatchFile, patch);
|
|
109
|
-
await execAsync(`patch "${filePath}" < "${tempPatchFile}"`, {
|
|
110
|
-
timeout: 5000,
|
|
111
|
-
});
|
|
112
|
-
await fs.unlink(tempPatchFile);
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
throw new Error(`Failed to apply patch: ${error.message}`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
async getFileTree(dirPath) {
|
|
119
|
-
try {
|
|
120
|
-
const { stdout } = await execAsync(`tree -L 3 -I "node_modules|.git|dist|build|.venv|venv|ios|android|.expo" -a --charset ascii "${dirPath}" 2>/dev/null || find "${dirPath}" -maxdepth 3 -not -path "*/node_modules/*" -not -path "*/.git/*" | head -500`, { timeout: 20000 });
|
|
121
|
-
return stdout;
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
return `Failed to generate file tree: ${error.message}`;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool 1: List all components
|
|
3
|
-
* Fetches from GitHub registry.json
|
|
4
|
-
*/
|
|
5
|
-
export declare function galaxyUIListComponents(params?: {
|
|
6
|
-
category?: 'form' | 'layout' | 'navigation' | 'interactive' | 'overlay' | 'data-display' | 'utility' | 'all';
|
|
7
|
-
}): Promise<{
|
|
8
|
-
total: number;
|
|
9
|
-
components: Array<{
|
|
10
|
-
name: string;
|
|
11
|
-
description: string;
|
|
12
|
-
category: string;
|
|
13
|
-
docsUrl: string;
|
|
14
|
-
}>;
|
|
15
|
-
}>;
|
|
16
|
-
/**
|
|
17
|
-
* Tool 2: Search components by keyword
|
|
18
|
-
* Searches in component name and description
|
|
19
|
-
*/
|
|
20
|
-
export declare function galaxyUISearchComponents(params: {
|
|
21
|
-
query: string;
|
|
22
|
-
}): Promise<{
|
|
23
|
-
total: number;
|
|
24
|
-
components: Array<{
|
|
25
|
-
name: string;
|
|
26
|
-
description: string;
|
|
27
|
-
category: string;
|
|
28
|
-
docsUrl: string;
|
|
29
|
-
relevance: 'high' | 'medium' | 'low';
|
|
30
|
-
}>;
|
|
31
|
-
}>;
|
|
32
|
-
/**
|
|
33
|
-
* Tool 3: Get component details
|
|
34
|
-
* Returns component info from registry + docs URL
|
|
35
|
-
*/
|
|
36
|
-
export declare function galaxyUIGetComponent(params: {
|
|
37
|
-
name: string;
|
|
38
|
-
framework?: 'vue' | 'react' | 'angular';
|
|
39
|
-
}): Promise<{
|
|
40
|
-
name: string;
|
|
41
|
-
description: string;
|
|
42
|
-
category: string;
|
|
43
|
-
dependencies: string[];
|
|
44
|
-
peerDependencies: string[];
|
|
45
|
-
docsUrl: string;
|
|
46
|
-
docsUrlFramework?: string;
|
|
47
|
-
installCommand: string;
|
|
48
|
-
}>;
|
|
49
|
-
/**
|
|
50
|
-
* Tool 4: Get component categories with counts
|
|
51
|
-
* Groups components by category from registry
|
|
52
|
-
*/
|
|
53
|
-
export declare function galaxyUIGetCategories(): Promise<{
|
|
54
|
-
categories: Array<{
|
|
55
|
-
name: string;
|
|
56
|
-
count: number;
|
|
57
|
-
components: string[];
|
|
58
|
-
}>;
|
|
59
|
-
}>;
|
|
60
|
-
/**
|
|
61
|
-
* Tool 5: Add components to project
|
|
62
|
-
* Executes: npx galaxy-design add [components...] --cwd [path]
|
|
63
|
-
*/
|
|
64
|
-
export declare function galaxyUIAddComponents(params: {
|
|
65
|
-
components: string[];
|
|
66
|
-
cwd?: string;
|
|
67
|
-
}): Promise<{
|
|
68
|
-
success: boolean;
|
|
69
|
-
message: string;
|
|
70
|
-
output: string;
|
|
71
|
-
}>;
|
|
72
|
-
/**
|
|
73
|
-
* Tool 6: Initialize Galaxy UI in project
|
|
74
|
-
* Executes: npx galaxy-design@latest init --yes --cwd [path]
|
|
75
|
-
*/
|
|
76
|
-
export declare function galaxyUIInit(params?: {
|
|
77
|
-
cwd?: string;
|
|
78
|
-
skipPrompts?: boolean;
|
|
79
|
-
}): Promise<{
|
|
80
|
-
success: boolean;
|
|
81
|
-
message: string;
|
|
82
|
-
output: string;
|
|
83
|
-
}>;
|
|
84
|
-
/**
|
|
85
|
-
* Tool 7: Get documentation URL
|
|
86
|
-
* Returns direct link to component docs or main docs
|
|
87
|
-
*/
|
|
88
|
-
export declare function galaxyUIGetDocsUrl(params?: {
|
|
89
|
-
component?: string;
|
|
90
|
-
language?: 'en' | 'vi';
|
|
91
|
-
}): {
|
|
92
|
-
url: string;
|
|
93
|
-
description: string;
|
|
94
|
-
};
|