@j-o-r/hello-dave 0.0.0 → 0.0.2

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/hdCode.js CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import AgentManager from '../lib/AgentManager.js';
3
3
  import { parseArgs, readIn } from '@j-o-r/sh';
4
- import { systemInfo } from '../lib/fafs.js';
5
4
 
6
5
  const name = 'hdCode';
7
6
  const api = 'grok';
@@ -49,7 +48,7 @@ OPTIONS:
49
48
  --model [grok-4|grok-3|grok-3-mini|grok-3-mini-fast|grok-code-fast-1]
50
49
  --top_p [float]: number > 0, 0.1 means no top_p
51
50
  --reasoning [low|high]
52
- --tools [javascript,bash] comma seperated list
51
+ --tools [javascript,bash,nushell,ssh] comma seperated list
53
52
  e.g.
54
53
  grok.js --model grok-3-mini --tokens 4000 --context 10000
55
54
 
@@ -61,15 +60,14 @@ if (help) {
61
60
  printHelp();
62
61
  }
63
62
 
64
- const sys = await systemInfo();
63
+ const agent = new AgentManager({ name });
64
+ const sys = (await agent.environment()).system;
65
65
  const prompt = `
66
- You are a coding assistant specializing in Bash and JavaScript (ESM/ESNext), with support for other languages. Assist by executing, reading, creating, querying, explaining, or helping with code. Use tools like 'execute_bash_script' for safe Bash execution. For writing and reading files, stay in the current working folder. Provide clear, step-by-step responses, examples, and ensure safety compliance.
67
- Update your 'memory' frequently.
66
+ You are a coding assistant specializing in Bash and JavaScript (ESM/ESNext), with support for other languages. Assist by executing, reading, creating, querying, explaining, or helping with code. Use tools like 'execute_bash_script' for code execution and for writing and reading files, stay in the current working folder. Provide clear, step-by-step responses, examples, and ensure safety compliance.
68
67
  ---env
69
68
  ${sys}
70
69
  ---
71
70
  `.trim();
