galaxy-code 0.1.3 → 0.1.5

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 (74) hide show
  1. package/dist/app.d.ts +1 -1
  2. package/dist/app.js +5 -5
  3. package/dist/cli.js +4 -4
  4. package/dist/connections/claude.d.ts +71 -0
  5. package/dist/connections/claude.js +303 -0
  6. package/dist/connections/gemini.d.ts +40 -0
  7. package/dist/connections/gemini.js +232 -0
  8. package/dist/connections/index.d.ts +11 -0
  9. package/dist/connections/index.js +11 -0
  10. package/dist/connections/ollama.d.ts +37 -0
  11. package/dist/connections/ollama.js +73 -0
  12. package/dist/connections/types.d.ts +22 -0
  13. package/dist/connections/types.js +7 -0
  14. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.d.ts.map +1 -1
  15. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.js +18 -18
  16. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.js.map +1 -1
  17. package/dist/prompts/ba-it-analyzer.d.ts +1 -0
  18. package/dist/prompts/ba-it-analyzer.js +143 -0
  19. package/dist/prompts/index.d.ts +11 -0
  20. package/dist/prompts/index.js +11 -0
  21. package/dist/prompts/orchestrator.d.ts +8 -0
  22. package/dist/prompts/orchestrator.js +88 -0
  23. package/dist/prompts/planning-agent.d.ts +8 -0
  24. package/dist/prompts/planning-agent.js +195 -0
  25. package/dist/prompts/universal-agent.d.ts +7 -0
  26. package/dist/prompts/universal-agent.js +111 -0
  27. package/dist/providers/agent-selector.d.ts +29 -0
  28. package/dist/providers/agent-selector.js +84 -0
  29. package/dist/providers/claude-agent.d.ts +29 -0
  30. package/dist/providers/claude-agent.js +121 -0
  31. package/dist/providers/gemini-agent.d.ts +36 -0
  32. package/dist/providers/gemini-agent.js +168 -0
  33. package/dist/providers/index.d.ts +12 -0
  34. package/dist/providers/index.js +12 -0
  35. package/dist/providers/ollama-agent.d.ts +53 -0
  36. package/dist/providers/ollama-agent.js +276 -0
  37. package/dist/providers/orchestrator.d.ts +16 -0
  38. package/dist/providers/orchestrator.js +76 -0
  39. package/dist/tools/ba-it-analyzer.d.ts +66 -0
  40. package/dist/tools/ba-it-analyzer.js +90 -0
  41. package/dist/tools/code-generate-agent.d.ts +51 -0
  42. package/dist/tools/code-generate-agent.js +159 -0
  43. package/dist/tools/command-runner.d.ts +14 -0
  44. package/dist/tools/command-runner.js +120 -0
  45. package/dist/tools/document-parser.d.ts +11 -0
  46. package/dist/tools/document-parser.js +83 -0
  47. package/dist/tools/file-operations.d.ts +17 -0
  48. package/dist/tools/file-operations.js +127 -0
  49. package/dist/tools/galaxy-ui-integration.d.ts +94 -0
  50. package/dist/tools/galaxy-ui-integration.js +244 -0
  51. package/dist/tools/git-operations.d.ts +11 -0
  52. package/dist/tools/git-operations.js +114 -0
  53. package/dist/tools/index.d.ts +10 -0
  54. package/dist/tools/index.js +10 -0
  55. package/dist/tools/planning-agent.d.ts +29 -0
  56. package/dist/tools/planning-agent.js +134 -0
  57. package/dist/tools/progress-reporter.d.ts +19 -0
  58. package/dist/tools/progress-reporter.js +52 -0
  59. package/dist/tools/registry.d.ts +21 -0
  60. package/dist/tools/registry.js +695 -0
  61. package/dist/tools/tool-event-emitter.d.ts +24 -0
  62. package/dist/tools/tool-event-emitter.js +25 -0
  63. package/dist/tools/types.d.ts +31 -0
  64. package/dist/tools/types.js +1 -0
  65. package/dist/types.d.ts +1 -1
  66. package/dist/utils/config-manager.d.ts +102 -0
  67. package/dist/utils/config-manager.js +326 -0
  68. package/dist/utils/devtools.d.ts +21 -0
  69. package/dist/utils/devtools.js +61 -0
  70. package/dist/utils/message-formatters.d.ts +32 -0
  71. package/dist/utils/message-formatters.js +590 -0
  72. package/dist/utils/progress-tracker.d.ts +59 -0
  73. package/dist/utils/progress-tracker.js +213 -0
  74. package/package.json +3 -2
