shoud-cli 1.0.10 → 1.0.11

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/tools/index.js +56 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shoud-cli",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "SHOUD Terminal Agent: Give your computer a job.",
5
5
  "main": "bin/shoud.js",
6
6
  "bin": {
@@ -112,4 +112,60 @@ function executeTool(toolName, input) {
112
112
  }
113
113
  }
114
114
 
115
+ /**
116
+ * Read an image/video file and return a data URL for Gemini.
117
+ */
118
+ function readImage(filePath) {
119
+ const safePath = sanitizePath(filePath);
120
+ try {
121
+ const stats = fs.statSync(safePath);
122
+ if (!stats.isFile()) throw new Error('Path is not a file.');
123
+ const buffer = fs.readFileSync(safePath);
124
+ const base64 = buffer.toString('base64');
125
+ const mimeType = getMimeType(safePath); // you need to define this helper
126
+ return `data:${mimeType};base64,${base64}`;
127
+ } catch (err) {
128
+ throw new Error(`Failed to read image: ${err.message}`);
129
+ }
130
+ }
131
+
132
+ // Helper: determine MIME type from file extension
133
+ function getMimeType(filePath) {
134
+ const ext = path.extname(filePath).toLowerCase();
135
+ const map = {
136
+ '.jpg': 'image/jpeg',
137
+ '.jpeg': 'image/jpeg',
138
+ '.png': 'image/png',
139
+ '.gif': 'image/gif',
140
+ '.webp': 'image/webp',
141
+ '.mp4': 'video/mp4',
142
+ '.mov': 'video/quicktime',
143
+ '.avi': 'video/x-msvideo',
144
+ '.webm': 'video/webm',
145
+ '.mkv': 'video/x-matroska',
146
+ '.pdf': 'application/pdf',
147
+ };
148
+ return map[ext] || 'application/octet-stream';
149
+ }
150
+
151
+ // In executeTool, add:
152
+ function executeTool(toolName, input) {
153
+ try {
154
+ switch (toolName) {
155
+ case 'execute_shell':
156
+ return executeShell(input.command);
157
+ case 'read_file':
158
+ return readFile(input.path);
159
+ case 'write_file':
160
+ return writeFile(input.path, input.content);
161
+ case 'read_image': // new
162
+ return readImage(input.path);
163
+ default:
164
+ throw new Error(`Tool "${toolName}" is not supported.`);
165
+ }
166
+ } catch (error) {
167
+ return `Tool execution failed: ${error.message}`;
168
+ }
169
+ }
170
+
115
171
  module.exports = { executeTool };