indusagi-coding-agent 0.1.23 → 0.1.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 (236) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +2 -0
  3. package/dist/cli/args.d.ts +117 -1
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +221 -52
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/config-selector.d.ts +58 -2
  8. package/dist/cli/config-selector.d.ts.map +1 -1
  9. package/dist/cli/config-selector.js +130 -12
  10. package/dist/cli/config-selector.js.map +1 -1
  11. package/dist/cli/file-processor.d.ts +70 -2
  12. package/dist/cli/file-processor.d.ts.map +1 -1
  13. package/dist/cli/file-processor.js +240 -15
  14. package/dist/cli/file-processor.js.map +1 -1
  15. package/dist/cli/list-models.d.ts +63 -3
  16. package/dist/cli/list-models.d.ts.map +1 -1
  17. package/dist/cli/list-models.js +202 -27
  18. package/dist/cli/list-models.js.map +1 -1
  19. package/dist/cli/login-handler.d.ts +82 -8
  20. package/dist/cli/login-handler.d.ts.map +1 -1
  21. package/dist/cli/login-handler.js +410 -77
  22. package/dist/cli/login-handler.js.map +1 -1
  23. package/dist/cli/session-picker.d.ts +74 -2
  24. package/dist/cli/session-picker.d.ts.map +1 -1
  25. package/dist/cli/session-picker.js +236 -12
  26. package/dist/cli/session-picker.js.map +1 -1
  27. package/dist/core/agent-session.d.ts +214 -9
  28. package/dist/core/agent-session.d.ts.map +1 -1
  29. package/dist/core/agent-session.js +214 -9
  30. package/dist/core/agent-session.js.map +1 -1
  31. package/dist/core/bash-executor.d.ts +302 -12
  32. package/dist/core/bash-executor.d.ts.map +1 -1
  33. package/dist/core/bash-executor.js +302 -12
  34. package/dist/core/bash-executor.js.map +1 -1
  35. package/dist/core/diagnostics.d.ts +191 -0
  36. package/dist/core/diagnostics.d.ts.map +1 -1
  37. package/dist/core/diagnostics.js +142 -0
  38. package/dist/core/diagnostics.js.map +1 -1
  39. package/dist/core/discover-packages.d.ts +6 -0
  40. package/dist/core/discover-packages.d.ts.map +1 -0
  41. package/dist/core/discover-packages.js +62 -0
  42. package/dist/core/discover-packages.js.map +1 -0
  43. package/dist/core/event-bus.d.ts +146 -0
  44. package/dist/core/event-bus.d.ts.map +1 -1
  45. package/dist/core/event-bus.js +93 -0
  46. package/dist/core/event-bus.js.map +1 -1
  47. package/dist/core/export-html/ansi-to-html.d.ts +4 -0
  48. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  49. package/dist/core/export-html/ansi-to-html.js +4 -0
  50. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  51. package/dist/core/export-html/index.d.ts +128 -0
  52. package/dist/core/export-html/index.d.ts.map +1 -1
  53. package/dist/core/export-html/index.js +128 -0
  54. package/dist/core/export-html/index.js.map +1 -1
  55. package/dist/core/export-html/tool-renderer.d.ts +4 -0
  56. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  57. package/dist/core/export-html/tool-renderer.js +4 -0
  58. package/dist/core/export-html/tool-renderer.js.map +1 -1
  59. package/dist/core/keybindings.d.ts +142 -0
  60. package/dist/core/keybindings.d.ts.map +1 -1
  61. package/dist/core/keybindings.js +142 -0
  62. package/dist/core/keybindings.js.map +1 -1
  63. package/dist/core/model-registry.d.ts +98 -1
  64. package/dist/core/model-registry.d.ts.map +1 -1
  65. package/dist/core/model-registry.js +98 -1
  66. package/dist/core/model-registry.js.map +1 -1
  67. package/dist/core/model-resolver.d.ts +99 -1
  68. package/dist/core/model-resolver.d.ts.map +1 -1
  69. package/dist/core/model-resolver.js +99 -1
  70. package/dist/core/model-resolver.js.map +1 -1
  71. package/dist/core/prompt-templates.js.map +1 -1
  72. package/dist/core/sdk.d.ts.map +1 -1
  73. package/dist/core/sdk.js +2 -0
  74. package/dist/core/sdk.js.map +1 -1
  75. package/dist/core/session-manager.d.ts +127 -0
  76. package/dist/core/session-manager.d.ts.map +1 -1
  77. package/dist/core/session-manager.js +125 -0
  78. package/dist/core/session-manager.js.map +1 -1
  79. package/dist/core/skills.js.map +1 -1
  80. package/dist/core/subagents.js.map +1 -1
  81. package/dist/core/tools/bash.d.ts +391 -11
  82. package/dist/core/tools/bash.d.ts.map +1 -1
  83. package/dist/core/tools/bash.js +269 -2
  84. package/dist/core/tools/bash.js.map +1 -1
  85. package/dist/core/tools/bg-process.d.ts +49 -0
  86. package/dist/core/tools/bg-process.d.ts.map +1 -0
  87. package/dist/core/tools/bg-process.js +69 -0
  88. package/dist/core/tools/bg-process.js.map +1 -0
  89. package/dist/core/tools/edit.d.ts +284 -6
  90. package/dist/core/tools/edit.d.ts.map +1 -1
  91. package/dist/core/tools/edit.js +238 -0
  92. package/dist/core/tools/edit.js.map +1 -1
  93. package/dist/core/tools/find.d.ts +169 -5
  94. package/dist/core/tools/find.d.ts.map +1 -1
  95. package/dist/core/tools/find.js +136 -0
  96. package/dist/core/tools/find.js.map +1 -1
  97. package/dist/core/tools/grep.d.ts +285 -5
  98. package/dist/core/tools/grep.d.ts.map +1 -1
  99. package/dist/core/tools/grep.js +247 -0
  100. package/dist/core/tools/grep.js.map +1 -1
  101. package/dist/core/tools/index.d.ts +45 -0
  102. package/dist/core/tools/index.d.ts.map +1 -1
  103. package/dist/core/tools/index.js +15 -0
  104. package/dist/core/tools/index.js.map +1 -1
  105. package/dist/core/tools/ls.d.ts +6 -0
  106. package/dist/core/tools/ls.d.ts.map +1 -1
  107. package/dist/core/tools/ls.js +6 -0
  108. package/dist/core/tools/ls.js.map +1 -1
  109. package/dist/core/tools/read.d.ts +308 -7
  110. package/dist/core/tools/read.d.ts.map +1 -1
  111. package/dist/core/tools/read.js +231 -0
  112. package/dist/core/tools/read.js.map +1 -1
  113. package/dist/core/tools/registry.d.ts +17 -0
  114. package/dist/core/tools/registry.d.ts.map +1 -0
  115. package/dist/core/tools/registry.js +108 -0
  116. package/dist/core/tools/registry.js.map +1 -0
  117. package/dist/core/tools/webfetch.d.ts +118 -3
  118. package/dist/core/tools/webfetch.d.ts.map +1 -1
  119. package/dist/core/tools/webfetch.js +118 -3
  120. package/dist/core/tools/webfetch.js.map +1 -1
  121. package/dist/core/tools/websearch.d.ts +130 -3
  122. package/dist/core/tools/websearch.d.ts.map +1 -1
  123. package/dist/core/tools/websearch.js +130 -3
  124. package/dist/core/tools/websearch.js.map +1 -1
  125. package/dist/core/tools/write.d.ts +251 -5
  126. package/dist/core/tools/write.d.ts.map +1 -1
  127. package/dist/core/tools/write.js +210 -0
  128. package/dist/core/tools/write.js.map +1 -1
  129. package/dist/main.d.ts.map +1 -1
  130. package/dist/main.js +12 -1
  131. package/dist/main.js.map +1 -1
  132. package/dist/modes/interactive/components/assistant-message.d.ts +164 -1
  133. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  134. package/dist/modes/interactive/components/assistant-message.js +164 -1
  135. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  136. package/dist/modes/interactive/components/bash-execution.d.ts +297 -1
  137. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  138. package/dist/modes/interactive/components/bash-execution.js +297 -1
  139. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  140. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  141. package/dist/modes/interactive/components/tool-execution.js +251 -1
  142. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  143. package/dist/modes/interactive/components/user-message.d.ts +186 -1
  144. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  145. package/dist/modes/interactive/components/user-message.js +186 -1
  146. package/dist/modes/interactive/components/user-message.js.map +1 -1
  147. package/dist/modes/interactive/interactive-mode.d.ts +1567 -13
  148. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  149. package/dist/modes/interactive/interactive-mode.js +1567 -13
  150. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  151. package/dist/modes/interactive/theme/theme.d.ts +422 -0
  152. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  153. package/dist/modes/interactive/theme/theme.js +422 -0
  154. package/dist/modes/interactive/theme/theme.js.map +1 -1
  155. package/dist/modes/print-mode.d.ts +538 -5
  156. package/dist/modes/print-mode.d.ts.map +1 -1
  157. package/dist/modes/print-mode.js +538 -5
  158. package/dist/modes/print-mode.js.map +1 -1
  159. package/dist/modes/rpc/rpc-client.d.ts +921 -8
  160. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  161. package/dist/modes/rpc/rpc-client.js +921 -8
  162. package/dist/modes/rpc/rpc-client.js.map +1 -1
  163. package/dist/modes/rpc/rpc-mode.d.ts +802 -9
  164. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  165. package/dist/modes/rpc/rpc-mode.js +802 -9
  166. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  167. package/dist/modes/rpc/rpc-types.d.ts +356 -3
  168. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  169. package/dist/modes/rpc/rpc-types.js +356 -3
  170. package/dist/modes/rpc/rpc-types.js.map +1 -1
  171. package/dist/modes/shared.d.ts +386 -0
  172. package/dist/modes/shared.d.ts.map +1 -0
  173. package/dist/modes/shared.js +543 -0
  174. package/dist/modes/shared.js.map +1 -0
  175. package/dist/utils/array.d.ts +389 -0
  176. package/dist/utils/array.d.ts.map +1 -0
  177. package/dist/utils/array.js +585 -0
  178. package/dist/utils/array.js.map +1 -0
  179. package/dist/utils/color-formatter.d.ts +318 -0
  180. package/dist/utils/color-formatter.d.ts.map +1 -0
  181. package/dist/utils/color-formatter.js +442 -0
  182. package/dist/utils/color-formatter.js.map +1 -0
  183. package/dist/utils/data-transformer.d.ts +326 -0
  184. package/dist/utils/data-transformer.d.ts.map +1 -0
  185. package/dist/utils/data-transformer.js +512 -0
  186. package/dist/utils/data-transformer.js.map +1 -0
  187. package/dist/utils/date-formatter.d.ts +281 -0
  188. package/dist/utils/date-formatter.d.ts.map +1 -0
  189. package/dist/utils/date-formatter.js +503 -0
  190. package/dist/utils/date-formatter.js.map +1 -0
  191. package/dist/utils/error-handler.d.ts +541 -0
  192. package/dist/utils/error-handler.d.ts.map +1 -0
  193. package/dist/utils/error-handler.js +726 -0
  194. package/dist/utils/error-handler.js.map +1 -0
  195. package/dist/utils/file-operations.d.ts +297 -0
  196. package/dist/utils/file-operations.d.ts.map +1 -0
  197. package/dist/utils/file-operations.js +505 -0
  198. package/dist/utils/file-operations.js.map +1 -0
  199. package/dist/utils/frontmatter.d.ts +268 -6
  200. package/dist/utils/frontmatter.d.ts.map +1 -1
  201. package/dist/utils/frontmatter.js +500 -21
  202. package/dist/utils/frontmatter.js.map +1 -1
  203. package/dist/utils/json-formatter.d.ts +259 -0
  204. package/dist/utils/json-formatter.d.ts.map +1 -0
  205. package/dist/utils/json-formatter.js +517 -0
  206. package/dist/utils/json-formatter.js.map +1 -0
  207. package/dist/utils/logger.d.ts +176 -0
  208. package/dist/utils/logger.d.ts.map +1 -0
  209. package/dist/utils/logger.js +346 -0
  210. package/dist/utils/logger.js.map +1 -0
  211. package/dist/utils/markdown-formatter.d.ts +211 -0
  212. package/dist/utils/markdown-formatter.d.ts.map +1 -0
  213. package/dist/utils/markdown-formatter.js +482 -0
  214. package/dist/utils/markdown-formatter.js.map +1 -0
  215. package/dist/utils/path-validator.d.ts +603 -0
  216. package/dist/utils/path-validator.d.ts.map +1 -0
  217. package/dist/utils/path-validator.js +870 -0
  218. package/dist/utils/path-validator.js.map +1 -0
  219. package/dist/utils/string-formatter.d.ts +609 -0
  220. package/dist/utils/string-formatter.d.ts.map +1 -0
  221. package/dist/utils/string-formatter.js +806 -0
  222. package/dist/utils/string-formatter.js.map +1 -0
  223. package/dist/utils/type-guards.d.ts +629 -0
  224. package/dist/utils/type-guards.d.ts.map +1 -0
  225. package/dist/utils/type-guards.js +662 -0
  226. package/dist/utils/type-guards.js.map +1 -0
  227. package/docs/COMPLETE-GUIDE.md +300 -0
  228. package/docs/COMPREHENSIVE-CLI-SUMMARY.md +900 -0
  229. package/docs/MODES-ARCHITECTURE.md +565 -0
  230. package/docs/PRINT-MODE-GUIDE.md +456 -0
  231. package/docs/RPC-GUIDE.md +705 -0
  232. package/docs/UTILS-IMPLEMENTATION-SUMMARY.md +647 -0
  233. package/docs/UTILS-MODULE-OVERVIEW.md +1480 -0
  234. package/docs/UTILS-QA-CHECKLIST.md +1061 -0
  235. package/docs/UTILS-USAGE-GUIDE.md +1419 -0
  236. package/package.json +7 -3