@@ -0,0 +1,66 @@
1
+ /**
2
+ * BA IT Analyzer - Business Analyst for IT Projects
3
+ * Analyzes user requirements and creates detailed functional specifications
4
+ * NOW WITH DEEP THINK INTEGRATION for complex technical decisions!
5
+ */
6
+ export interface ProjectRequirement {
7
+ type: 'create_project' | 'update_project';
8
+ projectName: string;
9
+ projectType: string;
10
+ description: string;
11
+ coreFeatures: Feature[];
12
+ technicalStack: TechnicalStack;
13
+ userStories: UserStory[];
14
+ dataModel: DataEntity[];
15
+ apiEndpoints?: APIEndpoint[];
16
+ estimatedComplexity: 'simple' | 'medium' | 'complex';
17
+ estimatedTime: string;
18
+ recommendations: string[];
19
+ questionsForUser: string[];
20
+ deepAnalysis?: {
21
+ question: string;
22
+ insights: string;
23
+ considerations: string[];
24
+ }[];
25
+ }
26
+ export interface Feature {
27
+ name: string;
28
+ description: string;
29
+ priority: 'must-have' | 'should-have' | 'nice-to-have';
30
+ userStory: string;
31
+ acceptanceCriteria: string[];
32
+ }
33
+ export interface TechnicalStack {
34
+ frontend?: string[];
35
+ backend?: string[];
36
+ database?: string[];
37
+ infrastructure?: string[];
38
+ thirdParty?: string[];
39
+ }
40
+ export interface UserStory {
41
+ as: string;
42
+ iWant: string;
43
+ soThat: string;
44
+ acceptanceCriteria: string[];
45
+ }
46
+ export interface DataEntity {
47
+ name: string;
48
+ description: string;
49
+ attributes: string[];
50
+ relationships: string[];
51
+ }
52
+ export interface APIEndpoint {
53
+ method: string;
54
+ path: string;
55
+ description: string;
56
+ requestBody?: string;
57
+ response: string;
58
+ }
59
+ export declare class BAITAnalyzer {
60
+ private ollama;
61
+ private model;
62
+ constructor();
63
+ private getConnection;
64
+ analyze(userRequest: string, context?: string): Promise<ProjectRequirement>;
65
+ private extractJSON;
66
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * BA IT Analyzer - Business Analyst for IT Projects
3
+ * Analyzes user requirements and creates detailed functional specifications
4
+ * NOW WITH DEEP THINK INTEGRATION for complex technical decisions!
5
+ */
6
+ import { OllamaConnection } from '../connections/ollama.js';
7
+ import { systemBAITAnalyzerPrompt } from '../prompts/ba-it-analyzer.js';
8
+ export class BAITAnalyzer {
9
+ constructor() {
10
+ Object.defineProperty(this, "ollama", {
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true,
14
+ value: null
15
+ });
16
+ Object.defineProperty(this, "model", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: 'gpt-oss:120b-cloud'
21
+ });
22
+ // Lazy initialization - only create connection when needed
23
+ }
24
+ getConnection() {
25
+ if (!this.ollama) {
26
+ this.ollama = new OllamaConnection({
27
+ model: this.model,
28
+ });
29
+ }
30
+ return this.ollama;
31
+ }
32
+ async analyze(userRequest, context) {
33
+ let userMessage = `User Request: ${userRequest}`;
34
+ if (context) {
35
+ userMessage += `\n\nAdditional Context:\n${context}`;
36
+ }
37
+ const response = await this.getConnection().generate({
38
+ prompt: userMessage,
39
+ system: systemBAITAnalyzerPrompt,
40
+ model: this.model,
41
+ });
42
+ // Extract and clean JSON from response
43
+ const jsonStr = this.extractJSON(response.response);
44
+ if (!jsonStr) {
45
+ throw new Error('Failed to extract JSON from BA analysis response');
46
+ }
47
+ const projectRequirement = JSON.parse(jsonStr);
48
+ return projectRequirement;
49
+ }
50
+ extractJSON(content) {
51
+ // Remove markdown code blocks if present
52
+ let cleanContent = content.trim();
53
+ cleanContent = cleanContent.replace(/```json\s*/g, '');
54
+ cleanContent = cleanContent.replace(/```\s*/g, '');
55
+ // Try to find JSON object with balanced braces
56
+ const startIdx = cleanContent.indexOf('{');
57
+ if (startIdx === -1)
58
+ return null;
59
+ let braceCount = 0;
60
+ let inString = false;
61
+ let escapeNext = false;
62
+ for (let i = startIdx; i < cleanContent.length; i++) {
63
+ const char = cleanContent[i];
64
+ if (escapeNext) {
65
+ escapeNext = false;
66
+ continue;
67
+ }
68
+ if (char === '\\') {
69
+ escapeNext = true;
70
+ continue;
71
+ }
72
+ if (char === '"' && !escapeNext) {
73
+ inString = !inString;
74
+ continue;
75
+ }
76
+ if (!inString) {
77
+ if (char === '{') {
78
+ braceCount++;
79
+ }
80
+ else if (char === '}') {
81
+ braceCount--;
82
+ if (braceCount === 0) {
83
+ return cleanContent.substring(startIdx, i + 1);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ }
@@ -0,0 +1,51 @@
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 type { ProjectRequirement } from './ba-it-analyzer.js';
7
+ export interface CodeGenerateInput {
8
+ step: number;
9
+ featureName: string;
10
+ featureDescription: string;
11
+ priority: string;
12
+ technicalStack: ProjectRequirement['technicalStack'];
13
+ userStories?: Array<{
14
+ as: string;
15
+ want: string;
16
+ so: string;
17
+ }>;
18
+ dataModel?: Array<{
19
+ entity: string;
20
+ attributes: any;
21
+ relationships: any;
22
+ }>;
23
+ apiEndpoints?: Array<{
24
+ path: string;
25
+ method: string;
26
+ description: string;
27
+ }>;
28
+ acceptanceCriteria?: string[];
29
+ }
30
+ export interface CodeGenerateAction {
31
+ action: 'read_file' | 'write_file' | 'run_command' | 'search_files';
32
+ path?: string;
33
+ content?: string;
34
+ command?: string;
35
+ pattern?: string;
36
+ }
37
+ export interface CodeGenerateOutput {
38
+ step: number;
39
+ featureName: string;
40
+ actions: CodeGenerateAction[];
41
+ }
42
+ export declare class CodeGenerateAgent {
43
+ private ollama;
44
+ private model;
45
+ constructor();
46
+ private getConnection;
47
+ execute(input: CodeGenerateInput): Promise<CodeGenerateOutput>;
48
+ private buildSystemPrompt;
49
+ private buildUserPrompt;
50
+ private parseActionPlan;
51
+ }
@@ -0,0 +1,159 @@
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
+ }
@@ -0,0 +1,14 @@
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
+ }
@@ -0,0 +1,120 @@
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
+ }
@@ -0,0 +1,11 @@
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
+ }
@@ -0,0 +1,83 @@
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
+ }
@@ -0,0 +1,17 @@
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
+ }