shoud-cli 1.0.8 → 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.
package/bin/shoud.js CHANGED
@@ -15,7 +15,7 @@ const BANNER_ART = [
15
15
  " ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ "
16
16
  ];
17
17
 
18
- // ─── Static Banner (no animation) ──────────────────────────
18
+ // ─── Static Banner (prints at the start of commands) ──────
19
19
  function printStaticBanner() {
20
20
  const color = chalk.hex('#B5F96C');
21
21
  console.log(color(BANNER_ART.join('\n')));
@@ -95,7 +95,7 @@ async function main() {
95
95
  args[0] === 'help' || args[0] === '--help' || args[0] === '-h' ||
96
96
  args[0] === '--version' || args[0] === '-v') {
97
97
  if (args[0] === '--version' || args[0] === '-v') {
98
- program.version('1.0.6');
98
+ program.version('1.0.9');
99
99
  program.parse(process.argv);
100
100
  return;
101
101
  }
@@ -105,13 +105,16 @@ async function main() {
105
105
  }
106
106
 
107
107
  program
108
- .version('1.0.6')
108
+ .version('1.0.9')
109
109
  .description('SHOUD Terminal Agent');
110
110
 
111
111
  program
112
112
  .command('login')
113
113
  .description('Authenticate this device with your SHOUD account')
114
- .action(login);
114
+ .action(() => {
115
+ // Optionally show banner before login? We'll keep it clean.
116
+ login();
117
+ });
115
118
 
116
119
  // Placeholder for status
117
120
  program
@@ -129,9 +132,10 @@ async function main() {
129
132
  return;
130
133
  }
131
134
  const taskPrompt = promptArr.join(' ');
132
- await executeTask(taskPrompt);
133
- // ✅ After task completes, show the static banner
135
+ // ✅ Show the static banner at the start
134
136
  printStaticBanner();
137
+ await executeTask(taskPrompt);
138
+ // No banner at the end (removed)
135
139
  });
136
140
 
137
141
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shoud-cli",
3
- "version": "1.0.8",
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 };