@@ -1,41 +1,240 @@
1
1
  /**
2
- * Process @file CLI arguments into text content and image attachments
2
+ * File Processor - Handle @file CLI arguments into text content and image attachments
3
+ *
4
+ * Responsibilities:
5
+ * - Parse @file arguments from CLI
6
+ * - Validate file existence and accessibility
7
+ * - Read text files and format for AI context
8
+ * - Process image files with optional resizing
9
+ * - Handle empty files gracefully
10
+ * - Provide clear error messages for file access issues
11
+ *
12
+ * Based on file handling patterns from indusagi-agent
13
+ * Original: https://github.com/varunisrani/indusagi-ts/vendor/indusagi-agent
14
+ *
15
+ * Adapted to:
16
+ * - Improve error messages
17
+ * - Add comprehensive documentation
18
+ * - Add file type validation
19
+ * - Add file size limit checks
20
+ * - Enhance security by validating file paths
3
21
  */
22
+ // ============================================================================
23
+ // IMPORTS
24
+ // ============================================================================
25
+ // Built-in modules
4
26
  import { access, readFile, stat } from "node:fs/promises";
5
- import chalk from "chalk";
6
27
  import { resolve } from "path";
28
+ import chalk from "chalk";
29
+ // Local module imports
7
30
  import { resolveReadPath } from "../core/tools/path-utils.js";
