@wonderwhy-er/desktop-commander 0.2.23 → 0.2.25

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 (70) hide show
  1. package/README.md +14 -55
  2. package/dist/config-manager.d.ts +5 -0
  3. package/dist/config-manager.js +9 -0
  4. package/dist/custom-stdio.d.ts +1 -0
  5. package/dist/custom-stdio.js +19 -0
  6. package/dist/handlers/filesystem-handlers.d.ts +4 -0
  7. package/dist/handlers/filesystem-handlers.js +120 -14
  8. package/dist/handlers/node-handlers.d.ts +6 -0
  9. package/dist/handlers/node-handlers.js +73 -0
  10. package/dist/index.js +5 -3
  11. package/dist/search-manager.d.ts +25 -0
  12. package/dist/search-manager.js +212 -0
  13. package/dist/server.d.ts +11 -0
  14. package/dist/server.js +188 -73
  15. package/dist/terminal-manager.d.ts +56 -2
  16. package/dist/terminal-manager.js +169 -13
  17. package/dist/tools/edit.d.ts +28 -4
  18. package/dist/tools/edit.js +87 -4
  19. package/dist/tools/filesystem.d.ts +23 -12
  20. package/dist/tools/filesystem.js +201 -416
  21. package/dist/tools/improved-process-tools.d.ts +2 -2
  22. package/dist/tools/improved-process-tools.js +244 -214
  23. package/dist/tools/mime-types.d.ts +1 -0
  24. package/dist/tools/mime-types.js +7 -0
  25. package/dist/tools/pdf/extract-images.d.ts +34 -0
  26. package/dist/tools/pdf/extract-images.js +132 -0
  27. package/dist/tools/pdf/index.d.ts +6 -0
  28. package/dist/tools/pdf/index.js +3 -0
  29. package/dist/tools/pdf/lib/pdf2md.d.ts +36 -0
  30. package/dist/tools/pdf/lib/pdf2md.js +76 -0
  31. package/dist/tools/pdf/manipulations.d.ts +13 -0
  32. package/dist/tools/pdf/manipulations.js +96 -0
  33. package/dist/tools/pdf/markdown.d.ts +7 -0
  34. package/dist/tools/pdf/markdown.js +37 -0
  35. package/dist/tools/pdf/utils.d.ts +12 -0
  36. package/dist/tools/pdf/utils.js +34 -0
  37. package/dist/tools/schemas.d.ts +167 -12
  38. package/dist/tools/schemas.js +54 -5
  39. package/dist/types.d.ts +2 -1
  40. package/dist/utils/ab-test.d.ts +8 -0
  41. package/dist/utils/ab-test.js +76 -0
  42. package/dist/utils/capture.js +5 -0
  43. package/dist/utils/feature-flags.js +7 -4
  44. package/dist/utils/files/base.d.ts +167 -0
  45. package/dist/utils/files/base.js +5 -0
  46. package/dist/utils/files/binary.d.ts +21 -0
  47. package/dist/utils/files/binary.js +65 -0
  48. package/dist/utils/files/excel.d.ts +24 -0
  49. package/dist/utils/files/excel.js +416 -0
  50. package/dist/utils/files/factory.d.ts +40 -0
  51. package/dist/utils/files/factory.js +101 -0
  52. package/dist/utils/files/image.d.ts +21 -0
  53. package/dist/utils/files/image.js +78 -0
  54. package/dist/utils/files/index.d.ts +10 -0
  55. package/dist/utils/files/index.js +13 -0
  56. package/dist/utils/files/pdf.d.ts +32 -0
  57. package/dist/utils/files/pdf.js +142 -0
  58. package/dist/utils/files/text.d.ts +63 -0
  59. package/dist/utils/files/text.js +357 -0
  60. package/dist/utils/open-browser.d.ts +9 -0
  61. package/dist/utils/open-browser.js +43 -0
  62. package/dist/utils/ripgrep-resolver.js +3 -2
  63. package/dist/utils/system-info.d.ts +5 -0
  64. package/dist/utils/system-info.js +71 -3
  65. package/dist/utils/usageTracker.js +6 -0
  66. package/dist/utils/welcome-onboarding.d.ts +9 -0
  67. package/dist/utils/welcome-onboarding.js +37 -0
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/package.json +14 -3
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Image file handler
3
+ * Handles reading image files and converting to base64
4
+ */
5
+ import fs from "fs/promises";
6
+ /**
7
+ * Image file handler implementation
8
+ * Supports: PNG, JPEG, GIF, WebP, BMP, SVG
9
+ */
10
+ export class ImageFileHandler {
11
+ canHandle(path) {
12
+ const lowerPath = path.toLowerCase();
13
+ return ImageFileHandler.IMAGE_EXTENSIONS.some(ext => lowerPath.endsWith(ext));
14
+ }
15
+ async read(path, options) {
16
+ // Images are always read in full, ignoring offset and length
17
+ const buffer = await fs.readFile(path);
18
+ const content = buffer.toString('base64');
19
+ const mimeType = this.getMimeType(path);
20
+ return {
21
+ content,
22
+ mimeType,
23
+ metadata: {
24
+ isImage: true
25
+ }
26
+ };
27
+ }
28
+ async write(path, content) {
29
+ // If content is base64 string, convert to buffer
30
+ if (typeof content === 'string') {
31
+ const buffer = Buffer.from(content, 'base64');
32
+ await fs.writeFile(path, buffer);
33
+ }
34
+ else {
35
+ await fs.writeFile(path, content);
36
+ }
37
+ }
38
+ async getInfo(path) {
39
+ const stats = await fs.stat(path);
40
+ return {
41
+ size: stats.size,
42
+ created: stats.birthtime,
43
+ modified: stats.mtime,
44
+ accessed: stats.atime,
45
+ isDirectory: stats.isDirectory(),
46
+ isFile: stats.isFile(),
47
+ permissions: stats.mode.toString(8).slice(-3),
48
+ fileType: 'image',
49
+ metadata: {
50
+ isImage: true
51
+ }
52
+ };
53
+ }
54
+ /**
55
+ * Get MIME type for image based on file extension
56
+ */
57
+ getMimeType(path) {
58
+ const lowerPath = path.toLowerCase();
59
+ for (const [ext, mimeType] of Object.entries(ImageFileHandler.IMAGE_MIME_TYPES)) {
60
+ if (lowerPath.endsWith(ext)) {
61
+ return mimeType;
62
+ }
63
+ }
64
+ return 'application/octet-stream'; // Fallback
65
+ }
66
+ }
67
+ ImageFileHandler.IMAGE_EXTENSIONS = [
68
+ '.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg'
69
+ ];
70
+ ImageFileHandler.IMAGE_MIME_TYPES = {
71
+ '.png': 'image/png',
72
+ '.jpg': 'image/jpeg',
73
+ '.jpeg': 'image/jpeg',
74
+ '.gif': 'image/gif',
75
+ '.webp': 'image/webp',
76
+ '.bmp': 'image/bmp',
77
+ '.svg': 'image/svg+xml'
78
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * File handling system
3
+ * Exports all file handlers, interfaces, and utilities
4
+ */
5
+ export * from './base.js';
6
+ export { getFileHandler, isExcelFile, isImageFile } from './factory.js';
7
+ export { TextFileHandler } from './text.js';
8
+ export { ImageFileHandler } from './image.js';
9
+ export { BinaryFileHandler } from './binary.js';
10
+ export { ExcelFileHandler } from './excel.js';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * File handling system
3
+ * Exports all file handlers, interfaces, and utilities
4
+ */
5
+ // Base interfaces and types
6
+ export * from './base.js';
7
+ // Factory function
8
+ export { getFileHandler, isExcelFile, isImageFile } from './factory.js';
9
+ // File handlers
10
+ export { TextFileHandler } from './text.js';
11
+ export { ImageFileHandler } from './image.js';
12
+ export { BinaryFileHandler } from './binary.js';
13
+ export { ExcelFileHandler } from './excel.js';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * PDF File Handler
3
+ * Implements FileHandler interface for PDF documents
4
+ */
5
+ import { FileHandler, FileResult, FileInfo, ReadOptions, EditResult } from './base.js';
6
+ /**
7
+ * File handler for PDF documents
8
+ * Extracts text and images, supports page-based pagination
9
+ */
10
+ export declare class PdfFileHandler implements FileHandler {
11
+ private readonly extensions;
12
+ /**
13
+ * Check if this handler can handle the given file
14
+ */
15
+ canHandle(path: string): boolean;
16
+ /**
17
+ * Read PDF content - extracts text as markdown with images
18
+ */
19
+ read(path: string, options?: ReadOptions): Promise<FileResult>;
20
+ /**
21
+ * Write PDF - creates from markdown or operations
22
+ */
23
+ write(path: string, content: any, mode?: 'rewrite' | 'append'): Promise<void>;
24
+ /**
25
+ * Edit PDF by range/operations
26
+ */
27
+ editRange(path: string, range: string, content: any, options?: Record<string, any>): Promise<EditResult>;
28
+ /**
29
+ * Get PDF file information
30
+ */
31
+ getInfo(path: string): Promise<FileInfo>;
32
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * PDF File Handler
3
+ * Implements FileHandler interface for PDF documents
4
+ */
5
+ import fs from 'fs/promises';
6
+ import { parsePdfToMarkdown, parseMarkdownToPdf, editPdf } from '../../tools/pdf/index.js';
7
+ /**
8
+ * File handler for PDF documents
9
+ * Extracts text and images, supports page-based pagination
10
+ */
11
+ export class PdfFileHandler {
12
+ constructor() {
13
+ this.extensions = ['.pdf'];
14
+ }
15
+ /**
16
+ * Check if this handler can handle the given file
17
+ */
18
+ canHandle(path) {
19
+ const ext = path.toLowerCase();
20
+ return this.extensions.some(e => ext.endsWith(e));
21
+ }
22
+ /**
23
+ * Read PDF content - extracts text as markdown with images
24
+ */
25
+ async read(path, options) {
26
+ const { offset = 0, length } = options ?? {};
27
+ try {
28
+ // Use existing PDF parser
29
+ // Ensure we pass a valid PageRange or number array
30
+ // If length is undefined, we assume "rest of file" which requires careful handling.
31
+ // If length is defined, we pass { offset, length }.
32
+ // If neither, we pass empty array (all pages).
33
+ // Note: offset defaults to 0 if undefined.
34
+ let range;
35
+ if (length !== undefined) {
36
+ range = { offset, length };
37
+ }
38
+ else if (offset > 0) {
39
+ // If offset provided but no length, try to read reasonable amount or all?
40
+ // PageRange requires length. Let's assume 0 means "all" or use a large number?
41
+ // Looking at pdf2md implementation, it uses generatePageNumbers(offset, length, total).
42
+ // We'll pass 0 for length to imply "rest" if supported, or just undefined length if valid.
43
+ // But typescript requires length.
44
+ range = { offset, length: 0 };
45
+ }
46
+ else {
47
+ range = [];
48
+ }
49
+ const pdfResult = await parsePdfToMarkdown(path, range);
50
+ return {
51
+ content: '', // Main content is in metadata.pages
52
+ mimeType: 'application/pdf',
53
+ metadata: {
54
+ isPdf: true,
55
+ author: pdfResult.metadata.author,
56
+ title: pdfResult.metadata.title,
57
+ totalPages: pdfResult.metadata.totalPages,
58
+ pages: pdfResult.pages
59
+ }
60
+ };
61
+ }
62
+ catch (error) {
63
+ const errorMessage = error instanceof Error ? error.message : String(error);
64
+ return {
65
+ content: `Error reading PDF: ${errorMessage}`,
66
+ mimeType: 'text/plain',
67
+ metadata: {
68
+ error: true,
69
+ errorMessage
70
+ }
71
+ };
72
+ }
73
+ }
74
+ /**
75
+ * Write PDF - creates from markdown or operations
76
+ */
77
+ async write(path, content, mode) {
78
+ // If content is string, treat as markdown to convert
79
+ if (typeof content === 'string') {
80
+ await parseMarkdownToPdf(content, path);
81
+ }
82
+ else if (Array.isArray(content)) {
83
+ // Array of operations - use editPdf
84
+ const resultBuffer = await editPdf(path, content);
85
+ await fs.writeFile(path, resultBuffer);
86
+ }
87
+ else {
88
+ throw new Error('PDF write requires markdown string or array of operations');
89
+ }
90
+ }
91
+ /**
92
+ * Edit PDF by range/operations
93
+ */
94
+ async editRange(path, range, content, options) {
95
+ try {
96
+ // For PDF, range editing isn't directly supported
97
+ // Could interpret range as page numbers in future
98
+ const resultBuffer = await editPdf(path, content);
99
+ await fs.writeFile(options?.outputPath || path, resultBuffer);
100
+ return { success: true, editsApplied: 1 };
101
+ }
102
+ catch (error) {
103
+ const errorMessage = error instanceof Error ? error.message : String(error);
104
+ return {
105
+ success: false,
106
+ editsApplied: 0,
107
+ errors: [{ location: range, error: errorMessage }]
108
+ };
109
+ }
110
+ }
111
+ /**
112
+ * Get PDF file information
113
+ */
114
+ async getInfo(path) {
115
+ const stats = await fs.stat(path);
116
+ // Get basic PDF metadata
117
+ let metadata = { isPdf: true };
118
+ try {
119
+ const pdfResult = await parsePdfToMarkdown(path, { offset: 0, length: 0 }); // Just metadata
120
+ metadata = {
121
+ isPdf: true,
122
+ title: pdfResult.metadata.title,
123
+ author: pdfResult.metadata.author,
124
+ totalPages: pdfResult.metadata.totalPages
125
+ };
126
+ }
127
+ catch {
128
+ // If we can't parse, just return basic info
129
+ }
130
+ return {
131
+ size: stats.size,
132
+ created: stats.birthtime,
133
+ modified: stats.mtime,
134
+ accessed: stats.atime,
135
+ isDirectory: false,
136
+ isFile: true,
137
+ permissions: (stats.mode & 0o777).toString(8),
138
+ fileType: 'binary',
139
+ metadata
140
+ };
141
+ }
142
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Text file handler
3
+ * Handles reading, writing, and editing text files
4
+ *
5
+ * Binary detection is handled at the factory level (factory.ts) using isBinaryFile.
6
+ * This handler only receives files that have been confirmed as text.
7
+ *
8
+ * TECHNICAL DEBT:
9
+ * This handler is missing editRange() - text search/replace logic currently lives in
10
+ * src/tools/edit.ts (performSearchReplace function) instead of here.
11
+ *
12
+ * For architectural consistency with ExcelFileHandler.editRange(), the fuzzy
13
+ * search/replace logic should be moved here. See comment in src/tools/edit.ts.
14
+ */
15
+ import { FileHandler, ReadOptions, FileResult, FileInfo } from './base.js';
16
+ /**
17
+ * Text file handler implementation
18
+ * Binary detection is done at the factory level - this handler assumes file is text
19
+ */
20
+ export declare class TextFileHandler implements FileHandler {
21
+ canHandle(_path: string): boolean;
22
+ read(filePath: string, options?: ReadOptions): Promise<FileResult>;
23
+ write(path: string, content: string, mode?: 'rewrite' | 'append'): Promise<void>;
24
+ getInfo(path: string): Promise<FileInfo>;
25
+ /**
26
+ * Count lines in text content
27
+ * Made static and public for use by other modules (e.g., writeFile telemetry in filesystem.ts)
28
+ */
29
+ static countLines(content: string): number;
30
+ /**
31
+ * Get file line count (for files under size limit)
32
+ */
33
+ private getFileLineCount;
34
+ /**
35
+ * Generate enhanced status message
36
+ */
37
+ private generateEnhancedStatusMessage;
38
+ /**
39
+ * Split text into lines while preserving line endings
40
+ * Made static and public for use by other modules (e.g., readFileInternal in filesystem.ts)
41
+ */
42
+ static splitLinesPreservingEndings(content: string): string[];
43
+ /**
44
+ * Read file with smart positioning for optimal performance
45
+ */
46
+ private readFileWithSmartPositioning;
47
+ /**
48
+ * Read last N lines efficiently by reading file backwards
49
+ */
50
+ private readLastNLinesReverse;
51
+ /**
52
+ * Read from end using readline with circular buffer
53
+ */
54
+ private readFromEndWithReadline;
55
+ /**
56
+ * Read from start/middle using readline
57
+ */
58
+ private readFromStartWithReadline;
59
+ /**
60
+ * Read from estimated byte position for very large files
61
+ */
62
+ private readFromEstimatedPosition;
63
+ }