72
- const agent = new AgentManager({ name });
73
71
  agent.setup({
74
72
  prompt,
75
73
  api,
@@ -77,6 +75,7 @@ agent.setup({
77
75
  toolsetMode,
78
76
  contextWindow
79
77
  });
78
+
80
79
  const toolset = agent.getToolset();
81
80
  if (toolset) {
82
81
  const addTools = (args['tools']) ? args['tools'].split(',') : ['bash'];
@@ -86,6 +85,12 @@ if (toolset) {
86
85
  if (addTools.includes('bash')) {
87
86
  agent.addGenericToolcall('execute_bash_script');
88
87
  }
88
+ if (addTools.includes('nushell')) {
89
+ agent.addGenericToolcall('execute_nushell_script');
90
+ }
91
+ if (addTools.includes('ssh')) {
92
+ agent.addGenericToolcall('execute_remote_script');
93
+ }
89
94
  }
90
95
  const cliIntro = `
91
96
  ${name} ${options.model}.
@@ -93,7 +98,7 @@ ${name} ${options.model}.
93
98
  - context: ${contextWindow}
94
99
  `.trim();
95
100
  const description = `
96
- Gateway to a specialized coding assistant for Bash, JavaScript (ESM/ESNext), and other languages. Handles execution, reading, creation, querying, explaining, and code help, with safety and folder restrictions.
101
+ Handles execution, reading, creation, querying, explaining and code help, with safety and folder restrictions.
97
102
  `.trim();
98
103
 
99
104
  if (input === '' && serve) {
@@ -343,7 +343,7 @@ const parseMessages = (response, prompt) => {
343
343
  /**
344
344
  * Process an openai response
345
345
  * @param {number} duration - the time is MS before and after the request
346
- * @param {import('lib/request.js').FetchResponse} res
346
+ * @param {import('@j-o-r/apiserver/types/request.js').FetchResponseObject} res
347
347
  * @param {Prompt} prompt
348
348
  * @param {ToolSet} [toolset]
349
349
  * @returns {Promise<void>}
package/lib/Cli.js CHANGED
@@ -155,6 +155,7 @@ class Cli {
155
155
  }
156
156
  }
157
157
  }
158
+ cli.startSpinner();
158
159
  });
159
160
  this.#prompt.on('truncated', () => {
160
161
  cli.focus('log');
package/lib/fafs.js CHANGED
@@ -67,6 +67,7 @@ async function env() {
67
67
  if (info) {
68
68
  const res = JSON.parse(info);
69
69
  res.cwd = cwd;
70
+ res.system = await systemInfo();
70
71
  return res;
71
72
  }
72
73
  const name = (await SH`getent passwd "$USER" | cut -d: -f5`.run()).replaceAll(',',' ').trim();
@@ -2,7 +2,7 @@ import { SH } from '@j-o-r/sh'
2
2
  import { ToolSet, env } from './index.js'
3
3
 
4
4
  const user = await env();
5
- const environment =`
5
+ const environment = `
6
6
  Name: ${user.name}
7
7
  System: ${user.system}
8
8
  City: ${user.city}
@@ -129,6 +129,28 @@ ${delim}
129
129
  `.run()
130
130
  }
131
131
  );
132
+ /*
133
+ ### nu shell Assumptions and Prerequisites
134
+ - You can install it via your package manager (e.g., on Ubuntu: `sudo apt install nushell` or download from the [official Nushell releases](https://github.com/nushell/nushell/releases)).
135
+ - The tool will use a heredoc approach (similar to the Bash tool) to pass the script content to `nu` for execution. This ensures multi-line scripts work reliably.
136
+ - The output from `nu` will be returned as-is, preserving its structured format (e.g., tables or JSON), which is beneficial for LLM consumption.o
137
+ */
138
+ tools.add(
139
+ 'execute_nushell_script',
140
+ 'Execute a Nushell script.',
141
+ {
142
+ type: 'object',
143
+ properties: {
144
+ nushell_script: { type: 'string', description: `The Nushell script to execute (${user.system})` }
145
+ },
146
+ required: ['nushell_script']
147
+ },
148
+ async (params) => {
149
+ const script = bashEscape(params.nushell_script);
150
+ return await SH`nu -c "${script}"`.run()
151
+ }
152
+ );
153
+
132
154
  tools.add(
133
155
  'send_email',
134
156
  'Send an email.',
@@ -166,5 +188,47 @@ tools.add(
166
188
  return await SH`xdg-open ${[params.url]}`.run();
167
189
  }
168
190
  );
169
- export default tools
191
+ tools.add(
192
+ 'execute_remote_script',
193
+ 'Execute a script (bash, nu, python, javascript) on a remote machine via SSH. Default type: nu.',
194
+ {
195
+ type: 'object',
196
+ properties: {
197
+ type: { type: 'string', enum: ['bash','nu','python','javascript'], description: 'Type of script (default: bash)' },
198
+ url: { type: 'string', description: 'SSH URL, e.g., ssh://user@host or ssh://user@host:port' },
199
+ script: { type: 'string', description: 'The script code to execute remotely' }
200
+ },
201
+ required: ['url', 'script']
202
+ },
203
+ async (params) => {
204
+ const { url, type = 'bash', script } = params;
205
+ if (!url.startsWith('ssh://')) throw new Error('Invalid SSH URL');
206
+ const withoutProto = url.slice(6);
207
+ const parts = withoutProto.split(':');
208
+ let port = 22;
209
+ let userHost = withoutProto;
210
+ if (parts.length > 1) {
211
+ userHost = parts[0];
212
+ port = parseInt(parts[1]);
213
+ }
214
+ const [user, host] = userHost.split('@');
215
+ if (!user || !host) throw new Error('Invalid SSH URL format');
216
+ let command;
217
+ if (type === 'nu') {
218
+ const escaped = bashEscape(script);
219
+ command = `nu -c "${escaped}"`;
220
+ } else {
221
+ const interpreters = { bash: 'bash', python: 'python3', javascript: 'node' };
222
+ const interpreter = interpreters[type];
223
+ if (!interpreter) throw new Error('Unsupported type');
224
+ const delim = `END_REMOTE_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
225
+ command = `${interpreter} <<'${delim}'
226
+ ${script}
227
+ ${delim}
228
+ `;
229
+ }
230
+ return await SH`ssh -p ${port} ${user}@${host} '${command}'`.run()
231
+ }
232
+ );
170
233
 
234
+ export default tools
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@j-o-r/hello-dave",
3
3
  "type": "module",
4
- "version": "0.0.0",
4
+ "version": "0.0.2",
5
5
  "description": "ESM toolkit for building AI agents with unified access to Grok, OpenAI, and Anthropic endpoints",
6
6
  "main": "lib/AgentManager.js",
7
7
  "types": "types/AgentManager.d.ts",
@@ -268,13 +268,13 @@ export function generateRequest(prompt: Prompt, tools?: void | import("../../Too
268
268
  /**
269
269
  * Process an openai response
270
270
  * @param {number} duration - the time is MS before and after the request
271
- * @param {import('lib/request.js').FetchResponse} res
271
+ * @param {import('@j-o-r/apiserver/types/request.js').FetchResponseObject} res
272
272
  * @param {Prompt} prompt
273
273
  * @param {ToolSet} [toolset]
274
274
  * @returns {Promise<void>}
275
275
  * @throws {Error}
276
276
  */
277
- export function parseResponse(duration: number, prompt: Prompt, res: any, toolset?: ToolSet): Promise<void>;
277
+ export function parseResponse(duration: number, prompt: Prompt, res: import("@j-o-r/apiserver/types/request.js").FetchResponseObject, toolset?: ToolSet): Promise<void>;
278
278
  /**
279
279
  * Do a request
280
280
  * @param {Prompt} prompt