8
31
  import { formatDimensionNote, resizeImage } from "../utils/image-resize.js";
9
32
  import { detectSupportedImageMimeTypeFromFile } from "../utils/mime.js";
10
- /** Process @file arguments into text content and image attachments */
33
+ // ============================================================================
34
+ // CONSTANTS
35
+ // ============================================================================
36
+ /** Maximum file size for text files in bytes (10MB) */
37
+ const MAX_TEXT_FILE_SIZE = 10 * 1024 * 1024;
38
+ /** Maximum file size for images in bytes (20MB) */
39
+ const MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
40
+ /** Supported text file extensions */
41
+ const SUPPORTED_TEXT_EXTENSIONS = new Set([
42
+ ".txt",
43
+ ".md",
44
+ ".ts",
45
+ ".tsx",
46
+ ".js",
47
+ ".jsx",
48
+ ".json",
49
+ ".yaml",
50
+ ".yml",
51
+ ".xml",
52
+ ".html",
53
+ ".css",
54
+ ".py",
55
+ ".rs",
56
+ ".go",
57
+ ".java",
58
+ ".c",
59
+ ".cpp",
60
+ ".h",
61
+ ".hpp",
62
+ ".sh",
63
+ ".bash",
64
+ ".zsh",
65
+ ".fish",
66
+ ".ps1",
67
+ ".sql",
68
+ ".graphql",
69
+ ".gql",
70
+ ]);
71
+ /** Supported image MIME types */
72
+ const SUPPORTED_IMAGE_MIME_TYPES = new Set([
73
+ "image/jpeg",
74
+ "image/png",
75
+ "image/gif",
76
+ "image/webp",
77
+ ]);
78
+ // ============================================================================
79
+ // CUSTOM ERROR CLASSES
80
+ // ============================================================================
81
+ /**
82
+ * File processing error with helpful suggestions
83
+ *
84
+ * @class FileProcessError
85
+ * @extends {Error}
86
+ */
87
+ export class FileProcessError extends Error {
88
+ constructor(message, code, suggestion) {
89
+ super(message);
90
+ this.code = code;
91
+ this.suggestion = suggestion;
92
+ this.name = "FileProcessError";
93
+ }
94
+ }
95
+ // ============================================================================
96
+ // VALIDATION FUNCTIONS
97
+ // ============================================================================
98
+ /**
99
+ * Validate file extension against supported text files
100
+ *
101
+ * @param filePath - Path to the file
102
+ * @returns True if file has a supported text extension
103
+ */
104
+ function isSupportedTextFile(filePath) {
105
+ const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
106
+ return SUPPORTED_TEXT_EXTENSIONS.has(ext);
107
+ }
108
+ /**
109
+ * Check if MIME type is a supported image
110
+ *
111
+ * @param mimeType - The MIME type to check
112
+ * @returns True if MIME type is in supported image types
113
+ */
114
+ function isSupportedImageMimeType(mimeType) {
115
+ return SUPPORTED_IMAGE_MIME_TYPES.has(mimeType);
116
+ }
117
+ /**
118
+ * Validate file size against limits
119
+ *
120
+ * @param filePath - Path to the file (for error messages)
121
+ * @param size - File size in bytes
122
+ * @param mimeType - Optional MIME type for determining which limit to apply
123
+ * @throws {FileProcessError} If file size exceeds limit
124
+ */
125
+ function validateFileSize(filePath, size, mimeType) {
126
+ const maxSize = mimeType && isSupportedImageMimeType(mimeType)
127
+ ? MAX_IMAGE_FILE_SIZE
128
+ : MAX_TEXT_FILE_SIZE;
129
+ if (size > maxSize) {
130
+ const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(1);
131
+ throw new FileProcessError(`File too large: ${filePath} (${(size / (1024 * 1024)).toFixed(1)}MB, max ${maxSizeMB}MB)`, "FILE_TOO_LARGE", "Consider compressing the file or splitting it into smaller parts");
132
+ }
133
+ }
134
+ // ============================================================================
135
+ // MAIN PROCESSING FUNCTIONS
136
+ // ============================================================================
137
+ /**
138
+ * Process @file arguments into text content and image attachments
139
+ *
140
+ * This function:
141
+ * 1. Resolves and validates each file path
142
+ * 2. Checks file existence and accessibility
143
+ * 3. Skips empty files
144
+ * 4. Detects file type (text or image)
145
+ * 5. Reads and formats text files with <file> tags
146
+ * 6. Processes images with optional resizing
147
+ * 7. Validates file sizes
148
+ *
149
+ * @param fileArgs - Array of file argument strings (from @file syntax)
150
+ * @param options - Processing options including image resize behavior
151
+ * @returns ProcessedFiles object with formatted text and image attachments
152
+ *
153
+ * @throws {FileProcessError} If file not found, cannot be read, or exceeds size limit
154
+ * @throws {Error} If image processing fails
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const result = await processFileArguments(["prompt.md", "image.png"], {
159
+ * autoResizeImages: true
160
+ * });
161
+ * // Returns: { text: "<file name=\"...\">...</file>\n...", images: [...] }
162
+ * ```
163
+ */
11
164
  export async function processFileArguments(fileArgs, options) {
12
165
  const autoResizeImages = options?.autoResizeImages ?? true;
13
166
  let text = "";
14
167
  const images = [];
15
168
  for (const fileArg of fileArgs) {
16
- // Expand and resolve path (handles ~ expansion and macOS screenshot Unicode spaces)
169
+ // ========================================================================
170
+ // PATH RESOLUTION AND VALIDATION
171
+ // ========================================================================
172
+ /**
173
+ * Expand and resolve path
174
+ * Handles:
175
+ * - ~ expansion to home directory
176
+ * - macOS screenshot Unicode spaces
177
+ * - Relative to absolute path conversion
178
+ */
17
179
  const absolutePath = resolve(resolveReadPath(fileArg, process.cwd()));
18
- // Check if file exists
180
+ /**
181
+ * Check if file exists
182
+ * Fails early with clear error message if file doesn't exist
183
+ */
19
184
  try {
20
185
  await access(absolutePath);
21
186
  }
22
187
  catch {
23
- console.error(chalk.red(`Error: File not found: ${absolutePath}`));
24
- process.exit(1);
188
+ throw new FileProcessError(`File not found: ${absolutePath}`, "FILE_NOT_FOUND", `Check that the file exists: ls -la "${absolutePath}"`);
25
189
  }
26
- // Check if file is empty
190
+ // ========================================================================
191
+ // FILE STATS AND VALIDATION
192
+ // ========================================================================
193
+ /**
194
+ * Get file statistics
195
+ * Used to check file size and detect empty files
196
+ */
27
197
  const stats = await stat(absolutePath);
198
+ /**
199
+ * Skip empty files
200
+ * Empty files provide no useful context
201
+ */
28
202
  if (stats.size === 0) {
29
- // Skip empty files
203
+ console.warn(chalk.yellow(`Warning: Skipping empty file: ${absolutePath}`));
30
204
  continue;
31
205
  }
206
+ // ========================================================================
207
+ // FILE TYPE DETECTION
208
+ // ========================================================================
209
+ /**
210
+ * Detect MIME type to determine file type
211
+ * Returns undefined for non-image (text) files
212
+ */
32
213
  const mimeType = await detectSupportedImageMimeTypeFromFile(absolutePath);
33
- if (mimeType) {
34
- // Handle image file
214
+ // ========================================================================
215
+ // FILE SIZE VALIDATION
216
+ // ========================================================================
217
+ /**
218
+ * Validate file size before processing
219
+ * Prevents loading excessively large files into memory
220
+ */
221
+ validateFileSize(absolutePath, stats.size, mimeType ?? undefined);
222
+ // ========================================================================
223
+ // IMAGE FILE PROCESSING
224
+ // ========================================================================
225
+ if (mimeType && isSupportedImageMimeType(mimeType)) {
226
+ /**
227
+ * Read image file contents
228
+ */
35
229
  const content = await readFile(absolutePath);
36
230
  const base64Content = content.toString("base64");
37
231
  let attachment;
38
232
  let dimensionNote;
233
+ /**
234
+ * Optionally resize image
235
+ * Resizes to max 2000x2000 while maintaining aspect ratio
236
+ * This reduces token usage and improves performance
237
+ */
39
238
  if (autoResizeImages) {
40
239
  const resized = await resizeImage({ type: "image", data: base64Content, mimeType });
41
240
  dimensionNote = formatDimensionNote(resized);
@@ -46,14 +245,24 @@ export async function processFileArguments(fileArgs, options) {
46
245
  };
47
246
  }
48
247
  else {
248
+ /**
249
+ * Use original image without resizing
250
+ */
49
251
  attachment = {
50
252
  type: "image",
51
253
  mimeType,
52
254
  data: base64Content,
53
255
  };
54
256
  }
257
+ /**
258
+ * Add image to attachments array
259
+ */
55
260
  images.push(attachment);
56
- // Add text reference to image with optional dimension note
261
+ /**
262
+ * Add text reference to image
263
+ * Includes dimension note if image was resized
264
+ * Format: <file name="/path/to/file.png">[resized to XxY]</file>
265
+ */
57
266
  if (dimensionNote) {
58
267
  text += `<file name="${absolutePath}">${dimensionNote}</file>\n`;
59
268
  }
@@ -61,16 +270,32 @@ export async function processFileArguments(fileArgs, options) {
61
270
  text += `<file name="${absolutePath}"></file>\n`;
62
271
  }
63
272
  }
273
+ // ========================================================================
274
+ // TEXT FILE PROCESSING
275
+ // ========================================================================
64
276
  else {
65
- // Handle text file
277
+ /**
278
+ * Validate file has a supported text extension
279
+ * Prevents processing binary files as text
280
+ */
281
+ if (!isSupportedTextFile(absolutePath)) {
282
+ console.warn(chalk.yellow(`Warning: File may not be text: ${absolutePath}. Attempting to read as text...`));
283
+ }
284
+ /**
285
+ * Read text file contents
286
+ * Uses UTF-8 encoding
287
+ */
66
288
  try {
67
289
  const content = await readFile(absolutePath, "utf-8");
68
290
  text += `<file name="${absolutePath}">\n${content}\n</file>\n`;
69
291
  }
70
292
  catch (error) {
293
+ /**
294
+ * Handle read errors with helpful message
295
+ * Includes suggestion for common issues
296
+ */
71
297
  const message = error instanceof Error ? error.message : String(error);
72
- console.error(chalk.red(`Error: Could not read file ${absolutePath}: ${message}`));
73
- process.exit(1);
298
+ throw new FileProcessError(`Could not read file ${absolutePath}: ${message}`, "READ_ERROR", "Check file permissions and ensure it's a text file");
74
299
  }
75
300
  }
76
301
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../../src/cli/file-processor.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,69 @@
1
1
  /**
2
- * List available models with optional fuzzy search
2
+ * Model List Formatter - Display available models with optional filtering
3
+ *
4
+ * Responsibilities:
5
+ * - Retrieve available models from model registry
6
+ * - Apply fuzzy search filtering
7
+ * - Sort models by provider and ID
8
+ * - Format model information in a readable table
9
+ * - Display model capabilities (context, max output, thinking, images)
10
+ *
11
+ * Based on model listing patterns from indusagi-agent
12
+ * Original: https://github.com/varunisrani/indusagi-ts/vendor/indusagi-agent
13
+ *
14
+ * Adapted to:
15
+ * - Improve display formatting
16
+ * - Add comprehensive documentation
17
+ * - Add model filtering options
18
+ * - Add model capability indicators
19
+ * - Enhance UX with better sorting
3
20
  */
4
21
  import type { ModelRegistry } from "../core/model-registry.js";
5
22
  /**
6
- * List available models, optionally filtered by search pattern
23
+ * Model filtering options
24
+ *
25
+ * @interface ModelFilterOptions
26
+ * @property {string} [provider] - Filter by provider name
27
+ * @property {boolean} [thinkingOnly] - Only show models with reasoning/thinking capability
28
+ * @property {boolean} [imageSupport] - Only show models with image input support
29
+ * @property {string} [searchPattern] - Fuzzy search pattern for model IDs and providers
7
30
  */
8
- export declare function listModels(modelRegistry: ModelRegistry, searchPattern?: string): Promise<void>;
31
+ export interface ModelFilterOptions {
32
+ provider?: string;
33
+ thinkingOnly?: boolean;
34
+ imageSupport?: boolean;
35
+ searchPattern?: string;
36
+ }
37
+ /**
38
+ * List available models, optionally filtered by search pattern or criteria
39
+ *
40
+ * This function:
41
+ * 1. Retrieves available models from the registry
42
+ * 2. Applies any requested filters (provider, thinking, images, search)
43
+ * 3. Sorts models by provider and ID
44
+ * 4. Formats model information into a readable table
45
+ * 5. Displays the table to stdout
46
+ *
47
+ * The table shows:
48
+ * - Provider name
49
+ * - Model ID
50
+ * - Context window size
51
+ * - Max output tokens
52
+ * - Thinking/reasoning capability
53
+ * - Image input support
54
+ *
55
+ * @param modelRegistry - Model registry instance
56
+ * @param searchPattern - Optional fuzzy search pattern for model IDs/providers
57
+ * @returns Promise that resolves when listing is complete
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // List all models
62
+ * await listModels(modelRegistry);
63
+ *
64
+ * // List models matching "sonnet"
65
+ * await listModels(modelRegistry, "sonnet");
66
+ * ```
67
+ */
68
+ export declare function listModels(modelRegistry: ModelRegistry, searchPattern?: string | ModelFilterOptions): Promise<void>;
9
69
  //# sourceMappingURL=list-models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list-models.d.ts","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAiB/D;;GAEG;AACH,wBAAsB,UAAU,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6EpG"}
1
+ {"version":3,"file":"list-models.d.ts","sourceRoot":"","sources":["../../src/cli/list-models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAM/D;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAsID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,UAAU,CAC/B,aAAa,EAAE,aAAa,EAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,kBAAkB,GACzC,OAAO,CAAC,IAAI,CAAC,CA+Hf"}